I'm trying to create a simple http server with basic GET and POST functionality. The program is supposed to GET requests by printing out a simple webpage that greets a user and askes how he would rather be greeted. When the user enters a greeting of his choice, the webpage should now greet him as he had chosen.
While GET seems to be working fine, POST is not. I tried debugging by printing at every code execution and it seems to be getting stuck here:
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
I'll paste the code full code below, along with my terminal output.
Code:
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
class webServerHandler(BaseHTTPRequestHandler):
def do_GET(self):
try:
if self.path.endswith("/hello"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>"
output += "<h1>Hello!</h1>"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output += "</body></html>"
self.wfile.write(output.encode(encoding = 'utf_8'))
print (output)
return
if self.path.endswith("/hola"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>"
output += "<h1>¡ Hola !</h1>"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output += "</body></html>"
self.wfile.write(output.encode(encoding = 'utf_8'))
print (output)
return
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
def do_POST(self):
try:
self.send_response(201)
print("Sent response")
self.send_header('Content-type', 'text/html')
print("Sent headers")
self.end_headers()
print("Ended header")
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
print("Parsed headers")
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
print("Receiver message content")
output = ""
output += "<html><body>"
output += " <h2> Okay, how about this: </h2>"
output += "<h1> %s </h1>" % messagecontent[0]
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output += "</body></html>"
print(output)
self.wfile.write(output.encode(encoding = 'utf_8'))
print ("Wrote through CGI")
except:
pass
def main():
try:
port = 8080
server = HTTPServer(('', port), webServerHandler)
print ("Web Server running on port", port)
server.serve_forever()
except KeyboardInterrupt:
print (" ^C entered, stopping web server....")
server.socket.close()
if __name__ == '__main__':
main()
Terminal Output:
Web Server running on port 8080
127.0.0.1 - - [28/Apr/2016 13:28:59] "GET /hello HTTP/1.1" 200 -
<html><body><h1>Hello!</h1><form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form></body></html>
127.0.0.1 - - [28/Apr/2016 13:29:09] "POST /hello HTTP/1.1" 201 -
Sent response
Sent headers
Ended header
As you can see, the POST function does not seem to go beyong the parse_header command. I cannot figure this out, and any help would be usefu!
It's too late now. However, I will still post this answer, as I was facing the same issue while following an online tutorial. Hope, this will help someone if someone stumble upon the same issue.
In the tutorial, the instructor was using python 2 and I was using python 3.6.
Changelog compared to what instructor said:
Here, is a copy of the working code
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
class webserverHandler(BaseHTTPRequestHandler):
"""docstring for webserverHandler"""
def do_GET(self):
try:
if self.path.endswith("/hello"):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
output = ""
output += '<html><body>Hello!'
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
return
if self.path.endswith("/hola"):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
output = ""
output += '<html><body>¡Hola <a href="/hello">Back to Hello</a>'
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
return
except IOError:
self.send_error(404, "File not found %s" % self.path)
def do_POST(self):
try:
self.send_response(301)
self.send_header('Content-Type', 'text/html')
self.end_headers()
ctype, pdict = cgi.parse_header(self.headers.get('Content-Type'))
pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
output = ''
output += '<html><body>'
output += '<h2> Okay, how about this: </h2>'
output += '<h1> %s </h1>' % messagecontent[0].decode("utf-8")
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
except:
self.send_error(404, "{}".format(sys.exc_info()[0]))
print(sys.exc_info())
def main():
try:
port = 8000
server = HTTPServer(('', port), webserverHandler)
print("Web server running on port %s" % port)
server.serve_forever()
except KeyboardInterrupt:
print(" ^C entered stopping web server...")
server.socket.close()
if __name__ == '__main__':
main()
In addition to Arpit Jain's answer, I have to add content_len = int(self.headers.get('Content-length'))
and pdict['CONTENT-LENGTH'] = content_len
to make it work.
Below is the full code,
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
import sys
class webserverHandler(BaseHTTPRequestHandler):
"""docstring for webserverHandler"""
def do_GET(self):
try:
if self.path.endswith("/hello"):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
output = ""
output += '<html><body>Hello!'
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
return
if self.path.endswith("/hola"):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
output = ""
output += '<html><body>¡Hola <a href="/hello">Back to Hello</a>'
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
return
except IOError:
self.send_error(404, "File not found %s" % self.path)
def do_POST(self):
try:
self.send_response(301)
self.send_header('Content-Type', 'text/html')
self.end_headers()
ctype, pdict = cgi.parse_header(self.headers.get('Content-Type'))
content_len = int(self.headers.get('Content-length'))
pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
pdict['CONTENT-LENGTH'] = content_len
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
message_content = fields.get('message')
output = ''
output += '<html><body>'
output += '<h2> Okay, How about this: </h2>'
output += '<h1> %s </h1>' % message_content[0]
output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
output += '</body></html>'
self.wfile.write(output.encode())
print(output)
except:
self.send_error(404, "{}".format(sys.exc_info()[0]))
print(sys.exc_info())
def main():
try:
port = 8080
server = HTTPServer(('', port), webserverHandler)
print("Web server running on port %s" % port)
server.serve_forever()
except KeyboardInterrupt:
print(" ^C entered stopping web server...")
server.socket.close()
if __name__ == '__main__':
main()
I was able to run your code properly, and get POST to work, after making the following change:
You have:
from http.server
Change that to:
from BaseHTTPServer
And it should work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.