Skip to content
Merged
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
Prev Previous commit
Next Next commit
Merge branch 'dev' into more-execute-overloads
# Conflicts:
#	RestSharp.sln.DotSettings
#	src/RestSharp/RestClient.Async.cs
#	src/RestSharp/RestClient.Extensions.Config.cs
#	src/RestSharp/RestClient.Extensions.cs
#	src/RestSharp/Sync/AsyncHelpers.cs
  • Loading branch information
alexeyzimarev committed Jul 4, 2023
commit 71bf9e36dea884adf7c8ca4528a3960470030c85
33 changes: 0 additions & 33 deletions RestSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Tests.Serializers
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Serializers.Xml", "src\RestSharp.Serializers.Xml\RestSharp.Serializers.Xml.csproj", "{4A35B1C5-520D-4267-BA70-2DCEAC0A5662}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Tests.Legacy", "test\RestSharp.Tests.Legacy\RestSharp.Tests.Legacy.csproj", "{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Serializers.CsvHelper", "src\RestSharp.Serializers.CsvHelper\RestSharp.Serializers.CsvHelper.csproj", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Tests.Serializers.Csv", "test\RestSharp.Tests.Serializers.Csv\RestSharp.Tests.Serializers.Csv.csproj", "{E6D94FFD-7811-40BE-ABC4-6D6AB41F0060}"
Expand Down Expand Up @@ -358,36 +356,6 @@ Global
{4A35B1C5-520D-4267-BA70-2DCEAC0A5662}.Release|x64.Build.0 = Release|Any CPU
{4A35B1C5-520D-4267-BA70-2DCEAC0A5662}.Release|x86.ActiveCfg = Release|Any CPU
{4A35B1C5-520D-4267-BA70-2DCEAC0A5662}.Release|x86.Build.0 = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|Any CPU.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|Any CPU.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|ARM.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|ARM.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|Mixed Platforms.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|x64.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|x64.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|x86.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug.Appveyor|x86.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|ARM.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|x64.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|x64.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|x86.ActiveCfg = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Debug|x86.Build.0 = Debug|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|Any CPU.Build.0 = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|ARM.ActiveCfg = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|ARM.Build.0 = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|x64.ActiveCfg = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|x64.Build.0 = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|x86.ActiveCfg = Release|Any CPU
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0}.Release|x86.Build.0 = Release|Any CPU
{2150E333-8FDC-42A3-9474-1A3956D46DE8}.Debug.Appveyor|Any CPU.ActiveCfg = Debug|Any CPU
{2150E333-8FDC-42A3-9474-1A3956D46DE8}.Debug.Appveyor|Any CPU.Build.0 = Debug|Any CPU
{2150E333-8FDC-42A3-9474-1A3956D46DE8}.Debug.Appveyor|ARM.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -492,7 +460,6 @@ Global
{6D7D1D60-4473-4C52-800C-9B892C6640A5} = {9051DDA0-E563-45D5-9504-085EBAACF469}
{E6D94C12-9AD7-46E6-AB62-3676F25FDE51} = {9051DDA0-E563-45D5-9504-085EBAACF469}
{4A35B1C5-520D-4267-BA70-2DCEAC0A5662} = {8C7B43EB-2F93-483C-B433-E28F9386AD67}
{5A8A5BBE-28DA-4C89-B393-BE39A96E8DC0} = {9051DDA0-E563-45D5-9504-085EBAACF469}
{2150E333-8FDC-42A3-9474-1A3956D46DE8} = {8C7B43EB-2F93-483C-B433-E28F9386AD67}
{E6D94FFD-7811-40BE-ABC4-6D6AB41F0060} = {9051DDA0-E563-45D5-9504-085EBAACF469}
{FE778406-ADCF-45A1-B775-A054B55BFC50} = {55B8F371-B2BA-4DEE-AB98-5BAB8A21B1C2}
Expand Down
3 changes: 2 additions & 1 deletion RestSharp.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=advisor/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Advisors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=appsettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deserialaized/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deserilization/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=formattable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=instagram/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Migrator/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -104,5 +104,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=usings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Zimarev/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,30 @@
using BenchmarkDotNet.Order;
using System.Globalization;

