CGI module for v2.0

Mar 2, 2011 at 9:06 AM
Edited Mar 2, 2011 at 9:37 AM


Some time ago I wrote a CGI module for v1.1. It was designed to replace the built-in file module, since there was a lot of duplicate code anyways.

Now, I started to port the module to v2.0 using the code of the new FileModule class as a basis and ran into 2 problems:

1. I wanted to have the cgi module in my own namespace, but since HttpFactory.Current is internal, getting the ResponseWriter from the factory is not possible. Copying my module to the HttpServer.Modules namespace of course solved the problem, but I guess that's not the intended way.

2. The duplicate code in the v.1.1 module was mainly due to resource handling. Now, in v2.0 you introduced the ResourceProvider. I'm using the modules like this

IResourceLoader resource = new FileResources("/", @"C:\Homepage");

FileModule fileModule = new FileModule();

CgiModule cgiModule = new CgiModule();
cgiModule.AddCgiApplication("php", @"C:\Program Files (x86)\PHP\php-cgi.exe");

Using the code from your FileModule, I had to add a GetPath method to the ResourceProvider and make GetFullFilePath in FileResources public to give me the physical path of my php files, so I could write

string path = _resourceManager.GetPath(context.Request.Uri.LocalPath);

 Is that the v2.0 way? I'm asking this, because at the moment my CGIModule class is creating the cgi process, but maybe I should create a CGIResources class deriving from FileResources which does this!?


Apr 19, 2011 at 11:45 AM
Edited Aug 1, 2011 at 5:04 PM

Ok, no answer.

By the way. The problem with the SendingResponse event not firing is still present ( I think it has to do with how you stop processing a request. Setting ProcessingResult.SendResponse you get the event, setting ProcessingResult.Abort you won't. This is probably not what a user would expect, since in either way, a response is sent to the client.

Anyways. Here's the code for the cgi module. Maybe you could comment on it (regarding the original post). And remember that I had to do some changes to the webserver code as mentioned above ...

EDIT: You can find the code on

Apr 19, 2011 at 1:36 PM
Edited Apr 25, 2011 at 11:24 AM

EDIT: Created issue (

Another problem I came across:

When executing a php script with phpinfo() you usually get to see the php logo as a gif. Instead the graphics, the server produces a "500 Index was outside the bounds of the array.".

Here's the request and the stack trace:

GET /info.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv: Gecko/20110319 Firefox/3.6.16
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive

at System.String.get_Chars(Int32 index)
at HttpServer.Tools.StringReader.GetString(Int32 startIndex, Int32 endIndex, Boolean trimEnd) in C:\HttpServer\Tools\StringReader.cs:line 38
at HttpServer.Tools.StringReader.ReadToEnd(String delimiters) in C:\HttpServer\Tools\StringReader.cs:line 248
at HttpServer.Tools.UrlParser.Parse(ITextReader reader) in C:\HttpServer\Tools\UrlParser.cs:line 25
at HttpServer.Tools.UrlParser.Parse(String queryString) in C:\HttpServer\Tools\UrlParser.cs:line 63
at HttpServer.Messages.Request..ctor(String method, String path, String version) in C:\HttpServer\Messages\Request.cs:line 45
at HttpServer.Messages.MessageFactory.CreateRequest(String method, String uri, String version) in C:\HttpServer\Messages\MessageFactory.cs:line 63
at HttpServer.Messages.MessageFactoryContext.OnRequestLine(Object sender, RequestLineEventArgs e) in C:\HttpServer\Messages\MessageFactoryContext.cs:line 89
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at HttpServer.Messages.Parser.HttpParser.OnFirstLine(String[] words) in C:\HttpServer\Messages\Parser\HttpParser.cs:line 215
at HttpServer.Messages.Parser.HttpParser.ParseFirstLine() in C:\HttpServer\Messages\Parser\HttpParser.cs:line 270
at HttpServer.Messages.Parser.HttpParser.Parse(Byte[] buffer, Int32 offset, Int32 count) in C:\HttpServer\Messages\Parser\HttpParser.cs:line 239
at HttpServer.Messages.MessageFactoryContext.Parse(Byte[] buffer, Int32 offset, Int32 length) in C:\HttpServer\Messages\MessageFactoryContext.cs:line 108
at HttpServer.HttpContext.ParseBuffer(Int32 bytesLeft) in C:\HttpServer\HttpContext.cs:line 311
at HttpServer.HttpContext.OnReceive(IAsyncResult ar) in C:\HttpServer\HttpContext.cs:line 226