aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2015-05-01 10:31:45 +1200
committerAldo Cortesi <aldo@nullcube.com>2015-05-01 10:31:45 +1200
commit601cdf70c7339a59537cc8402e4f2648f398b28d (patch)
tree3365e9749edee6d86de1546033dc3481afc77ead
parent3a3ea9d927969750bc1b6fff6994048aa1b928d2 (diff)
downloadmitmproxy-601cdf70c7339a59537cc8402e4f2648f398b28d.tar.gz
mitmproxy-601cdf70c7339a59537cc8402e4f2648f398b28d.tar.bz2
mitmproxy-601cdf70c7339a59537cc8402e4f2648f398b28d.zip
websockets: progressive masking.
-rw-r--r--libpathod/language.py38
1 files changed, 36 insertions, 2 deletions
diff --git a/libpathod/language.py b/libpathod/language.py
index 0fd418a5..e4277eb2 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -191,6 +191,33 @@ v_naked_literal = pp.MatchFirst(
)
+class TransformGenerator:
+ """
+ Perform a byte-by-byte transform another generator - that is, for each
+ input byte, the transformation must produce one output byte.
+
+ gen: A generator to wrap
+ transform: A function (offset, data) -> transformed
+ """
+ def __init__(self, gen, transform):
+ self.gen = gen
+ self.transform = transform
+
+ def __len__(self):
+ return len(self.gen)
+
+ def __getitem__(self, x):
+ d = self.gen.__getitem__(x)
+ return self.transform(x, d)
+
+ def __getslice__(self, a, b):
+ d = self.gen.__getslice__(a, b)
+ return self.transform(a, d)
+
+ def __repr__(self):
+ return "'%s'"%self.gen
+
+
class LiteralGenerator:
def __init__(self, s):
self.s = s
@@ -935,7 +962,6 @@ class _HTTPMessage(_Message):
def preamble(self, settings): # pragma: no cover
pass
-
def values(self, settings):
vals = self.preamble(settings)
vals.append("\r\n")
@@ -1174,8 +1200,10 @@ class WebsocketFrame(_Message):
def values(self, settings):
vals = []
if self.body:
+ bodygen = self.body.value.get_generator(settings)
length = len(self.body.value.get_generator(settings))
else:
+ bodygen = None
length = 0
frame = websockets.FrameHeader(
mask = True,
@@ -1183,7 +1211,13 @@ class WebsocketFrame(_Message):
)
vals = [frame.to_bytes()]
if self.body:
- vals.append(self.body.value.get_generator(settings))
+ masker = websockets.Masker(frame.masking_key)
+ vals.append(
+ TransformGenerator(
+ bodygen,
+ masker.mask
+ )
+ )
return vals
def resolve(self, settings, msg=None):