Parsing HttpHeaders when they come from outside the Web API stack

Topics: ASP.NET Web API, General
Jul 24, 2012 at 1:19 PM
Edited Jul 24, 2012 at 1:23 PM

OK, let's say I have some arbitrary HTTP response as string (or stored as byte array)

 

200 OK
status: 200 OK
content-length: 10
x-xss-protection: 1; mode=block
server: gws
x-frame-options: SAMEORIGIN
content-type: application/json; charset=UTF-8
expires: -1
cache-control: private, max-age=0
version: HTTP/1.1

{name:"ali"}

 

I need to parse this to create an HttpResponseMessage. And on the hand, be able to dump an HttpResponseMessage and store it away.

Is there anything exposed for me to be able to do that the same way Web API does it? I have not yet found anything. With content, it is fairly easy to do and setting the response code and reason phrase easy but setting headers is tough.

Problem is this header contains both content level headers and HttpResponseMessage level headers and I would have to know which one goes where. 

So is there an easy way for me to do this please?

Jul 24, 2012 at 3:37 PM

Here's how to parse the message: Stick the raw message into a memory stream or a string and create an HttpContent around it (while setting the content type to "application/http; type=request"). Then call HttpContent.ReadAsHttpRequestMessage and voila you have an HttpRequestMessage (similar for responses).

To serialize, create HttpMessageContent from an HttpRequestMessage and  just call write CopyToAsync on it. That will serialize the content to the output stream.

As an example you can look at this test [1]:

    HttpContentMessageExtensionsTests.RoundtripClientRequest

which does something very similar

Hope this helps,

Henrik

[1] http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/1ccfcdfc11da#test%2fSystem.Net.Http.Formatting.Test%2fHttpMessageContentTests.cs

Jul 24, 2012 at 8:52 PM

Thanks a lot Henrik. This is awesome.

@AlexZeitler also pointed me to this but I remembered it from Brad's batching post and did not realise it can actually do this. So for the record, here is a snippet:

		public void Serialize(HttpResponseMessage response, Stream stream)
		{
			var httpMessageContent = new HttpMessageContent(response);
			var buffer = httpMessageContent.ReadAsByteArrayAsync().Result;
			stream.Write(buffer, 0, buffer.Length);
		}

		public HttpResponseMessage Deserialize(Stream stream)
		{
			var response = new HttpResponseMessage();
			var memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			response.Content = new ByteArrayContent(memoryStream.ToArray());
			response.Content.Headers.Add("Content-Type", "application/http;msgtype=response");
			return response.Content.ReadAsHttpResponseMessageAsync().Result;
		}