def setUp(self): self.channel = DummyChannel() self.request = request = Request(self.channel, False) # Simulate request handling request.startedWriting = True transport = WebSocketTransport(request) self.handler = TestHandler(transport) transport._attachHandler(self.handler)
def setUp(self): self.channel = DummyChannel() request = Request(self.channel, False) transport = WebSocketTransport(request) handler = TestHandler(transport) transport._attachHandler(handler) self.decoder = WebSocketFrameDecoder(request, handler) self.decoder.MAX_LENGTH = 100
def _checkClientHandshake(self): """ Verify client handshake, closing the connection in case of problem. @return: C{None} if a problem was detected, or a tuple of I{Origin} header, I{Host} header, I{WebSocket-Protocol} header, and C{WebSocketHandler} instance. The I{WebSocket-Protocol} header will be C{None} if not specified by the client. """ def finish(): self.channel.transport.loseConnection() if self.queued: return finish() originHeaders = self.requestHeaders.getRawHeaders("Origin", []) if len(originHeaders) != 1: return finish() hostHeaders = self.requestHeaders.getRawHeaders("Host", []) if len(hostHeaders) != 1: return finish() handlerFactory = self.site.handlers.get(self.uri) if not handlerFactory: return finish() transport = WebSocketTransport(self) handler = handlerFactory(transport) transport._attachHandler(handler) protocolHeaders = self.requestHeaders.getRawHeaders( "WebSocket-Protocol", []) if len(protocolHeaders) not in (0, 1): return finish() if protocolHeaders: if protocolHeaders[0] not in self.site.supportedProtocols: return finish() protocolHeader = protocolHeaders[0] else: protocolHeader = None return originHeaders[0], hostHeaders[0], protocolHeader, handler
def _clientHandshake76(self): """ Complete hixie-76 handshake, which consists of a challenge and response. If the request is not identified with a proper WebSocket handshake, the connection will be closed. Otherwise, the response to the handshake is sent and a C{WebSocketHandler} is created to handle the request. """ def finish(): self.channel.transport.loseConnection() if self.queued: return finish() secKey1 = self.requestHeaders.getRawHeaders("Sec-WebSocket-Key1", []) secKey2 = self.requestHeaders.getRawHeaders("Sec-WebSocket-Key2", []) if len(secKey1) != 1 or len(secKey2) != 1: return finish() # copied originHeaders = self.requestHeaders.getRawHeaders("Origin", []) if len(originHeaders) != 1: return finish() hostHeaders = self.requestHeaders.getRawHeaders("Host", []) if len(hostHeaders) != 1: return finish() handlerFactory = self.site.handlers.get(self.uri) if not handlerFactory: return finish() # key1 and key2 exist and are a string of characters # filter both keys to get a string with all numbers in order key1 = secKey1[0] key2 = secKey2[0] numBuffer1 = ''.join([x for x in key1 if x in _ascii_numbers]) numBuffer2 = ''.join([x for x in key2 if x in _ascii_numbers]) # make sure numbers actually exist if not numBuffer1 or not numBuffer2: return finish() # these should be int-like num1 = int(numBuffer1) num2 = int(numBuffer2) # count the number of spaces in each character string numSpaces1 = 0 for x in key1: if x == ' ': numSpaces1 += 1 numSpaces2 = 0 for x in key2: if x == ' ': numSpaces2 += 1 # there should be at least one space in each if numSpaces1 == 0 or numSpaces2 == 0: return finish() # get two resulting numbers, as specified in hixie-76 num1 = num1 / numSpaces1 num2 = num2 / numSpaces2 transport = WebSocketTransport(self) handler = handlerFactory(transport) transport._attachHandler(handler) self.channel.setRawMode() def finishHandshake(nonce): """ Receive nonce value from request body, and calculate repsonse. """ protocolHeaders = self.requestHeaders.getRawHeaders( "WebSocket-Protocol", []) if len(protocolHeaders) not in (0, 1): return finish() if protocolHeaders: if protocolHeaders[0] not in self.site.supportedProtocols: return finish() protocolHeader = protocolHeaders[0] else: protocolHeader = None originHeader = originHeaders[0] hostHeader = hostHeaders[0] self.startedWriting = True handshake = [ "HTTP/1.1 101 Web Socket Protocol Handshake", "Upgrade: WebSocket", "Connection: Upgrade" ] handshake.append("Sec-WebSocket-Origin: %s" % (originHeader)) if self.isSecure(): scheme = "wss" else: scheme = "ws" handshake.append("Sec-WebSocket-Location: %s://%s%s" % (scheme, hostHeader, self.uri)) if protocolHeader is not None: handshake.append("Sec-WebSocket-Protocol: %s" % protocolHeader) for header in handshake: self.write("%s\r\n" % header) self.write("\r\n") # concatenate num1 (32 bit in), num2 (32 bit int), nonce, and take md5 of result res = struct.pack('>II8s', num1, num2, nonce) server_response = md5(res).digest() self.write(server_response) # XXX we probably don't want to set _transferDecoder self.channel._transferDecoder = WebSocketFrameDecoder( self, handler) transport._connectionMade() # we need the nonce from the request body self.channel._transferDecoder = _IdentityTransferDecoder( 0, lambda _: None, finishHandshake)