Skip to content
Open
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
94 changes: 78 additions & 16 deletions docs/Tutorials/Compression/Requests.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,59 @@
# Requests

You can send Requests to your Pode server that use compression on the payload, such as a JSON payload compressed via GZip.
Pode supports sending requests with compressed payloads (such as JSON compressed with GZip), but it's important to use the correct approach for compression and decompression.

Pode supports the following compression methods:

* gzip
* deflate
* br (Brotli, supported when running under PowerShell Core)

There are a number of ways you can specify the compression type, and these are defined below. When your request uses compression, Pode will first decompress the payload, and then attempt to parse it if needed.
## Important Note on Compression Headers

## Request
> **Note:** While Pode allows the use of the `Transfer-Encoding` header for compatibility with some clients, this is **not** the recommended way to compress request payloads. Pode does **not** decompress the payload on the fly using `Transfer-Encoding`. Instead, Pode expects compressed payloads to be indicated using the `Content-Encoding` header, which is the standard way for HTTP payload compression.

The most common way is to define the a request's compression type in the request's `Transfer-Endocing` header.
If you use `Transfer-Encoding`, Pode will not automatically decompress the request body. This option is only available for legacy or compatibility reasons.

An example of the header in the request is as follows:
## Recommended Approach: Content-Encoding Header

To ensure Pode correctly decompresses the payload, use the `Content-Encoding` header in your requests. For example:

```text
Content-Encoding: gzip
Content-Encoding: deflate
```

Pode will automatically decompress the payload if this header is present and matches a supported encoding.

## Enabling Compression on Routes

To configure how Pode handles compressed payloads, use the `Add-PodeRouteCompression` function. This allows you to enable or disable compression for specific routes and specify which encodings are supported. For example:

```powershell
Add-PodeRoute -Method Post -Path '/upload' -ScriptBlock { ... } -PassThru |
Add-PodeRouteCompression -Enable -Encoding gzip,deflate -Direction Request
```

**Parameters for `Add-PodeRouteCompression`:**

- `-Enable` : Enables compression for the specified route(s).
- `-Disable` : Disables compression for the specified route(s).
- `-Encoding <string[]>` : Specifies one or more compression algorithms to allow. Valid values are: `gzip`, `deflate`, and `br` (Brotli, PowerShell Core only).
- `-Direction <string>` : Sets the direction of compression. Valid values are:
- `Request` (decompress incoming requests)
- `Response` (compress outgoing responses, default)
- `Both` (enable for both requests and responses)
- `-PassThru` : Returns the updated route object(s) to the pipeline for further processing.

This will ensure that incoming requests to `/upload` are decompressed if they use `Content-Encoding: gzip`, `Content-Encoding: deflate`, or `Content-Encoding: br` (Brotli, PowerShell Core only).

## Legacy/Compatibility: Transfer-Encoding Header

Pode still supports the `Transfer-Encoding` header for compatibility with some clients, but this is not the preferred method. If you use this header, Pode will not decompress the payload automatically. Example:

