From 2b8885974e8d9f522e787805000553f4f7cce8a0 Mon Sep 17 00:00:00 2001 From: fumoboy007 <2100868+fumoboy007@users.noreply.github.com> Date: Mon, 6 Mar 2023 16:12:21 -0800 Subject: [PATCH] Do not add a `Content-Type` header to the HTTP upgrade request (#127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not add a `Content-Type` header to the HTTP upgrade request. Fixes #126. [Some](https://alpaca.markets/docs/api-references/trading-api/streaming/) WebSocket servers use the `Content-Type` header to determine which serialization format to use for its WebSocket messages. However, `HTTPInitialRequestHandler` [adds](https://github.com/vapor/websocket-kit/blob/62f568aa9d338aa33790534fa7b5800976f93af8/Sources/WebSocketKit/HTTPInitialRequestHandler.swift#L24) a hard-coded `Content-Type: text/plain; charset=utf-8` header to the WebSocket client’s HTTP upgrade request, so the client cannot customize the header value. Given that the HTTP upgrade request body is empty, there is no need for `HTTPInitialRequestHandler` to add the `Content-Type` header. This will allow the client to add their own, if desired. Co-authored-by: fumoboy007 Co-authored-by: Tim Condon <0xTim@users.noreply.github.com> --- .../HTTPInitialRequestHandler.swift | 1 - .../WebSocketKitTests/WebSocketKitTests.swift | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Sources/WebSocketKit/HTTPInitialRequestHandler.swift b/Sources/WebSocketKit/HTTPInitialRequestHandler.swift index 9dbe9368..e74cbf2e 100644 --- a/Sources/WebSocketKit/HTTPInitialRequestHandler.swift +++ b/Sources/WebSocketKit/HTTPInitialRequestHandler.swift @@ -21,7 +21,6 @@ final class HTTPInitialRequestHandler: ChannelInboundHandler, RemovableChannelHa func channelActive(context: ChannelHandlerContext) { var headers = self.headers - headers.add(name: "Content-Type", value: "text/plain; charset=utf-8") headers.add(name: "Host", value: self.host) var uri = self.path.hasPrefix("/") ? self.path : "/" + self.path diff --git a/Tests/WebSocketKitTests/WebSocketKitTests.swift b/Tests/WebSocketKitTests/WebSocketKitTests.swift index b0e080ed..19bef5a1 100644 --- a/Tests/WebSocketKitTests/WebSocketKitTests.swift +++ b/Tests/WebSocketKitTests/WebSocketKitTests.swift @@ -179,12 +179,20 @@ final class WebSocketKitTests: XCTestCase { func testHeadersAreSent() throws { let promiseAuth = self.elg.next().makePromise(of: String.self) - // make sure there is no content-length header - let promiseNoContentLength = self.elg.next().makePromise(of: Bool.self) + // make sure there are no unwanted headers such as `Content-Length` or `Content-Type` + let promiseHasUnwantedHeaders = self.elg.next().makePromise(of: Bool.self) let server = try ServerBootstrap.webSocket(on: self.elg) { req, ws in - promiseAuth.succeed(req.headers.first(name: "Auth")!) - promiseNoContentLength.succeed(req.headers.contains(name: "content-length")) + let headers = req.headers + + promiseAuth.succeed(headers.first(name: "Auth")!) + + let hasUnwantedHeaders = ( + headers.contains(name: "Content-Length") || + headers.contains(name: "Content-Type") + ) + promiseHasUnwantedHeaders.succeed(hasUnwantedHeaders) + ws.close(promise: nil) }.bind(host: "localhost", port: 0).wait() @@ -201,7 +209,7 @@ final class WebSocketKitTests: XCTestCase { }.cascadeFailure(to: promiseAuth) try XCTAssertEqual(promiseAuth.futureResult.wait(), "supersecretsauce") - try XCTAssertFalse(promiseNoContentLength.futureResult.wait()) + try XCTAssertFalse(promiseHasUnwantedHeaders.futureResult.wait()) try server.close(mode: .all).wait() }