Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple Python 3 HTTP server for logging all GET and POST requests
#!/usr/bin/env python3
"""
Very simple HTTP server in python for logging requests
Usage::
./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
class S(BaseHTTPRequestHandler):
def _set_response(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
self._set_response()
self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))
def do_POST(self):
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length) # <--- Gets the data itself
logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
str(self.path), str(self.headers), post_data.decode('utf-8'))
self._set_response()
self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
def run(server_class=HTTPServer, handler_class=S, port=8080):
logging.basicConfig(level=logging.INFO)
server_address = ('', port)
httpd = server_class(server_address, handler_class)
logging.info('Starting httpd...\n')
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
logging.info('Stopping httpd...\n')
if __name__ == '__main__':
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
@hihei

This comment has been minimized.

Copy link

@hihei hihei commented May 2, 2018

hey . can you tell me how it works ? i am not sure how much pressure it can be push. Thanks

@jmarshall9120

This comment has been minimized.

Copy link

@jmarshall9120 jmarshall9120 commented Sep 18, 2018

What do you do when content-length is wrong or missing?

@aapjeisbaas

This comment has been minimized.

Copy link

@aapjeisbaas aapjeisbaas commented Mar 20, 2019

love it!
thanks Soooo much ;-D

@drjoms

This comment has been minimized.

Copy link

@drjoms drjoms commented May 16, 2019

arm... i amkinda new to python.
saved file throws this:

File "sample_post_server.py", line 48
run()
^
IndentationError: expected an indented block

i added a few new line characters for good measure. Still same error

@grumo35

This comment has been minimized.

Copy link

@grumo35 grumo35 commented Jun 4, 2019

arm... i amkinda new to python.
saved file throws this:

File "sample_post_server.py", line 48
run()
^
IndentationError: expected an indented block

i added a few new line characters for good measure. Still same error

You probably failed to create the exact same copy of the file, you have to take care of the indentation.
make sure everything is indented as intended.

@menkrep1337

This comment has been minimized.

Copy link

@menkrep1337 menkrep1337 commented Jun 10, 2019

THX

@aaninu

This comment has been minimized.

Copy link

@aaninu aaninu commented Jun 23, 2019

Thanks

@unaimillan

This comment has been minimized.

Copy link

@unaimillan unaimillan commented Jul 2, 2019

❤️ Thanks ❤️

@David3310273

This comment has been minimized.

Copy link

@David3310273 David3310273 commented Oct 26, 2019

How do you get the params of the POST request?

@mdonkers

This comment has been minimized.

Copy link
Owner Author

@mdonkers mdonkers commented Oct 28, 2019

Which parameters do you mean @David3310273? It logs the full path (I believe), the headers and the body. Otherwise feel free to look into Python methods on how to extract the parameters from a POST request.

@desibabu

This comment has been minimized.

Copy link

@desibabu desibabu commented Nov 26, 2019

Man this is awesome so big thank you for that!!

One request could it be possible to print data in post if data is compressed with gzip format.

@dheerajmpai

This comment has been minimized.

Copy link

@dheerajmpai dheerajmpai commented Dec 17, 2019

This is fantastic. I will make a pypi library out of this it's ok with you

@mdonkers

This comment has been minimized.

Copy link
Owner Author

@mdonkers mdonkers commented Dec 17, 2019

@dheerajmpai Knock yourself out :-)
(in other words; feel free and go ahead)

@dheerajmpai

This comment has been minimized.

Copy link

@dheerajmpai dheerajmpai commented Dec 18, 2019

Haha. Thanks

@dheerajmpai

This comment has been minimized.

Copy link

@dheerajmpai dheerajmpai commented Dec 18, 2019

Have made a pypi module with this code.

You can install with

pip install pyserv

And start a server with

serv

or

serv [port number]

Thats it!

Note : The command serv works on python 3 on Ubuntu . Still working to make it work on Windows.

@dheerajmpai

This comment has been minimized.

Copy link

@dheerajmpai dheerajmpai commented Dec 18, 2019

Link to the python project

https://pypi.org/project/pyserv/

@talbz

This comment has been minimized.

Copy link

@talbz talbz commented Jan 19, 2020

@divisathyan

This comment has been minimized.

Copy link

@divisathyan divisathyan commented Mar 4, 2020

Thanks! I got the basic GET and POST working within no time

@mjl778374

This comment has been minimized.

Copy link

@mjl778374 mjl778374 commented Mar 26, 2020

Aquí comparto este código fuente de un servidor web escrito en Python:

`#!/usr/bin/env python

-- coding: utf-8 --

import os
from http.server import HTTPServer, CGIHTTPRequestHandler
import sys

PuertoXDefecto = 8000
PuertoXServir = PuertoXDefecto

ArchivoIndexXDefecto = "index.html"
ArchivoIndex = ArchivoIndexXDefecto

NombreArchivoServidor = sys.argv[0]

for Argumento in sys.argv:
ArgumentoPuerto = Argumento[0: 7]
ArgumentoIndex = Argumento[0: 6]

if ArgumentoPuerto == "puerto=":
    try:
        PuertoXServir = int(Argumento[7:])
    except ValueError:
        PuertoXServir = PuertoXDefecto
elif ArgumentoIndex == "index=":
    try:
        ArchivoIndex = Argumento[6:]
    except ValueError:
        ArchivoIndex = ArchivoIndexXDefecto

class Handler(CGIHTTPRequestHandler):
cgi_directories = []
cgi_directories.append("/")
cgi_directories.append("/carpetaArchivosPython")

def SePuedeServirPath(self):
    NombreArchivoXServir = os.path.split(self.path)[1]
    IndiceInicioParametros = NombreArchivoXServir.find("?")

    if IndiceInicioParametros >= 0:
        NombreArchivoXServir = NombreArchivoXServir[0: IndiceInicioParametros]

    if NombreArchivoXServir.lower() == NombreArchivoServidor.lower():
        return False
    else:
        return True

def RepararPathXServir(self):
    RutaXDefecto = ArchivoIndex
    NombreArchivoXServir = os.path.basename(self.path)

    if NombreArchivoXServir == "":
        NombreArchivoXServir = RutaXDefecto
        self.path = os.path.join(self.path, NombreArchivoXServir)
    elif len(NombreArchivoXServir) > 0:
        Parametros = NombreArchivoXServir
        PrimerCaracterParametros = Parametros[0:1]

        if PrimerCaracterParametros == "?":
            Carpeta = os.path.split(self.path)[0]
            NombreArchivoXServir = RutaXDefecto + Parametros
            self.path = os.path.join(Carpeta, NombreArchivoXServir)

def MostrarPathXServir(self):
    NombrePeticion = self.command
    print("Petición {1}. Sirviendo archivo {0}".format(self.path, NombrePeticion))

def ManejarPeticion(self, FuncionXServir):
    self.RepararPathXServir()

    if self.SePuedeServirPath():
        self.MostrarPathXServir()
        FuncionXServir(self)

def do_GET(self):
    self.ManejarPeticion(CGIHTTPRequestHandler.do_GET)

def do_POST(self):
    self.ManejarPeticion(CGIHTTPRequestHandler.do_POST)

httpd = HTTPServer(("", PuertoXServir), Handler)
print("Sirviendo desde el puerto", PuertoXServir)
httpd.serve_forever()`

@mjl778374

This comment has been minimized.

Copy link

@mjl778374 mjl778374 commented Mar 27, 2020

El programa del servidor web Python que había posteado previamente, tiene el problema de que si por ejemplo, se intenta servir el archivo "http://localhost:8000/carpetaArchivosPython/archivosEstaticos/Tutoriel_OpenBoard_1.5EN.pdf" se indica como error que no es un script CGI ejecutable. El problema se podría resolver si no se consideran como archivos CGI, aquellos que no se encuentran en alguna de las carpetas indicadas en la variable "cgi_directories". (En este caso "/carpetaArchivosPython/archivosEstaticos").

@passkwall

This comment has been minimized.

Copy link

@passkwall passkwall commented May 27, 2020

Awesome little template. Thanks so much!

@tl986r

This comment has been minimized.

Copy link

@tl986r tl986r commented Jul 17, 2020

this is great. Big thanks!!!

@stephenboston

This comment has been minimized.

Copy link

@stephenboston stephenboston commented Jul 31, 2020

Thank you! What a great little service.

@matiaspl

This comment has been minimized.

Copy link

@matiaspl matiaspl commented Aug 6, 2020

If there's no content-length set in the requests (which can happen for POST requests), a default value is needed. If you happen to get an exception try changing line 11 to:

content_length = int(self.headers.get('content-length', 0))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.