Search code examples
pythonhttpserver

How do I configure a python server for POST?


I'm trying out some PHP on my pc and made a little python server to host the files, one problem: It can't do POST, I always get the error 501. I've heard that you can implement POST in these servers, but I didn't find how to do this, can someone help?

Here's my current server:

import http.server
import socketserver

PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

Solution

  • This is the script I personally use for when I need this kind of functionality:

    #!/usr/env python3
    import http.server
    import os
    import logging
    
    try:
        import http.server as server
    except ImportError:
        # Handle Python 2.x
        import SimpleHTTPServer as server
    
    class HTTPRequestHandler(server.SimpleHTTPRequestHandler):
        """
        SimpleHTTPServer with added bonus of:
    
        - handle PUT requests
        - log headers in GET request
        """
    
        def do_GET(self):
            server.SimpleHTTPRequestHandler.do_GET(self)
            logging.warning(self.headers)
    
        def do_PUT(self):
            """Save a file following a HTTP PUT request"""
            filename = os.path.basename(self.path)
    
            # Don't overwrite files
            if os.path.exists(filename):
                self.send_response(409, 'Conflict')
                self.end_headers()
                reply_body = '"%s" already exists\n' % filename
                self.wfile.write(reply_body.encode('utf-8'))
                return
    
            file_length = int(self.headers['Content-Length'])
            with open(filename, 'wb') as output_file:
                output_file.write(self.rfile.read(file_length))
            self.send_response(201, 'Created')
            self.end_headers()
            reply_body = 'Saved "%s"\n' % filename
            self.wfile.write(reply_body.encode('utf-8'))
    
    if __name__ == '__main__':
        server.test(HandlerClass=HTTPRequestHandler)
    

    But perhaps a more fitting, and simpler script would be the following, as found on Flavio Copes' blog:

    from http.server import BaseHTTPRequestHandler, HTTPServer
    
    class handler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
    
            message = "Hello, World! Here is a GET response"
            self.wfile.write(bytes(message, "utf8"))
        def do_POST(self):
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
    
            message = "Hello, World! Here is a POST response"
            self.wfile.write(bytes(message, "utf8"))
    
    with HTTPServer(('', 8000), handler) as server:
        server.serve_forever()