@@ -90,27 +90,18 @@ function mask!(bytes::Vector{UInt8}, mask)
90
90
end
91
91
return
92
92
end
93
-
94
- function compress (data:: T ) where T <: AbstractVector{UInt8}
95
- compressed = transcode (DeflateCompressor, data)
96
- push! (compressed, 0x00 )
97
- return compressed
98
- end
99
-
100
- function compress (data:: String )
101
- compressed = transcode (DeflateCompressor, data)
102
- push! (compressed, 0x00 )
103
- return String (compressed)
93
+ function final_deflate_codecs (t:: Tuple )
94
+ CodecZlib. TranscodingStreams. finalize (t[1 ])
95
+ CodecZlib. TranscodingStreams. finalize (t[2 ])
104
96
end
105
97
106
- function decompress (data:: T ) where T <: AbstractVector{UInt8}
107
- decompressed = transcode (DeflateDecompressor, append! (data, [0x00 , 0x00 , 0xff , 0xff , 0x03 , 0x00 ]))
108
- return decompressed
109
- end
98
+ function init_deflate_codecs ()
99
+ codecco = DeflateCompressor ()
100
+ CodecZlib. TranscodingStreams. initialize (codecco)
101
+ codecde = DeflateDecompressor ()
102
+ CodecZlib. TranscodingStreams. initialize (codecde)
110
103
111
- function decompress (data:: String )
112
- decompressed = transcode (DeflateDecompressor, append! (Vector {UInt8} (data), [0x00 , 0x00 , 0xff , 0xff , 0x03 , 0x00 ]))
113
- return String (decompressed)
104
+ return (codecco, codecde)
114
105
end
115
106
116
107
@@ -316,20 +307,21 @@ mutable struct WebSocket
316
307
writebuffer:: Vector{UInt8}
317
308
readclosed:: Bool
318
309
writeclosed:: Bool
319
- isdeflate :: Bool
310
+ deflate :: Union{Nothing, Tuple{CodecZlib.CompressorCodec, CodecZlib.DecompressorCodec}}
320
311
end
321
312
322
313
const DEFAULT_MAX_FRAG = 1024
323
314
324
315
WebSocket (io:: Connection , req= Request (), resp= Response (); client:: Bool = true , maxframesize:: Integer = typemax (Int), maxfragmentation:: Integer = DEFAULT_MAX_FRAG, isdeflate:: Bool = false ) =
325
- WebSocket (uuid4 (), io, req, resp, maxframesize, maxfragmentation, client, UInt8[], UInt8[], false , false , isdeflate)
316
+ WebSocket (uuid4 (), io, req, resp, maxframesize, maxfragmentation, client, UInt8[], UInt8[], false , false , isdeflate ? init_deflate_codecs () : nothing )
326
317
327
318
"""
328
319
WebSockets.isclosed(ws) -> Bool
329
320
330
321
Check whether a `WebSocket` has sent and received CLOSE frames.
331
322
"""
332
323
isclosed (ws:: WebSocket ) = ws. readclosed && ws. writeclosed
324
+ isdeflate (ws:: WebSocket ) = ! isnothing (ws. deflate)
333
325
334
326
# Handshake
335
327
" Check whether a HTTP.Request or HTTP.Response is a websocket upgrade request/response"
@@ -534,7 +526,7 @@ function Sockets.send(ws::WebSocket, x)
534
526
# so we can appropriately set the FIN bit for the last fragmented frame
535
527
nextstate = iterate (x, st)
536
528
while true
537
- n += writeframe (ws. io, Frame (nextstate === nothing , first ? opcode (item) : CONTINUATION, ws. client, payload (ws, item); rsv1 = first ? ws . isdeflate : false ))
529
+ n += writeframe (ws. io, Frame (nextstate === nothing , first ? opcode (item) : CONTINUATION, ws. client, payload (ws, item); rsv1 = first ? isdeflate (ws) : false ))
538
530
first = false
539
531
nextstate === nothing && break
540
532
item, st = nextstate
@@ -543,8 +535,8 @@ function Sockets.send(ws::WebSocket, x)
543
535
else
544
536
# single binary or text frame for message
545
537
@label write_single_frame
546
- pl = ws . isdeflate ? compress (payload (ws, x)) : payload (ws, x)
547
- return writeframe (ws. io, Frame (true , opcode (x), ws. client, pl; rsv1= ws . isdeflate))
538
+ pl = isdeflate (ws) ? compress (ws, payload (ws, x)) : payload (ws, x)
539
+ return writeframe (ws. io, Frame (true , opcode (x), ws. client, pl; rsv1= isdeflate (ws) ))
548
540
end
549
541
end
550
542
@@ -620,11 +612,34 @@ function Base.close(ws::WebSocket, body::CloseFrameBody=CloseFrameBody(1000, "")
620
612
@assert ws. readclosed
621
613
# if we're the server, it's our job to close the underlying socket
622
614
! ws. client && isopen (ws. io) && close (ws. io)
615
+ final_deflate_codecs (ws. deflate)
623
616
return
624
617
end
625
618
626
619
# Receiving messages
627
620
621
+ function compress (ws:: WebSocket , data:: T ) where T <: AbstractVector{UInt8}
622
+ compressed = transcode (ws. deflate[1 ], data)
623
+ push! (compressed, 0x00 )
624
+ return compressed
625
+ end
626
+
627
+ function compress (ws:: WebSocket , data:: String )
628
+ compressed = transcode (ws. deflate[1 ], data)
629
+ push! (compressed, 0x00 )
630
+ return String (compressed)
631
+ end
632
+
633
+ function decompress (ws:: WebSocket , data:: T ) where T <: AbstractVector{UInt8}
634
+ decompressed = transcode (ws. deflate[2 ], append! (data, [0x00 , 0x00 , 0xff , 0xff , 0x03 , 0x00 ]))
635
+ return decompressed
636
+ end
637
+
638
+ function decompress (ws:: WebSocket , data:: String )
639
+ decompressed = transcode (ws. deflate[2 ], append! (Vector {UInt8} (data), [0x00 , 0x00 , 0xff , 0xff , 0x03 , 0x00 ]))
640
+ return String (decompressed)
641
+ end
642
+
628
643
# returns whether additional frames should be read
629
644
# true if fragmented message or a ping/pong frame was handled
630
645
@noinline control_len_check (len) = len > 125 && throw (WebSocketError (CloseFrameBody (1002 , " Invalid length for control frame" )))
@@ -686,7 +701,7 @@ function receive(ws::WebSocket)
686
701
done = checkreadframe! (ws, frame)
687
702
# common case of reading single non-control frame
688
703
if done
689
- payload = ws . isdeflate ? decompress (frame. payload) : frame. payload
704
+ payload = isdeflate (ws) ? decompress (ws, frame. payload) : frame. payload
690
705
payload isa String && utf8check (payload)
691
706
return payload
692
707
end
@@ -704,7 +719,7 @@ function receive(ws::WebSocket)
704
719
end
705
720
done && break
706
721
end
707
- payload = ws . isdeflate ? decompress (payload) : payload
722
+ payload = isdeflate (ws) ? decompress (ws, payload) : payload
708
723
payload isa String && utf8check (payload)
709
724
@debugv 2 " Read message: $(payload[1 : min (1024 , sizeof (payload))]) "
710
725
return payload
0 commit comments