Skip to content

Instantly share code, notes, and snippets.

@nk0t
Created August 9, 2013 15:34
Show Gist options
  • Save nk0t/6194602 to your computer and use it in GitHub Desktop.
Save nk0t/6194602 to your computer and use it in GitHub Desktop.
simple http server in python
import os
import os.path
import socket
import threading
import subprocess
import locale
server_string = 'Server: httpy/1.0\r\n'
document_root = ''
index_page = ''
def headers(client):
client.send('HTTP/1.0 200 OK\r\n')
client.send(server_string)
client.send('Content-Type: text/html\r\n')
client.send('\r\n')
def not_found(client):
client.send('HTTP/1.0 404 NOT FOUND\r\n')
client.send(server_string)
client.send('Content-Type: text/html\r\n')
client.send('\r\n')
client.send('<HTML><TITLE>Not Found</TITLE>\r\n')
client.send('<BODY><P>The server could not fulfill\r\n')
client.send('your request because the resource specified\r\n')
client.send('is unavailable or nonexistent.\r\n')
client.send('</BODY></HTML>\r\n')
def bad_request(client):
client.send('HTTP/1.0 400 BAD REQUEST\r\n')
client.send('Content-type: text/html\r\n')
client.send('\r\n')
client.send('<P>Your browser sent a bad request, \r\n')
client.send('such as a POST without a Content-Length.\r\n')
def unimplemented(client, method):
client.send('HTTP/1.0 501 Method Not Implemented\r\n')
client.send(server_string)
client.send('Content-Type: text/html\r\n')
client.send('\r\n')
client.send('<HTML><HEAD><TITLE>Method Not Implemented\r\n')
client.send('</TITLE></HEAD>\r\n')
client.send('<BODY><P>HTTP request ')
client.send(method)
client.send(' method not supported.')
client.send('\r\n</BODY></HTML>\r\n')
def accept_request(client):
request = client.recv(1024)
if(len(request) == 0):
client.close()
return
http_request = request.split('\r\n')[0]
http_headers = request[len(http_request):]
http_method, request_url, _ = http_request.split(' ')
if (http_method != 'GET') and (http_method != 'POST'):
unimplemented(client, http_method)
client.close()
return
url = request_url.split('?')[0]
query_string = request_url[len(url) + 1:]
cgi = url[-4:] == '.exe'
path = document_root + url
if path[-1:] == '/':
path = path + index_page
if not os.path.exists(path):
not_found(client)
else:
if os.path.isdir(path):
path = path + '/' + index_page
if cgi:
execute_cgi(client, path, http_method, http_headers, query_string)
else:
serve_file(client, path)
client.close()
def serve_file(client, filename):
headers(client)
with open(filename, 'r') as f:
for line in f:
client.send(line)
def execute_cgi(client, path, method, http_headers, query_string):
content_length = -1
env = os.environ.copy()
env['REQUEST_METHOD'] = method
if method == 'GET':
env['QUERY_STRING'] = query_string
client.send('HTTP/1.0 200 OK\r\n')
stdout, stderror = subprocess.Popen(args = [path,], stdout = subprocess.PIPE ,env = env).communicate()
client.send(stdout.rstrip())
else:
for header in http_headers.split('\r\n'):
if header.split(':')[0] == 'Content-Length':
content_length = int(header.split(':')[1])
if content_length == -1:
bad_request(client)
return
env['CONTENT_LENGTH'] = str(content_length)
content = http_headers[-content_length:]
client.send('HTTP/1.0 200 OK\r\n')
stdout, stderror = subprocess.Popen(args = [path,], stdout = subprocess.PIPE, stdin = subprocess.PIPE ,env = env).communicate(content)
client.send(stdout.rstrip())
def load_config():
global document_root
global index_page
current_directory = os.getcwd()
document_root = '{0}/htdocs'.format(current_directory)
index_page = 'index.html'
def server_main():
load_config()
host = socket.gethostbyname('localhost')
port = 12345
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1)
print 'httpd running on port {0}'.format(port)
while True:
client, address = sock.accept()
thread = threading.Thread(target = accept_request, args = (client,))
thread.start()
sock.close()
if __name__ == '__main__':
server_main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment