diff options
author | Aldo Cortesi <aldo@nullcube.com> | 2012-02-20 10:34:32 +1300 |
---|---|---|
committer | Aldo Cortesi <aldo@nullcube.com> | 2012-02-20 10:39:00 +1300 |
commit | 2616f490fee1b732aa0853318d67a550fc561cc4 (patch) | |
tree | b93ebc1f266682f422791fc63ad15ce3d5d0467d /libmproxy | |
parent | 25a06c3ec18a9ed49f34213024330aed59cb5322 (diff) | |
download | mitmproxy-2616f490fee1b732aa0853318d67a550fc561cc4.tar.gz mitmproxy-2616f490fee1b732aa0853318d67a550fc561cc4.tar.bz2 mitmproxy-2616f490fee1b732aa0853318d67a550fc561cc4.zip |
Rename Headers class to ODict
ODict is an ordered dictionary class that will be useful in many other parts of
our API.
Diffstat (limited to 'libmproxy')
-rw-r--r-- | libmproxy/console/connview.py | 4 | ||||
-rw-r--r-- | libmproxy/flow.py | 64 | ||||
-rw-r--r-- | libmproxy/proxy.py | 31 |
3 files changed, 48 insertions, 51 deletions
diff --git a/libmproxy/console/connview.py b/libmproxy/console/connview.py index ed038a11..b722f78e 100644 --- a/libmproxy/console/connview.py +++ b/libmproxy/console/connview.py @@ -371,7 +371,7 @@ class ConnectionView(common.WWrap): self.master.refresh_connection(self.flow) def set_headers(self, lst, conn): - conn.headers = flow.Headers(lst) + conn.headers = flow.ODict(lst) def set_query(self, lst, conn): conn.set_query(lst) @@ -384,7 +384,7 @@ class ConnectionView(common.WWrap): conn = self.flow.request else: if not self.flow.response: - self.flow.response = flow.Response(self.flow.request, 200, "OK", flow.Headers(), "") + self.flow.response = flow.Response(self.flow.request, 200, "OK", flow.ODict(), "") conn = self.flow.response self.flow.backup() diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 024d23e6..f29dcf27 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -44,7 +44,7 @@ class ScriptContext: self._master.replay_request(f) -class Headers: +class ODict: def __init__(self, lst=None): self.lst = lst or [] @@ -69,12 +69,12 @@ class Headers: new.append(i) return new - def __setitem__(self, k, hdrs): - if isinstance(hdrs, basestring): - raise ValueError("Header values should be lists.") + def __setitem__(self, k, values): + if isinstance(values, basestring): + raise ValueError("ODict values should be lists.") k = self._kconv(k) new = self._filter_lst(k, self.lst) - for i in hdrs: + for i in values: new.append((k, i)) self.lst = new @@ -102,22 +102,19 @@ class Headers: Returns a copy of this object. """ lst = copy.deepcopy(self.lst) - return Headers(lst) + return ODict(lst) def __repr__(self): - """ - Returns a string containing a formatted header string. - """ - headerElements = [] + elements = [] for itm in self.lst: - headerElements.append(itm[0] + ": " + itm[1]) - headerElements.append("") - return "\r\n".join(headerElements) + elements.append(itm[0] + ": " + itm[1]) + elements.append("") + return "\r\n".join(elements) def match_re(self, expr): """ - Match the regular expression against each header. For each (key, - value) pair a string of the following format is matched against: + Match the regular expression against each (key, value) pair. For + each pair a string of the following format is matched against: "key: value" """ @@ -127,32 +124,9 @@ class Headers: return True return False - def read(self, fp): - """ - Read a set of headers from a file pointer. Stop once a blank line - is reached. - """ - ret = [] - name = '' - while 1: - line = fp.readline() - if not line or line == '\r\n' or line == '\n': - break - if line[0] in ' \t': - # continued header - ret[-1][1] = ret[-1][1] + '\r\n ' + line.strip() - else: - i = line.find(':') - # We're being liberal in what we accept, here. - if i > 0: - name = line[:i] - value = line[i+1:].strip() - ret.append([name, value]) - self.lst = ret - def replace(self, pattern, repl, *args, **kwargs): """ - Replaces a regular expression pattern with repl in both header keys + Replaces a regular expression pattern with repl in both keys and values. Returns the number of replacements made. """ nlst, count = [], 0 @@ -199,7 +173,7 @@ class Request(HTTPMsg): Exposes the following attributes: client_conn: ClientConnection object, or None if this is a replay. - headers: Headers object + headers: ODict object content: Content of the request, or None scheme: URL scheme (http/https) @@ -276,7 +250,7 @@ class Request(HTTPMsg): self.scheme = state["scheme"] self.method = state["method"] self.path = state["path"] - self.headers = Headers._from_state(state["headers"]) + self.headers = ODict._from_state(state["headers"]) self.content = state["content"] self.timestamp = state["timestamp"] @@ -302,7 +276,7 @@ class Request(HTTPMsg): str(state["scheme"]), str(state["method"]), str(state["path"]), - Headers._from_state(state["headers"]), + ODict._from_state(state["headers"]), state["content"], state["timestamp"] ) @@ -434,7 +408,7 @@ class Response(HTTPMsg): request: Request object. code: HTTP response code msg: HTTP response message - headers: Headers object + headers: ODict object content: Response content timestamp: Seconds since the epoch """ @@ -508,7 +482,7 @@ class Response(HTTPMsg): def _load_state(self, state): self.code = state["code"] self.msg = state["msg"] - self.headers = Headers._from_state(state["headers"]) + self.headers = ODict._from_state(state["headers"]) self.content = state["content"] self.timestamp = state["timestamp"] @@ -527,7 +501,7 @@ class Response(HTTPMsg): request, state["code"], str(state["msg"]), - Headers._from_state(state["headers"]), + ODict._from_state(state["headers"]), state["content"], state["timestamp"], ) diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 43277a6c..ff5e3ec7 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -30,6 +30,31 @@ class ProxyConfig: self.reverse_proxy = reverse_proxy + +def read_headers(fp): + """ + Read a set of headers from a file pointer. Stop once a blank line + is reached. Return a ODict object. + """ + ret = [] + name = '' + while 1: + line = fp.readline() + if not line or line == '\r\n' or line == '\n': + break + if line[0] in ' \t': + # continued header + ret[-1][1] = ret[-1][1] + '\r\n ' + line.strip() + else: + i = line.find(':') + # We're being liberal in what we accept, here. + if i > 0: + name = line[:i] + value = line[i+1:].strip() + ret.append([name, value]) + return flow.ODict(ret) + + def read_chunked(fp, limit): content = "" total = 0 @@ -224,8 +249,7 @@ class ServerConnection: code = int(code) except ValueError: raise ProxyError(502, "Invalid server response: %s."%line) - headers = flow.Headers() - headers.read(self.rfile) + headers = read_headers(self.rfile) if code >= 100 and code <= 199: return self.read_response() if self.request.method == "HEAD" or code == 204 or code == 304: @@ -350,8 +374,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler): method, scheme, host, port, path, httpminor = parse_request_line(self.rfile.readline()) if scheme is None: scheme = "https" - headers = flow.Headers() - headers.read(self.rfile) + headers = read_headers(self.rfile) if host is None and "host" in headers: netloc = headers["host"][0] if ':' in netloc: |