Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge in fixes and tweaks to Matt's changes from Google.

  • Loading branch information...
commit 5558e74d0be41cdcbdbb994121786bd6f87b4926 1 parent 2864de0
Andrew Fleenor authored
Showing with 34 additions and 19 deletions.
  1. +22 −12 dpkt_http_replacement.py
  2. +3 −0  main.py
  3. +7 −5 pcaputil.py
  4. +2 −2 settings.py
View
34 dpkt_http_replacement.py
@@ -31,6 +31,21 @@ def parse_headers(f):
d[k] = v
return d
+
+def parse_length(s, base=10):
+ """Take a string and convert to int (not long), returning 0 if invalid"""
+ try:
+ n = int(s, base)
+ # int() can actually return long, which can't be used in file.read()
+ if isinstance(n, int):
+ return n
+ except ValueError:
+ pass
+ # if s was invalid or too big (that is, int returned long)...
+ logging.warn('Invalid HTTP content/chunk length "%s", assuming 0' % s)
+ return 0
+
+
def parse_body(f, version, headers):
"""Return HTTP body parsed from a file object, given HTTP header dict."""
if headers.get('transfer-encoding', '').lower() == 'chunked':
@@ -41,8 +56,8 @@ def parse_body(f, version, headers):
sz = f.readline().split(None, 1)[0]
except IndexError:
raise dpkt.UnpackError('missing chunk size')
- n = int(sz, 16)
- if n == 0:
+ n = parse_length(sz, 16)
+ if n == 0: # may happen if sz is invalid
found_end = True
buf = f.read(n)
if f.readline().strip():
@@ -56,18 +71,13 @@ def parse_body(f, version, headers):
body = ''.join(l)
elif 'content-length' in headers:
# Ethan K B: Have observed malformed 0,0 content lengths
- try:
- n = int(headers['content-length'])
- except ValueError:
- logging.warn('HTTP content-length "%s" is invalid, assuming 0' %
- headers['content-length'])
- n = 0
+ n = parse_length(headers['content-length'])
body = f.read(n)
if len(body) != n:
- logging.warn('HTTP content-length mismatch: expected %d, got %d', n,
- len(body))
- if settings.strict_http_parse_body:
- raise dpkt.NeedData('short body (missing %d bytes)' % (n - len(body)))
+ logging.warn('HTTP content-length mismatch: expected %d, got %d', n,
+ len(body))
+ if settings.strict_http_parse_body:
+ raise dpkt.NeedData('short body (missing %d bytes)' % (n - len(body)))
else:
# XXX - need to handle HTTP/0.9
# BTW, this function is not called if status code is 204 or 304
View
3  main.py
@@ -29,12 +29,15 @@
dest='resource_usage', default=False)
parser.add_option('--pad_missing_tcp_data', action='store_true',
dest='pad_missing_tcp_data', default=False)
+parser.add_option('--strict-http-parsing', action='store_true',
+ dest='strict_http_parsing', default=False)
options, args = parser.parse_args()
# copy options to settings module
settings.process_pages = options.pages
settings.drop_bodies = options.drop_bodies
settings.pad_missing_tcp_data = options.pad_missing_tcp_data
+settings.strict_http_parse_body = options.strict_http_parsing
# setup logs
logging.basicConfig(filename='pcap2har.log', level=logging.INFO)
View
12 pcaputil.py
@@ -4,11 +4,13 @@
import dpkt
-# use inet_ntoa to process IPs, if available (it's not on AppEngine)
-try:
- from socket import inet_ntoa
-except ImportError:
- inet_ntoa = lambda ip: ip
+# since it isn't available on AppEngine, we had to re-implement it
+# anyway so we figured we might as well stick with it.
+def inet_ntoa(packed):
+ '''Custom implementation of inet_ntoa'''
+ if not isinstance(packed, str) or len(packed) != 4:
+ raise ValueError('Argument to inet_ntoa must a string of length 4')
+ return '.'.join(str(ord(c)) for c in packed)
def friendly_tcp_flags(flags):
'''
View
4 settings.py
@@ -3,7 +3,7 @@
# Whether HTTP parsing should case whether the content length matches the
# content-length header.
-strict_http_parse_body = True
+strict_http_parse_body = False
# Whether to pad missing data in TCP flows with 0 bytes
-pad_missing_tcp_data = True
+pad_missing_tcp_data = False
Please sign in to comment.
Something went wrong with that request. Please try again.