Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
a minimal http server in python. Responds to GET, HEAD, POST requests, but will fail on anything else.
#!/usr/bin/env python
"""
Very simple HTTP server in python.
Usage::
./dummy-web-server.py [<port>]
Send a GET request::
curl http://localhost
Send a HEAD request::
curl -I http://localhost
Send a POST request::
curl -d "foo=bar&bin=baz" http://localhost
"""
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write("<html><body><h1>hi!</h1></body></html>")
def do_HEAD(self):
self._set_headers()
def do_POST(self):
# Doesn't do anything with posted data
self._set_headers()
self.wfile.write("<html><body><h1>POST!</h1></body></html>")
def run(server_class=HTTPServer, handler_class=S, port=80):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print 'Starting httpd...'
httpd.serve_forever()
if __name__ == "__main__":
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
@mhchia
mhchia commented Jun 24, 2016

Is import SocketServer unneeded ?!

@dneyirp
dneyirp commented Aug 8, 2016

No import SocketServer is not needed and can be removed.

@dneyirp
dneyirp commented Aug 8, 2016

Nice project.

Just one thing to add to it, if you want access to the POSTed data you do so like this:

def do_POST(self):
        # Doesn't do anything with posted data
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself
        self._set_headers()
        self.wfile.write("<html><body><h1>POST!</h1></body></html>")
@qianguozheng

Great job, this it what I finding, print the post data

@arvindsree

Nice

@scorpiodawg

Oh, and to print the POSTed data:

    def do_POST(self):
        # Doesn't do anything with posted data
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself
        self._set_headers()
        self.wfile.write("<html><body><h1>POST!</h1><pre>" + post_data + "</pre></body></html>")
@pincioc
pincioc commented Jan 6, 2017
def do_POST(self):
    # Doesn't do anything with posted data
    content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
    post_data = self.rfile.read(content_length) # <--- Gets the data itself
    print post_data # <-- Print post data
    self._set_headers()
@ml693
ml693 commented Feb 4, 2017

Nice, I would welcome very much if someone could answer the following:

suppose I post .txt file to this server. How to make server save this file in its local directory?
What's the extra code inside do_POST(self) for that?

@tarvos21
tarvos21 commented Mar 15, 2017 edited

Great script, thanks! Is there a Python3 version?

@derdigge
derdigge commented Apr 12, 2017 edited

@tarvos21:

just stumbled in here by google result. That one works 4 me in python3

#!/usr/bin/python3

import socket
from http.server import BaseHTTPRequestHandler, HTTPServer
import time

hostName = ""
hostPort = 80

class MyServer(BaseHTTPRequestHandler):

	#	GET is for clients geting the predi
	def do_GET(self):
		self.send_response(200)
		self.wfile.write(bytes("<p>You accessed path: %s</p>" % self.path, "utf-8"))

	#	POST is for submitting data.
	def do_POST(self):

		print( "incomming http: ", self.path )

		content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
		post_data = self.rfile.read(content_length) # <--- Gets the data itself
		self.send_response(200)

		client.close()

		#import pdb; pdb.set_trace()


myServer = HTTPServer((hostName, hostPort), MyServer)
print(time.asctime(), "Server Starts - %s:%s" % (hostName, hostPort))

try:
	myServer.serve_forever()
except KeyboardInterrupt:
	pass

myServer.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostName, hostPort))```
@vmrekhate

Any help to make this work for HTTPS as well?
I explored SSL and wrote some sample code using the examples here: SSL Python3 docs. I can capture the data in connstream, but still not sure how to handle the path in GET/POST requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment