From 244ef243d75145a01d9029589de65be51299b3f3 Mon Sep 17 00:00:00 2001 From: Krzysztof Bielicki Date: Tue, 10 Mar 2015 10:44:06 +0100 Subject: [#514] Add support for ignoring payload params in multipart/form-data --- libmproxy/utils.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'libmproxy/utils.py') diff --git a/libmproxy/utils.py b/libmproxy/utils.py index 51f2dc26..b84c589a 100644 --- a/libmproxy/utils.py +++ b/libmproxy/utils.py @@ -69,6 +69,33 @@ def urlencode(s): return urllib.urlencode(s, False) +def multipartdecode(hdrs, content): + """ + Takes a multipart boundary encoded string and returns list of (key, value) tuples. + """ + v = hdrs.get_first("content-type") + if v: + v = parse_content_type(v) + if not v: + return [] + boundary = v[2].get("boundary") + if not boundary: + return [] + + rx = re.compile(r'\bname="([^"]+)"') + r = [] + + for i in content.split("--" + boundary): + parts = i.splitlines() + if len(parts) > 1 and parts[0][0:2] != "--": + match = rx.search(parts[1]) + if match: + key = match.group(1) + value = "".join(parts[3+parts[2:].index(""):]) + r.append((key, value)) + return r + return [] + def pretty_size(size): suffixes = [ ("B", 2**10), -- cgit v1.2.3 From 842e23d3e386169d9a90cef2a634c55a3e5fdd8e Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 22 Mar 2015 21:00:41 +1300 Subject: Replace far-too-clever decorator LRU cache with something simpler --- libmproxy/utils.py | 53 +++++++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 30 deletions(-) (limited to 'libmproxy/utils.py') diff --git a/libmproxy/utils.py b/libmproxy/utils.py index 51f2dc26..5ed70a45 100644 --- a/libmproxy/utils.py +++ b/libmproxy/utils.py @@ -119,40 +119,33 @@ pkg_data = Data(__name__) class LRUCache: """ - A decorator that implements a self-expiring LRU cache for class - methods (not functions!). - - Cache data is tracked as attributes on the object itself. There is - therefore a separate cache for each object instance. + A simple LRU cache for generated values. """ def __init__(self, size=100): self.size = size + self.cache = {} + self.cacheList = [] + + def get(self, gen, *args): + """ + gen: A (presumably expensive) generator function. The identity of + gen is NOT taken into account by the cache. + *args: A list of immutable arguments, used to establish identiy by + *the cache, and passed to gen to generate values. + """ + if self.cache.has_key(args): + self.cacheList.remove(args) + self.cacheList.insert(0, args) + return self.cache[args] + else: + ret = gen(*args) + self.cacheList.insert(0, args) + self.cache[args] = ret + if len(self.cacheList) > self.size: + d = self.cacheList.pop() + self.cache.pop(d) + return ret - def __call__(self, f): - cacheName = "_cached_%s"%f.__name__ - cacheListName = "_cachelist_%s"%f.__name__ - size = self.size - - @functools.wraps(f) - def wrap(self, *args): - if not hasattr(self, cacheName): - setattr(self, cacheName, {}) - setattr(self, cacheListName, []) - cache = getattr(self, cacheName) - cacheList = getattr(self, cacheListName) - if cache.has_key(args): - cacheList.remove(args) - cacheList.insert(0, args) - return cache[args] - else: - ret = f(self, *args) - cacheList.insert(0, args) - cache[args] = ret - if len(cacheList) > size: - d = cacheList.pop() - cache.pop(d) - return ret - return wrap def parse_content_type(c): """ -- cgit v1.2.3 From 1c26516b1822d82e3b701539591a1d22831e0a19 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 30 Apr 2015 12:18:01 +1200 Subject: pretty_size now lives in netlib.utils --- libmproxy/utils.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'libmproxy/utils.py') diff --git a/libmproxy/utils.py b/libmproxy/utils.py index 02e8403b..7d0e369b 100644 --- a/libmproxy/utils.py +++ b/libmproxy/utils.py @@ -96,20 +96,6 @@ def multipartdecode(hdrs, content): return r return [] -def pretty_size(size): - suffixes = [ - ("B", 2**10), - ("kB", 2**20), - ("MB", 2**30), - ] - for suf, lim in suffixes: - if size >= lim: - continue - else: - x = round(size/float(lim/2**10), 2) - if x == int(x): - x = int(x) - return str(x) + suf def pretty_duration(secs): formatters = [ @@ -124,6 +110,7 @@ def pretty_duration(secs): #less than 1 sec return "{:.0f}ms".format(secs*1000) + class Data: def __init__(self, name): m = __import__(name) -- cgit v1.2.3 From a05a70d8168a07c92b2a3ecbbb1958d85532efe3 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 30 May 2015 12:03:28 +1200 Subject: Add coding style check, reformat. --- libmproxy/utils.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'libmproxy/utils.py') diff --git a/libmproxy/utils.py b/libmproxy/utils.py index 7d0e369b..a29a53f5 100644 --- a/libmproxy/utils.py +++ b/libmproxy/utils.py @@ -1,8 +1,14 @@ from __future__ import absolute_import -import os, datetime, urllib, re -import time, functools, cgi +import os +import datetime +import urllib +import re +import time +import functools +import cgi import json + def timestamp(): """ Returns a serializable UTC timestamp. @@ -91,7 +97,7 @@ def multipartdecode(hdrs, content): match = rx.search(parts[1]) if match: key = match.group(1) - value = "".join(parts[3+parts[2:].index(""):]) + value = "".join(parts[3 + parts[2:].index(""):]) r.append((key, value)) return r return [] @@ -107,8 +113,8 @@ def pretty_duration(secs): for limit, formatter in formatters: if secs >= limit: return formatter.format(secs) - #less than 1 sec - return "{:.0f}ms".format(secs*1000) + # less than 1 sec + return "{:.0f}ms".format(secs * 1000) class Data: @@ -126,7 +132,7 @@ class Data: """ fullpath = os.path.join(self.dirname, path) if not os.path.exists(fullpath): - raise ValueError, "dataPath: %s does not exist."%fullpath + raise ValueError("dataPath: %s does not exist." % fullpath) return fullpath pkg_data = Data(__name__) @@ -135,10 +141,11 @@ class LRUCache: """ A simple LRU cache for generated values. """ + def __init__(self, size=100): self.size = size self.cache = {} - self.cacheList = [] + self.cacheList = [] def get(self, gen, *args): """ @@ -147,7 +154,7 @@ class LRUCache: *args: A list of immutable arguments, used to establish identiy by *the cache, and passed to gen to generate values. """ - if self.cache.has_key(args): + if args in self.cache: self.cacheList.remove(args) self.cacheList.insert(0, args) return self.cache[args] @@ -195,14 +202,14 @@ def hostport(scheme, host, port): if (port, scheme) in [(80, "http"), (443, "https")]: return host else: - return "%s:%s"%(host, port) + return "%s:%s" % (host, port) def unparse_url(scheme, host, port, path=""): """ Returns a URL string, constructed from the specified compnents. """ - return "%s://%s%s"%(scheme, hostport(scheme, host, port), path) + return "%s://%s%s" % (scheme, hostport(scheme, host, port), path) def clean_hanging_newline(t): @@ -243,7 +250,7 @@ def parse_size(s): try: return int(s) * mult except ValueError: - raise ValueError("Invalid size specification: %s"%s) + raise ValueError("Invalid size specification: %s" % s) def safe_subn(pattern, repl, target, *args, **kwargs): -- cgit v1.2.3