Reading the request body while it is being received?

Topics: faq
Dec 7, 2008 at 6:40 PM
Hi,

First of all, you are doing a great job with this project. It allows me to embed the features of a web server in a simple way into my application. Best of all, it gives me the flexibility and the control that I need.

I have a scenario where I want to do some real-time processing (streaming) when receiving a request. I want to be able to read the body message while it is being received from the network after request headers have been received. For example, if a large music file is posted I need to process it while it is being received. Also, that needs to be done in an efficient way so that memory consumption isn't largely affected by the size of the request.

Is it possible somehow to achive this functionality with the current release?

I have tried both the HttpListener ( using RequestHandler) and the HttpServer ( using HttpModule) to achive this task. That made me relize that the whole request (headers and body) is received before the request handler code (RequestHandler or HttpModule) is called.

Having a posibility to attach a custom request body parser/handler for certain requests would do the trick. What is your opinion on handling this kind of functionality?

Thanks...
Coordinator
Dec 10, 2008 at 12:28 PM
Edited Dec 10, 2008 at 12:29 PM
Sorry, there are no easy way to do this today.

Most objects creations are hard coded, which means that you can't easily switch from our HttpRequestParser to your own. We've coded our own inversion of control framework in fadd (www.codeplex.com/fadd) which we'll probably use in upcoming versions of the webserver.

The webserver is working against a IHttpRequest interface, which means that you can use your own custom request (that are created by your own requestparser).
The HttpRequestParser are created by the HttpClientContextImp which are created by the HttpListener.

We are currently quite busy with the next version of our product, so no changes are planned for the http server in the next couple of weeks. But this is definatly something we'll take a look at later (if you havent dont it yourself already).
Coordinator
Jan 7, 2009 at 8:24 AM
This should be possible now. Look at the HttpContextFactory and implement your own. I've refactored the HttpRequestParser, it's now event driven and sends all parsed content to the IHttpClientContext. Create your own HttpClientContext or derive the built in one and override AddToBody (which receives content such as files or anything you stream).

Then do this do use your own IHttpContextFactory:

ComponentFactory factory = new ComponentFactory();
factory.Add<IHttpContextFactory, MyFactory>();
WebServer server = new WebServer(factory);

The fadd component factory (ioc container) can currently only handle singletons. We'll change this in the future.
Jan 27, 2009 at 2:31 PM
Thanks for this refactoring,

I am now able to do the real-time processing of the request, but there seems to be a problem when request body is being processed thought. I will address this in a separate thread.

I have created my own IHttpContextFactory to be able to inject a custom IHttpClientContext (derived from HttpClientContextImp).

However, I would prefer to benefit from the IHttpClientContext pooling mechanism in HttpContextFactory. Therefore, could you maybe provide a solution where I can use a custom IHttpClientContext  without loosing the pooling for it.

Posible solutions could be:

- Using ioc container and dependency injection to get new IHttpClientContext in HttpContextFactory
- protected virtual method like CreateNewClientContext on HttpContextFactory that I can override. Then I could simply derive HttpContextFactory and override this method
- Extract the pooling from HttpContextFactory
Coordinator
Jan 27, 2009 at 3:40 PM
Solution #2 was added. "CreateNewContext".
Jan 28, 2009 at 9:39 AM
Thanks, but could you make the method CreateNewContext "virtual" also so I can override it?

Also, is it possible to somehow know when the HttpClientContextImp is started (Start() method is called) and cleaned (Cleanup() method is called). I need to do some custom stuff in my derived HttpClientContextImp when those methods are called.

One way is to make those methods virtual but that can break the encapsulation of the class. What do you think?
Coordinator
Jan 28, 2009 at 9:57 AM
lol. sorry. missed that =)

Start and Cleanup is now virtual, and there are new events called Cleaned and Started. Pick the solution that suits you best.