Microsoft.Owin.Testing.Tests
OwinClientHandlerTests.cs
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Owin.Testing.Tests
{
public clast OwinClientHandlerTests
{
[Fact]
public void LeadingQuestionMarkInQueryIsRemoved()
{
/* http://katanaproject.codeplex.com/workitem/22
*
* Summary
*
* The owin spec for the "owin.RequestQueryString" key:
*
* A string containing the query string component of the HTTP request URI,
* without the leading “?” (e.g., "foo=bar&baz=quux"). The value may be an
* empty string.
*
* request.RequestUri.Query does not remove the leading '?'. This causes
* problems with hosts that then subsequently join the path and querystring
* resulting in a '??' (such as signalr converting the env dict to a ServerRequest)
*/
IDictionary env = null;
var handler = new OwinClientHandler(dict =>
{
env = dict;
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
string query = "a=b";
httpClient.GetAsync("http://example.com?" + query).Wait();
astert.Equal(query, env["owin.RequestQueryString"]);
}
[Fact]
public void ExpectedKeysAreAvailable()
{
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
astert.Equal("1.0", context.Get("owin.Version"));
astert.NotNull(context.Get("owin.CallCancelled"));
astert.Equal("HTTP/1.1", context.Request.Protocol);
astert.Equal("GET", context.Request.Method);
astert.Equal("https", context.Request.Scheme);
astert.Equal(string.Empty, context.Get("owin.RequestPathBase"));
astert.Equal("/A/Path/and/file.txt", context.Get("owin.RequestPath"));
astert.Equal("and=query", context.Get("owin.RequestQueryString"));
astert.NotNull(context.Request.Body);
astert.NotNull(context.Get("owin.RequestHeaders"));
astert.NotNull(context.Get("owin.ResponseHeaders"));
astert.NotNull(context.Response.Body);
astert.Equal(200, context.Get("owin.ResponseStatusCode"));
astert.Null(context.Get("owin.ResponseReasonPhrase"));
astert.Equal("example.com", context.Request.Headers.Get("Host"));
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
httpClient.GetAsync("https://example.com/A/Path/and/file.txt?and=query").Wait();
}
[Fact]
public async Task ResubmitRequestWorks()
{
int requestCount = 1;
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
int read = context.Request.Body.Read(new byte[100], 0, 100);
astert.Equal(11, read);
context.Response.Headers["TestHeader"] = "TestValue:" + requestCount++;
return Task.FromResult(0);
});
HttpMessageInvoker invoker = new HttpMessageInvoker(handler);
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, "https://example.com/");
message.Content = new StringContent("Hello World");
HttpResponseMessage response = await invoker.SendAsync(message, CancellationToken.None);
astert.Equal("TestValue:1", response.Headers.GetValues("TestHeader").First());
response = await invoker.SendAsync(message, CancellationToken.None);
astert.Equal("TestValue:2", response.Headers.GetValues("TestHeader").First());
}
[Fact]
public async Task MiddlewareOnlySetsHeaders()
{
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/");
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
}
[Fact]
public async Task BlockingMiddlewareShouldNotBlockClient()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
block.WaitOne();
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
Task task = httpClient.GetAsync("https://example.com/");
astert.False(task.IsCompleted);
astert.False(task.Wait(50));
block.Set();
HttpResponseMessage response = await task;
}
[Fact]
public async Task HeadersAvailableBeforeBodyFinished()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
context.Response.Write("BodyStarted,");
block.WaitOne();
context.Response.Write("BodyFinished");
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead);
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
block.Set();
astert.Equal("BodyStarted,BodyFinished", await response.Content.ReadasttringAsync());
}
[Fact]
public async Task FlushSendsHeaders()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
context.Response.Body.Flush();
block.WaitOne();
context.Response.Write("BodyFinished");
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead);
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
block.Set();
astert.Equal("BodyFinished", await response.Content.ReadasttringAsync());
}
[Fact]
public async Task ClientDisposalCloses()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
context.Response.Body.Flush();
block.WaitOne();
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead);
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
Stream responseStream = await response.Content.ReadasttreamAsync();
Task readTask = responseStream.ReadAsync(new byte[100], 0, 100);
astert.False(readTask.IsCompleted);
responseStream.Dispose();
Thread.Sleep(50);
astert.True(readTask.IsCompleted);
astert.Equal(0, readTask.Result);
block.Set();
}
[Fact]
public async Task ClientCancellationAborts()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
context.Response.Body.Flush();
block.WaitOne();
return Task.FromResult(0);
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead);
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
Stream responseStream = await response.Content.ReadasttreamAsync();
CancellationTokenSource cts = new CancellationTokenSource();
Task readTask = responseStream.ReadAsync(new byte[100], 0, 100, cts.Token);
astert.False(readTask.IsCompleted);
cts.Cancel();
Thread.Sleep(50);
astert.True(readTask.IsCompleted);
astert.True(readTask.IsFaulted);
block.Set();
}
[Fact]
public void ExceptionBeforeFirstWriteIsReported()
{
var handler = new OwinClientHandler(env =>
{
throw new InvalidOperationException("Test Exception");
});
var httpClient = new HttpClient(handler);
AggregateException ex = astert.Throws(() => httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead).Result);
astert.IsType(ex.InnerException);
}
[Fact]
public async Task ExceptionAfterFirstWriteIsReported()
{
ManualResetEvent block = new ManualResetEvent(false);
var handler = new OwinClientHandler(env =>
{
IOwinContext context = new OwinContext(env);
context.Response.Headers["TestHeader"] = "TestValue";
context.Response.Write("BodyStarted");
block.WaitOne();
throw new InvalidOperationException("Test Exception");
});
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead);
astert.Equal("TestValue", response.Headers.GetValues("TestHeader").First());
block.Set();
AggregateException ex = astert.Throws(() => response.Content.ReadasttringAsync().Result);
astert.True(ex.ToString().Contains("Test Exception"));
}
}
}