```text
Transfer-Encoding: gzip
Transfer-Encoding: deflate

// or:
Transfer-Encoding: gzip,chunked
```
Expand All @@ -35,7 +70,7 @@ Add-PodeRoute -Method Get -Path '/' -TransferEncoding gzip -ScriptBlock {

## Configuration

Using the `server.psd1` configuration file, you can define a default transfer encoding to use for every route, or you can define patterns to match multiple route paths to set transfer encodings on mass.
Pode also supports configuring default or pattern-based compression behavior in your `server.psd1` configuration file. This allows you to set a default transfer encoding for all routes, or define patterns to match multiple route paths and set transfer encodings in bulk.

### Default

Expand Down Expand Up @@ -70,18 +105,43 @@ For example, the following configuration in your `server.psd1` would bind all `/
}
```

## Precedence
> **Note:** These configuration options are primarily for compatibility and legacy support. For new projects, prefer using `Add-PodeRouteCompression` and the `Content-Encoding` header as described above.

The transfer encoding that will be used is determined by the following order:
## Example: Sending a GZip Encoded Payload (Legacy)

1. Being defined on the Route.
2. The Route matches a pattern defined in the configuration file.
3. A default transfer encoding is defined in the configuration file.
4. The transfer encoding is supplied on the web request.
The following is an example of sending a `gzip` encoded payload using the legacy `Transfer-Encoding` header:

## Example
```powershell
# get the JSON message in bytes
$data = @{
Name = "Deepthought"
Age = 42
}

The following is an example of sending a `gzip` encoded payload to some `/ping` route:
$message = ($data | ConvertTo-Json)
$bytes = [System.Text.Encoding]::UTF8.GetBytes($message)

# compress the message using gzip
$ms = [System.IO.MemoryStream]::new()
$gzip = [System.IO.Compression.GZipStream]::new($ms, [IO.Compression.CompressionMode]::Compress, $true)
$gzip.Write($bytes, 0, $bytes.Length)
$gzip.Close()
$ms.Position = 0

# send request
Invoke-RestMethod `
-Method Post `
-Uri 'http://localhost:8080/ping' `
-Body $ms.ToArray() `
-TransferEncoding gzip `
-ContentType application/json
```

This will ensure Pode correctly decompresses and processes the payload when using legacy `Transfer-Encoding` (not recommended for new projects).

# Example: Sending a GZip Encoded Payload (Recommended)

The following is an example of sending a `gzip` encoded payload using the recommended `Content-Encoding` header:

```powershell
# get the JSON message in bytes
Expand All @@ -105,6 +165,8 @@ Invoke-RestMethod `
-Method Post `
-Uri 'http://localhost:8080/ping' `
-Body $ms.ToArray() `
-TransferEncoding gzip `
-Headers @{ 'Content-Encoding' = 'gzip' } `
-ContentType application/json
```

This will ensure Pode correctly decompresses and processes the payload using the modern and recommended approach.
55 changes: 37 additions & 18 deletions docs/Tutorials/Compression/Responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,71 @@

Pode has support for sending back compressed Responses, if enabled, and if a client sends an appropriate `Accept-Encoding` header.

The followings compression methods are supported:
The following compression methods are supported:

* gzip
* deflate
* br (Brotli, supported when running under PowerShell Core)

When enabled, Pode will compress the response's bytes prior to sending the response; the `Content-Encoding` header will also be sent appropriately on the response.
## Enabling Response Compression with Add-PodeRouteCompression

## Enable

By default response compression is disabled in Pode. To enable compression you can set the following value in your server's `server.psd1` [configuration](../../Configuration) file:
The recommended way to enable response compression is to use the `Add-PodeRouteCompression` function when defining your routes. This allows you to enable or disable compression for specific routes and specify which encodings are supported.

```powershell
@{
Web = @{
Compression = @{
Enable = $true
}
}
}
Add-PodeRoute -Method Get -Path '/data' -ScriptBlock { ... } -PassThru |
Add-PodeRouteCompression -Enable -Encoding gzip,deflate,br -Direction Response
```

Once enabled, compression will be used if a valid `Accept-Encoding` header is sent in the request.
**Parameters for `Add-PodeRouteCompression`:**

* `-Enable` : Enables compression for the specified route(s).
* `-Disable` : Disables compression for the specified route(s).
* `-Encoding <string[]>` : Specifies one or more compression algorithms to allow. Valid values are: `gzip`, `deflate`, and `br` (Brotli, PowerShell Core only).
* `-Direction <string>` : Sets the direction of compression. Use `Response` to compress outgoing responses (default).
* `-PassThru` : Returns the updated route object(s) to the pipeline for further processing.

This will ensure that outgoing responses from `/data` are compressed if the client sends an `Accept-Encoding` header with a supported encoding.

## Headers

For your Pode server to compress the response, the client must send an `Accept-Encoding` header for with `gzip` or `deflate`:
For your Pode server to compress the response, the client must send an `Accept-Encoding` header with `gzip`, `deflate`, or `br` (PowerShell Core only):

```text
Accept-Encoding: gzip
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
```

Or any valid combination:

```text
Accept-Encoding: gzip,deflate
Accept-Encoding: gzip,deflate,br
```

If multiple encodings are sent, then Pode will use the first supported value. There is also support for quality values as well, so you can weight encodings or fully disable non-compression (if no q-value is on an encoding it is assumed to be 1)
If multiple encodings are sent, Pode will use the first supported value. There is also support for quality values as well, so you can weight encodings or fully disable non-compression (if no q-value is on an encoding it is assumed to be 1)

```text
Accept-Encoding: gzip,deflate,identity;q=0
Accept-Encoding: gzip,deflate,br,identity;q=0
```

In a scenario where no encodings are supported, and identity (no-compression) is disabled, then Pode will respond with a 406.
In a scenario where no encodings are supported, and identity (no-compression) is disabled, Pode will respond with a 406.

If an encoding is used to compress the response, then Pode will set the `Content-Encoding` on the response.

## Legacy Approach: Configuration File

By default, response compression is disabled in Pode. The legacy way to enable compression is to set the following value in your server's `server.psd1` [configuration](../../Configuration) file:

```powershell
@{
Web = @{
Compression = @{
Enable = $true
}
}
}
```

Once enabled, compression will be used if a valid `Accept-Encoding` header is sent in the request.
72 changes: 72 additions & 0 deletions docs/Tutorials/Mime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Responses

Pode has support for sending back compressed Responses, if enabled, and if a client sends an appropriate `Accept-Encoding` header.

The following compression methods are supported:

* gzip
* deflate
* br (Brotli, supported when running under PowerShell Core)

## Enabling Response Compression with Add-PodeRouteCompression

The recommended way to enable response compression is to use the `Add-PodeRouteCompression` function when defining your routes. This allows you to enable or disable compression for specific routes and specify which encodings are supported.

```powershell
Add-PodeRoute -Method Get -Path '/data' -ScriptBlock { ... } -PassThru |
Add-PodeRouteCompression -Enable -Encoding gzip,deflate,br -Direction Response
```

**Parameters for `Add-PodeRouteCompression`:**

* `-Enable` : Enables compression for the specified route(s).
* `-Disable` : Disables compression for the specified route(s).
* `-Encoding <string[]>` : Specifies one or more compression algorithms to allow. Valid values are: `gzip`, `deflate`, and `br` (Brotli, PowerShell Core only).
* `-Direction <string>` : Sets the direction of compression. Use `Response` to compress outgoing responses (default).
* `-PassThru` : Returns the updated route object(s) to the pipeline for further processing.

This will ensure that outgoing responses from `/data` are compressed if the client sends an `Accept-Encoding` header with a supported encoding.

## Headers

For your Pode server to compress the response, the client must send an `Accept-Encoding` header with `gzip`, `deflate`, or `br` (PowerShell Core only):

```text
Accept-Encoding: gzip
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
```

Or any valid combination:

```text
Accept-Encoding: gzip,deflate,br
```

If multiple encodings are sent, Pode will use the first supported value. There is also support for quality values as well, so you can weight encodings or fully disable non-compression (if no q-value is on an encoding it is assumed to be 1)

```text
Accept-Encoding: gzip,deflate,br,identity;q=0
```

In a scenario where no encodings are supported, and identity (no-compression) is disabled, Pode will respond with a 406.

If an encoding is used to compress the response, then Pode will set the `Content-Encoding` on the response.

## Legacy Approach: Configuration File

By default, response compression is disabled in Pode. The legacy way to enable compression is to set the following value in your server's `server.psd1` [configuration](../../Configuration) file:

```powershell
@{
Web = @{
Compression = @{
Enable = $true
}
}
}
```

Once enabled, compression will be used if a valid `Accept-Encoding` header is sent in the request.
Loading