NPH (Non-Parsed Header) Scripts

NPH scripts were originally created to let a CGI process write its output directly to the socket fd. This implementation has a performance benefit, as well as the following implications:

It is the latter attribute that many popular NPH scripts depend on.

Orenosv offers flexible output buffering facilities, one of which is unbuffered output. Unlike NPH, unbuffered output does parse and modify response headers but it won't buffer script output. Thus most NPH scripts can achieve its purpose by using unbuffered output. In order to offer further compatibilty, Orenosv also correctly parses raw response headers generated by NPH scripts.

This NPH compatibility mode can be enabled per script basis by prepending "nph-" prefix to the name of the script, regardless of the global "outbuf_mode" parameter.

Other points:

Multi-process implementation

Currently, processes in a process group (called "helper processes" hereafter) are implemented as an independent HTTP server that listens on a TCP port. So the main server acts as a specialized form of proxy. A helper process listens on IP address of "localhost"(127.0.0.1) and the port number that it will get from OS when it started up (using bind(0)).

This implementation may be resource intensive in terms of TCP ports if many helper processes are required, as well as main-helper communications overhead. There are several performance optimizations possible.

The security against localhost users is as follows. When a parent process starts up a child process, it generates a secret code and passes it on to the child via the pipe, which should be protected by the OS. The parent process adds this secret code to its HTTP request headers when passing the client request to the child process, and the child checks that secret to see if it's from the parent. TCP communications between "localhost" endpoints are also protected by the OS.

SSI limitations

The reason why SSI is a separate CGI executable is that its implementation will be never be complete. Its parser is very simple minded.

Since SSI is to parse user-created files, it must be robust in handling errorneous documents otherwise it might fall into a tight CPU loop. However it will never be internationalized so it can never handle all errorneous cases correctly. Making it a CGI enables Orenosv to kill it off after a certain time limit (using -x option in mod_cgi).

other limitations

Performance problem with using localhost(127.0.0.1)

I encountered this problem on one of my notebook PC. This problem is present in Windows 2000 from SP0 to SP2.

Look at MS Knowledge base artitle Q294769
Data Transfer to "Localhost" or Loopback Address Is Slow.

A workaround is to use hostname that is assigned a valid IP address.

About 'Content-Encoding' field

It seems to me that the interpretation of 'Content-Encoding' differs between Netscape and IE. In both Netscape 4.7 and Mozilla 0.9, it is the content handler that is responsible for handling 'Content-Encoding', which is understandable. In IE 5.0, the HTTP transport handles 'Content-Encoding', which is good because this field is defined in HTTP spec.

The latest HTTP 1.1 spec suggests to use 'Transfer-Encoding: gzip' instead of 'Content-Encoding' for the purpose of entity transfer. 'Content-Encoding', instead, should be used to represent a meta-data for the entity.

For example, the headers:
Contenet-Type: text/plain
Content-Encoding: gzip
suggests to the user agent that the file is a plain text compressed by gzip, and should present this entity in gzip'ped form to whatever the user agent is using to render the content. When saving to disk it should use these info to name the file according the OS spec on which the user-agent is running. On Unix and Windows, the file should be named like 'xxx.txt.gz'.

On the other hand when the server emits 'Transfer-Encoding:gzip', like:
Contenet-Type: text/plain
Transfer-Encoding: gzip
it suggests to the user agent that the entity will be transfered in the format specified with Transfer-Encoding. The user agent or the HTTP transport component of the user agent should uncompress the entity and present the ungzip'ped format to the upper layer. When saving to disk, the agent should save it in the uncompressed form.

Following the RFC strictly will confuse existing browsers. Actually I don't know if any current browser supports Transfer-Encoding: gzip yet. Anyway modfilt_zlib will have to have an option to use Transfer-Encoding instead of Content-Encoding.