We are using a self hosted WebApi and we are required to remove the server header (Server: Microsoft-HTTPAPI/2.0) of the responses sent.
Since it is self hosted, a HttpModule is not an option. Implementing a DelegatingHandler, access to headers as well as adding is possible. The asp.net website nicely details how one can do that.
But the server header seems to be added much later in the pipeline since it is not set in the HttpResponseMessage we return from the DelegatingHandler. However, we are able to add values.
async protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
response.Headers.Server.Add(new ProductInfoHeaderValue("TestProduct", "1.0"));
response.Headers.Add("Server", "TestServerHeader");
return response;
}
Both Server.Add and .Add work as expected. response.Headers.Remove("Server"); however does not work, because the server header is not set, response.Headers.Server is empty.
Is there anything i am missing?
There is no code solution to remove Server HTTP header on self host.
The only solution is to edit windows registry:
https://learn.microsoft.com/ru-ru/archive/blogs/dsnotes/wswcf-remove-server-header
add
appBuilder.Use((context, next) =>
{
context.Response.Headers.Remove("Server");
context.Response.Headers.Add("Server", new[] { "" });
return next.Invoke();
});
to Startup Configuration method just before
config.EnsureInitialized();
Related
I'm developing a webhook receiver for an external tool.
I’m using ASP.NET WebHooks framework (more : https://learn.microsoft.com/en-us/aspnet/webhooks/ )
Everything is working great, except one thing : I can’t return a HttpStatusCode.Unauthorized.
This is a structure of code in WebHookReceiver :
public override async Task<HttpResponseMessage> ReceiveAsync(string id, HttpRequestContext context, HttpRequestMessage request)
{
try
{
var authheader = request.Headers.Authorization;
if (authheader == null || string.IsNullOrEmpty(authheader.Parameter))
{
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
I was expecting a simple HTTP response with the code HttpStatusCode.Unauthorized (Side note, ANY other Http code works as expected). Instead it returns the whole HTML Microsoft login page. I don’t even know where it’s taking it from.
My solution for now is just returning “BadRequest” and message “Authorization failed”
Ok got it.
This is perfectly normal.
https://www.restapitutorial.com/httpstatuscodes.html
The request requires user authentication. The response MUST include a
WWW-Authenticate header field (section 14.47) containing a challenge
applicable to the requested resource.
For my case, I should use 403 Forbidden
I use Delgating handler to add correlation ids to inward requests to my application.
But, my MVC app makes frequent calls to remote domain https://remoteservice.net/xyz via an webapi client provided by them. The remote service API allows users to set correlation id via request header, but the webapi client doesn't provide a way to expose that.
So I am now thinking to set correlation id via owin pipeline for all outgoing remote calls from my MVC app. Is this possible? Any help?
You could extend an HttpClientHandler and add a correlationId header there:
public class CorrelatingHandler : HttpClientHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("currelationId", Guid.NewGuid());
return base.SendAsync(request, cancellationToken);
}
}
using(var client = new HttpClient(new CorrelatingHandler())){
.....
}
source: https://forums.asp.net/post/6025521.aspx
I have a 2 services(WebApi), one is azure cloud service that using IIS host and another one is azure service fabric stateless service that using Owin host. There is a handler that like below, and both services register this handler to handle the context(config.MessageHandlers.Add(new ContextHandler())).
Currently, what I met is: If I call cloud service api(just ping) using HTTP HEAD request, this will return '405 method not allowed'. But if I call fabric service, I will get 'Could not get any response' with 'there was an error connecting to...'.
When debug the code. For the cloud service using IIS, in the below code, the response.Content has no value. But for the fabric service using Owin, the response.Content has value '405 Method not allowed'.
My question is, what the difference between them? Why the Owin will return a response with content back as the request is HEAD request?
Thanks.
public class ContextHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// initialize context
using (new ApiRequestContextWrapper(request))
{
var context = ApiRequestContext.Current;
context.Log.Trace(
$"API Call {request.Method.Method}
{request.RequestUri.GetLeftPart(UriPartial.Path)}");
var response = await base.SendAsync(request,
cancellationToken).ConfigureAwait(false);
return response;
}
}
}
I'm using Azure Mobile Services from within a Xamarin.iOS app.
My service expects a custom header to be sent from the client.
In order to send this, I created my own message handler which I derive from `NativeMessageHandler (part of ModernHttpClient):
this.client = new MobileServiceClient (Constants.ApplicationURL, Constants.GatewayURL, new CustomMessageHandler ());
To get my header in there, the handler looks like this:
public class CustomMessageHandler: NativeMessageHandler
{
protected override Task<System.Net.Http.HttpResponseMessage> SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Headers.Add ("customHeader", "headerValue");
return base.SendAsync (request, cancellationToken);
}
}
The problem is that the header doesn't seem to arrive at the server when my service is deployed to Azure. It works when running it locally in VisualStudio. If I put a breakpoint into my handler, it is hit; so the header really gets added.
Why would it work locally but not on Azure?
And the answer is: D'oh!
I enabled "Authentication" for my Azure App. Hence I would get a 401 for every request. It had nothing to do with my handler. Turned it off and it works like charm.
Since ASP.NET Web API RC I was using some approach based on declaring void API controller's operations.
I was customizing a response object DTO (instead of using HttpResponseMessage) using AOP and PostSharp, and finally this was sent to the client using HttpContext.Response.Write(...) serializing the DTO into a JSON string.
When I upgraded my solution to ASP.NET Web API RTM, this approach didn't work anymore.
Whenever I send a response from the Web API and I receive it in the client-side, I find that the response is sent with a 204 status (NoContent) while I was setting a 200 status (OK) for the response itself.
Because this approach was working in the RC version of WebAPI I suspect that's an unknown breaking change when WebAPI development team transitioned to RTM version.
Am I wrong?
As far as I know, since RTM if a POST action does not return an HttpResponseMessage the default status code is 204 (and not 200 as was back in RC). There are two things, I know, we can do to keep clients from complaining about 204.
a) Change the response message from within your action:
[HttpPost]
public HttpResponseMessage DoWork(MyModel model)
{
// Do work
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new ObjectContent<MyModel>(model, FormatterConfig.JsonFormatter) };
}
b) Change the response in a DelegatingHandler (dirty by generic way)
public class ResponseHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = base.SendAsync(request, cancellationToken);
response.Result.StatusCode = response.Result.IsSuccessStatusCode ? System.Net.HttpStatusCode.OK : response.Result.StatusCode;
return response;
}
}
I am not aware of such breaking change but I can confirm that this doesn't work in the RTM. Anyway, that's such a wrong approach of using the Web API that it's probably a good thing that it doesn't work. You are killing the whole point of the Web API if you are going to manually write the response to the client. If you have some existing code that does this that you cannot modify then I would recommend you using a Generic ASHX handler until you are ready to upgrade.