Skip to content

Commit

Permalink
Rewrite Endpoint.Tests to use source-compat HTTP Utils APIs with .NET 6
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Jan 31, 2022
1 parent bef5ea9 commit d0e5401
Show file tree
Hide file tree
Showing 35 changed files with 302 additions and 160 deletions.
18 changes: 8 additions & 10 deletions src/ServiceStack.Client/AsyncServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,16 +397,14 @@ T Complete(T response)
GetAccessTokenResponse tokenResponse;
try
{
#if NET6_0_OR_GREATER
tokenResponse = (await HttpClient.SendStringToUrlAsync(uri, method:HttpMethods.Post,
requestBody:refreshRequest.ToJson(), token: token).ConfigAwait()).FromJson<GetAccessTokenResponse>();
#else
tokenResponse = (await uri.PostJsonToUrlAsync(refreshRequest, requestFilter: req => {
if (hasRefreshTokenCookie) {
req.CookieContainer = CookieContainer;
}
}, token: token).ConfigAwait()).FromJson<GetAccessTokenResponse>();
#endif
var httpReq = WebRequest.CreateHttp(uri);
tokenResponse = (await ServiceClientBase.SendStringToUrlAsync(httpReq, method:HttpMethods.Post,
requestFilter: req => {
if (hasRefreshTokenCookie) {
req.CookieContainer = CookieContainer;
}
}, requestBody:refreshRequest.ToJson(), accept:MimeTypes.Json, contentType:MimeTypes.Json, token: token)
.ConfigAwait()).FromJson<GetAccessTokenResponse>();
}
catch (WebException refreshEx)
{
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack.Client/AsyncUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal static class AsyncUtils
{
internal static HttpWebRequest CreateHttpWebRequest(this AsyncServiceClient client, string requestUri)
{
var webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
var webRequest = WebRequest.CreateHttp(requestUri);

PclExport.Instance.Config(webRequest);

Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack.Client/JsonApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public HttpClient GetHttpClient()
{
UseDefaultCredentials = Credentials == null,
Credentials = Credentials,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.Deflate | DecompressionMethods.GZip,
};
if (CookieContainer != null)
useHandler.CookieContainer = CookieContainer;
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack.Client/ServerEventsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public ServerEventsClient Start()
httpRes.EnsureSuccessStatusCode();
var stream = httpRes.Content.ReadAsStream();
#else
httpReq = (HttpWebRequest)WebRequest.Create(EventStreamUri);
httpReq = WebRequest.CreateHttp(EventStreamUri);
//share auth cookies
httpReq.CookieContainer = ((IHasCookieContainer)ServiceClient).CookieContainer;
httpReq.AllowReadStreamBuffering = false;
Expand Down
69 changes: 67 additions & 2 deletions src/ServiceStack.Client/ServiceClientBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,11 @@ public virtual TResponse Send<TResponse>(object request)
GetAccessTokenResponse tokenResponse;
try
{
tokenResponse = uri.PostJsonToUrl(refreshRequest).FromJson<GetAccessTokenResponse>();
var httpReq = WebRequest.CreateHttp(uri);
tokenResponse = SendStringToUrl(httpReq, method:HttpMethods.Post,
requestFilter: req => req.CookieContainer = CookieContainer,
requestBody:refreshRequest.ToJson(), accept:MimeTypes.Json, contentType:MimeTypes.Json)
.FromJson<GetAccessTokenResponse>();
}
catch (WebException refreshEx)
{
Expand Down Expand Up @@ -1002,7 +1006,7 @@ protected WebRequest PrepareWebRequest(string httpMethod, string requestUri, obj
}
}

var client = (HttpWebRequest)WebRequest.Create(requestUri);
var client = WebRequest.CreateHttp(requestUri);

try
{
Expand Down Expand Up @@ -1688,6 +1692,67 @@ public virtual HttpWebResponse Head(string relativeOrAbsoluteUrl)
return Send<HttpWebResponse>(HttpMethods.Head, ResolveUrl(HttpMethods.Head, relativeOrAbsoluteUrl), null);
}

public static string SendStringToUrl(HttpWebRequest webReq, string method, string requestBody, string contentType,
string accept="*/*", Action<HttpWebRequest> requestFilter=null, Action<HttpWebResponse> responseFilter=null)
{
if (method != null)
webReq.Method = method;
if (contentType != null)
webReq.ContentType = contentType;

webReq.Accept = accept;
PclExport.Instance.AddCompression(webReq);

requestFilter?.Invoke(webReq);

if (requestBody != null)
{
using var reqStream = PclExport.Instance.GetRequestStream(webReq);
using var writer = new StreamWriter(reqStream, HttpUtils.UseEncoding);
writer.Write(requestBody);
}
else if (method != null && HttpUtils.HasRequestBody(method))
{
webReq.ContentLength = 0;
}

using var webRes = webReq.GetResponse();
using var stream = webRes.GetResponseStream();
responseFilter?.Invoke((HttpWebResponse)webRes);
return stream.ReadToEnd(HttpUtils.UseEncoding);
}

public static async Task<string> SendStringToUrlAsync(HttpWebRequest webReq,
string method, string requestBody, string contentType, string accept="*/*",
Action<HttpWebRequest> requestFilter=null, Action<HttpWebResponse> responseFilter=null, CancellationToken token=default)
{
if (method != null)
webReq.Method = method;
if (contentType != null)
webReq.ContentType = contentType;

webReq.Accept = accept;
PclExport.Instance.AddCompression(webReq);

requestFilter?.Invoke(webReq);

if (requestBody != null)
{
using var reqStream = PclExport.Instance.GetRequestStream(webReq);
using var writer = new StreamWriter(reqStream, HttpUtils.UseEncoding);
await writer.WriteAsync(requestBody).ConfigAwait();
}
else if (method != null && HttpUtils.HasRequestBody(method))
{
webReq.ContentLength = 0;
}

using var webRes = await webReq.GetResponseAsync().ConfigAwait();
responseFilter?.Invoke((HttpWebResponse)webRes);
using var stream = webRes.GetResponseStream();
return await stream.ReadToEndAsync().ConfigAwait();
}

public virtual TResponse PostFilesWithRequest<TResponse>(object request, IEnumerable<UploadFile> files)
{
return PostFilesWithRequest<TResponse>(ResolveTypedUrl(HttpMethods.Post, request), request, files.ToArray());
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack.Client/StreamCompressors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public string Decompress(byte[] zipBuffer, Encoding? encoding = null)
}

public Stream Decompress(Stream zipBuffer, bool leaveOpen=false) =>
new DeflateStream(zipBuffer, CompressionMode.Decompress, leaveOpen);
new ZLibStream(zipBuffer, CompressionMode.Decompress, leaveOpen);

public byte[] DecompressBytes(byte[] zipBuffer)
{
Expand Down
4 changes: 2 additions & 2 deletions src/ServiceStack/Auth/IAuthHttpGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public async Task<AuthId> VerifyTwitterAccessTokenAsync(string consumerKey, stri
string url, string data = null)
{
var uri = new Uri(url);
var webReq = (HttpWebRequest)WebRequest.Create(uri);
var webReq = WebRequest.CreateHttp(uri);
webReq.Accept = MimeTypes.Json;

if (accessToken != null)
Expand All @@ -135,7 +135,7 @@ public async Task<AuthId> VerifyTwitterAccessTokenAsync(string consumerKey, stri
string url, string data = null, CancellationToken token=default)
{
var uri = new Uri(url);
var webReq = (HttpWebRequest)WebRequest.Create(uri);
var webReq = WebRequest.CreateHttp(uri);
webReq.Accept = MimeTypes.Json;

if (accessToken != null)
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack/HttpCacheFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private async Task<bool> CacheAndWriteResponse(CacheInfo cacheInfo, IRequest req
{
var httpResult = response as IHttpResult;
var dto = httpResult != null ? httpResult.Response : response;
if (dto == null || dto is IPartialWriter || dto is IPartialWriterAsync || dto is IStreamWriter || dto is IStreamWriterAsync)
if (dto is null or IPartialWriter or IPartialWriterAsync or IStreamWriter or IStreamWriterAsync)
return false;

var expiresIn = cacheInfo.ExpiresIn.GetValueOrDefault(DefaultExpiresIn);
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceStack/ProxyFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public override Task ProcessRequestAsync(IRequest req, IResponse response, strin
}

public virtual async Task ProxyRequestAsync(IHttpRequest httpReq, string url) =>
await ProxyRequestAsync(httpReq, (HttpWebRequest)WebRequest.Create(url));
await ProxyRequestAsync(httpReq, WebRequest.CreateHttp(url));

public async Task ProxyRequestAsync(IHttpRequest httpReq, HttpWebRequest webReq)
{
Expand Down
2 changes: 1 addition & 1 deletion tests/RazorRockstars.Console.Files/ReqStarsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ public void Does_execute_request_and_response_filter_attributes(IRestClient clie
[Test]
public void Can_Process_OPTIONS_request_with_Cors_ActionFilter()
{
var webReq = (HttpWebRequest)WebRequest.Create(Host + "/reqstars");
var webReq = WebRequest.CreateHttp(Host + "/reqstars");
webReq.Method = "OPTIONS";
using (var r = webReq.GetResponse())
{
Expand Down
2 changes: 1 addition & 1 deletion tests/RazorRockstars.Web.Tests/ReqStarsServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public void TestFixtureTearDown()
[Test]
public void Can_Process_OPTIONS_request_with_Cors_ActionFilter()
{
var webReq = (HttpWebRequest)WebRequest.Create(Host + "/reqstars");
var webReq = WebRequest.CreateHttp(Host + "/reqstars");
webReq.Method = "OPTIONS";
using (var r = webReq.GetResponse())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void Can_GET_single_gethttpresult_using_RestClient_with_JSONP_from_servic
var url = ListeningOn + "gethttpresult?callback=cb";
string response;

var webReq = (HttpWebRequest)WebRequest.Create(url);
var webReq = WebRequest.CreateHttp(url);
webReq.Accept = "*/*";
using (var webRes = webReq.GetResponse())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public void Can_GET_single_gethttpresult_using_RestClient_with_JSONP_from_servic
var url = ListeningOn + "gethttpresult?callback=cb";
string response;

var webReq = (HttpWebRequest)WebRequest.Create(url);
var webReq = WebRequest.CreateHttp(url);
webReq.Accept = "*/*";
using (var webRes = webReq.GetResponse())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,42 @@ namespace ServiceStack.WebHost.Endpoints.Tests
{
public abstract class AsyncServiceClientTests
{
protected const string ListeningOn = "http://localhost:1337/";

ExampleAppHostHttpListener appHost;

[OneTimeSetUp]
public void OnTestFixtureSetUp()
{
appHost = new ExampleAppHostHttpListener();
appHost.Init();
appHost.Start(ListeningOn);
appHost.Start(Config.ListeningOn);
}

[OneTimeTearDown]
public void OnTestFixtureTearDown()
{
appHost.Dispose();
}
public void OnTestFixtureTearDown() => appHost.Dispose();

protected abstract IServiceClient CreateServiceClient();
protected abstract IServiceClient CreateServiceClient(string compressionType=null);

[Test]
public async Task Can_call_SendAsync_on_ServiceClient()
{
var jsonClient = new JsonServiceClient(ListeningOn);
var client = CreateServiceClient();

var request = new GetFactorial { ForNumber = 3 };
var response = await jsonClient.SendAsync<GetFactorialResponse>(request);
var response = await client.SendAsync<GetFactorialResponse>(request);

Assert.That(response, Is.Not.Null, "No response received");
Assert.That(response.Result, Is.EqualTo(GetFactorialService.GetFactorial(request.ForNumber)));
}


#if NET6_0_OR_GREATER
[TestCase(CompressionTypes.Brotli)]
#endif
[TestCase(CompressionTypes.Deflate)]
[TestCase(CompressionTypes.GZip)]
public async Task Can_call_SendAsync_with_compression_on_ServiceClient(string compressionType)
{
var jsonClient = new JsonServiceClient(ListeningOn) { RequestCompressionType = compressionType };
var jsonClient = CreateServiceClient(compressionType);

var request = new GetFactorial { ForNumber = 3 };
var response = await jsonClient.SendAsync<GetFactorialResponse>(request);
Expand All @@ -52,40 +50,41 @@ public async Task Can_call_SendAsync_with_compression_on_ServiceClient(string co
Assert.That(response.Result, Is.EqualTo(GetFactorialService.GetFactorial(request.ForNumber)));
}

#if NET6_0_OR_GREATER
[TestFixture]
public class JsonAsyncApiClientTests : AsyncServiceClientTests
{
protected override IServiceClient CreateServiceClient(string compressionType=null) =>
new JsonApiClient(Config.ListeningOn) { RequestCompressionType = compressionType };
}
#endif

[TestFixture]
public class JsonAsyncServiceClientTests : AsyncServiceClientTests
{
protected override IServiceClient CreateServiceClient()
{
return new JsonServiceClient(ListeningOn);
}
protected override IServiceClient CreateServiceClient(string compressionType=null) =>
new JsonServiceClient(Config.ListeningOn) { RequestCompressionType = compressionType };
}

[TestFixture]
public class JsonAsyncHttpClientTests : AsyncServiceClientTests
{
protected override IServiceClient CreateServiceClient()
{
return new JsonHttpClient(ListeningOn);
}
protected override IServiceClient CreateServiceClient(string compressionType=null) =>
new JsonHttpClient(Config.ListeningOn) { RequestCompressionType = compressionType };
}

[TestFixture]
public class JsvAsyncServiceClientTests : AsyncServiceClientTests
{
protected override IServiceClient CreateServiceClient()
{
return new JsvServiceClient(ListeningOn);
}
protected override IServiceClient CreateServiceClient(string compressionType=null) =>
new JsvServiceClient(Config.ListeningOn) { RequestCompressionType = compressionType };
}

[TestFixture]
public class XmlAsyncServiceClientTests : AsyncServiceClientTests
{
protected override IServiceClient CreateServiceClient()
{
return new XmlServiceClient(ListeningOn);
}
protected override IServiceClient CreateServiceClient(string compressionType=null) =>
new XmlServiceClient(Config.ListeningOn) { RequestCompressionType = compressionType };
}
}

Expand Down
24 changes: 16 additions & 8 deletions tests/ServiceStack.WebHost.Endpoints.Tests/AuthTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -963,42 +963,50 @@ public void Does_return_empty_response_on_forbidden_access()
downloadBasicAuth(nameof(RequiresRole).AddQueryParam("Name", "test"));
Assert.Fail("Should throw");
}
catch (WebException e)
catch (Exception e)
{
Assert.That(e.GetResponseBody(), Does.Not.Contain("{"));
AssertStatus(e, HttpStatusCode.Forbidden);
}

try
{
downloadBasicAuth(nameof(RequiresAnyRole).AddQueryParam("Name", "test"));
Assert.Fail("Should throw");
}
catch (WebException e)
catch (Exception e)
{
Assert.That(e.GetResponseBody(), Does.Not.Contain("{"));
AssertStatus(e, HttpStatusCode.Forbidden);
}

try
{
downloadBasicAuth(nameof(RequiresPermission).AddQueryParam("Name", "test"));
Assert.Fail("Should throw");
}
catch (WebException e)
catch (Exception e)
{
Assert.That(e.GetResponseBody(), Does.Not.Contain("{"));
AssertStatus(e, HttpStatusCode.Forbidden);
}

try
{
downloadBasicAuth(nameof(RequiresAnyPermission).AddQueryParam("Name", "test"));
Assert.Fail("Should throw");
}
catch (WebException e)
catch (Exception e)
{
Assert.That(e.GetResponseBody(), Does.Not.Contain("{"));
AssertStatus(e, HttpStatusCode.Forbidden);
}
}

private static void AssertStatus(Exception e, HttpStatusCode statusCode)
{
Assert.That(e.GetStatus(), Is.EqualTo(statusCode));
#if NETFX
Assert.That(e.GetResponseBody(), Does.Not.Contain("{"));
#endif
}

[Test]
public void Does_work_with_CredentialsAuth_Multiple_Times()
{
Expand Down

0 comments on commit d0e5401

Please sign in to comment.