namespace RestSharp.Benchmarks.Requests {
[MemoryDiagnoser, RankColumn, Orderer(SummaryOrderPolicy.FastestToSlowest)]
public partial class AddObjectToRequestParametersBenchmarks {
Data _data;
namespace RestSharp.Benchmarks.Requests;

[GlobalSetup]
public void GlobalSetup() {
const string @string = "random string";
const int arraySize = 10_000;
var strings = new string[arraySize];
Array.Fill(strings, @string);
var ints = new int[arraySize];
Array.Fill(ints, int.MaxValue);
[MemoryDiagnoser, RankColumn, Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class AddObjectToRequestParametersBenchmarks {
Data _data;

Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("01/01/2013 03:03:12");
[GlobalSetup]
public void GlobalSetup() {
const string @string = "random string";
const int arraySize = 10_000;
var strings = new string[arraySize];
Array.Fill(strings, @string);
var ints = new int[arraySize];
Array.Fill(ints, int.MaxValue);

_data = new Data(@string, int.MaxValue, strings, ints, dateTime, strings);
}
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("01/01/2013 03:03:12");

[Benchmark(Baseline = true)]
public void AddObject() => new RestRequest().AddObject(_data);
_data = new Data(@string, int.MaxValue, strings, ints, dateTime, strings);
}

[Benchmark]
public void AddObjectStatic() => new RestRequest().AddObjectStatic(_data);
[Benchmark(Baseline = true)]
public void AddObject() => new RestRequest().AddObject(_data);

}
}
[Benchmark]
public void AddObjectStatic() => new RestRequest().AddObjectStatic(_data);
}
18 changes: 9 additions & 9 deletions benchmarks/RestSharp.Benchmarks/Requests/Data.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace RestSharp.Benchmarks.Requests {
sealed record Data(
string String,
[property: RequestProperty(Name = "PropertyName")] int Int32,
string[] Strings,
[property: RequestProperty(Format = "00000", ArrayQueryType = RequestArrayQueryType.ArrayParameters)] int[] Ints,
[property: RequestProperty(Name = "DateTime", Format = "hh:mm tt")] object DateTime,
object StringArray);
}
namespace RestSharp.Benchmarks.Requests;

sealed record Data(
string String,
[property: RequestProperty(Name = "PropertyName")] int Int32,
string[] Strings,
[property: RequestProperty(Format = "00000", ArrayQueryType = RequestArrayQueryType.ArrayParameters)] int[] Ints,
[property: RequestProperty(Name = "DateTime", Format = "hh:mm tt")] object DateTime,
object StringArray);
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
using BenchmarkDotNet.Attributes;
using RestSharp.Serializers.NewtonsoftJson;

namespace RestSharp.Benchmarks.Serializers
namespace RestSharp.Benchmarks.Serializers;

[MemoryDiagnoser]
public class JsonNetSerializeBenchmarks
{
[MemoryDiagnoser]
public class JsonNetSerializeBenchmarks
{
readonly JsonNetSerializer _serializer = new();
readonly JsonNetSerializer _serializer = new();

List<TestClass> _fakeData;
List<TestClass> _fakeData;

[Params(1, 10, 20)]
public int N { get; set; }
[Params(1, 10, 20)]
public int N { get; set; }

[GlobalSetup]
public void GlobalSetup() => _fakeData = new Fixture().CreateMany<TestClass>(N).ToList();
[GlobalSetup]
public void GlobalSetup() => _fakeData = new Fixture().CreateMany<TestClass>(N).ToList();

[Benchmark(Baseline = true)]
public string Serialize() => _serializer.Serialize(_fakeData);
}
}
[Benchmark(Baseline = true)]
public string Serialize() => _serializer.Serialize(_fakeData);
}
1 change: 1 addition & 0 deletions benchmarks/RestSharp.Benchmarks/Serializers/TestClass.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ReSharper disable UnusedMember.Global
namespace RestSharp.Benchmarks.Serializers;

