Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit 5423cb2

Browse files
author
Joseph Ross
committed
Deflate outgoing messages. Fixes #96.
1 parent d1761d9 commit 5423cb2

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

Source/WebSocket.swift

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ private class Delegate : NSObject, StreamDelegate {
359359
@_silgen_name("deflateInit2_") private func deflateInit2(_ strm : UnsafeMutableRawPointer, level : CInt, method : CInt, windowBits : CInt, memLevel : CInt, strategy : CInt, version : OpaquePointer, stream_size : CInt) -> CInt
360360
@_silgen_name("deflateInit_") private func deflateInit(_ strm : UnsafeMutableRawPointer, level : CInt, version : OpaquePointer, stream_size : CInt) -> CInt
361361
@_silgen_name("deflateEnd") private func deflateEnd(_ strm : UnsafeMutableRawPointer) -> CInt
362-
@_silgen_name("deflate") private func deflate(_ strm : UnsafeMutableRawPointer, flush : CInt) -> CInt
362+
@_silgen_name("deflate") private func deflateG(_ strm : UnsafeMutableRawPointer, flush : CInt) -> CInt
363363
@_silgen_name("inflateInit2_") private func inflateInit2(_ strm : UnsafeMutableRawPointer, windowBits : CInt, version : OpaquePointer, stream_size : CInt) -> CInt
364364
@_silgen_name("inflateInit_") private func inflateInit(_ strm : UnsafeMutableRawPointer, version : OpaquePointer, stream_size : CInt) -> CInt
365365
@_silgen_name("inflate") private func inflateG(_ strm : UnsafeMutableRawPointer, flush : CInt) -> CInt
@@ -470,25 +470,48 @@ private class Deflater {
470470
var memLevel = 0
471471
var strm = z_stream()
472472
var bufferSize = windowBufferSize
473-
var buffer = malloc(windowBufferSize)
473+
var buffer = [UInt8](repeating: 0, count: windowBufferSize)
474+
var headerRemoved = false
475+
474476
init?(windowBits : Int, memLevel : Int){
475-
if buffer == nil {
476-
return nil
477-
}
478477
self.windowBits = windowBits
479478
self.memLevel = memLevel
480-
let ret = deflateInit2(&strm, level: 6, method: 8, windowBits: -CInt(windowBits), memLevel: CInt(memLevel), strategy: 0, version: zlibVersion(), stream_size: CInt(MemoryLayout<z_stream>.size))
479+
let ret = deflateInit2(&strm, level: -1, method: 8, windowBits: -CInt(windowBits), memLevel: CInt(memLevel), strategy: 0, version: zlibVersion(), stream_size: CInt(MemoryLayout<z_stream>.size))
481480
if ret != 0 {
482481
return nil
483482
}
484483
}
485484
deinit{
486485
_ = deflateEnd(&strm)
487-
free(buffer)
488486
}
489-
/*func deflate(_ bufin : UnsafePointer<UInt8>, length : Int, final : Bool) -> (p : UnsafeMutablePointer<UInt8>, n : Int, err : NSError?){
490-
return (nil, 0, nil)
491-
}*/
487+
488+
let Z_SYNC_FLUSH:CInt = 2
489+
490+
public func deflate(_ bufin : [UInt8]) -> (bytes: [UInt8], err: Error?){
491+
var bytes = bufin
492+
var res : CInt
493+
var result = [UInt8]()
494+
strm.avail_in = CUnsignedInt(bytes.count)
495+
strm.next_in = &bytes+0
496+
repeat {
497+
strm.avail_out = CUnsignedInt(buffer.count)
498+
strm.next_out = &buffer+0
499+
res = deflateG(&strm, flush: Z_SYNC_FLUSH)
500+
if res < 0 {
501+
return ([UInt8](), zerror(res))
502+
}
503+
let have = buffer.count - Int(strm.avail_out)
504+
if have > 0 {
505+
result += Array(buffer[0...have-1])
506+
}
507+
} while (strm.avail_out == 0 && res != 1)
508+
if strm.avail_in != 0 {
509+
return ([UInt8](), zerror(-9999))
510+
}
511+
// Strip LEN and NLEN field added for Z_SYNC_FLUSH.
512+
result.removeLast(4)
513+
return (result, nil)
514+
}
492515
}
493516

494517
/// WebSocketDelegate is an Objective-C alternative to WebSocketEvents and is used to delegate the events for the WebSocket connection.
@@ -1413,16 +1436,13 @@ private class InnerWebSocket: Hashable {
14131436
throw WebSocketError.libraryError("cannot send unfinished frames")
14141437
}
14151438
var hlen = 0
1416-
let b : UInt8 = 0x80
1439+
var b : UInt8 = 0x80
14171440
var deflate = false
14181441
if deflater != nil {
14191442
if f.code == .binary || f.code == .text {
14201443
deflate = true
1421-
// b |= 0x40
14221444
}
14231445
}
1424-
head[hlen] = b | f.code.rawValue
1425-
hlen += 1
14261446
var payloadBytes : [UInt8]
14271447
var payloadLen = 0
14281448
if f.utf8.text != "" {
@@ -1432,8 +1452,15 @@ private class InnerWebSocket: Hashable {
14321452
}
14331453
payloadLen += payloadBytes.count
14341454
if deflate {
1435-
1455+
let (result, error) = deflater.deflate(payloadBytes)
1456+
if error == nil {
1457+
payloadBytes = result
1458+
payloadLen = payloadBytes.count
1459+
b |= 0x40
1460+
}
14361461
}
1462+
head[hlen] = b | f.code.rawValue
1463+
hlen += 1
14371464
var usingStatusCode = false
14381465
if f.statusCode != 0 && payloadLen != 0 {
14391466
payloadLen += 2

0 commit comments

Comments
 (0)