forked from USArmyResearchLab/Dshell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttpdecoder.py
89 lines (77 loc) · 3.94 KB
/
httpdecoder.py
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
#!/usr/bin/env python
import dshell, util, 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 blob.direction=='cs':
try:
self.requests[conn]=(blob.starttime,dpkt.http.Request(blob.data(self.errorH)))
except Exception, e: self.UnpackError(e)
elif blob.direction=='sc' and conn in self.requests:
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()