- Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathLoggingProxyHTTPHandler.py
More file actions
Latest commit
106 lines (93 loc) · 3.9 KB
/
Copy pathLoggingProxyHTTPHandler.py
File metadata and controls
106 lines (93 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
importBaseHTTPServer
importgzip
importrequests
importStringIO
defrewrite_headers(headers):
# Don't accept stuff that original request didn't accept
ifnot'accept-encoding'inheaders:
headers['accept-encoding'] ='identity'
result=dict()
fork, vinheaders.items():
newk='-'.join(map(lambdax: x.capitalize(), k.split('-')))
result[newk] =v
returnresult
classLoggingProxyHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# send_response pretty similar to BaseHTTPServer send_response
# but without Server or Date headers
defsend_response(self, code, message=None):
self.log_request(code)
ifmessageisNone:
ifcodeinself.responses:
message=self.responses[code][0]
else:
message=''
ifself.request_version!='HTTP/0.9':
response="{0} {1} {2}\r\n".format(self.protocol_version,
code, message)
self.wfile.write(response)
defrespond(self, response):
ifresponse.status_code<400:
self.send_response(response.status_code)
else:
self.send_error(response.status_code)
fork, vinrewrite_headers(response.headers).items():
self.send_header(k, v)
self.end_headers()
output=response.content
# handle gzip
# http://stackoverflow.com/questions/8506897/how-do-i-gzip-compress-a-string-in-python
if'content-encoding'inresponse.headersand \
response.headers['content-encoding'].lower() =='gzip':
buffer=StringIO.StringIO()
withgzip.GzipFile(fileobj=buffer, mode="w") asf:
f.write(output)
output=buffer.getvalue()
# handle chunking
# (thanks to https://gist.github.com/josiahcarlson/3250376)
# although we only pretend to chunk and send it all at once!
if'transfer-encoding'inresponse.headersand \
response.headers['transfer-encoding'].lower() =='chunked':
self.wfile.write('%X\r\n%s\r\n'%
(len(output), output))
# send the chunked trailer
self.wfile.write('0\r\n\r\n')
else:
self.wfile.write(output)
self.log_response(response)
defdo_GET(self):
headers=rewrite_headers(self.headers)
response=requests.get(self.path, headers=headers)
self.respond(response)
defdo_POST(self):
headers=rewrite_headers(self.headers)
self.data=self.rfile.read(int(self.headers['Content-Length']))
response=requests.post(self.path, headers=headers, data=self.data)
self.respond(response)
defdo_PUT(self):
headers=rewrite_headers(self.headers)
self.data=self.rfile.read(int(self.headers['Content-Length']))
response=requests.put(self.path, headers=headers, data=self.data)
self.respond(response)
deflog_error(format, *args):
pass
deflog_request(self, *args):
print"*** REQUEST ***"
printself.command+' '+self.path
for (k, v) inrewrite_headers(self.headers).items():
print"{0} = {1}".format(k, v)
print
ifself.commandin ['POST', 'PUT']:
printself.data
print"*** END REQUEST ***"
deflog_response(self, response):
print"*** RESPONSE ***"
ifresponse.status_codeinself.responses:
shortmessage, longmessage=self.responses[response.status_code]
else:
shortmessage=longmessage="Not a code known by requests module!"
print"{0} {1}".format(response.status_code, shortmessage)
for (k, v) inrewrite_headers(response.headers).items():
print"{0} = {1}".format(k, v)
print
printresponse.content
print"*** END RESPONSE ***"