| /** Implementation of the ISAPI_HttpRequest and related classes |
| * @file ISAPI_HttpContext.cpp |
| * @author Christian Aberger |
| * Copyright (C) 2001-2002 WebWare (http://www.webware.at) |
| */ |
| #include <cassert> |
| #include <algorithm> |
| #include "ISAPI_HttpContext.h" |
| using namespace std; |
| |
| static bool AddHeader( |
| ISAPI_HttpRequest& req, |
| EXTENSION_CONTROL_BLOCK& ecb, |
| const char *pszHeaderName, |
| LPCTSTR pszVariableName); |
| |
| ISAPI_HttpRequest::ISAPI_HttpRequest(EXTENSION_CONTROL_BLOCK *pECB) |
| : m_bHeadersParsed(false) |
| , m_pECB(pECB) |
| { |
| if (NULL != pECB) { |
| ParseHeaders(*pECB); |
| } |
| } |
| ISAPI_HttpRequest::~ISAPI_HttpRequest() { |
| } |
| EXTENSION_CONTROL_BLOCK *ISAPI_HttpRequest::ECB() const { |
| return m_pECB; |
| } |
| void ISAPI_HttpRequest::ParseHeaders(EXTENSION_CONTROL_BLOCK& ecb) { |
| _contentlength = ecb.cbTotalBytes; |
| AddHeader(ecb, "CONTENT-LENGTH", "CONTENT_LENGTH"); |
| AddHeader(ecb, "CONTENT-TYPE", "CONTENT_TYPE"); |
| AddHeader(ecb, "PATH-INFO", "PATH_INFO"); |
| string strValue; |
| ReadHeader(ecb, "REQUEST_METHOD", strValue); |
| if (0 == strcasecmp(strValue.c_str(), "GET")) { |
| _method = GET; |
| } else if (0 == strcasecmp(strValue.c_str(), "POST")) { |
| _method = POST; |
| } |
| _querystring = ecb.lpszQueryString; |
| ReadCustomHeaders(ecb); |
| m_bHeadersParsed = true; |
| } |
| /** add a ECB header variable to our content headers collection. |
| @param ecb the extension control block of the current IIS request |
| @param pszHeaderName the HTTP - standard name of the content header. |
| @param pszVariableName the name invented by Micro$oft for the same thing. |
| */ |
| bool ISAPI_HttpRequest::AddHeader(EXTENSION_CONTROL_BLOCK& ecb, const char *pszHeaderName, LPCTSTR pszVariableName) { |
| assert(NULL != pszVariableName); |
| |
| string strValue; |
| bool bRet = ReadHeader(ecb, pszVariableName, strValue); |
| if (bRet) { |
| ::OutputDebugString((pszHeaderName + string(": ") + strValue + "\r\n").c_str()); |
| m_ContentHeaders[pszHeaderName] = strValue; |
| } |
| return bRet; |
| } |
| /** Read a variable from the control block. |
| @param ecb the Extension Control Block. |
| @param pszVariableName the name of the variable to read |
| @strHeaderValue (output) the value of the variable |
| @return true if the header was found. |
| */ |
| bool ISAPI_HttpRequest::ReadHeader(EXTENSION_CONTROL_BLOCK& ecb, LPCTSTR pszVariableName, string& strHeaderValue) { |
| bool bRet = true; |
| char szVarName[128]; // :( GetServerVariable uses non-const name parameter, so we make a copy to be save. |
| strncpy(szVarName, pszVariableName, sizeof szVarName); |
| char szBuffer[2048]; |
| DWORD dwBufferSize = sizeof szBuffer; |
| BOOL bGet = ecb.GetServerVariable(ecb.ConnID, szVarName, szBuffer, &dwBufferSize); |
| if (bGet) { |
| strHeaderValue = szBuffer; |
| } else { |
| bRet = false; |
| strHeaderValue.erase(); |
| } |
| return bRet; |
| } |
| /** read all HTTP headers that were not already parsed into one of the ISAPI - ECB variables. |
| */ |
| void ISAPI_HttpRequest::ReadCustomHeaders(EXTENSION_CONTROL_BLOCK& ecb) { |
| const char szHTTP_[] = "HTTP_"; |
| char szBuffer[4096]; |
| DWORD dwBufferSize = sizeof szBuffer; |
| BOOL bGet = ecb.GetServerVariable(ecb.ConnID, "ALL_HTTP", szBuffer, &dwBufferSize); |
| if (bGet) { |
| // Find lines, split key/data pair and write them as output |
| LPTSTR pOpts = NULL; |
| LPTSTR pEnd = NULL; |
| for (LPTSTR pChar = szBuffer; '\0' != *pChar;) { |
| if (*pChar == '\r' || *pChar == '\n') { |
| pChar++; |
| continue; |
| } |
| pOpts = strchr(pChar, ':');// findseparator |
| if (pOpts && *pOpts) { |
| pEnd = pOpts; |
| while (*pEnd && *pEnd != '\r' && *pEnd != '\n') { |
| pEnd++; |
| } |
| *pOpts = '\0'; // split the strings |
| *pEnd = '\0'; |
| string strName = pChar; |
| if (0 == strncmp(strName.c_str(), szHTTP_, strlen(szHTTP_))) { |
| strName = strName.substr(strlen(szHTTP_)); |
| } |
| replace(strName.begin(), strName.end(), '_', '-'); |
| ::OutputDebugString((strName + ":" + (pOpts + 1) + "\r\n").c_str()); |
| m_ContentHeaders[strName] = pOpts + 1; |
| pChar = pEnd + 1; |
| } |
| } |
| } |
| } |