websockets: replace the "raw" with a simpler mechanism

You can now say "knone" to specifiy that no key should be generated
under any circumstances.
This commit is contained in:
Aldo Cortesi 2015-05-17 11:04:53 +12:00
parent e4feba5433
commit cd2fb13b3e
3 changed files with 25 additions and 24 deletions

View File

@ -9,7 +9,6 @@ from . import base, generators, actions, message
wf:fin:rsv1:rsv2:rsv3:mask wf:fin:rsv1:rsv2:rsv3:mask
wf:-fin:-rsv1:-rsv2:-rsv3:-mask wf:-fin:-rsv1:-rsv2:-rsv3:-mask
wf:k"mask"
wf:l234 wf:l234
""" """
@ -35,10 +34,6 @@ class Body(base.Value):
preamble = "b" preamble = "b"
class Raw(base.CaselessLiteral):
TOK = "r"
class Fin(base.Boolean): class Fin(base.Boolean):
name = "fin" name = "fin"
@ -64,6 +59,11 @@ class Key(base.FixedLengthValue):
length = 4 length = 4
class KeyNone(base.CaselessLiteral):
unique_name = "Key"
TOK = "knone"
class WebsocketFrame(message.Message): class WebsocketFrame(message.Message):
comps = ( comps = (
Body, Body,
@ -78,9 +78,8 @@ class WebsocketFrame(message.Message):
actions.PauseAt, actions.PauseAt,
actions.DisconnectAt, actions.DisconnectAt,
actions.InjectAt, actions.InjectAt,
KeyNone,
Key, Key,
Raw,
) )
logattrs = ["body"] logattrs = ["body"]
@property @property
@ -119,6 +118,10 @@ class WebsocketFrame(message.Message):
def key(self): def key(self):
return self.tok(Key) return self.tok(Key)
@property
def knone(self):
return self.tok(KeyNone)
@classmethod @classmethod
def expr(klass): def expr(klass):
parts = [i.expr() for i in klass.comps] parts = [i.expr() for i in klass.comps]
@ -139,7 +142,7 @@ class WebsocketFrame(message.Message):
tokens.append( tokens.append(
Mask(True) Mask(True)
) )
if self.mask and self.mask.value and not self.key: if not self.knone and self.mask and self.mask.value and not self.key:
tokens.append( tokens.append(
Key(base.TokValueLiteral(os.urandom(4))) Key(base.TokValueLiteral(os.urandom(4)))
) )
@ -159,7 +162,9 @@ class WebsocketFrame(message.Message):
) )
if self.mask and self.mask.value: if self.mask and self.mask.value:
frameparts["mask"] = True frameparts["mask"] = True
if self.key: if self.knone:
frameparts["masking_key"] = None
elif self.key:
key = self.key.values(settings)[0][:] key = self.key.values(settings)[0][:]
frameparts["masking_key"] = key frameparts["masking_key"] = key
for i in ["opcode", "fin", "rsv1", "rsv2", "rsv3", "mask"]: for i in ["opcode", "fin", "rsv1", "rsv2", "rsv3", "mask"]:

View File

@ -48,7 +48,8 @@
<td> k<a href="#valuespec">VALUE</a> </td> <td> k<a href="#valuespec">VALUE</a> </td>
<td> <td>
Set the masking key. The resulting value must be exactly 4 Set the masking key. The resulting value must be exactly 4
bytes long. bytes long. The special form <b>knone</b> specifies that no key
should be set, even if the mask bit is on.
</td> </td>
</tr> </tr>
@ -67,18 +68,6 @@
</td> </td>
</tr> </tr>
<tr>
<td> r </td>
<td>
Create a "raw" frame:
<ul>
<li> Don't auto-generate the masking key if the mask flag is
set </li>
<li> Don't set the mask flag if masking key is set. </li>
</td>
</tr>
<tr> <tr>
<td> [-]rsv1 </td> <td> [-]rsv1 </td>
<td> <td>

View File

@ -17,7 +17,7 @@ class TestWebsocketFrame:
"wf:b'foo'", "wf:b'foo'",
"wf:cbinary", "wf:cbinary",
"wf:c1", "wf:c1",
"wf:r", "wf:mask:knone",
"wf:fin", "wf:fin",
"wf:fin:rsv1:rsv2:rsv3:mask", "wf:fin:rsv1:rsv2:rsv3:mask",
"wf:-fin:-rsv1:-rsv2:-rsv3:-mask", "wf:-fin:-rsv1:-rsv2:-rsv3:-mask",
@ -67,7 +67,7 @@ class TestWebsocketFrame:
assert self.fr("wf:ctext").header.opcode ==\ assert self.fr("wf:ctext").header.opcode ==\
netlib.websockets.OPCODE.TEXT netlib.websockets.OPCODE.TEXT
def test_auto_raw(self): def test_construction(self):
# Simple server frame # Simple server frame
frm = self.fr("wf:b'foo'") frm = self.fr("wf:b'foo'")
assert not frm.header.mask assert not frm.header.mask
@ -99,3 +99,10 @@ class TestWebsocketFrame:
# We're reading back a corrupted frame - the first 3 characters of the # We're reading back a corrupted frame - the first 3 characters of the
# mask is mis-interpreted as the payload # mask is mis-interpreted as the payload
assert frm.payload == "abc" assert frm.payload == "abc"
def test_knone(self):
tutils.raises(
"expected 4 bytes",
self.fr,
"wf:b'foo':mask:knone",
)