public class TestClass {
Expand Down
65 changes: 52 additions & 13 deletions docs/authenticators.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
# Authenticators

RestSharp includes authenticators for basic HTTP (Authorization header),
NTLM and parameter-based systems.
RestSharp includes authenticators for basic HTTP, OAuth1 and token-based (JWT and OAuth2).

There are two ways to set the authenticator: client-wide or per-request.

Set the client-wide authenticator by assigning the `Authenticator` property of `RestClientOptions`:

```csharp
var options = new RestClientOptions("http://example.com") {
Authenticator = new HttpBasicAuthenticator("username", "password")
};
var client = new RestClient(options);
```

To set the authenticator per-request, assign the `Authenticator` property of `RestRequest`:

```csharp
var request = new RestRequest("/api/users/me") {
Authenticator = new HttpBasicAuthenticator("username", "password")
};
var response = await client.ExecuteAsync(request, cancellationToken);
```

## Basic Authentication

The `HttpBasicAuthenticator` allows you pass a username and password as a basic `Authorization` header using a base64 encoded string.

```csharp
var client = new RestClient("http://example.com");
client.Authenticator = new HttpBasicAuthenticator("username", "password");
var options = new RestClientOptions("http://example.com") {
Authenticator = new HttpBasicAuthenticator("username", "password")
};
var client = new RestClient(options);
```

## OAuth1
Expand All @@ -21,23 +42,29 @@ For OAuth1 authentication the `OAuth1Authenticator` class provides static method
This method requires a `consumerKey` and `consumerSecret` to authenticate.

```csharp
var client = new RestClient("http://example.com");
client.Authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret);
var options = new RestClientOptions("http://example.com") {
Authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret)
};
var client = new RestClient(options);
```

### Access token

This method retrieves an access token when provided `consumerKey`, `consumerSecret`, `oauthToken`, and `oauthTokenSecret`.

```csharp
client.Authenticator = OAuth1Authenticator.ForAccessToken(
var authenticator = OAuth1Authenticator.ForAccessToken(
consumerKey, consumerSecret, oauthToken, oauthTokenSecret
);
var options = new RestClientOptions("http://example.com") {
Authenticator = authenticator
};
var client = new RestClient(options);
```

This method also includes an optional parameter to specify the `OAuthSignatureMethod`.
```csharp
client.Authenticator = OAuth1Authenticator.ForAccessToken(
var authenticator = OAuth1Authenticator.ForAccessToken(
consumerKey, consumerSecret, oauthToken, oauthTokenSecret,
OAuthSignatureMethod.PlainText
);
Expand All @@ -48,7 +75,7 @@ client.Authenticator = OAuth1Authenticator.ForAccessToken(
The same access token authenticator can be used in 0-legged OAuth scenarios by providing `null` for the `consumerSecret`.

```csharp
client.Authenticator = OAuth1Authenticator.ForAccessToken(
var authenticator = OAuth1Authenticator.ForAccessToken(
consumerKey, null, oauthToken, oauthTokenSecret
);
```
Expand All @@ -64,9 +91,13 @@ RestSharp has two very simple authenticators to send the access token as part of
For example:

```csharp
client.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(
var authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(
token, "Bearer"
);
var options = new RestClientOptions("http://example.com") {
Authenticator = authenticator
};
var client = new RestClient(options);
```

The code above will tell RestSharp to send the bearer token with each request as a header. Essentially, the code above does the same as the sample for `JwtAuthenticator` below.
Expand All @@ -79,6 +110,10 @@ The JWT authentication can be supported by using `JwtAuthenticator`. It is a ver

```csharp
var authenticator = new JwtAuthenticator(myToken);
var options = new RestClientOptions("http://example.com") {
Authenticator = authenticator
};
var client = new RestClient(options);
```

For each request, it will add an `Authorization` header with the value `Bearer <your token>`.
Expand All @@ -91,10 +126,14 @@ You can write your own implementation by implementing `IAuthenticator` and
registering it with your RestClient:

```csharp
var client = new RestClient();
client.Authenticator = new SuperAuthenticator(); // implements IAuthenticator
var authenticator = new SuperAuthenticator(); // implements IAuthenticator
var options = new RestClientOptions("http://example.com") {
Authenticator = authenticator
};
var client = new RestClient(options);
```

The `Authenticate` method is the very first thing called upon calling `RestClient.Execute` or `RestClient.Execute<T>`. The `Authenticate` method is passed the `RestRequest` currently being executed giving you access to every part of the request data (headers, parameters, etc.)
The `Authenticate` method is the very first thing called upon calling `RestClient.Execute` or `RestClient.Execute<T>`.
It gets the `RestRequest` currently being executed giving you access to every part of the request data (headers, parameters, etc.)

You can find an example of a custom authenticator that fetches and uses an OAuth2 bearer token [here](usage.md#authenticator).
13 changes: 12 additions & 1 deletion docs/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ in favour of giving you the error as a property.
| `ThrowOnDeserializationError` | Changes the default behavior when failed deserialization results in empty `Data` property of the response. Setting this property to `true` will tell RestSharp to throw when deserialization fails. |
| `ThrowOnAnyError` | Setting this property to `true` changes the default behavior and forces RestSharp to throw if any errors occurs when making a request or during deserialization. |

Those properties are available for the `RestClient` instance and will be used for all request made with that instance.
Those properties are available for the `RestClientOptions` and will be used for all request made with the client instance.

For example, you can configure the client to throw an exception if any error occurs when making a request, or when a request returns a non-successful HTTP status code:

```csharp
var options = new RestClientOptions(url) {
ThrowOnAnyError = true
};
var client = new RestClient(options);
var request = new RestRequest("resource/{id}").AddUrlSegment("id", 123);
var response = await client.ExecuteGetAsync<ResponseModel>(request); // will throw if the request fails
```

::: warning
Please be aware that deserialization failures will only work if the serializer throws an exception when deserializing the response.
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.