Showing 1 changed files with 110 additions and 0 deletions
+110
httpserve.py
... ...
@@ -0,0 +1,110 @@
1
+#!/usr/bin/env python3
2
+"""
3
+Very simple HTTP server in python for logging POST and GET requests
4
+Usage::
5
+    ./server.py [<port>]
6
+"""
7
+from http.server import BaseHTTPRequestHandler, HTTPServer
8
+import logging
9
+import datetime
10
+
11
+output="httpserve.log"
12
+count=0
13
+lastPostBody=""
14
+lastPostBody2=""
15
+
16
+class S(BaseHTTPRequestHandler):
17
+    def log_message(self, format, *args):
18
+        # This is to silence a bit the server
19
+        return
20
+    def _set_response(self):
21
+        self.send_response(200)
22
+        self.send_header('Content-type', 'text/html')
23
+        self.end_headers()
24
+
25
+    def do_GET(self):
26
+        timestamp=datetime.datetime.utcnow().isoformat().split(":")
27
+        timestamp=timestamp[0]+timestamp[1]
28
+        print(timestamp+" ["+str(count)+"] GET : "+str(self.path))
29
+        self._set_response()
30
+        aggregContent=""
31
+        aggregContent+="<head>\n"
32
+        aggregContent+="<title>HTTP Watch</title>\n"
33
+        aggregContent+="<style>\n"
34
+        aggregContent+="html {font-family: arial, verdana, sans-serif;}\n"
35
+        aggregContent+="h1 { font-size:20px; font-weight:bold; padding-left: 4px; }\n"
36
+        aggregContent+="h2 { font-size:16px; font-weight:bold; }\n"
37
+        aggregContent+="h3 { font-size:14px; font-weight:bold; }\n"
38
+        aggregContent+=".header { background-color: #5b7e96; color: #ffffff; padding-top: 2px; padding-bottom: 2px;}\n"
39
+        aggregContent+=".pre {font-family: monospace;line-height:100%;font-size: 0.8em;}\n"
40
+        aggregContent+="</style>\n"
41
+        aggregContent+="<script type=\"text/javascript\"> \n\
42
+        setTimeout(function(){ \n\
43
+            location = '' \n\
44
+            },20000); \n\
45
+            </script>\n"
46
+        aggregContent+="</head>\n"
47
+        aggregContent+="<body>\n"
48
+        aggregContent+="<a name=\"top\"></a><div class=\"header\"><h1>HTTP Watch</h1></div>"
49
+        aggregContent+="<a href=\"#current\">Latest</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#previous\">Previous</a><br>"
50
+        aggregContent+="<a name=\"current\"></a><a href=\"#top\">&uArr;</a>Last POST was:\n"+lastPostBody+"\n"
51
+        aggregContent+="<a href=\"#top\">&uArr;</a>"
52
+        aggregContent+="<hr>"
53
+        aggregContent+="<a name=\"previous\"></a><a href=\"#top\">&uArr;</a>Previous POST was:\n"+lastPostBody2+"\n"
54
+        aggregContent+="<a href=\"#top\">&uArr;</a>"
55
+        aggregContent+="</body>\n"
56
+        self.wfile.write("{}".format(aggregContent).encode('utf-8'))
57
+        with open(output,"a+") as f:
58
+            f.write("["+str(count)+"] GET Request: -------------------------------------------\n")
59
+            f.write("["+str(count)+"] Path: "+str(self.path)+"\n")
60
+            f.write("["+str(count)+"] HeadersBegin:\n"+str(self.headers)+"\n")
61
+            f.write("["+str(count)+"] HeadersEnd: -----\n")
62
+            f.write("--------------------------------------------------------\n")
63
+
64
+    def do_POST(self):
65
+        global count
66
+        global lastPostBody
67
+        global lastPostBody2
68
+        timestamp=datetime.datetime.utcnow().isoformat().split(":")
69
+        timestamp=timestamp[0]+timestamp[1]
70
+        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
71
+        post_data = self.rfile.read(content_length) # <--- Gets the data itself
72
+        print(timestamp+" ["+str(count)+"] POST : "+str(self.path))
73
+
74
+        self._set_response()
75
+        self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
76
+
77
+        lastPostBody2=lastPostBody
78
+        lastPostBody=timestamp+" : "+str(count)+" <br>\n<pre>"+str(self.headers)+"</pre>\n<hr>\n<pre>\n"+post_data.decode('utf-8')+"\n</pre>\n"
79
+        #Nice-ing
80
+        lastPostBody=lastPostBody.replace("}","}\n").replace(",",",\n")
81
+        with open(output,"a+") as f:
82
+            f.write("["+str(count)+"] POST Request: "+timestamp+" -------------------------------------------\n")
83
+            f.write("["+str(count)+"] Path: "+str(self.path)+"\n")
84
+            f.write("["+str(count)+"] HeadersBegin:\n"+str(self.headers)+"\n")
85
+            f.write("["+str(count)+"] HeadersEnd: -----\n")
86
+            f.write("["+str(count)+"] BodyBegin:\n")
87
+            f.write(post_data.decode('utf-8')+"\n")
88
+            f.write("["+str(count)+"] BodyEnd:\n")
89
+            f.write("--------------------------------------------------------\n")
90
+        count+=1
91
+
92
+def run(server_class=HTTPServer, handler_class=S, port=8001):
93
+    logging.basicConfig(level=logging.INFO)
94
+    server_address = ('', port)
95
+    httpd = server_class(server_address, handler_class)
96
+    logging.info('Starting httpd on port '+str(port)+'...\n')
97
+    try:
98
+        httpd.serve_forever()
99
+    except KeyboardInterrupt:
100
+        pass
101
+    httpd.server_close()
102
+    logging.info('Stopping httpd...\n')
103
+
104
+if __name__ == '__main__':
105
+    from sys import argv
106
+
107
+    if len(argv) == 2:
108
+        run(port=int(argv[1]))
109
+    else:
110
+        run()