Skip to content

Commit bfb8961

Browse files
authored
Add websocket per-message deflate support [RFC 7692] (#4)
1 parent c5ada48 commit bfb8961

33 files changed

+2179
-159
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ Package.resolved
2828
.swiftpm
2929

3030
.build/
31+
32+
# auto-generated reports and logs
33+
Tests/integrationTests/autobahn/reports
34+
Tests/integrationTests/autobahn/scripts/*.log

NOTICE

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,12 @@ This product contains .swift-format from apple/swift-nio.
3939
* https://github.com/apple/swift-nio
4040

4141
---
42+
43+
This product contains compression and decompression code from apple/swift-nio-extras.
44+
45+
* LICENSE (Apache License 2.0):
46+
* https://github.com/apple/swift-nio-extras/blob/main/LICENSE.txt
47+
* HOMEPAGE:
48+
* https://github.com/apple/swift-nio-extras
49+
50+
---

Package.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ let package = Package(
1515
)
1616
],
1717
dependencies: [
18-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.76.1"),
18+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),
1919
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.23.0"),
2020
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.28.0"),
2121
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
@@ -25,6 +25,7 @@ let package = Package(
2525
.target(
2626
name: "LCLWebSocket",
2727
dependencies: [
28+
"CLCLWebSocketZlib",
2829
.product(name: "NIO", package: "swift-nio"),
2930
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
3031
.product(name: "NIOWebSocket", package: "swift-nio"),
@@ -40,10 +41,21 @@ let package = Package(
4041
.product(name: "Atomics", package: "swift-atomics"),
4142
]
4243
),
44+
.target(
45+
name: "CLCLWebSocketZlib",
46+
linkerSettings: [
47+
.linkedLibrary("z")
48+
]
49+
),
4350
.testTarget(
4451
name: "LCLWebSocketTests",
4552
dependencies: ["LCLWebSocket"]
4653
),
54+
.testTarget(
55+
name: "IntegrationTests",
56+
dependencies: ["LCLWebSocket"],
57+
exclude: ["autobahn", "Dockerfile"]
58+
),
4759
.executableTarget(
4860
name: "AutobahnClient",
4961
dependencies: ["LCLWebSocket"]

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ LCL WebSocket is a cross-platform WebSocket [[RFC 6455]](https://datatracker.iet
66

77
## Features
88

9-
- Conform to all [AutoBahn](https://github.com/crossbario/autobahn-testsuite) base cases
9+
- Conform to all [AutoBahn](https://github.com/crossbario/autobahn-testsuite) cases
1010
- High-performance WebSocket client and server, on top of SwiftNIO
1111
- TLS/SSL support
1212
- Thread-safe
1313
- Cross-platform
1414
- Customizable configurations
1515
- Comprehensive error handling
16+
- Support WebSocket per-message deflate extension (RFC 7692)
1617

1718
## Requirements
1819
- Swift 5.9+
@@ -89,12 +90,12 @@ try server.listen(host: "127.0.0.1", port: 8080, configuration: config).wait()
8990

9091

9192
## TODO
92-
- [ ] Support Swift Concurrency
93-
- [ ] Support WebSocket Compression Extension
93+
- [x] Support Swift Concurrency
94+
- [x] Support WebSocket Compression Extension
9495

9596

9697
## Contributing
9798
Any contribution and pull requests are welcome! However, before you plan to implement some features or try to fix an uncertain issue, it is recommended to open a discussion first. You can also join our [Discord channel](https://discord.com/invite/gn4DKF83bP), or visit our [website](https://seattlecommunitynetwork.org/).
9899

99100
## License
100-
LCLPing is released under Apache License. See [LICENSE](/LICENSE) for more details.
101+
lcl-websocket is released under Apache License. See [LICENSE](/LICENSE) for more details.

Sources/AutobahnClient/AutobahnClient.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import NIOPosix
1919
struct TestWebSocketClient {
2020

2121
static let config = LCLWebSocket.Configuration(
22-
maxFrameSize: 1 << 16,
22+
maxFrameSize: 1 << 24,
2323
autoPingConfiguration: .disabled,
2424
leftoverBytesStrategy: .forwardBytes
2525
)
@@ -57,7 +57,8 @@ struct TestWebSocketClient {
5757
}
5858
try client.connect(
5959
to: "ws://\(Self.serverAddress):\(Self.serverPort)/runCase?case=\(i)&agent=\(Self.agentName)",
60-
configuration: Self.config
60+
configuration: Self.config,
61+
supportedExtensions: []
6162
).wait()
6263
}
6364

Sources/AutobahnServer/AutohahnServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import NIOPosix
1919
struct AutohahnServer {
2020

2121
static let config = LCLWebSocket.Configuration(
22-
maxFrameSize: 1 << 16,
22+
maxFrameSize: 1 << 25,
2323
autoPingConfiguration: .disabled,
2424
leftoverBytesStrategy: .forwardBytes
2525
)

Sources/CLCLWebSocketZlib/empty.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// This source file is part of the LCL open source project
3+
//
4+
// Copyright (c) 2021-2024 Local Connectivity Lab and the project authors
5+
// Licensed under Apache License v2.0
6+
//
7+
// See LICENSE for license information
8+
// See CONTRIBUTORS for the list of project authors
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// This source file is part of the LCL open source project
3+
//
4+
// Copyright (c) 2021-2024 Local Connectivity Lab and the project authors
5+
// Licensed under Apache License v2.0
6+
//
7+
// See LICENSE for license information
8+
// See CONTRIBUTORS for the list of project authors
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
13+
#ifndef C_LCLWEBSOCKET_ZLIB_H
14+
#define C_LCLWEBSOCKET_ZLIB_H
15+
16+
#include <zlib.h>
17+
18+
static inline int CLCLWebSocketZlib_deflateInit2(z_streamp strm,
19+
int level,
20+
int method,
21+
int windowBits,
22+
int memLevel,
23+
int strategy) {
24+
return deflateInit2(strm, level, method, windowBits, memLevel, strategy);
25+
}
26+
27+
static inline int CLCLWebSocketZlib_inflateInit2(z_streamp strm, int windowBits) {
28+
return inflateInit2(strm, windowBits);
29+
}
30+
31+
static inline int CLCLWebSocketZlib_inflateReset(z_streamp strm) {
32+
return inflateReset(strm);
33+
}
34+
35+
static inline int CLCLWebSocketZlib_deflateReset(z_streamp strm) {
36+
return deflateReset(strm);
37+
}
38+
39+
static inline int CLCLWebSocketZlib_deflateBound(z_streamp strm, uLong sourceLen) {
40+
return deflateBound(strm, sourceLen);
41+
}
42+
43+
static inline Bytef *CLCLWebSocketZlib_voidPtr_to_BytefPtr(void *in) {
44+
return (Bytef *)in;
45+
}
46+
47+
#endif // C_LCLWEBSOCKET_ZLIB_H

0 commit comments

Comments
 (0)