...
|
...
|
@@ -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> <a href=\"#previous\">Previous</a><br>"
|
|
50
|
+ aggregContent+="<a name=\"current\"></a><a href=\"#top\">⇑</a>Last POST was:\n"+lastPostBody+"\n"
|
|
51
|
+ aggregContent+="<a href=\"#top\">⇑</a>"
|
|
52
|
+ aggregContent+="<hr>"
|
|
53
|
+ aggregContent+="<a name=\"previous\"></a><a href=\"#top\">⇑</a>Previous POST was:\n"+lastPostBody2+"\n"
|
|
54
|
+ aggregContent+="<a href=\"#top\">⇑</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()
|