Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion docs/docs/advanced/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ RestSharp allows configuring `RestClient` using client options, as mentioned at
| `PreAuthenticate` | Gets or sets a value that indicates whether the client sends an `Authorization` header with the request. Not supported in browsers. |
| `RemoteCertificateValidationCallback` | Custom function to validate the server certificate. Normally, it's used when the server uses a certificate that isn't trusted by default. |
| `BaseHost` | Value for the `Host` header sent with each request. |
| `CookieContainer` | Custom cookie container that will be shared among all calls made by the client. Normally not required as RestSharp handles cookies without using a client-level cookie container. |
| `CookieContainer` | Custom cookie container that will be shared among all calls made by the client. Normally not required as RestSharp handles cookies without using a client-level cookie container. On iOS and Mac Catalyst, see [iOS / MAUI Cookie Handling](ios-maui-cookies.md) for additional platform-specific setup required to receive `Set-Cookie` headers. |
| `Timeout` | Client-level timeout as `TimeSpan`. Default is 100 seconds. See [Configuring Timeouts](#configuring-timeouts) for details on timeout behavior. |
| `Encoding` | Default request encoding. Override it only if you don't use UTF-8. |
| `ThrowOnDeserializationError` | Forces the client to throw if it fails to deserialize the response. Remember that not all deserialization issues forces the serializer to throw. Default is `false`, so the client will return a `RestResponse` with deserialization exception details. Only relevant for `Execute...` functions. |
Expand Down
40 changes: 40 additions & 0 deletions docs/docs/advanced/ios-maui-cookies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: iOS / MAUI Cookie Handling
---

On iOS and Mac Catalyst, `Set-Cookie` response headers are silently absent from `RestResponse.Cookies` and from raw response headers, even though the same request works correctly on Android, Windows, and Linux.

## Root cause

Apple's networking stack, `NSURLSession`, intercepts `Set-Cookie` headers before they reach .NET's `HttpClient`. The cookies are stored in `NSHTTPCookieStorage` instead of being forwarded as headers, so RestSharp never sees them.

## Fix

Disable `NSURLSession`'s automatic cookie storage by supplying a custom session configuration via [`ConfigureMessageHandler`](configuration.md#using-custom-message-handler):

```csharp
#if IOS || MACCATALYST
using Foundation;

var options = new RestClientOptions(baseUrl) {
ConfigureMessageHandler = _ => {
var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
config.HttpCookieStorage = null;
config.HttpCookieAcceptPolicy = NSHttpCookieAcceptPolicy.Never;
return new NSUrlSessionHandler(config);
}
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
};
#endif
```

With this configuration, `NSURLSession` passes `Set-Cookie` headers through to .NET unchanged. RestSharp captures them in `RestResponse.Cookies` as it does on all other platforms.

## Multi-tenant safety

Disabling the system cookie store is the correct approach for API clients that serve multiple users or tenants. When `NSHTTPCookieStorage` is active, cookies from one user's session can leak into a subsequent request made by the same client instance. Opting out gives RestSharp full control: cookies are scoped to the individual request via the per-request [`CookieContainer`](../usage/request.md#cookies), and nothing is persisted outside that scope.

:::warning Anti-pattern: shared CookieContainer with UseCookies = true
Do **not** set `HttpClientHandler.UseCookies = true` with a shared `CookieContainer` on the handler. This pools cookies across every request made by the client, which is unsafe for any multi-tenant scenario on any platform.

RestSharp deliberately avoids this pattern. Cookies are managed at the request level; see [Cookies](../usage/request.md#cookies) for details.
:::
4 changes: 4 additions & 0 deletions docs/docs/usage/request.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ There is a `CookieContainer` instance on the request level. You can either assig

If your use case requires sharing cookies between requests made by the client instance, you can use the client-level `CookieContainer`, which you must provide as the options' property. You can add cookies to the container using the container API. No response cookies, however, would be auto-added to the container, but you can do it in code by getting cookies from the `Cookies` property of the response and adding them to the client-level container available via `IRestClient.Options.CookieContainer` property.

:::note iOS and Mac Catalyst
On iOS and Mac Catalyst, `NSURLSession` intercepts `Set-Cookie` headers before .NET can read them, so `RestResponse.Cookies` will be empty even on a successful request. See [iOS / MAUI Cookie Handling](../advanced/ios-maui-cookies.md) for the fix.
:::

## Request Body

RestSharp supports multiple ways to add a request body:
Expand Down