Skip to content

Commit

Permalink
Move the instantiation of RequestContent after calling the Authentica…
Browse files Browse the repository at this point in the history
…tor (#2062)

* Move the instantiation of RequestContent after calling the Authenticator
* Add auth tests
* Fix null content issues with .NET Framework
  • Loading branch information
alexeyzimarev committed Apr 9, 2023
1 parent 794348e commit 812c344
Show file tree
Hide file tree
Showing 75 changed files with 441 additions and 573 deletions.
33 changes: 0 additions & 33 deletions RestSharp.sln
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
1 change: 1 addition & 0 deletions RestSharp.sln.DotSettings
Expand Up @@ -103,5 +103,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>
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
@@ -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);
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
@@ -1,3 +1,4 @@
// ReSharper disable UnusedMember.Global
namespace RestSharp.Benchmarks.Serializers;

public class TestClass {
Expand Down
2 changes: 1 addition & 1 deletion src/RestSharp.Serializers.Xml/XmlExtensions.cs
Expand Up @@ -30,7 +30,7 @@ public static class XmlExtensions {
public static XName? AsNamespaced(this string? name, string? @namespace) {
XName? xName = name;

if (name != null && @namespace.IsNotEmpty()) xName = XName.Get(name, @namespace!);
if (name != null && @namespace.IsNotEmpty()) xName = XName.Get(name, @namespace);

return xName;
}
Expand Down
28 changes: 14 additions & 14 deletions src/RestSharp.Serializers.Xml/XmlSerializer.cs
Expand Up @@ -110,7 +110,7 @@ public class XmlSerializer : IXmlSerializer, IWithRootElement, IWithDateFormat {

var props = objType.GetProperties()
.Select(p => new { p, indexAttribute = p.GetAttribute<SerializeAsAttribute>() })
.Where(t => t.p.CanRead && t.p.CanWrite)
.Where(t => t.p is { CanRead: true, CanWrite: true })
.OrderBy(t => t.indexAttribute?.Index ?? int.MaxValue)
.Select(t => t.p);
var globalOptions = objType.GetAttribute<SerializeAsAttribute>();
Expand Down Expand Up @@ -177,7 +177,7 @@ public class XmlSerializer : IXmlSerializer, IWithRootElement, IWithDateFormat {
? setting.Name
: type.Name;

var instance = new XElement(itemTypeName!.AsNamespaced(Namespace)!);
var instance = new XElement(itemTypeName.AsNamespaced(Namespace)!);

Map(instance, item);

Expand Down Expand Up @@ -228,17 +228,17 @@ static string SerializeNumber(object number)
/// </summary>
static bool IsNumeric(object value)
=> value switch {
sbyte _ => true,
byte _ => true,
short _ => true,
ushort _ => true,
int _ => true,
uint _ => true,
long _ => true,
ulong _ => true,
float _ => true,
double _ => true,
decimal _ => true,
_ => false
sbyte => true,
byte => true,
short => true,
ushort => true,
int => true,
uint => true,
long => true,
ulong => true,
float => true,
double => true,
decimal => true,
_ => false
};
}
Expand Up @@ -21,7 +21,7 @@ static class StringExtensions {

public static string Then(this string input, string value) => string.Concat(input, value);

public static Uri AsUri(this string value) => new Uri(value);
public static Uri AsUri(this string value) => new(value);

public static byte[] GetBytes(this string input) => Encoding.UTF8.GetBytes(input);

Expand Down
3 changes: 3 additions & 0 deletions src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs
Expand Up @@ -75,6 +75,7 @@ public class OAuth1Authenticator : IAuthenticator {
Type = OAuthType.RequestToken
};

[PublicAPI]
public static OAuth1Authenticator ForRequestToken(string consumerKey, string? consumerSecret, string callbackUrl) {
var authenticator = ForRequestToken(consumerKey, consumerSecret);

Expand Down Expand Up @@ -102,6 +103,7 @@ public class OAuth1Authenticator : IAuthenticator {
Type = OAuthType.AccessToken
};

[PublicAPI]
public static OAuth1Authenticator ForAccessToken(
string consumerKey,
string? consumerSecret,
Expand Down Expand Up @@ -167,6 +169,7 @@ string sessionHandle
Type = OAuthType.ClientAuthentication
};

[PublicAPI]
public static OAuth1Authenticator ForProtectedResource(
string consumerKey,
string? consumerSecret,
Expand Down
17 changes: 10 additions & 7 deletions src/RestSharp/Authenticators/OAuth/OAuthTools.cs
Expand Up @@ -139,7 +139,7 @@ static class OAuthTools {
/// </summary>
/// <param name="parameters">A collection of parameters to sort</param>
/// <returns>A sorted parameter collection</returns>
public static IEnumerable<string> SortParametersExcludingSignature(WebPairCollection parameters)
internal static IEnumerable<string> SortParametersExcludingSignature(WebPairCollection parameters)
=> parameters
.Where(x => !x.Name.EqualsIgnoreCase("oauth_signature"))
.Select(x => new WebPair(UrlEncodeStrict(x.Name), UrlEncodeStrict(x.Value)))
Expand Down Expand Up @@ -231,9 +231,9 @@ public static IEnumerable<string> SortParametersExcludingSignature(WebPairCollec
if (tokenSecret.IsEmpty()) tokenSecret = string.Empty;
if (consumerSecret.IsEmpty()) consumerSecret = string.Empty;

var unencodedConsumerSecret = consumerSecret!;
consumerSecret = Uri.EscapeDataString(consumerSecret!);
tokenSecret = Uri.EscapeDataString(tokenSecret!);
var unencodedConsumerSecret = consumerSecret;
consumerSecret = Uri.EscapeDataString(consumerSecret);
tokenSecret = Uri.EscapeDataString(tokenSecret);

var signature = signatureMethod switch {
HmacSha1 => GetHmacSignature(new HMACSHA1(), consumerSecret, tokenSecret, signatureBase),
Expand All @@ -254,9 +254,12 @@ public static IEnumerable<string> SortParametersExcludingSignature(WebPairCollec

provider.FromXmlString(unencodedConsumerSecret);

#if NET
var hash = SHA1.HashData(Encoding.GetBytes(signatureBase));
#else
var hasher = SHA1.Create();
var hash = hasher.ComputeHash(Encoding.GetBytes(signatureBase));

var hash = hasher.ComputeHash(Encoding.GetBytes(signatureBase));
#endif
return Convert.ToBase64String(provider.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")));
}
}
Expand All @@ -266,4 +269,4 @@ public static IEnumerable<string> SortParametersExcludingSignature(WebPairCollec
crypto.Key = Encoding.GetBytes(key);
return signatureBase.HashWith(crypto);
}
}
}
30 changes: 14 additions & 16 deletions src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
Expand Up @@ -21,19 +21,19 @@ namespace RestSharp.Authenticators.OAuth;
/// A class to encapsulate OAuth authentication flow.
/// </summary>
sealed class OAuthWorkflow {
public string? Version { get; set; }
public string? ConsumerKey { get; set; }
public string? ConsumerSecret { get; set; }
public string? Token { get; set; }
public string? TokenSecret { get; set; }
public string? CallbackUrl { get; set; }
public string? Verifier { get; set; }
public string? SessionHandle { get; set; }
public OAuthSignatureMethod SignatureMethod { get; set; }
public OAuthSignatureTreatment SignatureTreatment { get; set; }
public string? Version { get; init; }
public string? ConsumerKey { get; init; }
public string? ConsumerSecret { get; init; }
public string? Token { get; init; }
public string? TokenSecret { get; init; }
public string? CallbackUrl { get; init; }
public string? Verifier { get; init; }
public string? SessionHandle { get; init; }
public OAuthSignatureMethod SignatureMethod { get; init; }
public OAuthSignatureTreatment SignatureTreatment { get; init; }
public OAuthParameterHandling ParameterHandling { get; set; }
public string? ClientUsername { get; set; }
public string? ClientPassword { get; set; }
public string? ClientUsername { get; init; }
public string? ClientPassword { get; init; }
public string? RequestTokenUrl { get; set; }
public string? AccessTokenUrl { get; set; }

Expand Down Expand Up @@ -164,9 +164,7 @@ sealed class OAuthWorkflow {
Ensure.NotEmpty(ClientUsername, nameof(ClientUsername));
}

void ValidateProtectedResourceState() {
Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));
}
void ValidateProtectedResourceState() => Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));

WebPairCollection GenerateAuthParameters(string timestamp, string nonce)
=> new WebPairCollection {
Expand All @@ -181,7 +179,7 @@ WebPairCollection GenerateAuthParameters(string timestamp, string nonce)
.AddNotEmpty("oauth_session_handle", SessionHandle!);

WebPairCollection GenerateXAuthParameters(string timestamp, string nonce)
=> new WebPairCollection {
=> new() {
new("x_auth_username", Ensure.NotNull(ClientUsername, nameof(ClientUsername))),
new("x_auth_password", Ensure.NotNull(ClientPassword, nameof(ClientPassword))),
new("x_auth_mode", "client_auth"),
Expand Down
Expand Up @@ -20,6 +20,7 @@ namespace RestSharp.Authenticators.OAuth2;
/// <remarks>
/// Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.1
/// </remarks>
[PublicAPI]
public class OAuth2AuthorizationRequestHeaderAuthenticator : AuthenticatorBase {
readonly string _tokenType;

Expand Down
Expand Up @@ -20,6 +20,7 @@ namespace RestSharp.Authenticators.OAuth2;
/// <remarks>
/// Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.2
/// </remarks>
[PublicAPI]
public class OAuth2UriQueryParameterAuthenticator : AuthenticatorBase {
/// <summary>
/// Initializes a new instance of the <see cref="OAuth2UriQueryParameterAuthenticator" /> class.
Expand Down

0 comments on commit 812c344

Please sign in to comment.