Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996 - 1998, Microsoft Corporation.
  4. //
  5. // File: gibralt.hxx
  6. //
  7. // Contents: Abstraction of the interface to gibraltar
  8. //
  9. // History: 96/Jan/3 DwightKr Created
  10. //
  11. //----------------------------------------------------------------------------
  12. #pragma once
  13. #include <httpext.h>
  14. #include <wininet.h>
  15. #include <weblcid.hxx>
  16. #include <ci64.hxx>
  17. #define HTTP_HEADER "200 OK"
  18. #define HTTP_DATA "Content-Type: text/html\r\n\r\n"
  19. #define CANONIC_DATA "Content-Type: application/octet-stream\r\n\r\n"
  20. #define GIFIMAGE_DATA "Content-Type: image/gif\r\n\r\n"
  21. #define JPEGIMAGE_DATA "Content-Type: image/jpeg\r\n\r\n"
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Class: CWebServer
  25. //
  26. // Purpose: An abstraction of the interface to gibraltar
  27. //
  28. // History: 96/Jan/23 DwightKr Created
  29. // 96-Mar-01 DwightKr Added copy constructor
  30. //
  31. //----------------------------------------------------------------------------
  32. class CWebServer
  33. {
  34. public:
  35. CWebServer( EXTENSION_CONTROL_BLOCK *pEcb ) : _pEcb( pEcb ),
  36. _fWroteHeader( FALSE ),
  37. _codePage( GetACP() ),
  38. _lcid( InvalidLCID ),
  39. _ccLocale( 0 ) {}
  40. void SetCodePage( UINT codePage ) { _codePage = codePage; }
  41. BOOL GetCGIVariable( CHAR const * pszVariableName,
  42. CHAR * pbBuffer,
  43. ULONG * pcbBuffer )
  44. {
  45. Win4Assert ( IsValid() );
  46. return _pEcb->GetServerVariable( _pEcb->ConnID,
  47. (char *) pszVariableName,
  48. pbBuffer,
  49. pcbBuffer );
  50. }
  51. BOOL GetCGIVariable( CHAR const * pszVariableName,
  52. XArray<WCHAR> & wcsValue,
  53. ULONG & cwcBuffer );
  54. BOOL GetCGIVariableW( WCHAR const * wcsVariableName,
  55. XArray<WCHAR> & wcsValue,
  56. ULONG & cwcBuffer );
  57. BOOL GetCGI_REQUEST_METHOD( XArray<WCHAR> & wcsValue,
  58. ULONG & cwcBuffer )
  59. {
  60. Win4Assert( 0 != _pEcb->lpszMethod );
  61. if ( 0 == * (_pEcb->lpszMethod) )
  62. return FALSE;
  63. cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszMethod,
  64. strlen( _pEcb->lpszMethod ),
  65. _codePage,
  66. wcsValue );
  67. return TRUE;
  68. }
  69. BOOL GetCGI_QUERY_STRING( XArray<WCHAR> & wcsValue,
  70. ULONG & cwcBuffer )
  71. {
  72. Win4Assert( 0 != _pEcb->lpszQueryString );
  73. if ( 0 == * (_pEcb->lpszQueryString) )
  74. return FALSE;
  75. cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszQueryString,
  76. strlen( _pEcb->lpszQueryString ),
  77. _codePage,
  78. wcsValue );
  79. return TRUE;
  80. }
  81. BOOL GetCGI_PATH_INFO( XArray<WCHAR> & wcsValue,
  82. ULONG & cwcBuffer )
  83. {
  84. Win4Assert( 0 != _pEcb->lpszPathInfo );
  85. if ( 0 == * (_pEcb->lpszPathInfo) )
  86. return FALSE;
  87. cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathInfo,
  88. strlen( _pEcb->lpszPathInfo ),
  89. _codePage,
  90. wcsValue );
  91. return TRUE;
  92. }
  93. BOOL GetCGI_PATH_TRANSLATED( XArray<WCHAR> & wcsValue,
  94. ULONG & cwcBuffer )
  95. {
  96. Win4Assert( 0 != _pEcb->lpszPathTranslated );
  97. if ( 0 == * (_pEcb->lpszPathTranslated) )
  98. return FALSE;
  99. cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathTranslated,
  100. strlen( _pEcb->lpszPathTranslated ),
  101. _codePage,
  102. wcsValue );
  103. return TRUE;
  104. }
  105. BOOL GetCGI_PATH_TRANSLATED( WCHAR *pwcPath,
  106. ULONG &cwcBuffer )
  107. {
  108. Win4Assert( 0 != _pEcb->lpszPathTranslated );
  109. Win4Assert( 0 != * ( _pEcb->lpszPathTranslated ) );
  110. cwcBuffer = MultiByteToWideChar(
  111. CP_ACP,
  112. 0,
  113. (const char *) _pEcb->lpszPathTranslated,
  114. strlen(_pEcb->lpszPathTranslated) + 1,
  115. pwcPath,
  116. cwcBuffer );
  117. return 0 != cwcBuffer;
  118. }
  119. BOOL GetCGI_CONTENT_TYPE( XArray<WCHAR> & wcsValue,
  120. ULONG & cwcBuffer )
  121. {
  122. Win4Assert( 0 != _pEcb->lpszContentType );
  123. if ( 0 == * (_pEcb->lpszContentType) )
  124. return FALSE;
  125. cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszContentType,
  126. strlen( _pEcb->lpszContentType ),
  127. _codePage,
  128. wcsValue );
  129. return TRUE;
  130. }
  131. DWORD GetPhysicalPath( WCHAR const * wcsVirtualPath,
  132. WCHAR * wcsPhysicalPath,
  133. ULONG cwcPhysicalPath,
  134. DWORD dwAccessMask = 0 ); // HSE_URL_FLAGS_*
  135. void SetHttpStatus( DWORD dwStatus )
  136. {
  137. Win4Assert ( IsValid() );
  138. Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST );
  139. Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST );
  140. Win4Assert( dwStatus >= HTTP_STATUS_FIRST );
  141. Win4Assert( dwStatus <= HTTP_STATUS_LAST );
  142. _pEcb->dwHttpStatusCode = dwStatus;
  143. }
  144. DWORD GetHttpStatus() const
  145. {
  146. Win4Assert ( IsValid() );
  147. Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST );
  148. Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST );
  149. return _pEcb->dwHttpStatusCode;
  150. }
  151. const CHAR * GetQueryString() const
  152. {
  153. Win4Assert ( IsValid() );
  154. return (const CHAR *) _pEcb->lpszQueryString;
  155. }
  156. const CHAR * GetMethod() const
  157. {
  158. Win4Assert ( IsValid() );
  159. return (const CHAR *) _pEcb->lpszMethod;
  160. }
  161. const CHAR * GetClientData( DWORD & cbData ) const
  162. {
  163. Win4Assert ( IsValid() );
  164. cbData = _pEcb->cbAvailable;
  165. return (const CHAR *) _pEcb->lpbData;
  166. }
  167. BOOL IsValid() const { return _pEcb != 0; }
  168. BOOL WriteHeader( const char * pszData = HTTP_DATA,
  169. const char * pszHeader = HTTP_HEADER )
  170. {
  171. Win4Assert( !_fWroteHeader );
  172. Win4Assert ( IsValid() );
  173. _fWroteHeader = TRUE;
  174. DWORD dwDataSize = pszData != 0 ? strlen(pszData)+1 : 0;
  175. return _pEcb->ServerSupportFunction( _pEcb->ConnID,
  176. HSE_REQ_SEND_RESPONSE_HEADER,
  177. (LPVOID) pszHeader,
  178. &dwDataSize,
  179. (LPDWORD)pszData);
  180. }
  181. BOOL WriteClient( const WCHAR * wcsMessage )
  182. {
  183. Win4Assert ( IsValid() );
  184. if (! _fWroteHeader && ! WriteHeader() )
  185. return FALSE;
  186. DWORD cwcMessage = wcslen( (WCHAR *) wcsMessage ) + 1;
  187. XArray<BYTE> pszMessage ( cwcMessage + cwcMessage/8 );
  188. DWORD cbMessage = WideCharToXArrayMultiByte( wcsMessage,
  189. cwcMessage,
  190. _codePage,
  191. pszMessage );
  192. return _pEcb->WriteClient( _pEcb->ConnID,
  193. pszMessage.Get(),
  194. &cbMessage,
  195. 0 );
  196. }
  197. BOOL WriteClient( CVirtualString & vsMessage )
  198. {
  199. Win4Assert ( IsValid() );
  200. if (! _fWroteHeader && ! WriteHeader() )
  201. return FALSE;
  202. DWORD cwcMessage = vsMessage.StrLen() + 1;
  203. XArray<BYTE> pszMessage( cwcMessage + cwcMessage/8 );
  204. DWORD cbMessage = WideCharToXArrayMultiByte( vsMessage.Get(),
  205. cwcMessage,
  206. _codePage,
  207. pszMessage );
  208. return _pEcb->WriteClient( _pEcb->ConnID,
  209. pszMessage.Get(),
  210. &cbMessage,
  211. 0 );
  212. }
  213. BOOL WriteClient( const BYTE * pcsMessage, DWORD ccMessage )
  214. {
  215. Win4Assert ( IsValid() );
  216. if (! _fWroteHeader && !WriteHeader() )
  217. return FALSE;
  218. return _pEcb->WriteClient( _pEcb->ConnID,
  219. (void *) pcsMessage,
  220. &ccMessage,
  221. 0 );
  222. }
  223. void RawWriteClient( BYTE * pbData, ULONG cbData )
  224. {
  225. Win4Assert ( IsValid() );
  226. _pEcb->WriteClient( _pEcb->ConnID,
  227. pbData,
  228. &cbData,
  229. 0 );
  230. }
  231. BOOL ReleaseSession( DWORD dwStatus )
  232. {
  233. Win4Assert ( IsValid() );
  234. Win4Assert( HTTP_STATUS_ACCEPTED != _pEcb->dwHttpStatusCode );
  235. BOOL fSuccess = _pEcb->ServerSupportFunction( _pEcb->ConnID,
  236. HSE_REQ_DONE_WITH_SESSION,
  237. &dwStatus,
  238. 0, 0 );
  239. _pEcb = 0;
  240. return fSuccess;
  241. }
  242. // void WriteLogData( WCHAR const * wcsLogData );
  243. UINT CodePage() { return _codePage; }
  244. inline void SetLCID( LCID lcid,
  245. WCHAR const * pwszLocale,
  246. unsigned ccLocale );
  247. BOOL IsLCIDValid() { return (InvalidLCID != _lcid); }
  248. LCID GetLCID() { return _lcid; }
  249. unsigned LocaleSize() { return _ccLocale; }
  250. WCHAR const * GetLocale() { return _wszLocale; }
  251. ULONG GetServerInstance()
  252. {
  253. //
  254. // Retrieve the metabase instance number of the ISAPI request
  255. //
  256. char acBuf[ 40 ];
  257. ULONG cbBuf = sizeof acBuf;
  258. if ( !GetCGIVariable( "INSTANCE_ID", acBuf, &cbBuf ) )
  259. THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
  260. ULONG ulInstance = atoi( acBuf );
  261. Win4Assert( 0 != ulInstance );
  262. return ulInstance;
  263. }
  264. BOOL IsPortSecure()
  265. {
  266. //
  267. // Returns TRUE if the port is SSL secured, FALSE otherwise.
  268. // There is no way to switch the setting on the fly; the only
  269. // way to enable SSL is to mark the vdir as SSL secured in the
  270. // metabase.
  271. //
  272. char acBuf[ 40 ];
  273. ULONG cbBuf = sizeof acBuf;
  274. if ( ! _pEcb->GetServerVariable( _pEcb->ConnID,
  275. "HTTPS", //PORT_SECURE",
  276. acBuf,
  277. &cbBuf ) )
  278. THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
  279. return ( !_stricmp( acBuf, "on" ) );
  280. }
  281. private:
  282. EXTENSION_CONTROL_BLOCK *_pEcb;
  283. BOOL _fWroteHeader;
  284. UINT _codePage;
  285. LCID _lcid;
  286. WCHAR _wszLocale[16]; // Don't optimize long locales
  287. unsigned _ccLocale;
  288. };
  289. DWORD ProcessWebRequest( CWebServer & webServer );
  290. //+---------------------------------------------------------------------------
  291. //
  292. // Member: CWebServer::SetLCID, public
  293. //
  294. // Synopsis: Caches locale info for fast access
  295. //
  296. // Arguments: [lcid] -- Locale ID
  297. // [pwszLocale] -- String version of LCID (e.g. "EN-US")
  298. // [ccLocale] -- Size in characters of [pwszLocale], including null.
  299. //
  300. // History: 11-Jun-97 KyleP Created
  301. //
  302. //----------------------------------------------------------------------------
  303. inline void CWebServer::SetLCID( LCID lcid,
  304. WCHAR const * pwszLocale,
  305. unsigned ccLocale )
  306. {
  307. if ( lcid == _lcid )
  308. return;
  309. if ( ccLocale <= sizeof(_wszLocale)/sizeof(WCHAR) )
  310. {
  311. RtlCopyMemory( _wszLocale, pwszLocale, ccLocale * sizeof(WCHAR) );
  312. _ccLocale = ccLocale;
  313. _lcid = lcid;
  314. }
  315. else
  316. {
  317. //
  318. // Just take first component
  319. //
  320. WCHAR * pwc = wcschr( pwszLocale, L',' );
  321. if ( (pwc - pwszLocale) < sizeof(_wszLocale)/sizeof(WCHAR) )
  322. {
  323. _ccLocale = CiPtrToUint( pwc - pwszLocale );
  324. _lcid = lcid;
  325. RtlCopyMemory( _wszLocale, pwszLocale, _ccLocale * sizeof(WCHAR) );
  326. _wszLocale[_ccLocale] = 0;
  327. _ccLocale++;
  328. }
  329. else
  330. {
  331. THROW( CException(E_FAIL) );
  332. }
  333. }
  334. }