Ah, yes... GetServerVariable is one of the most frequently used function call of ISAPI Extension and ISAPI Filter APIs, but unfortunately, it is also one of the most incorrectly used.
Very few people heed the documentation to check the return value and handle errors correctly, and considering this API call reads data from the client, it is a very dangerous thing to do...
Hi David,
I found your page when searching for a solution on a problem I'm having.
I was hoping you could tell me something about it.
I hope you have time to take a look at it.
The situation:
I use an ISAPI application to get some ServerVariables. As far as I know the programmer uses the GetServerVariable.
In my IIS6.0 (Server 2003 WebEdition) this doesn't work. I've tried it on a IIS5.1 (Windows XP Pro system) and it does work.
So there must be something with IIS6.0
Do you know about any issues regarding IIS6.0 and the GetServerVariable ?
The strange thing is that when we use the ie. UNICODE_REMOTE_ADDR we get a value. But the ISAPI program isn't written for UNICODE.
Besides the scripts we create using the ISAPI code must work on all IIS systems.
We also have a CGI version, and that works with no problems.
I hope you have a solution....
I am not aware of any issues with GetServerVariable on any IIS version.
If you think there is an issue, please provide the following information so that we can reproduce it:
Now, let's get to the details of what you have asked...
Now, I can only offer empirical evidence with my test ISAPI Extension DLL which retrieves all possible server variables (including Unicode versions), and the exact same binary loads and runs just fine on all IIS versions from IIS4 through IIS7. I realize that you believe your programmer writes perfectly flawless and bug-free ISAPI code, but please humor me and show me some better evidence to back up your conclusion of "so there must be something [wrong] with IIS 6.0" with regards to GetServerVariable. :-)
For example, the fact that something "worked" on IIS 5.1 is insufficient. Your programmer could have written code that looks like:
if ( OS_Version != "5.1" ) { // Fail } else { // Succeed }
This code also works on IIS 5.1 but fails on IIS 6.0, but I think we both agree that it would not be correct to conclude that "there must be something [wrong] with IIS 6.0".
Below, I am going to show below the canonical way to use GetServerVariable. I look forward to your reply.
//David
#define DEFAULT_BUFFER_SIZE 1024 #define MAX_BUFFER_SIZE 4096 ... DWORD WINAPI HttpExtensionProc( EXTENSION_CONTROL_BLOCK * pecb ) { DWORD dwRet = HSE_STATUS_SUCCESS; BOOL fRet = FALSE; CHAR pBuf[ DEFAULT_BUFFER_SIZE ]; CHAR * pszBuf = pBuf; DWORD cbBuf = DEFAULT_BUFFER_SIZE; fRet = pfc->GetServerVariable( pecb->ConnID, "ALL_RAW", pszBuf, &cbBuf ); if ( fRet == FALSE ) { // // Buffer is not large enough. // Reallocate but bound it to MAX_BUFFER_SIZE // if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER && cbBuf < MAX_BUFFER_SIZE ) { pszBuf = new CHAR[ cbBuf ]; if ( pszBuf == NULL ) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); goto Finished; } fRet = pfc->GetServerVariable( pecb->ConnID, "ALL_RAW", pszBuf, &cbBuf ); if ( fRet == FALSE ) { // // Unexpected failure. Bail. // goto Finished; } } else if ( GetLastError() == ERROR_INVALID_INDEX ) { // // Did not find the named Server Variable. // May be an error or not. Depends on your logic. // } else { // // Something unexpected happened. Bail. // goto Finished; } } // // At this point, pszBuf points to the variable value and // cbBuf indicates size of buffer, including terminating NULL. // ... SetLastError( NO_ERROR ); Finished: if ( pszBuf != pBuf ) { delete pszBuf; } if ( GetLastError() != NO_ERROR ) { // // Handle the error case. Send back 500, etc. // dwRet = HSE_STATUS_ERROR; } return dwRet; }