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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ RestSharp.IntegrationTests/config.json
/docs/.vuepress/dist/
.vscode/
.temp/
*.trx
*.trx
.DS_Store
.grok/
55 changes: 48 additions & 7 deletions docs/docs/advanced/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ For example:

```csharp
var client = new RestClient(options => {
options.BaseUrl = new Url("https://localhost:5000/api"),
options.DisableCharset = true
options.BaseUrl = new Uri("https://localhost:5000/api");
options.DisableCharset = true;
});
```

Expand Down Expand Up @@ -161,12 +161,13 @@ RestSharp allows configuring `RestClient` using client options, as mentioned at
| `UseDefaultCredentials` | Whether to use default OS credentials for NTLM or Kerberos authentication. Not supported in browsers. |
| `DisableCharset` | When set to `true`, the `Content-Type` header won't have the `charset` portion. Some older web servers don't understand the `charset` portion in the header and fail to process the request. |
| `AutomaticDecompression` | Allows customizing supported decompression methods. Default is `All` except for .NET Framework that only support `GZip`. Not supported in browsers. |
| `MaxRedirects` | The number of redirects to follow. Not supported in browsers. |
| `MaxRedirects` | The number of redirects to follow. Delegates to `RedirectOptions.MaxRedirects`. Default is 50. |
| `ClientCertificates` | A collection of X.509 client certificates to be used for authentication. Not supported in browsers. |
| `Proxy` | Can be used if the client needs to use an explicit, non-default proxy. Not supported in browsers, on iOS and tvOS. |
| `CachePolicy` | Shortcut for setting the default value for `Cache-Control` header. |
| `FollowRedirects` | Instructs the client to follow redirects. Default is `true`. |
| `Expect100Continue` | Gets or sets a value that indicates if the `Expect` header for an HTTP request contains `Continue`. |
| `FollowRedirects` | Instructs the client to follow redirects. Default is `true`. Delegates to `RedirectOptions.FollowRedirects`. |
| `RedirectOptions` | Fine-grained control over redirect behavior. See [Redirect Options](#redirect-options) below. |
| `Expect100Continue` | Gets or sets a value that indicates if the `Expect` header for an HTTP request contains `Continue`. Set per-request, not on `HttpClient.DefaultRequestHeaders`. |
| `UserAgent` | Allows overriding the default value for `User-Agent` header, which is `RestSharp/{version}`. |
| `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. |
Expand All @@ -186,10 +187,8 @@ Some of the options are used by RestSharp code, but some are only used to config
- `UseDefaultCredentials`
- `AutomaticDecompression`
- `PreAuthenticate`
- `MaxRedirects`
- `RemoteCertificateValidationCallback`
- `ClientCertificates`
- `FollowRedirects`
- `Proxy`

:::note
Expand All @@ -207,6 +206,7 @@ Client options apply to all requests made by the client. Sometimes, you want to
| `AlwaysMultipartFormData` | When set to `true`, the request will be sent as a multipart form, even though it's not required. By default, RestSharp only sends requests with multiple attachments as multipart forms. Default is `false`. |
| `AlwaysSingleFileAsContent` | When set to true, the request with file attachment will not be sent as a multipart form, but as plain content. Default is `false`. It cannot be set to `true` when `AlwaysMultipartFormData` is set to `true`, or when the request has `POST` parameters. |
| `MultipartFormQuoteBoundary` | Default is `true`, which means that the form boundary string will be wrapped in quotes. If the server has an issue with that, setting this to `false` will remove quotes around the boundary. |
| `MultipartFormQuoteParameters` | Whether to quote parameter names in multipart form `Content-Disposition` headers per RFC 7578. Default is `true` (changed from `false` in v114). |
| `FormBoundary` | Allows specifying a custom multipart form boundary instead of using the default random string. |
| `RequestParameters` | Collection of request parameters. Normally, you won't need to use it as parameters are added to the request using `Add...` functions. |
| `CookieContainer` | Custom request-level cookie container. Default is `null`. You can still set request cookies using `AddCookie` and get response cookies from the response object without using cooking container. |
Expand Down Expand Up @@ -275,3 +275,44 @@ var longRunningRequest = new RestRequest("long-operation") {
Timeout = Timeout.InfiniteTimeSpan
};
```

## Redirect Options

RestSharp handles redirects internally (rather than delegating to `HttpClient`) so it can capture `Set-Cookie` headers from intermediate redirect responses. The `RedirectOptions` class provides fine-grained control over redirect behavior.

The convenience properties `RestClientOptions.FollowRedirects` and `RestClientOptions.MaxRedirects` delegate to `RedirectOptions` for backward compatibility.

```csharp
var options = new RestClientOptions("https://api.example.com") {
RedirectOptions = new RedirectOptions {
FollowRedirects = true,
MaxRedirects = 10,
ForwardAuthorization = true,
FollowRedirectsToInsecure = false
}
};
```

| Option | Default | Description |
|-----------------------------------|---------|--------------------------------------------------------------------------------------------------------------|
| `FollowRedirects` | `true` | Whether to follow redirects. |
| `MaxRedirects` | `50` | Maximum number of redirects to follow. |
| `FollowRedirectsToInsecure` | `false` | Whether to follow redirects from HTTPS to HTTP. |
| `ForwardHeaders` | `true` | Whether to forward request headers on redirect. |
| `ForwardAuthorization` | `false` | Whether to forward the `Authorization` header on same-host redirects. |
| `ForwardAuthorizationToExternalHost` | `false` | Whether to forward `Authorization` on cross-host redirects. Only applies when `ForwardAuthorization` is true. |
| `ForwardCookies` | `true` | Whether to forward cookies on redirect. `Set-Cookie` headers are always captured regardless. |
| `ForwardBody` | `true` | Whether to forward the request body when the HTTP verb is preserved. Body is always dropped when verb changes to GET. |
| `ForwardQuery` | `true` | Whether to forward the original query string parameters on redirect. |
| `RedirectStatusCodes` | 301, 302, 303, 307, 308 | HTTP status codes considered as redirects. |

## Parameter formatting

By default, all generic parameter methods (`AddParameter<T>`, `AddQueryParameter<T>`, `AddUrlSegment<T>`, `AddHeader<T>`, etc.) format values using `CultureInfo.InvariantCulture`. This ensures consistent behavior regardless of the server's or client's locale.

If you need locale-specific formatting, pass a `CultureInfo` explicitly:

```csharp
request.AddParameter("price", 1234.56, culture: new CultureInfo("da-DK"));
// Sends: price=1234,56
```
2 changes: 2 additions & 0 deletions docs/docs/advanced/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ If there is a network transport error (network is down, failed DNS lookup, etc.)
If an API returns a 404, `ResponseStatus` will still be `Completed`. If you need access to the HTTP status code returned, you will find it at `RestResponse.StatusCode`.
The `Status` property is an indicator of completion independent of the API error handling.

When a request times out, `ResponseStatus` is set to `TimedOut` and `ErrorMessage` will say `"The request timed out."`. For other transport errors, `ErrorMessage` shows the root cause by using `GetBaseException().Message`, so you see the actual error (e.g., a TLS failure) rather than a generic wrapper message like `"An error occurred while sending the request"`. The full exception chain is always available in `ErrorException`.

Normally, RestSharp doesn't throw an exception if the request fails.

However, it is possible to configure RestSharp to throw in different situations when it normally doesn't throw
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/advanced/serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You can tell RestSharp to use a custom serializer by using the `configureSeriali
```csharp
var client = new RestClient(
options,
configureSerialization: s => s.UseSerializer(() => new CustomSerializer());
configureSerialization: s => s.UseSerializer(() => new CustomSerializer())
);
```

Expand Down
34 changes: 30 additions & 4 deletions docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,36 @@ For release notes of previous versions, please check the [Releases page](https:/

Changes between major versions are documented in the documentation for each version on this website.

# v112.0
## v114.0

* Security fix for [CVE-2024-45302](https://github.com/restsharp/RestSharp/security/advisories/GHSA-4rr6-2v9v-wcpc). Header values cannot contain `CRLF`.
### Breaking changes

## v112.1
* **`IAuthenticator` interface signature changed** — `Authenticate` now accepts an optional `CancellationToken` parameter. All custom authenticator implementations must be recompiled. ([#2362](https://github.com/restsharp/RestSharp/pull/2362))
* **`FollowRedirects` and `MaxRedirects` removed from `ReadOnlyRestClientOptions`** — these properties are now excluded from the generated immutable wrapper. Use `RedirectOptions` instead. Code accessing these properties on `ReadOnlyRestClientOptions` must be updated. ([#2360](https://github.com/restsharp/RestSharp/pull/2360))
* **Extension method signatures changed** — `AddParameter<T>`, `AddOrUpdateParameter<T>`, `AddHeader<T>`, `AddOrUpdateHeader<T>`, `AddQueryParameter<T>`, and `AddUrlSegment<T>` now have an additional optional `CultureInfo? culture` parameter. Assemblies compiled against v113 must be recompiled. ([#2354](https://github.com/restsharp/RestSharp/pull/2354))

* Follow up on v112.0 security fix: remove `\t` from the list of forbidden characters in headers.
### New features

* **OAuth2 token lifecycle authenticators** — new `OAuth2ClientCredentialsAuthenticator`, `OAuth2RefreshTokenAuthenticator`, and `OAuth2TokenAuthenticator` that handle obtaining, caching, and refreshing tokens automatically. ([#2362](https://github.com/restsharp/RestSharp/pull/2362))
* **Custom redirect handling with `RedirectOptions`** — RestSharp now manages redirects internally instead of delegating to `HttpClient`, fixing lost `Set-Cookie` headers on redirects. New `RedirectOptions` class provides fine-grained control over redirect behavior. ([#2360](https://github.com/restsharp/RestSharp/pull/2360))
* **`MergedParameters` on `RestResponse`** — provides a combined view of request and default parameters at execution time, useful for logging and debugging. ([#2349](https://github.com/restsharp/RestSharp/pull/2349))
* **Restored `AddCookie(name, value)` overload** — the simple two-parameter form defers domain resolution to execution time. ([#2351](https://github.com/restsharp/RestSharp/pull/2351))

### Behavior changes

* **`MultipartFormQuoteParameters` now defaults to `true`** — multipart form parameter names are now quoted per RFC 7578. ([#2357](https://github.com/restsharp/RestSharp/pull/2357))
* **`InvariantCulture` used for parameter formatting** — all generic parameter methods now format values using `CultureInfo.InvariantCulture` by default. Pass a `CultureInfo` explicitly if locale-specific formatting is needed. ([#2354](https://github.com/restsharp/RestSharp/pull/2354))
* **Improved `ErrorMessage` for timeouts** — now shows `"The request timed out."` instead of `"A task was canceled."`. ([#2356](https://github.com/restsharp/RestSharp/pull/2356))
* **`ErrorMessage` surfaces root cause** — uses `GetBaseException().Message` to show the actual error instead of generic wrapper messages. ([#2352](https://github.com/restsharp/RestSharp/pull/2352))
* **`HttpClient.DefaultRequestHeaders` no longer modified** — `Expect100Continue` is now set per-request. Safe to share an `HttpClient` across multiple `RestClient` instances. ([#2363](https://github.com/restsharp/RestSharp/pull/2363))

### Bug fixes

* Fix `ConfigureAwait(false)` missing on several `await` calls, preventing deadlocks in sync-over-async scenarios. ([#2367](https://github.com/restsharp/RestSharp/pull/2367))
* Fix `ResponseUri` returning original URL instead of redirect target when `FollowRedirects=false`. ([#2350](https://github.com/restsharp/RestSharp/pull/2350))
* Fix default parameter merging bugs (multi-value dedup, request mutation, `BuildUriString` without execute). ([#2349](https://github.com/restsharp/RestSharp/pull/2349))
* Fix OAuth1 double-encoding of RFC 3986 special characters in URL paths. ([#2341](https://github.com/restsharp/RestSharp/pull/2341))
* Fix pipe character encoding when `AddQueryParameter` is used with `encode=false`. ([#2345](https://github.com/restsharp/RestSharp/pull/2345))
* Fix `XmlDeserializer` when XML uses same tag name in nested elements. ([#2339](https://github.com/restsharp/RestSharp/pull/2339))
* Fix credential/`UseDefaultCredentials` property order on `HttpClientHandler`. ([#2353](https://github.com/restsharp/RestSharp/pull/2353))
* Fix URL escaping on .NET Framework 4.6.2. ([#2327](https://github.com/restsharp/RestSharp/pull/2327))
8 changes: 4 additions & 4 deletions docs/docs/usage/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Here's an example of how to create a client using the same base path as in the p
```csharp
// Creates a client using the options object
var options = new RestClientOptions("https://localhost:5000") {
MaxTimeout = 1000
Timeout = TimeSpan.FromSeconds(1)
};
var client = new RestClient(options);
```
Expand All @@ -47,7 +47,7 @@ Another way to create the client instance is to use a simple client factory. The
* `RemoteCertificateValidationCallback`
* `ClientCertificates`
* `MaxRedirects`
* `MaxTimeout`
* `Timeout`
* `UserAgent`
* `Expect100Continue`

Expand All @@ -66,8 +66,8 @@ RestSharp uses `HttpClient` internally to make HTTP requests. It's possible to r

One way of doing it is to use `RestClient` constructors that accept an instance of `HttpClient` or `HttpMessageHandler` as an argument. Note that in that case not all the options provided via `RestClientOptions` will be used. Here is the list of options that will work:

- `BaseAddress` is be used to set the base address of the `HttpClient` instance if base address is not set there already.
- `MaxTimeout` is used to cancel the call using the cancellation token source, so
- `BaseUrl` will be taken from `httpClient.BaseAddress` if not set explicitly.
- `Timeout` is used to cancel the call using the cancellation token source.
- `UserAgent` will be added to the `RestClient.DefaultParameters` list as a HTTP header. This will be added to each request made by the `RestClient`, and the `HttpClient` instance will not be modified. This is to allow the `HttpClient` instance to be reused for scenarios where different `User-Agent` headers are required.
- `Expect100Continue`

Expand Down
Loading
Loading