def test_complete_hybi00_wikipedia(self): """ Test complete_hybi00() using the keys listed on Wikipedia's WebSockets page. """ headers = { "Sec-WebSocket-Key1": "4 @1 46546xW%0l 1 5", "Sec-WebSocket-Key2": "12998 5 Y3 1 .P00", } challenge = "^n:ds[4U" self.assertEqual(complete_hybi00(headers, challenge), six.b("8jKS'y:G*Co,Wxa-"))
def dataReceived(self, data): self.buf += data oldstate = None while oldstate != self.state: oldstate = self.state # Handle initial requests. These look very much like HTTP # requests, but aren't. We need to capture the request path for # those browsers which want us to echo it back to them (Chrome, # mainly.) # These lines look like: # GET /some/path/to/a/websocket/resource HTTP/1.1 if self.state == REQUEST: separator = six.b("\r\n") if separator in self.buf: request, chaff, self.buf = self.buf.partition(separator) request = request.decode('utf-8') try: verb, self.location, version = request.split(" ") except ValueError: self.loseConnection() else: self.state = NEGOTIATING elif self.state == NEGOTIATING: # Check to see if we've got a complete set of headers yet. separator = six.b("\r\n\r\n") if separator in self.buf: head, chaff, self.buf = self.buf.partition(separator) head = head.decode('utf-8') self.headers = http_headers(head) # Validate headers. This will cause a state change. if not self.validateHeaders(): self.loseConnection() elif self.state == CHALLENGE: # Handle the challenge. This is completely exclusive to # HyBi-00/Hixie-76. if len(self.buf) >= 8: challenge, self.buf = self.buf[:8], self.buf[8:] challenge = challenge.decode('utf-8') response = complete_hybi00(self.headers, challenge) self.sendHyBi00Preamble() self.writeEncoded(response) log.msg("Completed HyBi-00/Hixie-76 handshake") # We're all finished here; start sending frames. self.state = FRAMES elif self.state == FRAMES: self.parseFrames() # Kick any pending frames. This is needed because frames might have # started piling up early; we can get write()s from our protocol above # when they makeConnection() immediately, before our browser client # actually sends any data. In those cases, we need to manually kick # pending frames. if self.pending_frames: self.sendFrames()