//+--------------------------------------------------------------------------- // // Copyright (C) 1996 - 1998, Microsoft Corporation. // // File: gibralt.hxx // // Contents: Abstraction of the interface to gibraltar // // History: 96/Jan/3 DwightKr Created // //---------------------------------------------------------------------------- #pragma once #include #include #include #include #define HTTP_HEADER "200 OK" #define HTTP_DATA "Content-Type: text/html\r\n\r\n" #define CANONIC_DATA "Content-Type: application/octet-stream\r\n\r\n" #define GIFIMAGE_DATA "Content-Type: image/gif\r\n\r\n" #define JPEGIMAGE_DATA "Content-Type: image/jpeg\r\n\r\n" //+--------------------------------------------------------------------------- // // Class: CWebServer // // Purpose: An abstraction of the interface to gibraltar // // History: 96/Jan/23 DwightKr Created // 96-Mar-01 DwightKr Added copy constructor // //---------------------------------------------------------------------------- class CWebServer { public: CWebServer( EXTENSION_CONTROL_BLOCK *pEcb ) : _pEcb( pEcb ), _fWroteHeader( FALSE ), _codePage( GetACP() ), _lcid( InvalidLCID ), _ccLocale( 0 ) {} void SetCodePage( UINT codePage ) { _codePage = codePage; } BOOL GetCGIVariable( CHAR const * pszVariableName, CHAR * pbBuffer, ULONG * pcbBuffer ) { Win4Assert ( IsValid() ); return _pEcb->GetServerVariable( _pEcb->ConnID, (char *) pszVariableName, pbBuffer, pcbBuffer ); } BOOL GetCGIVariable( CHAR const * pszVariableName, XArray & wcsValue, ULONG & cwcBuffer ); BOOL GetCGIVariableW( WCHAR const * wcsVariableName, XArray & wcsValue, ULONG & cwcBuffer ); BOOL GetCGI_REQUEST_METHOD( XArray & wcsValue, ULONG & cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszMethod ); if ( 0 == * (_pEcb->lpszMethod) ) return FALSE; cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszMethod, strlen( _pEcb->lpszMethod ), _codePage, wcsValue ); return TRUE; } BOOL GetCGI_QUERY_STRING( XArray & wcsValue, ULONG & cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszQueryString ); if ( 0 == * (_pEcb->lpszQueryString) ) return FALSE; cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszQueryString, strlen( _pEcb->lpszQueryString ), _codePage, wcsValue ); return TRUE; } BOOL GetCGI_PATH_INFO( XArray & wcsValue, ULONG & cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszPathInfo ); if ( 0 == * (_pEcb->lpszPathInfo) ) return FALSE; cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathInfo, strlen( _pEcb->lpszPathInfo ), _codePage, wcsValue ); return TRUE; } BOOL GetCGI_PATH_TRANSLATED( XArray & wcsValue, ULONG & cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszPathTranslated ); if ( 0 == * (_pEcb->lpszPathTranslated) ) return FALSE; cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathTranslated, strlen( _pEcb->lpszPathTranslated ), _codePage, wcsValue ); return TRUE; } BOOL GetCGI_PATH_TRANSLATED( WCHAR *pwcPath, ULONG &cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszPathTranslated ); Win4Assert( 0 != * ( _pEcb->lpszPathTranslated ) ); cwcBuffer = MultiByteToWideChar( CP_ACP, 0, (const char *) _pEcb->lpszPathTranslated, strlen(_pEcb->lpszPathTranslated) + 1, pwcPath, cwcBuffer ); return 0 != cwcBuffer; } BOOL GetCGI_CONTENT_TYPE( XArray & wcsValue, ULONG & cwcBuffer ) { Win4Assert( 0 != _pEcb->lpszContentType ); if ( 0 == * (_pEcb->lpszContentType) ) return FALSE; cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszContentType, strlen( _pEcb->lpszContentType ), _codePage, wcsValue ); return TRUE; } DWORD GetPhysicalPath( WCHAR const * wcsVirtualPath, WCHAR * wcsPhysicalPath, ULONG cwcPhysicalPath, DWORD dwAccessMask = 0 ); // HSE_URL_FLAGS_* void SetHttpStatus( DWORD dwStatus ) { Win4Assert ( IsValid() ); Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST ); Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST ); Win4Assert( dwStatus >= HTTP_STATUS_FIRST ); Win4Assert( dwStatus <= HTTP_STATUS_LAST ); _pEcb->dwHttpStatusCode = dwStatus; } DWORD GetHttpStatus() const { Win4Assert ( IsValid() ); Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST ); Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST ); return _pEcb->dwHttpStatusCode; } const CHAR * GetQueryString() const { Win4Assert ( IsValid() ); return (const CHAR *) _pEcb->lpszQueryString; } const CHAR * GetMethod() const { Win4Assert ( IsValid() ); return (const CHAR *) _pEcb->lpszMethod; } const CHAR * GetClientData( DWORD & cbData ) const { Win4Assert ( IsValid() ); cbData = _pEcb->cbAvailable; return (const CHAR *) _pEcb->lpbData; } BOOL IsValid() const { return _pEcb != 0; } BOOL WriteHeader( const char * pszData = HTTP_DATA, const char * pszHeader = HTTP_HEADER ) { Win4Assert( !_fWroteHeader ); Win4Assert ( IsValid() ); _fWroteHeader = TRUE; DWORD dwDataSize = pszData != 0 ? strlen(pszData)+1 : 0; return _pEcb->ServerSupportFunction( _pEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, (LPVOID) pszHeader, &dwDataSize, (LPDWORD)pszData); } BOOL WriteClient( const WCHAR * wcsMessage ) { Win4Assert ( IsValid() ); if (! _fWroteHeader && ! WriteHeader() ) return FALSE; DWORD cwcMessage = wcslen( (WCHAR *) wcsMessage ) + 1; XArray pszMessage ( cwcMessage + cwcMessage/8 ); DWORD cbMessage = WideCharToXArrayMultiByte( wcsMessage, cwcMessage, _codePage, pszMessage ); return _pEcb->WriteClient( _pEcb->ConnID, pszMessage.Get(), &cbMessage, 0 ); } BOOL WriteClient( CVirtualString & vsMessage ) { Win4Assert ( IsValid() ); if (! _fWroteHeader && ! WriteHeader() ) return FALSE; DWORD cwcMessage = vsMessage.StrLen() + 1; XArray pszMessage( cwcMessage + cwcMessage/8 ); DWORD cbMessage = WideCharToXArrayMultiByte( vsMessage.Get(), cwcMessage, _codePage, pszMessage ); return _pEcb->WriteClient( _pEcb->ConnID, pszMessage.Get(), &cbMessage, 0 ); } BOOL WriteClient( const BYTE * pcsMessage, DWORD ccMessage ) { Win4Assert ( IsValid() ); if (! _fWroteHeader && !WriteHeader() ) return FALSE; return _pEcb->WriteClient( _pEcb->ConnID, (void *) pcsMessage, &ccMessage, 0 ); } void RawWriteClient( BYTE * pbData, ULONG cbData ) { Win4Assert ( IsValid() ); _pEcb->WriteClient( _pEcb->ConnID, pbData, &cbData, 0 ); } BOOL ReleaseSession( DWORD dwStatus ) { Win4Assert ( IsValid() ); Win4Assert( HTTP_STATUS_ACCEPTED != _pEcb->dwHttpStatusCode ); BOOL fSuccess = _pEcb->ServerSupportFunction( _pEcb->ConnID, HSE_REQ_DONE_WITH_SESSION, &dwStatus, 0, 0 ); _pEcb = 0; return fSuccess; } // void WriteLogData( WCHAR const * wcsLogData ); UINT CodePage() { return _codePage; } inline void SetLCID( LCID lcid, WCHAR const * pwszLocale, unsigned ccLocale ); BOOL IsLCIDValid() { return (InvalidLCID != _lcid); } LCID GetLCID() { return _lcid; } unsigned LocaleSize() { return _ccLocale; } WCHAR const * GetLocale() { return _wszLocale; } ULONG GetServerInstance() { // // Retrieve the metabase instance number of the ISAPI request // char acBuf[ 40 ]; ULONG cbBuf = sizeof acBuf; if ( !GetCGIVariable( "INSTANCE_ID", acBuf, &cbBuf ) ) THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) ); ULONG ulInstance = atoi( acBuf ); Win4Assert( 0 != ulInstance ); return ulInstance; } BOOL IsPortSecure() { // // Returns TRUE if the port is SSL secured, FALSE otherwise. // There is no way to switch the setting on the fly; the only // way to enable SSL is to mark the vdir as SSL secured in the // metabase. // char acBuf[ 40 ]; ULONG cbBuf = sizeof acBuf; if ( ! _pEcb->GetServerVariable( _pEcb->ConnID, "HTTPS", //PORT_SECURE", acBuf, &cbBuf ) ) THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) ); return ( !_stricmp( acBuf, "on" ) ); } private: EXTENSION_CONTROL_BLOCK *_pEcb; BOOL _fWroteHeader; UINT _codePage; LCID _lcid; WCHAR _wszLocale[16]; // Don't optimize long locales unsigned _ccLocale; }; DWORD ProcessWebRequest( CWebServer & webServer ); //+--------------------------------------------------------------------------- // // Member: CWebServer::SetLCID, public // // Synopsis: Caches locale info for fast access // // Arguments: [lcid] -- Locale ID // [pwszLocale] -- String version of LCID (e.g. "EN-US") // [ccLocale] -- Size in characters of [pwszLocale], including null. // // History: 11-Jun-97 KyleP Created // //---------------------------------------------------------------------------- inline void CWebServer::SetLCID( LCID lcid, WCHAR const * pwszLocale, unsigned ccLocale ) { if ( lcid == _lcid ) return; if ( ccLocale <= sizeof(_wszLocale)/sizeof(WCHAR) ) { RtlCopyMemory( _wszLocale, pwszLocale, ccLocale * sizeof(WCHAR) ); _ccLocale = ccLocale; _lcid = lcid; } else { // // Just take first component // WCHAR * pwc = wcschr( pwszLocale, L',' ); if ( (pwc - pwszLocale) < sizeof(_wszLocale)/sizeof(WCHAR) ) { _ccLocale = CiPtrToUint( pwc - pwszLocale ); _lcid = lcid; RtlCopyMemory( _wszLocale, pwszLocale, _ccLocale * sizeof(WCHAR) ); _wszLocale[_ccLocale] = 0; _ccLocale++; } else { THROW( CException(E_FAIL) ); } } }