Search code examples
pythonhttpserver

HTTP web server POST returning blank page (Python)


I have been facing some difficulty for the better part of today and I finally decided to come over to this fantastic community for help.

I am learning full-stack principles using Python. My issue is creating working with a HTTP server. The idea is to have an 'echo page', meaning, there is a HTML input field, and any text submitted through this field is echoed back.

The HTML input field is rendered by the server's do_GET, and an echo page is returned using the server's do_POST

Following a tutorial on the principles of HTTP, here is some code I wrote to execute a do_GET using Python's http.server module. (I must add that I am using Python 3.9, and I learned that I had to change the imported modules from this:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

to this:

from http.server import BaseHTTPRequestHandler, HTTPServer

I also leaned that using version 3.X of Python, I needed to encode() the wfile.write() content. These are the tweaks that allowed the do_GET method to work.

Here is my full script:

import cgi
from http.server import BaseHTTPRequestHandler, HTTPServer


class serverHandler(BaseHTTPRequestHandler):
 def do_GET(self):
     if self.path.endswith('/hello'):
         self.send_response(200)
         self.send_header('Content-type', 'text/html')
         self.end_headers()

         output = ""
         output += "<html><body> Hey There!"
         output += "<form method='POST' enctype='multipart/form-data' action='/hello'>"
         output += "<h2> What would you like me to say?</h2>"
         output += "<input name = 'message' type = 'text' />"
         output += "<input type = 'submit' value = 'Submit'/>"
         output += "</form>"

         output += "</body></html>"
         # must encode for python 3+
         self.wfile.write(output.encode())
         print(output)
         return
     else:
         self.send_error(404, 'File not found: {}'.format(self.path))

 def do_POST(self):
     try:
         self.send_response(301)
         self.send_header('Content-type', 'text/html')
         self.end_headers()
         message_content = None
         param_dict = None
         content_type, param_dict = cgi.parse_header(
             self.headers.getheader('content-type'))
         if content_type == 'multipart/form-data':
             fields = cgi.parse_multipart(self.rfile, param_dict)
             message_content = fields.get('message')
         output = ''
         output += '<html><body>'
         output += '<h2> You Said: </h2>'
         output += '<h1> %s </h1>' % message_content[0]
         output += "<form method='POST' enctype='multipart/form-data' action='/hello'>"
         output += "<h2> What would you like me to say?</h2>"
         output += "<input name = 'message' type = 'text' />"
         output += "<input type = 'submit' value = 'Submit'/>"
         output += "</form>"
         output += '</body></html>'
         self.wfile.write(output.encode())
         print(output)

     except:
         pass


def main():
 server = None
 try:
     port = 8080
     server = HTTPServer(('', port), serverHandler)
     print('Server running on port {}'.format(port))
     server.serve_forever()
 except KeyboardInterrupt:
     print('Server shutting down...')
     server.socket.close()


main()

As expected, the server runs on port 8080 as specified in the main function. In the serverHandler class, I specified a \hello path, on which the page with the HTML input field is rendered.

The problem comes in when I type in text to the input field and click on the submit button.

Ideally, the page returned from do_POST should have a HTML h2 element that displays the text that was keyed in on submit, and below it, a blank input field should be shown to allow for new text to be entered and echoed.

This however, as I have mentioned, does not happen, and I instead see a blank page on my browser upon clicking the submit button.

Here is the terminal output when the script is run:

Anthony ~\..\digitization\back-end git: Development ≣ +1 ~1 -0 ! ❯❯❯ python .\webserver.py

Server running on port 8080
127.0.0.1 - - [28/Dec/2020 21:12:36] "GET /hello HTTP/1.1" 200 -
<html><body> Hey There!<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/Dec/2020 21:12:42] "POST /hello HTTP/1.1" 301 -

There seems to be something off with my do_POST method.

As mentioned, I am in the process of learning, and the original script was written in Python 2.X linked here.

I will appreciate insights on what is happening, and a solution to get round it. Thank you in advance

:)


Solution

  • I dug a little deeper into the community and found a workaround that proved to solve my particular issue.

    Kindly note that this answer worked in my scenario, however if it doesn't work for you, you could follow the thread and try out the various suggestions outlined.

    :)