Permalink
Browse files

handle situations when WebSocket opening handshake was never complete…

…d; add test case for the former - fixes #7
  • Loading branch information...
oberstet committed Oct 17, 2014
1 parent 833a744 commit 3684191838e3c47e780b1e918d16856c5269d728
@@ -18,6 +18,8 @@
import pickle
+from autobahn.websocket.protocol import WebSocketProtocol
+
class Case:
@@ -98,29 +100,34 @@ def onConnectionLost(self, failedByMe):
self.result = "Actual events match at least one expected."
break
- # check the close status
- if self.expectedClose["closedByMe"] != self.p.closedByMe:
- self.behaviorClose = Case.FAILED
- self.resultClose = "The connection was failed by the wrong endpoint"
- elif self.expectedClose["requireClean"] and not self.p.wasClean:
- self.behaviorClose = Case.UNCLEAN
- self.resultClose = "The spec requires the connection to be failed cleanly here"
- elif self.p.remoteCloseCode != None and self.p.remoteCloseCode not in self.expectedClose["closeCode"]:
- self.behaviorClose = Case.WRONG_CODE
- self.resultClose = "The close code should have been %s or empty" % ','.join(map(str,self.expectedClose["closeCode"]))
- elif not self.p.factory.isServer and self.p.droppedByMe:
- self.behaviorClose = Case.FAILED_BY_CLIENT
- self.resultClose = "It is preferred that the server close the TCP connection"
+ if self.p.connectionWasOpen:
+ # check the close status
+ if self.expectedClose["closedByMe"] != self.p.closedByMe:
+ self.behaviorClose = Case.FAILED
+ self.resultClose = "The connection was failed by the wrong endpoint"
+ elif self.expectedClose["requireClean"] and not self.p.wasClean:
+ self.behaviorClose = Case.UNCLEAN
+ self.resultClose = "The spec requires the connection to be failed cleanly here"
+ elif self.p.remoteCloseCode != None and self.p.remoteCloseCode not in self.expectedClose["closeCode"]:
+ self.behaviorClose = Case.WRONG_CODE
+ self.resultClose = "The close code should have been %s or empty" % ','.join(map(str,self.expectedClose["closeCode"]))
+ elif not self.p.factory.isServer and self.p.droppedByMe:
+ self.behaviorClose = Case.FAILED_BY_CLIENT
+ self.resultClose = "It is preferred that the server close the TCP connection"
+ else:
+ self.behaviorClose = Case.OK
+ self.resultClose = "Connection was properly closed"
+
+ ## for UTF8 tests, closing by wrong endpoint means case failure, since
+ ## the peer then did not detect the invalid UTF8 at all
+ ##
+ closedByWrongEndpointIsFatal = self.expectedClose.get("closedByWrongEndpointIsFatal", False)
+ if closedByWrongEndpointIsFatal and self.expectedClose["closedByMe"] != self.p.closedByMe:
+ self.behavior = Case.FAILED
else:
- self.behaviorClose = Case.OK
- self.resultClose = "Connection was properly closed"
+ self.behaviorClose = Case.FAILED
+ self.resultClose = "The WebSocket opening handshake was never completed!"
- ## for UTF8 tests, closing by wrong endpoint means case failure, since
- ## the peer then did not detect the invalid UTF8 at all
- ##
- closedByWrongEndpointIsFatal = self.expectedClose.get("closedByWrongEndpointIsFatal", False)
- if closedByWrongEndpointIsFatal and self.expectedClose["closedByMe"] != self.p.closedByMe:
- self.behavior = Case.FAILED
def finishWhenDone(self):
# if we match at least one expected outcome check if we are supposed to
@@ -34,14 +34,18 @@ def onOpen(self):
def onConnectionLost(self, failedByMe):
Case.onConnectionLost(self, failedByMe)
- frames_expected = {}
- frames_expected[0] = len(self.payload) / self.p.autoFragmentSize
- frames_expected[1] = 1 if len(self.payload) % self.p.autoFragmentSize > 0 else 0
- frames_got = {}
- frames_got[0] = self.p.txFrameStats[0]
- frames_got[1] = self.p.txFrameStats[1]
- if frames_expected == frames_got:
- pass
+ if self.p.connectionWasOpen:
+ frames_expected = {}
+ frames_expected[0] = len(self.payload) / self.p.autoFragmentSize
+ frames_expected[1] = 1 if len(self.payload) % self.p.autoFragmentSize > 0 else 0
+ frames_got = {}
+ frames_got[0] = self.p.txFrameStats[0]
+ frames_got[1] = self.p.txFrameStats[1]
+ if frames_expected == frames_got:
+ pass
+ else:
+ self.behavior = Case.FAILED
+ self.result = "Frames transmitted %s does not match what we expected %s." % (str(frames_got), str(frames_expected))
else:
self.behavior = Case.FAILED
- self.result = "Frames transmitted %s does not match what we expected %s." % (str(frames_got), str(frames_expected))
+ self.result = "WebSocket connection was never open"
@@ -38,7 +38,10 @@ def onConnectionLost(self, failedByMe):
## the close reason we sent was invalid UTF8, so we
## convert to HEX representation for later case reporting
- self.p.localCloseReason = binascii.b2a_hex(self.p.localCloseReason)
+ if self.p.localCloseReason:
+ self.p.localCloseReason = binascii.b2a_hex(self.p.localCloseReason)
+ else:
+ self.p.localCloseReason = "?"
def onOpen(self):
self.payload = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5\xed\xa0\x80\x65\x64\x69\x74\x65\x64'
@@ -86,7 +86,7 @@ class FuzzingProtocol:
def connectionMade(self):
- attrs = ['case', 'runCase', 'caseAgent', 'caseStarted']
+ attrs = ['case', 'runCase', 'caseAgent', 'caseStarted', 'connectionWasOpen']
for attr in attrs:
if not hasattr(self, attr):
@@ -277,6 +277,8 @@ def closeAfter(self, delay):
def onOpen(self):
+ self.connectionWasOpen = True
+
if self.runCase:
cc_id = self.factory.CaseSet.caseClasstoId(self.runCase.__class__)
@@ -0,0 +1,21 @@
+from twisted.internet.protocol import Protocol
+from twisted.internet.protocol import Factory
+from twisted.internet.endpoints import TCP4ServerEndpoint
+from twisted.internet import reactor
+
+
+class ClosingServerProtocol(Protocol):
+
+ def connectionMade(self):
+ self.transport.loseConnection()
+
+
+class ClosingServerFactory(Factory):
+
+ protocol = ClosingServerProtocol
+
+
+
+endpoint = TCP4ServerEndpoint(reactor, 9001)
+endpoint.listen(ClosingServerFactory())
+reactor.run()

0 comments on commit 3684191

Please sign in to comment.