views:

319

answers:

2

I have a need to override the receipt of a raw HTTP request as it is being communicated to an IIS server. I want to know if this is possible.

We have a client who sends huge Web Service calls (tens of Mb) and we want to start acting on portions of those calls as they are being received (in order to get a faster total time of execution for the Web Service call).

Currently, using normal web service methods, our application code is handed the Web Service call after it is totally received.

I realize this isn't the ideal way of handling Web Services, and we're not building our business on this, but we do have an need that we're trying to fill for a limited range of customers.

I have created a handler that implements IHttpHandler, but it appears that at this point in the process pipeline, the Request has been fully received by IIS (which doesn't get us any benefit over our current model). That is, I can read the InputStream directly, but the full request has already been transferred over the wire before I have access to this stream.

I think the answer is that I have to code an ISAPI filter to get this far down, but I don't have the skills to do this in C/C++. Does anyone know if there's another way I can do this without the ISAPI filter route?

An acceptable answer could be, "You have to do this as and ISAPI filter, to do it in C#, check this doc".

A: 

There are plenty of examples of building ISAPI filters, but none in C#. I am sure it is possible, but not practical and not without lots dirty tricks.

Your C# investment will hold up well in C++, let me know if you need help. By the way, I recommend you invest in the my standard trio - try to keep up a healthy knowledge of C#, C++ and Java.

I also recommend you consider Apache modules, they may offer more overall flexibility. This is what I would do:

  1. host these web services off of IIS - you never know when IIS will bite you by resetting the application.
  2. Use WCF services, host these from Windows services, use redirection to route the service to the WCF service.
  3. Consider writting a raw sockets application. This one would implement the minimal WS:* protocol to your service and act as a proxy for the real service. When the proxy detects that the inbound message is exceeding a threshold it would begin analyzing the message to extract out what it could process right away.

The result would be standard WCF (through proxy) for smaller messages and non-standard processing for everything else.

Let me know if I can help you build it - this is the kind of thing I like to do...

Oh - and I recall now that WCF is completely configurable. You will be able to provide your own handlers for a variaty of layers and resolve everything from within managed code after all.

cmdematos.com
Thanks cmdematos, I think you're right, this requires an ISAPI filter. I'm not sure we're it going to sense for us to go forward with this project given the fact that, we're not a C++ shop and that your 3rd suggestion would probably be the way we'd have to go. I'm going to have to wait for the higher-ups to make a call (this was a deliverable for Monday ;)
Patrick Farrell
+1  A: 

You can use a custom HttpModule to hook almost any part of the IIS pipeline. They work in both IIS 6 (under ASP.NET) and are the primary extension mechanism in IIS 7.

Jeff Hardy
I could be wrong here, having never tried it - but I don't think HttpModule would work in this scenario. The key here is to begin processing the request before the request has been fully received. It seems that by the time HttpModule is called the entire requests has already been read in (albeit not processed) by IIS. The only way to process a large request "while it is being read in" would be by processing the raw stream of data from the socket - or as close as possible to that. ISAPI filter seems low enough for this, if anyone knows better let us know.
cmdematos.com
cmdemanto, this is has been my experience in trying to use the HttpModule. Thanks for the help, Jeff, but it appears that IIS doesn't raise the BeginRequest event until after the entire request stream has been read. At least, this is what I've been able to determine. If you know that I'm wrong, I'd really appreciate some code, because I can't figure out how to do it.
Patrick Farrell
NeatUpload (http://www.brettle.com/neatupload) seems to do something similar to what you want to do. It's open source, so maybe you can check it out? (It was what I was thinking of when I saw your question.)
Jeff Hardy
Jeff, that is cool. I'll check it out. It may be something that will work. I've also found that your answer mamy be the correct on. IIS 7, when operated in Integrated Pipeline mode empowers HttpModules to have access override native code functions (maybe). I don't run Vista, so I can't test now, but my code may "magically" work we I deploy. I'll post back here with my results. Thanks a lot for the info.
Patrick Farrell