forked from USArmyResearchLab/Dshell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttpdecoder.py
More file actions
101 lines (85 loc) · 3.98 KB
/
httpdecoder.py
File metadata and controls
101 lines (85 loc) · 3.98 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
#!/usr/bin/env python
import dshell
import util
import dpkt
# for HTTPDecoder gzip decompression
import gzip
import cStringIO
class HTTPDecoder(dshell.TCPDecoder):
'''extend HTTPDecoder to handle HTTP request/responses
will call HTTPHandler(
conn=Connection(),
request=dpkt.http.Request,
response=dpkt.http.Response,
requesttime=timestamp, responsetime=timestamp
)
after each response.
config: noresponse: if True and connection closes w/o response, will call with response,responsetime=None,None (True)
gunzip: if True will decompress gzip encoded response bodies (default True)
'''
def __init__(self, **kwargs):
self.noresponse = True
self.gunzip = True
dshell.TCPDecoder.__init__(self, **kwargs)
self.requests = {}
# Custom error handler for data reassembly --- ignores errors, keep data
def errorH(self, **x):
return True
def blobHandler(self, conn, blob):
'''buffer the request blob and call the handler once we have the response blob'''
if conn not in self.requests:
try:
self.requests[conn] = (
blob.starttime, dpkt.http.Request(blob.data(self.errorH)))
except Exception, e:
self.UnpackError(e)
else:
try:
if 'HTTPHandler' in dir(self):
response = dpkt.http.Response(blob.data(self.errorH))
if self.gunzip and 'gzip' in util.getHeader(response, 'content-encoding'):
bodyUnzip = self.decompressGzipContent(response.body)
if bodyUnzip != None:
response.body = bodyUnzip
self.HTTPHandler(conn=conn,
request=self.requests[conn][1],
response=response,
requesttime=self.requests[conn][0],
responsetime=blob.starttime)
del self.requests[conn]
except Exception, e:
self.UnpackError(e)
self.HTTPHandler(conn=conn, request=self.requests[conn][
1], response=None, requesttime=self.requests[conn][0], responsetime=blob.starttime)
del self.requests[conn]
def connectionHandler(self, conn):
'''when the connection closes, flush out any request blobs that did not have a response'''
if conn in self.requests:
if self.noresponse and 'HTTPHandler' in dir(self):
self.HTTPHandler(conn=conn,
request=self.requests[conn][1],
response=None,
requesttime=self.requests[conn][0],
responsetime=self.requests[conn][0])
del self.requests[conn]
def decompressGzipContent(self, httpcontent):
'''utility function to decompress gzip compressed content'''
cstr = cStringIO.StringIO(httpcontent)
try:
return gzip.GzipFile(fileobj=cstr).read()
except:
return None
def UnpackError(self, error):
self._exc(error)
class displaystub(dshell.Decoder):
def __init__(self):
dshell.Decoder.__init__(self,
name='httpdecoder',
description='Intermediate class to support HTTP based decoders.',
longdescription="See source code or pydoc for details on use."
)
if __name__ == '__main__':
dObj = displaystub()
print dObj
else:
dObj = displaystub()