Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 54 additions & 8 deletions Hummingbird.docc/Articles/ServerProtocol.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# TLS and HTTP/2
# Server protocol

@Metadata {
@PageImage(purpose: icon, source: "logo")
}

Adding support for TLS and HTTP/2 upgrades.
Support for TLS and HTTP2 upgrades

## Overview

By default a Hummingbird application runs with a HTTP/1.1 server. The Hummingbird comes with additional libraries that allow you to change this to leverage TLS, HTTP/2 and WebSockets. WebSocket upgrade handling is covered in <doc:WebSocketServerUpgrade>.
By default a Hummingbird application runs with a HTTP/1.1 server. The Hummingbird comes with additional libraries that allow you to change this to use TLS, HTTP2 and WebSockets

### Setting server protocol

Expand All @@ -27,11 +27,10 @@ HTTPS is pretty much a requirement for a server these days. Many people run Ngin

```swift
import HummingbirdTLS
import NIOSSL

let tlsConfiguration = TLSConfiguration.makeServerConfiguration(
certificateChain: try NIOSSLCertificate.fromPEMFile("/path/to/certificate.pem").map { .certificate($0) },
privateKey: .privateKey(try NIOSSLPrivateKey(file: "/path/to/privatekey.pem", format: .pem))
certificateChain: certificateChain,
privateKey: privateKey
)
let app = Application(
router: router,
Expand Down Expand Up @@ -63,14 +62,61 @@ let app = Application(
```

The HTTP2 upgrade protocol has a fair amount of configuration. It includes a number of different timeouts,
- `idleTimeout`: How long a connection is kept open while idle.
- `gracefulCloseTimeout`: The maximum amount of time to wait for the client to respond before all streams are closed during graceful close of the connection.
- `idleTimeout`: How long a connection is kept open while idle
- `gracefulCloseTimeout`: The maximum amount of time to wait for the client to respond before all streams are closed after the second GOAWAY is sent
- `maxAgeTimeout`: a maximum amount of time a connection should be open.
Then each HTTP2 stream (request) has its own idle timeout as well.

## WebSockets

WebSocket upgrades are also implemented via the server protocol parameter.

```swift
import HummingbirdWebSocket

let app = Application(
router: router,
server: .http1WebSocketUpgrade { request, channel, logger in
// upgrade if request URI is "/ws"
guard request.uri == "/ws" else { return .dontUpgrade }
// The upgrade response includes the headers to include in the response and
// the WebSocket handler
return .upgrade([:]) { inbound, outbound, context in
for try await frame in inbound {
// send "Received" for every frame we receive
try await outbound.write(.text("Received"))
}
}
}
)
```

In a similar way you add TLS encryption to the HTTP1 connection you can also add TLS to a connection that accepts WebSocket upgrades.

```swift
let app = Application(
router: router,
server: .tls(
.http1WebSocketUpgrade { request, channel, logger in
// upgrade if request URI is "/ws"
guard request.uri == "/ws" else { return .dontUpgrade }
// The upgrade response includes the headers to include in the response and
// the WebSocket handler
return .upgrade([:]) { inbound, outbound, context in
try await outbound.write(.text("Hello"))
}
},
tlsConfiguration: tlsConfiguration
)
)
```

To find out more about WebSocket upgrades and handling WebSocket connections read <doc:WebSocketServerUpgrade>.

## Topics

### Reference

- ``HummingbirdHTTP2``
- ``HummingbirdTLS``
- ``HummingbirdWebSocket``
8 changes: 8 additions & 0 deletions Hummingbird.docc/HummingbirdHTTP2/HummingbirdHTTP2.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ Add HTTP2 support to Hummingbird server.

## Overview

HummingbirdHTTP2 is bundled with Hummingbird, but is not enabled by default. To enable HTTP2 support, you need to add the target dependency to your target:

```sh
swift package add-target-dependency HummingbirdHTTP2 <MyApp> --package hummingbird
```

Make sure to replace `<MyApp>` with the name of your App's target.

HummingbirdHTTP2 provides HTTP2 upgrade support via ``HTTP2UpgradeChannel``. You can add this to your application using ``HummingbirdCore/HTTPServerBuilder/http2Upgrade(tlsConfiguration:additionalChannelHandlers:)``.

