diff options
author | Aldo Cortesi <aldo@nullcube.com> | 2012-06-24 17:47:55 +1200 |
---|---|---|
committer | Aldo Cortesi <aldo@nullcube.com> | 2012-06-24 17:47:55 +1200 |
commit | f8622ea914b506013625c539388349d53b4a7e58 (patch) | |
tree | c79d233fb8ce6c17224f80f9086a7c3e4ef3d796 /libpathod/rparse.py | |
parent | 75f06d56cd87c9458a758277bdc1905d0637a532 (diff) | |
download | mitmproxy-f8622ea914b506013625c539388349d53b4a7e58.tar.gz mitmproxy-f8622ea914b506013625c539388349d53b4a7e58.tar.bz2 mitmproxy-f8622ea914b506013625c539388349d53b4a7e58.zip |
Simple request spec parsing.
Diffstat (limited to 'libpathod/rparse.py')
-rw-r--r-- | libpathod/rparse.py | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/libpathod/rparse.py b/libpathod/rparse.py index 3824406d..50ae9804 100644 --- a/libpathod/rparse.py +++ b/libpathod/rparse.py @@ -1,6 +1,7 @@ import operator, string, random, mmap, os, time import contrib.pyparsing as pp from netlib import http_status +import utils BLOCKSIZE = 1024 @@ -305,7 +306,7 @@ class Method: # it to be canonical. The user can specify a different case by using a # string value literal. if isinstance(value, basestring): - value = value.upper() + value = ValueLiteral(value.upper()) self.value = value def accept(self, settings, r): @@ -406,6 +407,46 @@ class Code: return e.setParseAction(lambda x: klass(*x)) +class Request: + comps = ( + Body, + Header, + PauseAt, + DisconnectAt, + ShortcutContentType, + ) + version = "HTTP/1.1" + body = LiteralGenerator("") + def __init__(self): + self.headers = [] + self.actions = [] + + @classmethod + def expr(klass): + parts = [i.expr() for i in klass.comps] + atom = pp.MatchFirst(parts) + resp = pp.And( + [ + Method.expr(), + pp.ZeroOrMore(pp.Literal(":").suppress() + atom) + ] + ) + return resp + + +class CraftedRequest(Request): + def __init__(self, settings, spec, tokens): + Request.__init__(self) + self.spec, self.tokens = spec, tokens + for i in tokens: + i.accept(settings, self) + + def serve(self, fp): + d = Request.serve(self, fp) + d["spec"] = self.spec + return d + + class Response: comps = ( Body, @@ -423,12 +464,6 @@ class Response: self.headers = [] self.actions = [] - def get_header(self, hdr): - for k, v in self.headers: - if k[:len(hdr)].lower() == hdr: - return v - return None - @classmethod def expr(klass): parts = [i.expr() for i in klass.comps] @@ -454,7 +489,7 @@ class Response: def serve(self, fp): started = time.time() - if self.body and not self.get_header("Content-Length"): + if self.body and not utils.get_header("Content-Length", self.headers): self.headers.append( ( LiteralGenerator("Content-Length"), @@ -540,3 +575,10 @@ def parse_response(settings, s): return CraftedResponse(settings, s, Response.expr().parseString(s, parseAll=True)) except pp.ParseException, v: raise ParseException(v.msg, v.line, v.col) + + +def parse_request(settings, s): + try: + return CraftedRequest(settings, s, Request.expr().parseString(s, parseAll=True)) + except pp.ParseException, v: + raise ParseException(v.msg, v.line, v.col) |