diff --git a/PackageTesters/PackageTester.NET45/PackageTester.NET45.csproj b/PackageTesters/PackageTester.NET45/PackageTester.NET45.csproj index dfecf7f8..6d235b4f 100644 --- a/PackageTesters/PackageTester.NET45/PackageTester.NET45.csproj +++ b/PackageTesters/PackageTester.NET45/PackageTester.NET45.csproj @@ -31,11 +31,11 @@ 4 - - ..\..\packages\Flurl.2.5.1\lib\net40\Flurl.dll + + ..\..\packages\Flurl.2.6.0\lib\net45\Flurl.dll - - ..\..\packages\Flurl.Http.2.1.0\lib\net45\Flurl.Http.dll + + ..\..\packages\Flurl.Http.2.1.1\lib\net45\Flurl.Http.dll ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll diff --git a/PackageTesters/PackageTester.NET45/packages.config b/PackageTesters/PackageTester.NET45/packages.config index 424784dc..8ad1c134 100644 --- a/PackageTesters/PackageTester.NET45/packages.config +++ b/PackageTesters/PackageTester.NET45/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/PackageTesters/PackageTester.NET461/PackageTester.NET461.csproj b/PackageTesters/PackageTester.NET461/PackageTester.NET461.csproj index f41ae75d..7fe7627e 100644 --- a/PackageTesters/PackageTester.NET461/PackageTester.NET461.csproj +++ b/PackageTesters/PackageTester.NET461/PackageTester.NET461.csproj @@ -33,11 +33,11 @@ 4 - - ..\..\packages\Flurl.2.5.1\lib\net40\Flurl.dll + + ..\..\packages\Flurl.2.6.0\lib\net45\Flurl.dll - - ..\..\packages\Flurl.Http.2.1.0\lib\net45\Flurl.Http.dll + + ..\..\packages\Flurl.Http.2.1.1\lib\net45\Flurl.Http.dll ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll diff --git a/PackageTesters/PackageTester.NET461/packages.config b/PackageTesters/PackageTester.NET461/packages.config index ad095dcb..2150c446 100644 --- a/PackageTesters/PackageTester.NET461/packages.config +++ b/PackageTesters/PackageTester.NET461/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/PackageTesters/PackageTester.NETCore/PackageTester.NETCore.csproj b/PackageTesters/PackageTester.NETCore/PackageTester.NETCore.csproj index 672a2957..abdf2d5c 100644 --- a/PackageTesters/PackageTester.NETCore/PackageTester.NETCore.csproj +++ b/PackageTesters/PackageTester.NETCore/PackageTester.NETCore.csproj @@ -2,13 +2,13 @@ Exe - netcoreapp1.1 + netcoreapp2.0 - + \ No newline at end of file diff --git a/Test/Flurl.Test/Flurl.Test.csproj b/Test/Flurl.Test/Flurl.Test.csproj index b35ff87a..1026a58f 100644 --- a/Test/Flurl.Test/Flurl.Test.csproj +++ b/Test/Flurl.Test/Flurl.Test.csproj @@ -1,13 +1,13 @@  - net45;netcoreapp1.1; + net45;netcoreapp2.0; - - - + + + diff --git a/Test/Flurl.Test/Http/RealHttpTests.cs b/Test/Flurl.Test/Http/RealHttpTests.cs index 2c26539d..4a16628d 100644 --- a/Test/Flurl.Test/Http/RealHttpTests.cs +++ b/Test/Flurl.Test/Http/RealHttpTests.cs @@ -17,6 +17,37 @@ namespace Flurl.Test.Http [TestFixture, Parallelizable] public class RealHttpTests { + class StackExResponse + { + public object[] items { get; set; } + public bool has_more { get; set; } + public int backoff { get; set; } + + internal static int last_page = 0; + internal static int last_backoff = 0; + } + + [TestCase("gzip")] + [TestCase("deflate")] + [NonParallelizable] + public async Task decompresses_automatically(string encoding) { + if (StackExResponse.last_backoff > 0) { + Console.WriteLine($"Backing off StackExchange for {StackExResponse.last_backoff} seconds..."); + await Task.Delay(TimeSpan.FromSeconds(StackExResponse.last_backoff)); + } + + StackExResponse.last_page++; + var result = await $"https://api.stackexchange.com/2.2/answers?site=stackoverflow&pagesize=10" + .SetQueryParam("page", ++StackExResponse.last_page) + .WithHeader("Accept-Encoding", encoding) + .GetJsonAsync(); + + StackExResponse.last_backoff = result.backoff; + + Assert.AreEqual(10, result.items.Length); + Assert.IsTrue(result.has_more); + } + [Test] public async Task can_download_file() { var folder = "c:\\flurl-test-" + Guid.NewGuid(); // random so parallel tests don't trip over each other diff --git a/Test/Flurl.Test/UrlBuilderTests.cs b/Test/Flurl.Test/UrlBuilderTests.cs index 19525f69..f24ddffc 100644 --- a/Test/Flurl.Test/UrlBuilderTests.cs +++ b/Test/Flurl.Test/UrlBuilderTests.cs @@ -279,7 +279,7 @@ public void encodes_illegal_path_chars() { } [Test] - public void can_encodes_reserved_path_chars() { + public void can_encode_reserved_path_chars() { // should encode '/' (tests optional fullyEncode arg) var url = "http://www.mysite.com".AppendPathSegment("hi there/bye now", true); Assert.AreEqual("http://www.mysite.com/hi%20there%2Fbye%20now", url.ToString()); @@ -309,6 +309,12 @@ public void reencodes_encoded_query_values_when_isEncoded_false() { Assert.AreEqual("http://www.mysite.com?x=%25CD%25EE%25E2%25FB%25E9%2520%25E3%25EE%25E4", url.ToString()); } + [Test] + public void does_not_encode_reserved_chars_in_query_param_name() { + var url = "http://www.mysite.com".SetQueryParam("$x", 1); + Assert.AreEqual("http://www.mysite.com?$x=1", url.ToString()); + } + [Test] public void Url_implicitly_converts_to_string() { var url = new Url("http://www.mysite.com/more?x=1&y=2"); diff --git a/src/Flurl.Http.CodeGen/Flurl.Http.CodeGen.csproj b/src/Flurl.Http.CodeGen/Flurl.Http.CodeGen.csproj index 6d25f413..f94b956a 100644 --- a/src/Flurl.Http.CodeGen/Flurl.Http.CodeGen.csproj +++ b/src/Flurl.Http.CodeGen/Flurl.Http.CodeGen.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp1.1 + netcoreapp2.0 \ No newline at end of file diff --git a/src/Flurl.Http/Configuration/DefaultHttpClientFactory.cs b/src/Flurl.Http/Configuration/DefaultHttpClientFactory.cs index 44396763..0e5fc956 100644 --- a/src/Flurl.Http/Configuration/DefaultHttpClientFactory.cs +++ b/src/Flurl.Http/Configuration/DefaultHttpClientFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using System.Net.Http; namespace Flurl.Http.Configuration @@ -28,7 +29,10 @@ public virtual HttpClient CreateHttpClient(HttpMessageHandler handler) { /// customize the result. /// public virtual HttpMessageHandler CreateMessageHandler() { - return new HttpClientHandler(); + return new HttpClientHandler { + // #266 + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate + }; } } } \ No newline at end of file diff --git a/src/Flurl.Http/Configuration/FlurlHttpSettings.cs b/src/Flurl.Http/Configuration/FlurlHttpSettings.cs index 18d744ce..4e426332 100644 --- a/src/Flurl.Http/Configuration/FlurlHttpSettings.cs +++ b/src/Flurl.Http/Configuration/FlurlHttpSettings.cs @@ -224,21 +224,11 @@ public override void ResetDefaults() { /// public class TestFlurlHttpSettings : ClientFlurlHttpSettings { - /// - /// Gets or sets the factory that defines creating, caching, and reusing FlurlClient instances - /// within the context of this HttpTest - /// - public IFlurlClientFactory FlurlClientFactory { - get => Get(() => FlurlClientFactory); - set => Set(() => FlurlClientFactory, value); - } - /// /// Resets all test settings to their Flurl.Http-defined default values. /// public override void ResetDefaults() { base.ResetDefaults(); - FlurlClientFactory = new TestFlurlClientFactory(); HttpClientFactory = new TestHttpClientFactory(); } } diff --git a/src/Flurl.Http/Flurl.Http.csproj b/src/Flurl.Http/Flurl.Http.csproj index 02d4fc63..d4826424 100644 --- a/src/Flurl.Http/Flurl.Http.csproj +++ b/src/Flurl.Http/Flurl.Http.csproj @@ -1,10 +1,10 @@  - net45;netstandard1.3;netstandard1.1; + net45;netstandard1.1;netstandard1.3;netstandard2.0; True Flurl.Http - 2.1.1 + 2.2.0-pre1 Todd Menier Flurl.Http is a fluent, portable, testable HTTP client library that extends Flurl's URL builder chain. http://tmenier.github.io/Flurl @@ -27,7 +27,7 @@ - + @@ -35,6 +35,10 @@ + + + + diff --git a/src/Flurl.Http/HttpResponseMessageExtensions.cs b/src/Flurl.Http/HttpResponseMessageExtensions.cs index 2d7cad87..5d67d8f0 100644 --- a/src/Flurl.Http/HttpResponseMessageExtensions.cs +++ b/src/Flurl.Http/HttpResponseMessageExtensions.cs @@ -3,9 +3,6 @@ using System.Dynamic; using System.IO; using System.Net.Http; -#if NETSTANDARD1_3 -using System.Text; -#endif using System.Threading.Tasks; using Flurl.Util; @@ -65,8 +62,8 @@ public static async Task> ReceiveJsonList(this TaskA Task whose result is the response body as a string. /// s = await url.PostAsync(data).ReceiveString() public static async Task ReceiveString(this Task response) { -#if NETSTANDARD1_3 - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); +#if NETSTANDARD1_3 || NETSTANDARD2_0 + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); #endif var resp = await response.ConfigureAwait(false); if (resp == null) return null; diff --git a/src/Flurl.Http/Testing/HttpTest.cs b/src/Flurl.Http/Testing/HttpTest.cs index 0bae6900..0b710af5 100644 --- a/src/Flurl.Http/Testing/HttpTest.cs +++ b/src/Flurl.Http/Testing/HttpTest.cs @@ -13,6 +13,9 @@ namespace Flurl.Http.Testing /// An object whose existence puts Flurl.Http into test mode where actual HTTP calls are faked. Provides a response /// queue, call log, and assertion helpers for use in Arrange/Act/Assert style tests. /// +#if !NETSTANDARD1_1 + [Serializable] // fixes MSTest issue? #207 +#endif public class HttpTest : IDisposable { private readonly Lazy _httpClient; @@ -171,7 +174,7 @@ public void Dispose() { #if NET45 private static void SetCurrentTest(HttpTest test) => System.Runtime.Remoting.Messaging.CallContext.LogicalSetData("FlurlHttpTest", test); private static HttpTest GetCurrentTest() => System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("FlurlHttpTest") as HttpTest; -#elif NETSTANDARD1_3 +#elif NETSTANDARD1_3 || NETSTANDARD2_0 private static System.Threading.AsyncLocal _test = new System.Threading.AsyncLocal(); private static void SetCurrentTest(HttpTest test) => _test.Value = test; private static HttpTest GetCurrentTest() => _test.Value; @@ -180,5 +183,5 @@ public void Dispose() { private static void SetCurrentTest(HttpTest test) => _test = test; private static HttpTest GetCurrentTest() => _test; #endif - } + } } \ No newline at end of file diff --git a/src/Flurl.Http/Testing/TestFactories.cs b/src/Flurl.Http/Testing/TestFactories.cs deleted file mode 100644 index 98e6b5ac..00000000 --- a/src/Flurl.Http/Testing/TestFactories.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Net.Http; -using Flurl.Http.Configuration; - -namespace Flurl.Http.Testing -{ - /// - /// IHttpClientFactory implementation used to fake and record calls in tests. - /// - public class TestHttpClientFactory : DefaultHttpClientFactory - { - /// - /// Creates an instance of FakeHttpMessageHander, which prevents actual HTTP calls from being made. - /// - /// - public override HttpMessageHandler CreateMessageHandler() { - return new FakeHttpMessageHandler(); - } - } - - /// - /// IFlurlClientFactory implementation used to fake and record calls in tests. - /// - public class TestFlurlClientFactory : FlurlClientFactoryBase - { - private readonly Lazy _client = new Lazy(() => new FlurlClient()); - - /// - /// Returns the FlurlClient sigleton used for testing - /// - /// The URL. - /// The FlurlClient instance. - public override IFlurlClient Get(Url url) { - return _client.Value; - } - - /// - /// Not used. Singleton FlurlClient used for lifetime of test. - /// - /// - /// - protected override string GetCacheKey(Url url) { - return null; - } - } -} \ No newline at end of file diff --git a/src/Flurl.Http/Testing/TestHttpClientFactory.cs b/src/Flurl.Http/Testing/TestHttpClientFactory.cs new file mode 100644 index 00000000..b4a2b736 --- /dev/null +++ b/src/Flurl.Http/Testing/TestHttpClientFactory.cs @@ -0,0 +1,20 @@ +using System; +using System.Net.Http; +using Flurl.Http.Configuration; + +namespace Flurl.Http.Testing +{ + /// + /// IHttpClientFactory implementation used to fake and record calls in tests. + /// + public class TestHttpClientFactory : DefaultHttpClientFactory + { + /// + /// Creates an instance of FakeHttpMessageHander, which prevents actual HTTP calls from being made. + /// + /// + public override HttpMessageHandler CreateMessageHandler() { + return new FakeHttpMessageHandler(); + } + } +} \ No newline at end of file diff --git a/src/Flurl/Flurl.csproj b/src/Flurl/Flurl.csproj index dc91544a..12ea057b 100644 --- a/src/Flurl/Flurl.csproj +++ b/src/Flurl/Flurl.csproj @@ -1,10 +1,10 @@  - net40;net45;netstandard1.3;netstandard1.0; + net40;netstandard1.0;netstandard1.3;netstandard2.0; True Flurl - 2.6.0 + 2.7.0-pre1 Todd Menier A fluent, portable URL builder. To make HTTP calls off the fluent chain, check out Flurl.Http. http://tmenier.github.io/Flurl diff --git a/src/Flurl/QueryParameter.cs b/src/Flurl/QueryParameter.cs index 2ddad43a..01f6a922 100644 --- a/src/Flurl/QueryParameter.cs +++ b/src/Flurl/QueryParameter.cs @@ -61,7 +61,7 @@ from v in (_value as IEnumerable).Cast() } private static string BuildPair(string name, object value, bool valueIsEncoded, bool encodeSpaceAsPlus) { - name = Url.Encode(name, encodeSpaceAsPlus); + name = Url.EncodeIllegalCharacters(name, encodeSpaceAsPlus); if (value == null) return name; diff --git a/src/Flurl/Url.cs b/src/Flurl/Url.cs index 1743900d..f6fc7b9e 100644 --- a/src/Flurl/Url.cs +++ b/src/Flurl/Url.cs @@ -139,8 +139,8 @@ public static string Decode(string s, bool interpretPlusAsSpace) { /// /// The string to encode. /// If true, spaces will be encoded as + signs. Otherwise, they'll be encoded as %20. - /// - public static string Encode(string s, bool encodeSpaceAsPlus) { + /// The encoded URL. + public static string Encode(string s, bool encodeSpaceAsPlus = false) { if (string.IsNullOrEmpty(s)) return s; @@ -164,10 +164,15 @@ public static string Encode(string s, bool encodeSpaceAsPlus) { /// URL-encodes characters in a string that are neither reserved nor unreserved. Avoids encoding reserved characters such as '/' and '?'. Avoids encoding '%' if it begins a %-hex-hex sequence (i.e. avoids double-encoding). /// /// The string to encode. - public static string EncodeIllegalCharacters(string s) { + /// If true, spaces will be encoded as + signs. Otherwise, they'll be encoded as %20. + /// The encoded URL. + public static string EncodeIllegalCharacters(string s, bool encodeSpaceAsPlus = false) { if (string.IsNullOrEmpty(s)) return s; + if (encodeSpaceAsPlus) + s = s.Replace(" ", "+"); + // Uri.EscapeUriString mostly does what we want - encodes illegal characters only - but it has a quirk // in that % isn't illegal if it's the start of a %-encoded sequence https://stackoverflow.com/a/47636037/62600