Skip to content

Commit 7c0ea7b

Browse files
authored
Fixes including - Don't include Content-Length in request (#25)
1 parent 9476ce3 commit 7c0ea7b

File tree

4 files changed

+43
-9
lines changed

4 files changed

+43
-9
lines changed

Sources/WSClient/Client/URI.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
/// Simple URL parser
1616
struct URI: Sendable, CustomStringConvertible, ExpressibleByStringLiteral {
17-
struct Scheme: RawRepresentable, Equatable {
17+
struct Scheme: RawRepresentable, Equatable, CustomStringConvertible {
1818
let rawValue: String
1919

2020
init(rawValue: String) {
@@ -28,6 +28,8 @@ struct URI: Sendable, CustomStringConvertible, ExpressibleByStringLiteral {
2828
static var https_unix: Self { .init(rawValue: "https_unix") }
2929
static var ws: Self { .init(rawValue: "ws") }
3030
static var wss: Self { .init(rawValue: "wss") }
31+
32+
var description: String { self.rawValue }
3133
}
3234

3335
let string: String

Sources/WSClient/WebSocketClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public struct WebSocketClient {
163163
configuration: self.configuration
164164
),
165165
tlsConfiguration: TLSConfiguration.makeClientConfiguration(),
166-
serverHostname: host
166+
serverHostname: self.configuration.sniHostname ?? host
167167
),
168168
address: .hostname(host, port: port),
169169
eventLoopGroup: self.eventLoopGroup,

Sources/WSClient/WebSocketClientChannel.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ struct WebSocketClientChannel: ClientConnectionChannel {
3030

3131
let urlPath: String
3232
let hostHeader: String
33+
let originHeader: String
3334
let handler: WebSocketDataHandler<WebSocketClient.Context>
3435
let configuration: WebSocketClientConfiguration
3536

3637
init(handler: @escaping WebSocketDataHandler<WebSocketClient.Context>, url: URI, configuration: WebSocketClientConfiguration) throws {
37-
guard let hostHeader = Self.urlHostHeader(for: url) else { throw WebSocketClientError.invalidURL }
38+
guard let (hostHeader, originHeader) = Self.urlHostAndOriginHeaders(for: url) else { throw WebSocketClientError.invalidURL }
3839
self.hostHeader = hostHeader
40+
self.originHeader = originHeader
3941
self.urlPath = Self.urlPath(for: url)
4042
self.handler = handler
4143
self.configuration = configuration
@@ -63,8 +65,8 @@ struct WebSocketClientChannel: ClientConnectionChannel {
6365
)
6466

6567
var headers = HTTPHeaders()
66-
headers.add(name: "Content-Length", value: "0")
67-
headers.add(name: "Host", value: self.hostHeader)
68+
headers.replaceOrAdd(name: "Host", value: self.hostHeader)
69+
headers.replaceOrAdd(name: "Origin", value: self.originHeader)
6870
let additionalHeaders = HTTPHeaders(self.configuration.additionalHeaders)
6971
headers.add(contentsOf: additionalHeaders)
7072
// add websocket extensions to headers
@@ -128,12 +130,13 @@ struct WebSocketClientChannel: ClientConnectionChannel {
128130
url.path + (url.query.map { "?\($0)" } ?? "")
129131
}
130132

131-
static func urlHostHeader(for url: URI) -> String? {
132-
guard let host = url.host else { return nil }
133+
static func urlHostAndOriginHeaders(for url: URI) -> (host: String, origin: String)? {
134+
guard let scheme = url.scheme, let host = url.host else { return nil }
135+
let origin = "\(scheme)://\(host)"
133136
if let port = url.port {
134-
return "\(host):\(port)"
137+
return (host: "\(host):\(port)", origin: origin)
135138
} else {
136-
return host
139+
return (host: host, origin: origin)
137140
}
138141
}
139142
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Hummingbird server framework project
4+
//
5+
// Copyright (c) 2025 the Hummingbird authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Logging
16+
import XCTest
17+
18+
@testable import WSClient
19+
20+
final class ClientChannelTests: XCTestCase {
21+
22+
func testInitialRequestHeader() async throws {
23+
let ws = try WebSocketClientChannel(handler: { _, _, _ in }, url: "wss://echo.websocket.org:443/ws", configuration: .init())
24+
25+
XCTAssertEqual(ws.urlPath, "/ws")
26+
XCTAssertEqual(ws.hostHeader, "echo.websocket.org:443")
27+
XCTAssertEqual(ws.originHeader, "wss://echo.websocket.org")
28+
}
29+
}

0 commit comments

Comments
 (0)