public static void VerifySelectOperationWithAutoRedirectMode(string requestUri, string operationName, UriAndMethodOperationSelector httpOperationSelector, bool shouldAutoRedirect) { string matchedOperationName; bool matchDifferByTrailingSlash; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri); bool result = httpOperationSelector.TrySelectOperation(request, out matchedOperationName, out matchDifferByTrailingSlash); Assert.IsTrue(result); Assert.AreEqual(matchedOperationName, operationName, String.Format("request {0} should match the operation {1}", requestUri, operationName)); Assert.AreEqual(matchDifferByTrailingSlash, shouldAutoRedirect); Uri originalUri = new Uri(requestUri); UriBuilder uriBuilder = new UriBuilder(originalUri); uriBuilder.Path = originalUri.AbsolutePath.EndsWith("/") ? uriBuilder.Path.TrimEnd('/') : uriBuilder.Path + "/"; Uri backSlashAlteredUri = uriBuilder.Uri; if (!shouldAutoRedirect) { matchedOperationName = httpOperationSelector.SelectOperation(request); Assert.AreEqual(matchedOperationName, operationName, String.Format("request {0} should match the operation {1}", requestUri, operationName)); } else { ExceptionAssert.Throws <HttpResponseException>( () => httpOperationSelector.SelectOperation(request), (responseException) => { HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, originalUri, backSlashAlteredUri); HttpAssert.AreEqual(expectedResponse, responseException.Response); }); } }
public void SelectOperationThrowsWithMatchDifferingByTrailingSlash() { HttpOperationAssert.Execute <UriTemplateService>( (operations) => { Uri baseAddress = new Uri("http://localhost/baseAddress"); UriAndMethodOperationSelector selector = new UriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.AutoRedirect); foreach (HttpOperationDescription operation in operations) { UriTemplate uriTemplate = operation.GetUriTemplate(); HttpMethod method = operation.GetHttpMethod(); string expectedOperation = operation.Name; string[] uriParameters = uriTemplate.PathSegmentVariableNames .Concat(uriTemplate.QueryValueVariableNames) .ToArray(); Uri requestUri = uriTemplate.BindByPosition(baseAddress, uriParameters); UriBuilder uriBuilder = new UriBuilder(requestUri); uriBuilder.Path = requestUri.AbsolutePath.EndsWith("/") ? uriBuilder.Path.TrimEnd('/') : uriBuilder.Path + "/"; Uri backSlashAlteredUri = uriBuilder.Uri; // Because UriTemplate.BindByPosition always adds a backslash for templates "" and "/", // the original requestUri is actually the correct backSlashAlteredUri in these cases. if (uriTemplate.ToString() == "" || uriTemplate.ToString() == "/") { Uri temp = requestUri; requestUri = backSlashAlteredUri; backSlashAlteredUri = temp; } HttpRequestMessage request = new HttpRequestMessage(method, backSlashAlteredUri); ExceptionAssert.Throws <HttpResponseException>( () => selector.SelectOperation(request), (responseException) => { HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, backSlashAlteredUri, requestUri); HttpAssert.AreEqual(expectedResponse, responseException.Response); }); } }); }
/// <summary> /// Selects a service operation based on the HTTP verb and the request Uri of the incoming request message. /// </summary> /// <param name="request">The incoming <see cref="HttpRequestMessage"/>.</param> /// <returns>The name of the operation to be associated with the message.</returns> protected override sealed string OnSelectOperation(HttpRequestMessage request) { Fx.Assert(request != null, "The base class ensures that the 'request' parameter will not be null."); bool matchDifferByTrailingSlash; string operationName = null; HttpResponseMessage errorResponse = null; if (request.RequestUri != null) { if (this.TrySelectOperation(request, out operationName, out matchDifferByTrailingSlash)) { if (matchDifferByTrailingSlash && this.trailingSlashMode == TrailingSlashMode.AutoRedirect) { Uri newLocation = BuildUriDifferingByTrailingSlash(request); errorResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, request.RequestUri, newLocation); } } else if (!CanUriMatch(this.wildcardTable, request.RequestUri, out operationName)) { IEnumerable <HttpMethod> allowedMethods = this.RetrieveAllowedMethodsIfAny(request); if (allowedMethods != null) { errorResponse = StandardHttpResponseMessageBuilder.CreateMethodNotAllowedResponse(request, allowedMethods, this.HelpPageUri); } } } if (operationName == null && errorResponse == null) { errorResponse = StandardHttpResponseMessageBuilder.CreateNotFoundResponse(request, this.HelpPageUri); } if (errorResponse != null) { throw Fx.Exception.AsError(new HttpResponseException(errorResponse)); } return(operationName); }