//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.Test.OpenId;
using DotNetOpenAuth.Yadis;
internal class MockHttpRequest {
private readonly Dictionary registeredMockResponses = new Dictionary();
private MockHttpRequest(IDirectWebRequestHandler mockHandler) {
Contract.Requires(mockHandler != null);
this.MockWebRequestHandler = mockHandler;
}
internal IDirectWebRequestHandler MockWebRequestHandler { get; private set; }
internal static MockHttpRequest CreateUntrustedMockHttpHandler() {
TestWebRequestHandler testHandler = new TestWebRequestHandler();
UntrustedWebRequestHandler untrustedHandler = new UntrustedWebRequestHandler(testHandler);
if (!untrustedHandler.WhitelistHosts.Contains("localhost")) {
untrustedHandler.WhitelistHosts.Add("localhost");
}
untrustedHandler.WhitelistHosts.Add(OpenIdTestBase.OPUri.Host);
MockHttpRequest mock = new MockHttpRequest(untrustedHandler);
testHandler.Callback = mock.GetMockResponse;
return mock;
}
internal void RegisterMockResponse(IncomingWebResponse response) {
Contract.Requires(response != null);
if (this.registeredMockResponses.ContainsKey(response.RequestUri)) {
Logger.Http.WarnFormat("Mock HTTP response already registered for {0}.", response.RequestUri);
} else {
this.registeredMockResponses.Add(response.RequestUri, response);
}
}
internal void RegisterMockResponse(Uri requestUri, string contentType, string responseBody) {
this.RegisterMockResponse(requestUri, requestUri, contentType, responseBody);
}
internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, string responseBody) {
this.RegisterMockResponse(requestUri, responseUri, contentType, new WebHeaderCollection(), responseBody);
}
internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string responseBody) {
Contract.Requires(requestUri != null);
Contract.Requires(responseUri != null);
Contract.Requires(!String.IsNullOrEmpty(contentType));
// Set up the redirect if appropriate
if (requestUri != responseUri) {
this.RegisterMockRedirect(requestUri, responseUri);
}
string contentEncoding = null;
MemoryStream stream = new MemoryStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(responseBody);
sw.Flush();
stream.Seek(0, SeekOrigin.Begin);
this.RegisterMockResponse(new CachedDirectWebResponse(responseUri, responseUri, headers ?? new WebHeaderCollection(), HttpStatusCode.OK, contentType, contentEncoding, stream));
}
internal void RegisterMockXrdsResponses(IDictionary requestUriAndResponseBody) {
foreach (var pair in requestUriAndResponseBody) {
this.RegisterMockResponse(new Uri(pair.Key), "text/xml; saml=false; https=false; charset=UTF-8", pair.Value);
}
}
internal void RegisterMockXrdsResponse(IdentifierDiscoveryResult endpoint) {
Contract.Requires(endpoint != null);
string identityUri;
if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) {
identityUri = endpoint.UserSuppliedIdentifier;
} else {
identityUri = endpoint.UserSuppliedIdentifier ?? endpoint.ClaimedIdentifier;
}
this.RegisterMockXrdsResponse(new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint });
}
internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable endpoints) {
Contract.Requires(endpoints != null);
StringBuilder xrds = new StringBuilder();
xrds.AppendLine(@"
");
foreach (var endpoint in endpoints) {
string template = @"
{0}
{1}
{2}
{2}
";
string serviceTypeUri;
if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) {
serviceTypeUri = endpoint.Protocol.OPIdentifierServiceTypeURI;
} else {
serviceTypeUri = endpoint.Protocol.ClaimedIdentifierServiceTypeURI;
}
string xrd = string.Format(
CultureInfo.InvariantCulture,
template,
HttpUtility.HtmlEncode(serviceTypeUri),
HttpUtility.HtmlEncode(endpoint.ProviderEndpoint.AbsoluteUri),
HttpUtility.HtmlEncode(endpoint.ProviderLocalIdentifier));
xrds.Append(xrd);
}
xrds.Append(@"
");
this.RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString());
}
internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) {
IdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(
directedIdentityAssignedIdentifier,
directedIdentityAssignedIdentifier,
providerEndpoint.ProviderLocalIdentifier,
new ProviderEndpointDescription(providerEndpoint.ProviderEndpoint, providerEndpoint.Capabilities),
10,
10);
this.RegisterMockXrdsResponse(identityEndpoint);
}
internal Identifier RegisterMockXrdsResponse(string embeddedResourcePath) {
UriIdentifier id = new Uri(new Uri("http://localhost/"), embeddedResourcePath);
this.RegisterMockResponse(id, "application/xrds+xml", OpenIdTestBase.LoadEmbeddedFile(embeddedResourcePath));
return id;
}
internal void RegisterMockRPDiscovery() {
string template = @"
{0}
{1}
{2}
";
string xrds = string.Format(
CultureInfo.InvariantCulture,
template,
HttpUtility.HtmlEncode(Protocol.V20.RPReturnToTypeURI),
HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUri.AbsoluteUri),
HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUriSsl.AbsoluteUri));
this.RegisterMockResponse(OpenIdTestBase.RPRealmUri, ContentTypes.Xrds, xrds);
this.RegisterMockResponse(OpenIdTestBase.RPRealmUriSsl, ContentTypes.Xrds, xrds);
}
internal void DeleteResponse(Uri requestUri) {
this.registeredMockResponses.Remove(requestUri);
}
internal void RegisterMockRedirect(Uri origin, Uri redirectLocation) {
var redirectionHeaders = new WebHeaderCollection {
{ HttpResponseHeader.Location, redirectLocation.AbsoluteUri },
};
IncomingWebResponse response = new CachedDirectWebResponse(origin, origin, redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream());
this.RegisterMockResponse(response);
}
internal void RegisterMockNotFound(Uri requestUri) {
CachedDirectWebResponse errorResponse = new CachedDirectWebResponse(
requestUri,
requestUri,
new WebHeaderCollection(),
HttpStatusCode.NotFound,
"text/plain",
Encoding.UTF8.WebName,
new MemoryStream(Encoding.UTF8.GetBytes("Not found.")));
this.RegisterMockResponse(errorResponse);
}
private IncomingWebResponse GetMockResponse(HttpWebRequest request) {
IncomingWebResponse response;
if (this.registeredMockResponses.TryGetValue(request.RequestUri, out response)) {
// reset response stream position so this response can be reused on a subsequent request.
response.ResponseStream.Seek(0, SeekOrigin.Begin);
return response;
} else {
////Assert.Fail("Unexpected HTTP request: {0}", uri);
Logger.Http.WarnFormat("Unexpected HTTP request: {0}", request.RequestUri);
return new CachedDirectWebResponse(request.RequestUri, request.RequestUri, new WebHeaderCollection(), HttpStatusCode.NotFound, "text/html", null, new MemoryStream());
}
}
}
}