python-as-http / httpserve.py /
Yanik Cawidrone Added main script
1157acf 2 years ago
1 contributor
110 lines | 4.829kb
#!/usr/bin/env python3
"""
Very simple HTTP server in python for logging POST and GET requests
Usage::
    ./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
import datetime

output="httpserve.log"
count=0
lastPostBody=""
lastPostBody2=""

class S(BaseHTTPRequestHandler):
    def log_message(self, format, *args):
        # This is to silence a bit the server
        return
    def _set_response(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        timestamp=datetime.datetime.utcnow().isoformat().split(":")
        timestamp=timestamp[0]+timestamp[1]
        print(timestamp+" ["+str(count)+"] GET : "+str(self.path))
        self._set_response()
        aggregContent=""
        aggregContent+="<head>\n"
        aggregContent+="<title>HTTP Watch</title>\n"
        aggregContent+="<style>\n"
        aggregContent+="html {font-family: arial, verdana, sans-serif;}\n"
        aggregContent+="h1 { font-size:20px; font-weight:bold; padding-left: 4px; }\n"
        aggregContent+="h2 { font-size:16px; font-weight:bold; }\n"
        aggregContent+="h3 { font-size:14px; font-weight:bold; }\n"
        aggregContent+=".header { background-color: #5b7e96; color: #ffffff; padding-top: 2px; padding-bottom: 2px;}\n"
        aggregContent+=".pre {font-family: monospace;line-height:100%;font-size: 0.8em;}\n"
        aggregContent+="</style>\n"
        aggregContent+="<script type=\"text/javascript\"> \n\
        setTimeout(function(){ \n\
            location = '' \n\
            },20000); \n\
            </script>\n"
        aggregContent+="</head>\n"
        aggregContent+="<body>\n"
        aggregContent+="<a name=\"top\"></a><div class=\"header\"><h1>HTTP Watch</h1></div>"
        aggregContent+="<a href=\"#current\">Latest</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#previous\">Previous</a><br>"
        aggregContent+="<a name=\"current\"></a><a href=\"#top\">&uArr;</a>Last POST was:\n"+lastPostBody+"\n"
        aggregContent+="<a href=\"#top\">&uArr;</a>"
        aggregContent+="<hr>"
        aggregContent+="<a name=\"previous\"></a><a href=\"#top\">&uArr;</a>Previous POST was:\n"+lastPostBody2+"\n"
        aggregContent+="<a href=\"#top\">&uArr;</a>"
        aggregContent+="</body>\n"
        self.wfile.write("{}".format(aggregContent).encode('utf-8'))
        with open(output,"a+") as f:
            f.write("["+str(count)+"] GET Request: -------------------------------------------\n")
            f.write("["+str(count)+"] Path: "+str(self.path)+"\n")
            f.write("["+str(count)+"] HeadersBegin:\n"+str(self.headers)+"\n")
            f.write("["+str(count)+"] HeadersEnd: -----\n")
            f.write("--------------------------------------------------------\n")

    def do_POST(self):
        global count
        global lastPostBody
        global lastPostBody2
        timestamp=datetime.datetime.utcnow().isoformat().split(":")
        timestamp=timestamp[0]+timestamp[1]
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself
        print(timestamp+" ["+str(count)+"] POST : "+str(self.path))

        self._set_response()
        self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))

        lastPostBody2=lastPostBody
        lastPostBody=timestamp+" : "+str(count)+" <br>\n<pre>"+str(self.headers)+"</pre>\n<hr>\n<pre>\n"+post_data.decode('utf-8')+"\n</pre>\n"
        #Nice-ing
        lastPostBody=lastPostBody.replace("}","}\n").replace(",",",\n")
        with open(output,"a+") as f:
            f.write("["+str(count)+"] POST Request: "+timestamp+" -------------------------------------------\n")
            f.write("["+str(count)+"] Path: "+str(self.path)+"\n")
            f.write("["+str(count)+"] HeadersBegin:\n"+str(self.headers)+"\n")
            f.write("["+str(count)+"] HeadersEnd: -----\n")
            f.write("["+str(count)+"] BodyBegin:\n")
            f.write(post_data.decode('utf-8')+"\n")
            f.write("["+str(count)+"] BodyEnd:\n")
            f.write("--------------------------------------------------------\n")
        count+=1

def run(server_class=HTTPServer, handler_class=S, port=8001):
    logging.basicConfig(level=logging.INFO)
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    logging.info('Starting httpd on port '+str(port)+'...\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()