Merge pull request #2732 from mitmproxy/websocket-flow-kill

fix flow.kill
This commit is contained in:
Maximilian Hils 2017-12-29 23:33:37 +01:00 committed by GitHub
commit 0b80fd00d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 16 deletions

View File

@ -230,7 +230,7 @@ class AddonManager:
self.trigger(name, message) self.trigger(name, message)
if message.reply.state != "taken": if message.reply.state == "start":
message.reply.take() message.reply.take()
if not message.reply.has_message: if not message.reply.has_message:
message.reply.ack() message.reply.ack()

View File

@ -105,16 +105,16 @@ class Reply:
self.q.put(self.value) self.q.put(self.value)
def ack(self, force=False): def ack(self, force=False):
if self.state not in {"start", "taken"}:
raise exceptions.ControlException(
"Reply is {}, but expected it to be start or taken.".format(self.state)
)
self.send(self.obj, force) self.send(self.obj, force)
def kill(self, force=False): def kill(self, force=False):
self.send(exceptions.Kill, force) self.send(exceptions.Kill, force)
def send(self, msg, force=False): def send(self, msg, force=False):
if self.state not in {"start", "taken"}:
raise exceptions.ControlException(
"Reply is {}, but expected it to be start or taken.".format(self.state)
)
if self.has_message and not force: if self.has_message and not force:
raise exceptions.ControlException("There is already a reply message.") raise exceptions.ControlException("There is already a reply message.")
self.value = msg self.value = msg

View File

@ -1,13 +1,12 @@
import time import time
import typing # noqa
import uuid import uuid
from mitmproxy import controller # noqa
from mitmproxy import stateobject
from mitmproxy import connections from mitmproxy import connections
from mitmproxy import controller, exceptions # noqa
from mitmproxy import stateobject
from mitmproxy import version from mitmproxy import version
import typing # noqa
class Error(stateobject.StateObject): class Error(stateobject.StateObject):
@ -145,7 +144,11 @@ class Flow(stateobject.StateObject):
@property @property
def killable(self): def killable(self):
return self.reply and self.reply.state == "taken" return (
self.reply and
self.reply.state in {"start", "taken"} and
self.reply.value != exceptions.Kill
)
def kill(self): def kill(self):
""" """
@ -153,13 +156,7 @@ class Flow(stateobject.StateObject):
""" """
self.error = Error("Connection killed") self.error = Error("Connection killed")
self.intercepted = False self.intercepted = False
# reply.state should be "taken" here, or .take() will raise an
# exception.
if self.reply.state != "taken":
self.reply.take()
self.reply.kill(force=True) self.reply.kill(force=True)
self.reply.commit()
self.live = False self.live = False
def intercept(self): def intercept(self):

View File

@ -221,6 +221,25 @@ class TestSimple(_WebSocketTest):
assert frame.payload == b'foo' assert frame.payload == b'foo'
class TestKillFlow(_WebSocketTest):
@classmethod
def handle_websockets(cls, rfile, wfile):
wfile.write(bytes(websockets.Frame(fin=1, opcode=websockets.OPCODE.TEXT, payload=b'server-foobar')))
wfile.flush()
def test_kill(self):
class KillFlow:
def websocket_message(self, f):
f.kill()
self.master.addons.add(KillFlow())
self.setup_connection()
with pytest.raises(exceptions.TcpDisconnect):
websockets.Frame.from_file(self.client.rfile)
class TestSimpleTLS(_WebSocketTest): class TestSimpleTLS(_WebSocketTest):
ssl = True ssl = True