Call redirect func from BaseHTTPRequestHandler

838 views Asked by At

I have a class which extends from BaseHTTPRequestHandler:

class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
    # send headers
    self.send_response(200)
    self.send_header('Content-type', 'text/html; charset=utf-8')
    self.end_headers()
    if re.findall(r'^/favicon.ico$', self.path) \
        or re.findall(r'^/public/.*$', self.path):
        pass
    else:
        run = Router(self.path)
        data = run.run_action()
        print(data)
        self.wfile.write(data.encode())

def do_POST(self):
    length = int(self.headers.get('Content-length', 0))
    data = self.rfile.read(length).decode()
    message = clean(parse_qs(data))
    self.send_response(200)
    self.send_header('Content-type', 'text/html; charset=utf-8')
    self.end_headers()
    if re.findall(r'^/favicon.ico$', self.path) \
            or re.findall(r'^/public/.*$', self.path):
        pass
    else:
        run = Router(self.path, message)
        data = run.run_action()
        self.wfile.write(data.encode())

def redirect(self, url):
    self.send_response(302)
    self.send_header('Location', url)
    self.end_headers()

I want to create function for redirect user. For example, after submit POST. How can I call redirect function outside this class?

P.S: I found a decision with analyze input data. I made changes to the code the following way:

class Handler(http.server.BaseHTTPRequestHandler):
def send_headers(self, status, content_type, value):
    self.send_response(status)
    self.send_header(content_type, value)
    self.end_headers()

def do_GET(self):
    if re.findall(r'^/favicon.ico$', self.path) \
            or re.findall(r'^/public/.*$', self.path):
        pass
    else:
        run = Router(self.path)

        data = run.run_action()
        uri = re.findall(r"'Location': '([\/a-z0-9-]+)'", data)
        if bool(uri):
            self.redirect(uri[0])
            run = Router(uri[0])
            data = run.run_action()
            self.wfile.write(data.encode())
        else:
            self.send_headers(200, 'Content-type',
                              'text/html; charset=utf-8')
            self.wfile.write(data.encode())

def do_POST(self):
    length = int(self.headers.get('Content-length', 0))
    data = self.rfile.read(length).decode()
    message = clean(parse_qs(data))
    self.send_headers(200, 'Content-type', 'text/html; charset=utf-8')

    if re.findall(r'^/favicon.ico$', self.path) \
            or re.findall(r'^/public/.*$', self.path):
        pass
    else:
        run = Router(self.path, message)
        data = run.run_action()
        self.wfile.write(data.encode())

def redirect(self, url):
    self.send_headers(302, 'Location', url)

function the redirect looks like:

def redirect(url):
   return "'Location': '{}'".format(url)

Decision is working, but maybe someone can offer a better way?

I found in python doc

Note CGI scripts run by the CGIHTTPRequestHandler class cannot execute redirects (HTTP code 302), because code 200 (script output follows) is sent prior to execution of the CGI script. This pre-empts the status code.

0

There are 0 answers