Add "text" subprotocol, and make it the default.
Websockify previously forced you to specify, "binary" or "base64"
when constructing a WebSocket, forcing you to either handle Blobs
or start all your processing in btoa().
This patch gives a mode to websockify to pass data unprocessed without
marking it with the 0x2 opcode that makes browsers interpret websocket
frames as Blobs. This lets client code that works against other WebSocket
implementations, such as AutobahnPython, to also work unchanged.
In code, the difference is, previously you would have to do:
```
var ws = new WebSocket("ws://localhost:8080", "binary")
ws.onmessage = function(e) {
var F = new FileReader();
var payload = null;
F.readAsText(e.data);
F.onloadend = function() {
payload = F.result;
}
}
```
or
```
var ws = new WebSocket("ws://localhost:8080", "base64")
ws.onmessage = function(e) {
var payload = btoa(e.data);
}
```
Now you can just do
```
var ws = new WebSocket("ws://localhost:8080")
ws.onmessage = function(e) {
var payload = e.data;
}
```
This patch still *allows* the old way to work (in particular, when pushing
lots of data, careful Blob processing of should help performance.. I think.)
This commit is contained in:
parent
63209f84ca
commit
f345e4e86a
|
|
@ -147,13 +147,16 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
@staticmethod
|
||||
def encode_hybi(buf, opcode, base64=False):
|
||||
""" Encode a HyBi style WebSocket frame.
|
||||
Optional opcode:
|
||||
Opcode, defined by the HyBi spec:
|
||||
0x0 - continuation
|
||||
0x1 - text frame (base64 encode buf)
|
||||
0x2 - binary frame (use raw buf)
|
||||
0x1 - text frame
|
||||
0x2 - binary frame
|
||||
0x8 - connection close
|
||||
0x9 - ping
|
||||
0xA - pong
|
||||
|
||||
If base64 is set, the buffer will be base64 encoded before being sent.
|
||||
This is probably only useful in conjunction with opcode=0x1.
|
||||
"""
|
||||
if base64:
|
||||
buf = b64encode(buf)
|
||||
|
|
@ -297,10 +300,12 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
if bufs:
|
||||
for buf in bufs:
|
||||
if self.base64:
|
||||
if self.mode == 'base64':
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=1, base64=True)
|
||||
else:
|
||||
elif self.mode == 'binary':
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=2, base64=False)
|
||||
elif self.mode == 'text':
|
||||
encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=1, base64=False)
|
||||
|
||||
if self.rec:
|
||||
self.rec.write("%s,\n" %
|
||||
|
|
@ -415,12 +420,13 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
|
||||
# Choose binary if client supports it
|
||||
if 'binary' in protocols:
|
||||
self.base64 = False
|
||||
self.mode = 'binary'
|
||||
elif 'base64' in protocols:
|
||||
self.base64 = True
|
||||
self.mode = 'base64'
|
||||
elif 'text' in protocols:
|
||||
self.mode = 'text'
|
||||
else:
|
||||
self.send_error(400, "Client must support 'binary' or 'base64' protocol")
|
||||
return False
|
||||
self.mode = 'text'
|
||||
|
||||
# Generate the hash value for the accept header
|
||||
accept = b64encode(sha1(s2b(key + self.GUID)).digest())
|
||||
|
|
@ -431,15 +437,23 @@ class WebSocketRequestHandler(SimpleHTTPRequestHandler):
|
|||
self.send_header("Sec-WebSocket-Accept", b2s(accept))
|
||||
if self.base64:
|
||||
self.send_header("Sec-WebSocket-Protocol", "base64")
|
||||
else:
|
||||
elif self.binary:
|
||||
self.send_header("Sec-WebSocket-Protocol", "binary")
|
||||
# no header for "text" mode; it is the default websocket mode.
|
||||
|
||||
self.end_headers()
|
||||
return True
|
||||
else:
|
||||
self.send_error(400, "Missing Sec-WebSocket-Version header. Hixie protocols not supported.")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@property
|
||||
def base64(self): return self.mode == 'base64'
|
||||
|
||||
@property
|
||||
def binary(self): return self.mode == 'binary'
|
||||
|
||||
def handle_websocket(self):
|
||||
"""Upgrade a connection to Websocket, if requested. If this succeeds,
|
||||
new_websocket_client() will be called. Otherwise, False is returned.
|
||||
|
|
|
|||
Loading…
Reference in New Issue