```swift
Expand Down
13 changes: 11 additions & 2 deletions Hummingbird.docc/HummingbirdTLS/HummingbirdTLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ Add TLS support to Hummingbird server.

## Overview

HummingbirdTLS provides TLS support via ``TLSChannel``. You can add this to your application using ``HummingbirdCore/HTTPServerBuilder/tls(_:tlsConfiguration:)``.
HummingbirdTLS is bundled with Hummingbird, but is not enabled by default. To enable TLS support, you need to add the target dependency to your target:

```sh
swift package add-target-dependency HummingbirdTLS <MyApp> --package hummingbird
```

Make sure to replace `<MyApp>` with the name of your App's target.

HummingbirdTLS provides TLS protocol support via ``TLSChannel``. You can add this to your application using ``HummingbirdCore/HTTPServerBuilder/tls(_:tlsConfiguration:)``.

```swift
// Load certificates and private key to construct server TLS configuration
Expand All @@ -26,7 +34,7 @@ let app = Application(
)
```

The function `tls` can be used to wrap any other child channel in the example above we use it to wrap an HTTP1 channel.
The function `tls` can be used to wrap another protocol. In the example above we use it to wrap HTTP1 server, and you can also wrap a WebSocket Supporting HTTP/1 server.

## Topics

Expand All @@ -41,3 +49,4 @@ The function `tls` can be used to wrap any other child channel in the example ab
- ``Hummingbird``
- ``HummingbirdCore``
- ``HummingbirdHTTP2``
- ``HummingbirdWebSocket``
45 changes: 43 additions & 2 deletions Hummingbird.docc/HummingbirdWebSocket/HummingbirdWebSocket.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,50 @@ Adds support for upgrading HTTP connections to WebSocket.

## Overview

WebSockets is a protocol providing simultaneous two-way communication channels over a single TCP connection. Unlike HTTP where client requests are paired with a server response, WebSockets allow for communication in both directions asynchronously. It is designed to work over the HTTP ports 80 and 443 via an upgrade process where an initial HTTP request is sent before the connection is upgraded to a WebSocket connection.
WebSockets is a protocol providing simultaneous two-way communication channels over a single TCP connection. Unlike HTTP where client requests are paired with a server response, WebSockets allow for communication in both directions asynchronously, for a prolonged period of time.

HummingbirdWebSocket allows you to implement an HTTP1 server with WebSocket upgrade.
It is designed to work over the HTTP ports 80 and 443 via an upgrade process where an initial HTTP request is sent before the connection is upgraded to a WebSocket connection.

HummingbirdWebSocket allows you to implement an HTTP1 server with WebSocket upgrade. HummingbirdWebSocket passes all the tests in the [Autobahn test suite](https://github.com/crossbario/autobahn-testsuite), supporting both compression and TLS.

To add `HummingbirdWebSocket` to your project, run the following command in your Terminal:

```sh
# From the root directory of your project
# Where Package.swift is located

# Add the package to your dependencies
swift package add-dependency https://github.com/hummingbird-project/hummingbird-websocket.git --from 2.2.0

# Add the target dependency to your target
swift package add-target-dependency HummingbirdWebSocket <MyApp> --package hummingbird-websocket
```

Make sure to replace `<MyApp>` with the name of your App's target.

To integrate `HummingbirdWebSocket` into your project, you need to specify WebSocket support in your `Application`'s configuration:

```swift
import Hummingbird
import HummingbirdWebSocket

let app = Application(
router: router,
server: .http1WebSocketUpgrade { request, channel, logger in
// upgrade if request URI is "/ws"
guard request.uri == "/ws" else { return .dontUpgrade }
// The upgrade response includes the headers to include in the response and
// the WebSocket handler
return .upgrade([:]) { inbound, outbound, context in
// Send "Hello" to the client
try await outbound.write(.text("Hello"))
// Ending this function automatically closes the connection
}
}
)
```

Get started with the WebSockets here: <doc:WebSocketServerUpgrade>

## Topics

Expand Down