Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
32 changes: 31 additions & 1 deletion RestSharp.sln
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,7 +35,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharp.Tests.Serializers
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SourceGen", "SourceGen", "{55B8F371-B2BA-4DEE-AB98-5BAB8A21B1C2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerator", "gen\SourceGenerator\SourceGenerator.csproj", "{FE778406-ADCF-45A1-B775-A054B55BFC50}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGenerator", "gen\SourceGenerator\SourceGenerator.csproj", "{FE778406-ADCF-45A1-B775-A054B55BFC50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand DownExpand Up@@ -446,6 +446,36 @@ Global
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x64.Build.0 = Release|Any CPU
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x86.ActiveCfg = Release|Any CPU
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x86.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Any CPU.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Any CPU.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|ARM.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|ARM.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Mixed Platforms.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x64.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x64.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x86.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x86.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|ARM.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x64.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x86.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Any CPU.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|ARM.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|ARM.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x64.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x64.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x86.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion gen/SourceGenerator/SourceGenerator.csproj
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand Down
57 changes: 57 additions & 0 deletions src/RestSharp/Interceptors/Interceptor.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
// Copyright (c) .NET Foundation and Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// 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.
//

namespace RestSharp.Interceptors;

/// <summary>
/// Base Interceptor
/// </summary>
public abstract class Interceptor {
/// <summary>
/// Intercepts the request before serialization
/// </summary>
/// <param name="request">RestRequest before serialization</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeSerialization(RestRequest request) {
return new();
}

/// <summary>
/// Intercepts the request before being sent
/// </summary>
/// <param name="req">HttpRequestMessage before being sent</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeRequest(HttpRequestMessage req) {
return new();
}

/// <summary>
/// Intercepts the request before being sent
/// </summary>
/// <param name="responseMessage">HttpResponseMessage as received from Server</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptAfterRequest(HttpResponseMessage responseMessage) {
return new();
}

/// <summary>
/// Intercepts the request before deserialization
/// </summary>
/// <param name="response">HttpResponseMessage as received from Server</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeDeserialize(RestResponse response) {
return new();
}
}
3 changes: 3 additions & 0 deletions src/RestSharp/Options/RestClientOptions.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
using System.Text;
using RestSharp.Authenticators;
using RestSharp.Extensions;
using RestSharp.Interceptors;

// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable PropertyCanBeMadeInitOnly.Global
Expand DownExpand Up@@ -64,6 +65,8 @@ public RestClientOptions(string baseUrl) : this(new Uri(Ensure.NotEmptyString(ba
/// </summary>
public IAuthenticator? Authenticator { get; set; }

public List<Interceptor> Interceptors { get; set; } = new();

/// <summary>
/// Passed to <see cref="HttpMessageHandler"/> <code>Credentials</code> property
/// </summary>
Expand Down
33 changes: 31 additions & 2 deletions src/RestSharp/RestClient.Async.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -76,7 +76,7 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
if (_disposed) {
throw new ObjectDisposedException(nameof(RestClient));
}

await OnBeforeSerialization(request);
request.ValidateParameters();
var authenticator = request.Authenticator ?? Options.Authenticator;
if (authenticator != null) await authenticator.Authenticate(this, request).ConfigureAwait(false);
Expand DownExpand Up@@ -107,8 +107,8 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
.AddCookieHeaders(url, Options.CookieContainer);

message.AddHeaders(headers);

if (request.OnBeforeRequest != null) await request.OnBeforeRequest(message).ConfigureAwait(false);
await OnBeforeRequest(message);

var responseMessage = await HttpClient.SendAsync(message, request.CompletionOption, ct).ConfigureAwait(false);

Expand All@@ -121,6 +121,7 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
}

if (request.OnAfterRequest != null) await request.OnAfterRequest(responseMessage).ConfigureAwait(false);
await OnAfterRequest(responseMessage);

return new HttpResponse(responseMessage, url, cookieContainer, null, timeoutCts.Token);
}
Expand All@@ -129,6 +130,34 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
}
}

/// <summary>
/// Will be called before the Request becomes Serialized
/// </summary>
/// <param name="request">RestRequest before it will be serialized</param>
async Task OnBeforeSerialization(RestRequest request) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptBeforeSerialization(request); //.ThrowExceptionIfAvailable();
}
}
/// <summary>
/// Will be called before the Request will be sent
/// </summary>
/// <param name="requestMessage">HttpRequestMessage ready to be sent</param>
async Task OnBeforeRequest(HttpRequestMessage requestMessage) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptBeforeRequest(requestMessage);
}
}
/// <summary>
/// Will be called after the Response has been received from Server
/// </summary>
/// <param name="responseMessage">HttpResponseMessage as received from server</param>
async Task OnAfterRequest(HttpResponseMessage responseMessage) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptAfterRequest(responseMessage);
}
}

record HttpResponse(
HttpResponseMessage? ResponseMessage,
Uri Url,
Expand Down
3 changes: 3 additions & 0 deletions src/RestSharp/RestSharp.csproj
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,4 +39,7 @@
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\gen\SourceGenerator\SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
</ItemGroup>
</Project>
11 changes: 11 additions & 0 deletions src/RestSharp/Serializers/RestSerializers.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ internal RestResponse<T> Deserialize<T>(RestRequest request, RestResponse raw, R

try {
request.OnBeforeDeserialization?.Invoke(raw);
OnBeforeDeserialization(raw, options).ConfigureAwait(true);
response.Data = DeserializeContent<T>(raw);
}
catch (Exception ex) {
Expand All@@ -53,6 +54,16 @@ internal RestResponse<T> Deserialize<T>(RestRequest request, RestResponse raw, R

return response;
}
/// <summary>
/// Will be called before the Data will be serialized
/// </summary>
/// <param name="raw">RestResponse with Data still in Content</param>
/// <param name="options">RestClient options but readonly</param>
async Task OnBeforeDeserialization(RestResponse raw, ReadOnlyRestClientOptions options) {
foreach (var interceptor in options.Interceptors) {
await interceptor.InterceptBeforeDeserialize(raw); //.ThrowExceptionIfAvailable();
}
}

/// <summary>
/// Deserialize the response content into the specified type
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,4 +8,7 @@
<ProjectReference Include="$(RepoRoot)\src\RestSharp\RestSharp.csproj" />
<ProjectReference Include="..\RestSharp.Tests.Shared\RestSharp.Tests.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit.assert" Version="2.4.2" />
</ItemGroup>
</Project>
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,15 +23,15 @@ public class status {
public string in_reply_to_screen_name { get; set; }

// ignore contributors for now
public user user { get; set; }
public User user { get; set; }

// ignore geo
public long id { get; set; }

public string text { get; set; }
}

public class user {
public class User {
public string url { get; set; }

public string description { get; set; }
Expand DownExpand Up@@ -105,7 +105,7 @@ public class complexStatus {
public string in_reply_to_screen_name { get; set; }

// ignore contributors for now
[DeserializeAs(Name = "user.following")]
[DeserializeAs(Name = "User.following")]
public bool follow { get; set; }

// ignore geo
Expand Down