Python Redirect not working

2019-07-26 18:32发布

问题:

I'm trying to redirect the user to my homepage. Its suppose to be as simple as

print "Location:http://localhost:8000/index.html"
print ""

This isn't working for some reason. I'm running CGIHTTPServer on Kali Linux. I'm using Python 2.7.3 When I try to run the script it simply prints out

Location:http://localhost:8000/index.html

I have also tried using 127.0.0.1 instead of localhost. It doesn't work either.Here is the CGI script that I'm trying to run

#!/usr/bin/python
import MySQLdb,cgi, os, sys
db=MySQLdb.connect(host="localhost", user="root", passwd="", db="test")
flag=False
query = db.cursor()
sys.stdout.write("Content-type: text/html\r\n\r\n")
sys.stdout.write("")
sys.stdout.write("<html><body>")
form = cgi.FieldStorage()
name = form.getvalue('temp')
passwd = form.getvalue('temp2')

if(query.execute("select * from cred where uname='"+name+"' and pass='"+passwd+"'")):
    db.commit()
    sys.stdout.write("Hello "+name)

else:
    db.commit()
    flag=True
sys.stdout.write("</body></html>")

if(flag == True):
    print "Location:http://localhost:8000/"
    print ""

回答1:

You have 2 problems here:

  1. You always write the Content-Type header plus extra newlines at the start. You've now completed all headers and you can no longer add more.

    Write these headers only when you are not redirecting.

  2. A Location header is only used for redirects, a status 30x HTTP response. You'll need to add a Status: header to signal to the web server to respond with a status other than 200.

Adjusting your code to address these issues:

#!/usr/bin/python
import cgitb
cgitb.enable()

import MySQLdb, cgi, os, sys

db = MySQLdb.connect(host="localhost", user="root", passwd="", db="test")

form = cgi.FieldStorage()
name = form.getvalue('temp')
passwd = form.getvalue('temp2')

with db as query:
    query.execute("select * from cred where uname=%s and %s", (name, passwd))
    result = query.fetchone()

if result is None:
    # no such user, redirect
    print 'Status: 302 Found'
    print 'Location: http://localhost:8000/'
    print

else:
    print 'Content-type: text/html'
    print
    print '<html><body>Hello {}</body></html>'.format(name)

Note that I altered the code somewhat to use some best practices:

  1. NEVER use string interpolation to put user-information into a SQL query. You'll get hammered by a SQL injection attack that way. Use SQL parameters to have the database driver escape the values for you.

  2. You can use the connection as a context manager to auto-commit.

  3. I used string formatting to produce the HTML output.



回答2:

As the accepted answer states, you'll need a Status: 302 Found or Status: 301 Moved Permanently header along with the Location header to do your redirect properly.

Also, the Python built-in CGIHTTPServer "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." (https://docs.python.org/2/library/cgihttpserver.html)

Unfortunately this is also the case in Python 3. (https://docs.python.org/3/library/http.server.html#http.server.CGIHTTPRequestHandler)

There's a ticket about it (http://bugs.python.org/issue10487) but as of right now, there's no way to use the Status header. This shouldn't be a problem with other CGI servers.



标签: python cgi