Repository: deno
Issue: RFC: `Deno.upgradeHttpConnect` API
Labels: suggestion,ext/http

# RFC: Deno.upgradeHttpConnect API for HTTP CONNECT Upgrade

## Overview

This introduces a `Deno.upgradeHttpConnect` function for the Deno `serve` API, enabling the upgrade of incoming HTTP requests with a specific `CONNECT` method. This upgrade mechanism extends the capabilities of the `serve` API, allowing transitions to a tunnelled connection (see [HTTP/1.1 CONNECT Method](https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.6) and [HTTP/2 CONNECT Method](https://datatracker.ietf.org/doc/html/rfc7540#section-8.3)).

To ensure strict adherence to Deno's security model and sandboxing principles, the `Deno.upgradeHttpConnect` function requires users to explicitly provide a `Conn` object. This deliberate requirement serves multiple purposes: 

 - it avoids making implicit connections, forcing the developer to use APIs that are already controlled by the `--allow-net` permissions granted to the Deno application, and
 - it allows Deno to connect the two ends of the connection together without any JavaScript read/write operations, allowing for the most efficient background transfer
 
This API enables developers to handle advanced connection upgrades securely within the Deno runtime environment, while still allowing them to maintain control over network-related permissions.

## Motivation

HTTP proxies play a pivotal role in modern networking by acting as intermediaries between clients and servers. They facilitate various functionalities, including caching, content filtering, access control, and network optimization.

The implementation of HTTP's `CONNECT` method is fundamental for building HTTP proxies that perform transparent SSL proxing. The `CONNECT` HTTP method establishes a tunnel through an HTTP server, allowing clients to directly communicate with external servers, enabling advanced use cases such as low-overhead proxying of WebSocket connections, secure tunneling for SSL/TLS, and accessing resources beyond typical HTTP traffic.

## Proposal

### `Deno.upgradeHttpConnect` API

The `Deno.upgradeHttpConnect` function facilitates the upgrade of an incoming HTTP request with the `CONNECT` method to a raw connection.

#### Syntax:

```typescript
function upgradeHttpConnect(
  request: ServerRequest,
  options?: UpgradeHttpOptions
): HttpConnectUpgradeResult;
```

#### Parameters:

- `request`: A `ServerRequest` object representing the incoming HTTP request to be upgraded.
- `options` (optional): An object containing configuration options for the upgrade process.

#### Return value:

An `HttpConnectUpgradeResult` object representing the upgraded connection and response to be used for the upgrade.

### UpgradeHttpOptions

The `UpgradeHttpOptions` object allows for configuring the upgrade process and includes:

#### Properties:

- `conn`: A `Conn` object representing the target connection for the upgrade process.

This updated structure enables explicit control and specification of the target connection to be used during the upgrade process.

```typescript
interface UpgradeHttpOptions {
  conn: Deno.Conn;
  // Other optional properties as needed
}
```

### HttpConnectUpgradeResult

The `HttpConnectUpgradeResult` object represents the upgraded connection and includes:

#### Properties:

- `response`: A sentinel `Response` object representing the HTTP response to be returned from the `Deno.serve` handler. The response is unused, but satisfies the TypeScript interface of the `Deno.serve` handler function.

## Example Usage

```typescript
if (req.method === "CONNECT") {
  if (req.uri !== "internal.server:1234") {
    throw new Error("Invalid server");
  }
  const { response } = Deno.upgradeHttpConnect(req, { conn: await Deno.connect({ host: "internal.server", port: 1234 }));
  
  // Return the sentinel response
  return response;
}
```

## Protocol Notes

### HTTP/1 CONNECT

The `Deno.upgradeHttpConnect` method for HTTP/1 effectively "hijacks" the underlying HTTP/1 connection when transitioning to an upgraded connection. The connection is no longer usable by HTTP transactions after this operation.

### HTTP/2 CONNECT

In contrast to HTTP/1, in HTTP/2, the `Deno.upgradeHttpConnect` method leverages the re-use of a single HTTP/2 stream to transition to an upgraded connection. This maintains the existing HTTP/2 connection while employing a dedicated stream for the upgraded communication protocol.

## Security Considerations

The `Deno.upgradeHttpConnect` API introduces powerful capabilities for upgrading HTTP connections, which inherently raises security considerations that developers must address to ensure robust and safe application behavior.

### Network Permissions and Sandbox Compliance

The requirement for users to provide a `Conn` object within the `Deno.upgradeHttpConnect` function serves as a deliberate security measure. This necessity ensures adherence to Deno's permission system, particularly the `--allow-net` flag, which governs network-related activities. By requiring the explicit provision of a connection object rather than automatically making the underlying connection, it forces the user to make the underlying network connection operation explicit and visible.

### Potential Risks of Arbitrary Connections

Allowing arbitrary connections through the `Deno.upgradeHttpConnect` API poses inherent risks, particularly when handling external or untrusted sources. Attackers could potentially exploit this capability to intrude into private networks or initiate malicious activities. Developers must meticulously validate and authenticate connections before upgrading them, implementing robust authorization checks and validating the target server's legitimacy to mitigate potential security threats.

Generally, and as with all CONNECT implementations, this API should only be available within the security boundaries of an organization, and should not be available for outside use.

### Protection Against Denial-of-Service (DoS) Attacks

The ability to upgrade connections can potentially expose the application to Denial-of-Service (DoS) attacks. Malicious actors might attempt to overwhelm the application by initiating numerous connection upgrade requests. To mitigate such risks, developers should implement rate limiting, request throttling, and robust request validation mechanisms to safeguard the application and other reachable servers against DoS attacks.

## References

- [HTTP/1.1 CONNECT Method](https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.6)
- [HTTP/2 CONNECT Method](https://datatracker.ietf.org/doc/html/rfc7540#section-8.3)