A multithreaded, IOCP-based, ISAPI extension for the Simple Common Gateway Protocol.
isapi_scgi ISAPI extension for Microsoft IIS implements the Simple
Common Gateway Interface (SCGI). SCGI is a standard for communicating
with web servers on the back end. Requests received by IIS are passed
on to the application server over the SCGI protocol and the response
sent back to the client. Unlike CGI, where the web server will start
a new process for every request, SCGI involves a long-running process
(the SCGI server) which is handed off requests from the web server and
responds as per the protocol. It has the following benefits compared
It is an order of magnitude or more faster as it avoids all the startup costs associated with the latter, such as process creation, interpreter initialization, loading of application code and re-establishing database connections.
Because communication with the web server is on top of TCP, the application code can actually run on a different server if desired for performance or security reasons.
This guide describes
installation and usage but assumes you know how to configure your SCGI
isapi_scgi has the following features:
Supports Microsoft IIS versions 6, 7 and 8.
Can optionally start the SCGI application server automatically
Ability to control parameters like number of threads, outstanding IOCP requests etc. for tuning to your particular environment.
Implemented as an ISAPI C extension and uses I/O completion ports for minimal memory and CPU usage
Supports non-parsed headers
No other dependencies. Even the C runtime is either not needed or is statically bound
Open source with a liberal BSD license that allows free use even in commercial environments.
The latest version of
isapi_scgi can be downloaded from the
section of the
the files into a temporary folder before following the instructions
The examples and description in this document refer to the extension
isapi_scgi is installed like any other ISAPI extension. The sample
sessions below illustrate installation under IIS 6 on Windows XP and
IIS 8 on Windows 8. Installation for other IIS versions are very
We assume a simple configuration where the extension will be accessed
/sandbox/isapi_scgi.dll/. All requests to URLs below this will
be passed by the extension to the SCGI server. Obviously you may use
techniques such as URL rewriting to hide the use of the DLL but that
is not described here.
Installing for IIS 6
Start up the MMC IIS manager and create a new virtual directory, sandbox, under the default Web site as shown in the screenshot below.
Right click on the sandbox virtual directory and configure its properties as shown below.
We have mapped the sandbox virtual directory to a physical directory,
c:\scgi-example, on the local system. The important thing to note in
the above configuration screen is that 'Execute Permissions' have been
set to 'Scripts and Executables'. This is required for ISAPI extensions
to be enabled for the virtual directory. Also, setting the 'Application
Protection' value to 'Low' instead of 'Medium' as above will give higher
isapi_scgi.dll from the temporary directory where you
extracted the distribution into the physical directory,
c:\scgi-example, in the above example. The IIS manager console will
look as follows after refreshing.
The extension is now installed.
Installing for IIS 8
We now illustrate installing
isapi_scgi for IIS 8, this time using
the 64-bit extension
Start up the IIS manager and right-click on the
Default Web Site
node to bring up the menu.
Add Virtual Directory… menu item and fill the dialog
that comes up as shown.
We have mapped the sandbox virtual directory to a physical directory,
c:\scgi-example, on the local system.
isapi_scgi64.dll to this physical directory.
Now select the newly created
sandbox virtual directory node and in the middle
plane double click the
Handler Mappings item.
This will bring up the handler settings for the
sandbox virtual directory
as shown below. Note that ISAPI is disabled and needs to be enabled. To
do this, select the
ISAPI-dll line and click the
Edit Feature Permissions…
item in the
Fill out the dialog as shown below ensuring all checkboxes are selected.
OK in the above dialog, you should see
Handler Mappings pane for the
sandbox virtual directory.
This is required for ISAPI extensions to be enabled for the virtual directory.
There is one final step needed. By default, IIS will not allow unknown
extensions to run so we need to add it to the system-wide list of
permitted ISAPI extensions. To do this, select the system node
in IIS Manager and double click the
ISAPI and CGI Restriction item
in the middle pane.
Add item in the
Actions pane and fill the presented dialog
Click OK to save the configuration.
The extension is now installed.
If you are not running the default SCGI server address and port,
follow the steps described in the configuration section to set up
Finally, stop and restart IIS and the default Web site. The
extension will now be invoked whenever a request for a URL beginning
/sandbox/isapi_scgi64.dll is received
Upgrading from earlier versions
Please note that beginning with Version 0.8,
isapi_scgi will parse
SCGI response headers by default. This differs from earlier releases
which only supported non-parsed headers operation. To keep the
earlier behaviour, the
NonParsedHeaders configuration option must be set to
a non-0 value. See SCGI response headers.
SCGI request headers
As recommended in the SCGI specification,
isapi_scgi passes the following CGI headers to the SCGI server as part
of the request:
In addition, it passes the following protocol specific headers
if they were present in the client request:
Please refer to RFC3875 for the meaning of the above headers.
If any URL rewriters generate the
it is passed as well.
In the case where the request is over an HTTPS connection, the following
additional headers are added:
Please refer to the IIS documentation for the meaning of the above headers.
Handling custom headers
For the SCGI server to be passed any additional or custom headers,
they have to be explicitly configured in the
configuration file. These may be specific to IIS such as
URL. They may also
be based on custom HTTP headers sent from the client or generated
by other extensions or filters such as URL rewriters.
To have these headers passed by
isapi_scgi they must be added as
keys to the
SCGI_HEADER_EXTENSIONS section of the
configuration file. In the case of custom HTTP headers, the
key is formed by prefixing the actual header name with
- characters in the name with
_. An example section
is shown below:
[SCGI_HEADER_EXTENSIONS] INSTANCE_ID= (1) HTTP_X_REWRITE_URL= (2) HTTP_X_CUSTOM_HEADER= (3)
|1||Passes the IIS-specific header containing the IIS instance id|
|2||Passes the header generated by an installed URL rewriting filter|
|3||Passes the X-Custom-Header non-standard header sent by the client|
Note that the value assigned to the keys is currently immaterial but should be left empty.
SCGI response headers
The SCGI specification states:
Two formats for the response are supported by
to the equivalent CGI specification defined by
In the normal CGI case, the SCGI server sends a response header
separated from the body by a blank line. The header may contain
a 'Status:' line indicating the HTTP status. If absent, a status
of "200 Ok" is assumed. The
isapi_scgi extension will then generate
HTTP headers based on the SCGI response headers.
The non-parsed header (NPH) case is enabled when the
NonParsedHeaders configuration setting is set to a non-0 value.
In this case,
isapi_scgi passes all bytes sent from the SCGI
server back to the client with no modification at all.
The SCGI server is responsible for the entire content passed back
to the client.
See RFC3875 for more details about these behaviours.
isapi_scgi is configured through the
isapi_scgi.ini file which
must be located in the same directory as the
extension. This file is in the standard Windows INI file format and
may contain the variables described below. These must be defined in
[SCGI] section of the file.
Note that the file is only needed if the defaults described below do not match your desired configuration.
Integer value corresponding to the maximum number of queued IOCP requests.
If non-0, the extension keeps certain statistics that can be useful in troubleshooting or tuning.
Path to the log file.
Verbosity of logging. 0 turns off, 1 logs only errors.
Whether non-parsed headers (NPH) are in use. 1 to turn on NPH, 0 to turn off.
Integer value corresponding to the number of worker threads to be run.
IP address of the SCGI server.
Port the SCGI server is listening on.
Command to execute to start the SCGI application server. See Starting SCGI servers automatically.
None. No server is started by default.
Command to execute stop the SCGI application server. See Starting the SCGI server automatically.
Controls how often statistics are written to the log file. The interval is given in seconds.
The optimal values for
IOCPQueueMax depend on the
system (memory, number of processors and their speed, etc.) and
configuration (for example, whether the SCGI server on a different
system). On heavily loaded systems, you should determine these values
empirically through load testing.
Starting SCGI servers automatically
You may choose to start your SCGI server automatically and
independently of IIS. Alternatively, you can configure
start the server automatically when the first request is received and
to shut it down when IIS unloads the extension (for example, when IIS
is shut down).
isapi_scgi automatically start the SCGI server, set the
SCGIServerStartCommand. The value must be the
full command including a full path and arguments, if any.
will execute this command without any validation or error
checking. Similarly, to have
isapi_scgi automatically shut down the
SCGI server, set the configuration variable
example, if your SCGI server runs as the Windows service
you might have the following two lines in the
[SCGI] SCGIServerStartCommand= net start myscgiapp SCGIServerStopCommand= net stop myscgiapp
Logging in isapi_scgi
isapi_scgi will log to the file
isapi_scgi.log in the same
isapi_scgi.dll is located. This can be changed by
LogFile variable in the configuration.
The messages logged can be controlled by setting the
default, only errors are logged (
LogLevel=1). Setting its value to
will turn off all logging and setting it to
2 will log informational
messages as well as errors, including connection requests.