Source code of Windows XP (NT5)
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.

741 lines
15 KiB

  1. #ifndef _W3REQUEST_HXX_
  2. #define _W3REQUEST_HXX_
  3. #define W3_REQUEST_SIGNATURE ((DWORD) 'QR3W')
  4. #define W3_REQUEST_SIGNATURE_FREE ((DWORD) 'qr3w')
  5. class W3_CONTEXT;
  6. class W3_REQUEST
  7. {
  8. protected:
  9. DWORD _dwSignature;
  10. //
  11. // We provide a friendly wrapper of the UL_HTTP_REQUEST from UL
  12. //
  13. HTTP_REQUEST * _pUlHttpRequest;
  14. HTTP_UNKNOWN_HEADER * _pExtraUnknown;
  15. //
  16. // If a filter changes the URL, unknown verb, etc., we need a new buffer
  17. // pointed into by UL_HTTP_REQUEST
  18. //
  19. CHUNK_BUFFER _HeaderBuffer;
  20. //
  21. // If we are going to insert entity body (child requests) then we'll
  22. // need a HTTP_DATA_CHUNK to store the pointer
  23. //
  24. HTTP_DATA_CHUNK _InsertedEntityBodyChunk;
  25. //
  26. // Preloaded entity
  27. //
  28. BUFFER _buffEntityBodyPreload;
  29. //
  30. // Keep track of the "wire user" for this request
  31. //
  32. STRA _strRequestUserName;
  33. //
  34. // Keep track of original full URL of request (can be changed by filter)
  35. //
  36. WCHAR * _pszOriginalFullUrl;
  37. DWORD _cchOriginalFullUrl;
  38. static PHOSTENT sm_pHostEnt;
  39. public:
  40. W3_REQUEST()
  41. : _dwSignature( W3_REQUEST_SIGNATURE ),
  42. _pUlHttpRequest( NULL ),
  43. _pExtraUnknown( NULL ),
  44. _pszOriginalFullUrl( NULL ),
  45. _cchOriginalFullUrl( 0 )
  46. {
  47. _InsertedEntityBodyChunk.DataChunkType = HttpDataChunkFromMemory;
  48. }
  49. virtual ~W3_REQUEST()
  50. {
  51. if ( _pExtraUnknown != NULL )
  52. {
  53. LocalFree( _pExtraUnknown );
  54. _pExtraUnknown = NULL;
  55. }
  56. _dwSignature = W3_REQUEST_SIGNATURE_FREE;
  57. }
  58. VOID
  59. SetHttpRequest(
  60. HTTP_REQUEST * pRequest
  61. )
  62. {
  63. _pUlHttpRequest = pRequest;
  64. _pszOriginalFullUrl = pRequest->CookedUrl.pFullUrl;
  65. _cchOriginalFullUrl = pRequest->CookedUrl.FullUrlLength / sizeof(WCHAR);
  66. }
  67. static
  68. HRESULT
  69. Initialize(
  70. VOID
  71. );
  72. static
  73. VOID
  74. Terminate(
  75. VOID
  76. );
  77. HRESULT
  78. SetNewPreloadedEntityBody(
  79. VOID * pvBuffer,
  80. DWORD cbBuffer
  81. );
  82. HRESULT AppendEntityBody(
  83. VOID * pvBuffer,
  84. DWORD cbBuffer
  85. );
  86. HRESULT PreloadEntityBody(
  87. W3_CONTEXT * pW3Context,
  88. BOOL * pfComplete
  89. );
  90. HRESULT
  91. PreloadCompletion(
  92. W3_CONTEXT * pW3Context,
  93. DWORD cbRead,
  94. DWORD dwStatus,
  95. BOOL * pfComplete
  96. );
  97. VOID
  98. RemoveDav(
  99. VOID
  100. );
  101. HRESULT
  102. SetUrl(
  103. STRU & strNewUrl,
  104. BOOL fResetQueryString = TRUE
  105. );
  106. HRESULT
  107. SetUrlA(
  108. STRA & strNewUrl,
  109. BOOL fResetQueryString = TRUE
  110. );
  111. HTTP_CONNECTION_ID
  112. QueryConnectionId(
  113. VOID
  114. ) const
  115. {
  116. return _pUlHttpRequest->ConnectionId;
  117. }
  118. BOOL
  119. QueryMoreEntityBodyExists(
  120. VOID
  121. )
  122. {
  123. return _pUlHttpRequest->MoreEntityBodyExists;
  124. }
  125. HTTP_REQUEST_ID
  126. QueryRequestId(
  127. VOID
  128. ) const
  129. {
  130. return _pUlHttpRequest->RequestId;
  131. }
  132. DWORD
  133. QuerySiteId(
  134. VOID
  135. ) const
  136. {
  137. return (DWORD)(_pUlHttpRequest->UrlContext >> 32);
  138. }
  139. DWORD
  140. QueryLocalAddress(
  141. VOID
  142. ) const;
  143. DWORD
  144. QueryRemoteAddress(
  145. VOID
  146. ) const;
  147. USHORT
  148. QueryLocalPort(
  149. VOID
  150. ) const;
  151. USHORT
  152. QueryRemotePort(
  153. VOID
  154. ) const;
  155. BOOL
  156. IsProxyRequest(
  157. VOID
  158. );
  159. BOOL
  160. IsChunkedRequest(
  161. VOID
  162. );
  163. BOOL
  164. IsLocalRequest(
  165. VOID
  166. ) const;
  167. BOOL
  168. IsSecureRequest(
  169. VOID
  170. ) const
  171. {
  172. DBG_ASSERT( _pUlHttpRequest != NULL );
  173. return _pUlHttpRequest->pSslInfo != NULL;
  174. }
  175. HTTP_SSL_INFO *
  176. QuerySslInfo(
  177. VOID
  178. ) const
  179. {
  180. DBG_ASSERT( _pUlHttpRequest != NULL );
  181. return _pUlHttpRequest->pSslInfo;
  182. }
  183. HTTP_SSL_CLIENT_CERT_INFO *
  184. QueryClientCertInfo(
  185. VOID
  186. ) const
  187. {
  188. DBG_ASSERT( _pUlHttpRequest != NULL );
  189. if ( _pUlHttpRequest->pSslInfo != NULL )
  190. {
  191. return _pUlHttpRequest->pSslInfo->pClientCertInfo;
  192. }
  193. else
  194. {
  195. return NULL;
  196. }
  197. }
  198. VOID
  199. SetClientCertInfo(
  200. HTTP_SSL_CLIENT_CERT_INFO * pClientCertInfo
  201. )
  202. {
  203. DBG_ASSERT( pClientCertInfo != NULL );
  204. DBG_ASSERT( _pUlHttpRequest != NULL );
  205. DBG_ASSERT( _pUlHttpRequest->pSslInfo != NULL );
  206. _pUlHttpRequest->pSslInfo->pClientCertInfo = pClientCertInfo;
  207. }
  208. HTTP_RAW_CONNECTION_ID
  209. QueryRawConnectionId(
  210. VOID
  211. ) const
  212. {
  213. DBG_ASSERT( _pUlHttpRequest != NULL );
  214. return _pUlHttpRequest->RawConnectionId;
  215. }
  216. HRESULT
  217. GetRawUrl(
  218. STRA * pstrRawUrl
  219. )
  220. {
  221. if ( pstrRawUrl == NULL )
  222. {
  223. DBG_ASSERT( FALSE );
  224. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  225. }
  226. return pstrRawUrl->Copy( _pUlHttpRequest->pRawUrl,
  227. _pUlHttpRequest->RawUrlLength );
  228. }
  229. HRESULT
  230. GetOriginalFullUrl(
  231. STRU * pstrFullUrl
  232. )
  233. {
  234. if ( pstrFullUrl == NULL )
  235. {
  236. DBG_ASSERT( FALSE );
  237. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  238. }
  239. return pstrFullUrl->Copy( _pszOriginalFullUrl, _cchOriginalFullUrl );
  240. }
  241. HRESULT
  242. GetFullUrl(
  243. STRU * pstrFullUrl
  244. )
  245. {
  246. if ( pstrFullUrl == NULL )
  247. {
  248. DBG_ASSERT( FALSE );
  249. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  250. }
  251. return pstrFullUrl->Copy( _pUlHttpRequest->CookedUrl.pFullUrl,
  252. _pUlHttpRequest->CookedUrl.FullUrlLength / sizeof(WCHAR) );
  253. }
  254. HRESULT
  255. GetAllHeaders(
  256. STRA * pstrHeaders,
  257. BOOL fISAPIStyle
  258. );
  259. BOOL
  260. IsSuspectUrl(
  261. VOID
  262. );
  263. HRESULT
  264. GetUrl(
  265. STRU * pstrUrl
  266. )
  267. {
  268. if ( pstrUrl == NULL )
  269. {
  270. DBG_ASSERT( FALSE );
  271. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  272. }
  273. return pstrUrl->Copy( _pUlHttpRequest->CookedUrl.pAbsPath,
  274. _pUlHttpRequest->CookedUrl.AbsPathLength / sizeof(WCHAR) );
  275. }
  276. VOID
  277. QueryUrl(
  278. WCHAR ** ppszUrl,
  279. USHORT * pcbUrl)
  280. {
  281. *ppszUrl = _pUlHttpRequest->CookedUrl.pAbsPath;
  282. *pcbUrl = _pUlHttpRequest->CookedUrl.AbsPathLength;
  283. }
  284. HRESULT
  285. GetHostAddr(
  286. IN OUT STRU *pstrHostAddr
  287. )
  288. {
  289. WCHAR * pchTail;
  290. if ( pstrHostAddr == NULL )
  291. {
  292. DBG_ASSERT( FALSE );
  293. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  294. }
  295. pchTail = wcspbrk( _pUlHttpRequest->CookedUrl.pHost, L":" );
  296. if( !pchTail )
  297. {
  298. DBG_ASSERT( FALSE );
  299. return E_FAIL;
  300. }
  301. else
  302. {
  303. return pstrHostAddr->Copy( _pUlHttpRequest->CookedUrl.pHost,
  304. DIFF(pchTail - _pUlHttpRequest->CookedUrl.pHost) );
  305. }
  306. }
  307. BOOL
  308. QueryClientWantsDisconnect(
  309. VOID
  310. );
  311. HRESULT
  312. GetVerbString(
  313. STRA * pstrVerb
  314. );
  315. VOID
  316. QueryVerb(
  317. CHAR ** ppszVerb,
  318. USHORT * pcchVerb
  319. );
  320. HRESULT
  321. GetVersionString(
  322. STRA * pstrVersion
  323. );
  324. HRESULT
  325. GetAuthType(
  326. STRA * pstrAuthType
  327. );
  328. HRESULT
  329. GetRequestUserName(
  330. STRA * pstrUserName
  331. )
  332. {
  333. if ( pstrUserName == NULL )
  334. {
  335. DBG_ASSERT( FALSE );
  336. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  337. }
  338. return pstrUserName->Copy( _strRequestUserName );
  339. }
  340. HRESULT
  341. SetRequestUserName(
  342. STRA & strUserName
  343. )
  344. {
  345. return _strRequestUserName.Copy( strUserName );
  346. }
  347. STRA *
  348. QueryRequestUserName()
  349. {
  350. return &_strRequestUserName;
  351. }
  352. HTTP_VERSION
  353. QueryVersion(
  354. VOID
  355. )
  356. {
  357. return _pUlHttpRequest->Version;
  358. }
  359. HRESULT
  360. GetQueryString(
  361. STRU * pstrQueryString
  362. )
  363. {
  364. DBG_ASSERT ( pstrQueryString != NULL );
  365. if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
  366. {
  367. return pstrQueryString->Copy( _pUlHttpRequest->CookedUrl.pQueryString + 1,
  368. _pUlHttpRequest->CookedUrl.QueryStringLength / sizeof(WCHAR) - 1 );
  369. }
  370. else
  371. {
  372. return pstrQueryString->Copy( L"", 0 );
  373. }
  374. }
  375. HRESULT
  376. GetQueryStringA(
  377. STRA * pstrQueryString
  378. )
  379. {
  380. DBG_ASSERT ( pstrQueryString != NULL );
  381. if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
  382. {
  383. return pstrQueryString->CopyWTruncate( _pUlHttpRequest->CookedUrl.pQueryString + 1);
  384. }
  385. else
  386. {
  387. return pstrQueryString->Copy( "", 0 );
  388. }
  389. }
  390. HRESULT
  391. SetVerb(
  392. STRA & strVerb
  393. );
  394. HRESULT
  395. SetVersion(
  396. STRA & strVersion
  397. );
  398. HRESULT
  399. BuildFullUrl(
  400. STRA& strPath,
  401. STRA * pstrRedirect,
  402. BOOL fIncludeParameters = TRUE
  403. );
  404. HRESULT
  405. BuildFullUrl(
  406. STRU& strPath,
  407. STRU * pstrRedirect,
  408. BOOL fIncludeParameters = TRUE
  409. );
  410. HTTP_VERB
  411. QueryVerbType(
  412. VOID
  413. ) const
  414. {
  415. return _pUlHttpRequest->Verb;
  416. }
  417. VOID
  418. SetVerbType(
  419. HTTP_VERB NewVerb
  420. )
  421. {
  422. _pUlHttpRequest->Verb = NewVerb;
  423. }
  424. CHAR *
  425. GetHeader(
  426. ULONG index,
  427. USHORT * pcchLength = NULL
  428. )
  429. {
  430. if (pcchLength)
  431. {
  432. *pcchLength = _pUlHttpRequest->Headers.pKnownHeaders[ index ].RawValueLength;
  433. }
  434. return _pUlHttpRequest->Headers.pKnownHeaders[ index ].pRawValue;
  435. }
  436. CHAR *
  437. GetHeader(
  438. CHAR * pszHeaderName
  439. );
  440. HRESULT
  441. GetHeader(
  442. STRA & strHeaderName,
  443. STRA * pstrValue,
  444. BOOL fIsUnknownHeader = FALSE
  445. )
  446. {
  447. return GetHeader( strHeaderName.QueryStr(),
  448. strHeaderName.QueryCCH(),
  449. pstrValue,
  450. fIsUnknownHeader );
  451. }
  452. HRESULT
  453. GetHeader(
  454. CHAR * pszHeaderName,
  455. DWORD cchHeaderName,
  456. STRA * pstrValue,
  457. BOOL fIsUnknownHeader = FALSE
  458. );
  459. HRESULT
  460. CloneRequest(
  461. DWORD dwCloneFlags,
  462. W3_REQUEST ** ppRequest
  463. );
  464. HRESULT
  465. DeleteHeader(
  466. CHAR * pszHeaderName
  467. );
  468. HRESULT
  469. SetHeader(
  470. STRA & strHeaderName,
  471. STRA & strHeaderValue,
  472. BOOL fAppend = FALSE
  473. );
  474. HRESULT
  475. SetHeadersByStream(
  476. CHAR * pszHeaderStream
  477. );
  478. CHAR *
  479. QueryRawUrl(
  480. USHORT *pcchUrl
  481. ) const
  482. {
  483. *pcchUrl = _pUlHttpRequest->RawUrlLength;
  484. return _pUlHttpRequest->pRawUrl;
  485. }
  486. LPVOID
  487. QueryEntityBody(
  488. VOID
  489. )
  490. {
  491. if ( _pUlHttpRequest->EntityChunkCount == 0 )
  492. {
  493. return NULL;
  494. }
  495. //
  496. // we only expect one memory type chunk
  497. //
  498. DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
  499. DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
  500. return _pUlHttpRequest->pEntityChunks[0].FromMemory.pBuffer;
  501. }
  502. DWORD
  503. QueryAvailableBytes(
  504. VOID
  505. )
  506. {
  507. if ( _pUlHttpRequest->EntityChunkCount == 0 )
  508. {
  509. return 0;
  510. }
  511. //
  512. // we only expect one memory type chunk
  513. //
  514. DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
  515. DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
  516. return _pUlHttpRequest->pEntityChunks[0].FromMemory.BufferLength;
  517. }
  518. private:
  519. HRESULT
  520. BuildISAPIHeaderLine(
  521. CHAR * pszHeaderName,
  522. DWORD cchHeaderName,
  523. CHAR * pszHeaderValue,
  524. DWORD cchHeaderValue,
  525. STRA * pstrHeaderLine
  526. );
  527. HRESULT
  528. BuildRawHeaderLine(
  529. CHAR * pszHeaderName,
  530. DWORD cchHeaderName,
  531. CHAR * pszHeaderValue,
  532. DWORD cchHeaderValue,
  533. STRA * pstrHeaderLine
  534. );
  535. };
  536. //
  537. // Cloned request used for executing child requests
  538. //
  539. #define W3_REQUEST_CLONE_BASICS 0x01
  540. #define W3_REQUEST_CLONE_HEADERS 0x02
  541. #define W3_REQUEST_CLONE_ENTITY 0x04
  542. #define W3_REQUEST_CLONE_NO_PRECONDITION 0x08
  543. #define W3_REQUEST_CLONE_NO_DAV 0x10
  544. class W3_CLONE_REQUEST : public W3_REQUEST
  545. {
  546. public:
  547. W3_CLONE_REQUEST()
  548. {
  549. _pUlHttpRequest = &_ulHttpRequest;
  550. }
  551. virtual ~W3_CLONE_REQUEST()
  552. {
  553. }
  554. HRESULT
  555. CopyMinimum(
  556. HTTP_REQUEST * pRequestToClone
  557. );
  558. HRESULT
  559. CopyHeaders(
  560. HTTP_REQUEST * pRequestToClone
  561. );
  562. HRESULT
  563. CopyBasics(
  564. HTTP_REQUEST * pRequestToClone
  565. );
  566. HRESULT
  567. CopyEntity(
  568. HTTP_REQUEST * pRequestToClone
  569. );
  570. VOID
  571. RemoveConditionals(
  572. VOID
  573. );
  574. VOID *
  575. operator new(
  576. size_t size
  577. )
  578. {
  579. DBG_ASSERT( size == sizeof( W3_CLONE_REQUEST ) );
  580. DBG_ASSERT( sm_pachCloneRequests != NULL );
  581. return sm_pachCloneRequests->Alloc();
  582. }
  583. VOID
  584. operator delete(
  585. VOID * pCloneRequest
  586. )
  587. {
  588. DBG_ASSERT( pCloneRequest != NULL );
  589. DBG_ASSERT( sm_pachCloneRequests != NULL );
  590. DBG_REQUIRE( sm_pachCloneRequests->Free( pCloneRequest ) );
  591. }
  592. static
  593. HRESULT
  594. Initialize(
  595. VOID
  596. );
  597. static
  598. VOID
  599. Terminate(
  600. VOID
  601. );
  602. private:
  603. HTTP_REQUEST _ulHttpRequest;
  604. //
  605. // Lookaside for main contexts
  606. //
  607. static ALLOC_CACHE_HANDLER * sm_pachCloneRequests;
  608. };
  609. HRESULT
  610. UlCleanAndCopyUrl(
  611. IN PUCHAR pSource,
  612. IN ULONG SourceLength,
  613. OUT PULONG pBytesCopied,
  614. IN OUT PWSTR pDestination,
  615. OUT PWSTR * ppQueryString
  616. );
  617. #endif