PRB: CGI Applications Hang Under IIS 4.0 With POSTID: Q203298
|
Common gateway interface (CGI) applications that worked correctly under Microsoft Internet Information Server (IIS) 3.0 with the HTTP POST method appear to hang under IIS 4.0. Using CGI with the HTTP GET method still works correctly.
A typical scenario is that you upgrade your Microsoft Internet Information Server 3.0 to 4.0 and suddenly all or some of your CGI applications appear to hang when called with a POST method.
The most likely reason for this is that the CGI in question was not written correctly. Under certain conditions, an incorrectly written CGI can work properly with IIS 3.0 and earlier, but will appear to break with IIS 4.0. The reason for this is that IIS 3.0 and earlier was more tolerant of incorrectly written CGI applications. Browsers like Internet Explorer and Netscape Navigator will append a Carriage Return + Line Feed (CRLF) pair to the end of any posted data. IIS 3.0 and earlier will pass this extra CRLF pair to the CGI application, so that CGIs written depend on this additional CRLF (which is against CGI and HTTP specifications) to work with IIS 3.0 and earlier.
However, any CGI application running under IIS 4.0 reading from standard input and waiting for a CRLF character to indicate when the Posted data is complete will hang until a timeout occurs (or the user aborts the session). This is because IIS 4.0 will no longer pass on the additional CRLF pair to the CGI application.
The following CGI code sample is typical of this problem:
int main(int argc, char* argv[])
{
char szBuf[1024];
gets(szBuf);
// Do something with szBuf...
return 0;
}
The prior code hangs on the gets() call.
The correct solution is to rewrite the CGI application so it will adhere to the CGI and HTTP specifications. Typically, there are two issues to deal with:
int main(int argc, char* argv[])
{
char* pCL = getenv("CONTENT_LENGTH");
if(pCL != NULL)
{
int nCL = atoi(pCL);
if(nCL > 0)
{
// WARNING: Error checking removed for clarity...
printf("Content-Type: text/html\r\n\r\n");
_setmode( _fileno( stdin ), _O_BINARY );
char* szBuf = new char[nCL + 1];
fread(szBuf + nRead, sizeof(char), nCL-nRead, stdin);
szBuf[nCL] = '\0';
// Do something with szBuf...
delete [] szBuf;
}
}
return 0;
}
This behavior is by design.
From the HTTP 1.1 Specification (RFC2068):
NOTE: Certain buggy HTTP/1.0 client implementations generate an
extra CRLF's after a POST request. To restate what is explicitly
forbidden by the BNF, an HTTP/1.1 client must not preface or follow
a request with an extra CRLF.
Which implies that server applications cannot rely on client's sending an extra CRLF.
You should also be aware that similar problems could result in scripts as well as executables. While some script interpreters may internally buffer up the posted data before executing the actual script resulting in correct script behavior, the scripts should adhere to the correct behavior.
The third-party contact information included in this article is provided
to help you find the technical support you need. This contact information
is subject to change without notice. Microsoft in no way guarantees the
accuracy of this third-party contact information.
For more information on the Common Gateway Interface 1.1 Specification see the following website at:
http://hoohoo.ncsa.uiuc.edu/cgi/interface.htmlFor more information on the HTTP 1.1 Specification (RFC 2068) see the following website at:
ftp://ftp.isi.edu/in-notes/rfc2068.txt
Additional query words: kbDSupport
Keywords : kbDSupport kbIIS
Version : winnt:4.0
Platform : winnt
Issue type : kbprb
Last Reviewed: August 9, 1999