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.

890 lines
19 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. STRA _strRequestPassword;
  34. //
  35. // Keep track of original full URL of request (can be changed by filter)
  36. //
  37. WCHAR * _pszOriginalFullUrl;
  38. DWORD _cchOriginalFullUrl;
  39. static LPADDRINFO sm_pHostAddrInfo;
  40. public:
  41. W3_REQUEST()
  42. : _dwSignature( W3_REQUEST_SIGNATURE ),
  43. _pUlHttpRequest( NULL ),
  44. _pExtraUnknown( NULL ),
  45. _pszOriginalFullUrl( NULL ),
  46. _cchOriginalFullUrl( 0 )
  47. {
  48. _InsertedEntityBodyChunk.DataChunkType = HttpDataChunkFromMemory;
  49. }
  50. virtual ~W3_REQUEST()
  51. {
  52. if ( _pExtraUnknown != NULL )
  53. {
  54. LocalFree( _pExtraUnknown );
  55. _pExtraUnknown = NULL;
  56. }
  57. if( _strRequestPassword.QueryCB() )
  58. {
  59. ZeroMemory( ( VOID * )_strRequestPassword.QueryStr(),
  60. _strRequestPassword.QueryCB() );
  61. }
  62. _dwSignature = W3_REQUEST_SIGNATURE_FREE;
  63. }
  64. VOID
  65. SetHttpRequest(
  66. HTTP_REQUEST * pRequest
  67. )
  68. {
  69. _pUlHttpRequest = pRequest;
  70. _pszOriginalFullUrl = (PWSTR) pRequest->CookedUrl.pFullUrl;
  71. _cchOriginalFullUrl = pRequest->CookedUrl.FullUrlLength / sizeof(WCHAR);
  72. }
  73. static
  74. HRESULT
  75. Initialize(
  76. VOID
  77. );
  78. static
  79. VOID
  80. Terminate(
  81. VOID
  82. );
  83. HRESULT
  84. SetNewPreloadedEntityBody(
  85. VOID * pvBuffer,
  86. DWORD cbBuffer
  87. );
  88. HRESULT AppendEntityBody(
  89. VOID * pvBuffer,
  90. DWORD cbBuffer
  91. );
  92. HRESULT PreloadEntityBody(
  93. W3_CONTEXT * pW3Context,
  94. BOOL * pfComplete
  95. );
  96. HRESULT
  97. PreloadCompletion(
  98. W3_CONTEXT * pW3Context,
  99. DWORD cbRead,
  100. DWORD dwStatus,
  101. BOOL * pfComplete
  102. );
  103. VOID
  104. RemoveDav(
  105. VOID
  106. );
  107. HRESULT
  108. SetUrl(
  109. STRU & strNewUrl,
  110. BOOL fResetQueryString = TRUE
  111. );
  112. HRESULT
  113. SetUrlA(
  114. STRA & strNewUrl,
  115. BOOL fResetQueryString = TRUE
  116. );
  117. HTTP_CONNECTION_ID
  118. QueryConnectionId(
  119. VOID
  120. ) const
  121. {
  122. return _pUlHttpRequest->ConnectionId;
  123. }
  124. BOOL
  125. QueryMoreEntityBodyExists(
  126. VOID
  127. )
  128. {
  129. return 0 != (_pUlHttpRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS);
  130. }
  131. HTTP_REQUEST_ID
  132. QueryRequestId(
  133. VOID
  134. ) const
  135. {
  136. return _pUlHttpRequest->RequestId;
  137. }
  138. DWORD
  139. QuerySiteId(
  140. VOID
  141. ) const
  142. {
  143. return (DWORD)(_pUlHttpRequest->UrlContext >> 32);
  144. }
  145. USHORT
  146. QueryLocalAddressType(
  147. VOID
  148. ) const
  149. {
  150. return _pUlHttpRequest->Address.pLocalAddress->sa_family;
  151. }
  152. USHORT
  153. QueryRemoteAddressType(
  154. VOID
  155. ) const
  156. {
  157. return _pUlHttpRequest->Address.pRemoteAddress->sa_family;
  158. }
  159. DWORD
  160. QueryIPv4LocalAddress(
  161. VOID
  162. ) const;
  163. DWORD
  164. QueryIPv4RemoteAddress(
  165. VOID
  166. ) const;
  167. IN6_ADDR *
  168. QueryIPv6LocalAddress(
  169. VOID
  170. ) const;
  171. IN6_ADDR *
  172. QueryIPv6RemoteAddress(
  173. VOID
  174. ) const;
  175. USHORT
  176. QueryLocalPort(
  177. VOID
  178. ) const;
  179. USHORT
  180. QueryRemotePort(
  181. VOID
  182. ) const;
  183. PSOCKADDR
  184. QueryLocalSockAddress(
  185. VOID
  186. ) const;
  187. PSOCKADDR
  188. QueryRemoteSockAddress(
  189. VOID
  190. ) const;
  191. BOOL
  192. QueryUrlChanged(
  193. VOID
  194. ) const
  195. {
  196. return _pszOriginalFullUrl != (PWSTR) _pUlHttpRequest->CookedUrl.pFullUrl;
  197. }
  198. BOOL
  199. IsProxyRequest(
  200. VOID
  201. );
  202. BOOL
  203. IsChunkedRequest(
  204. VOID
  205. );
  206. BOOL
  207. IsLocalRequest(
  208. VOID
  209. ) const;
  210. BOOL
  211. IsSecureRequest(
  212. VOID
  213. ) const
  214. {
  215. DBG_ASSERT( _pUlHttpRequest != NULL );
  216. return _pUlHttpRequest->pSslInfo != NULL;
  217. }
  218. HTTP_SSL_INFO *
  219. QuerySslInfo(
  220. VOID
  221. ) const
  222. {
  223. DBG_ASSERT( _pUlHttpRequest != NULL );
  224. return _pUlHttpRequest->pSslInfo;
  225. }
  226. HTTP_SSL_CLIENT_CERT_INFO *
  227. QueryClientCertInfo(
  228. VOID
  229. ) const
  230. {
  231. DBG_ASSERT( _pUlHttpRequest != NULL );
  232. if ( _pUlHttpRequest->pSslInfo != NULL )
  233. {
  234. return _pUlHttpRequest->pSslInfo->pClientCertInfo;
  235. }
  236. else
  237. {
  238. return NULL;
  239. }
  240. }
  241. VOID
  242. SetClientCertInfo(
  243. HTTP_SSL_CLIENT_CERT_INFO * pClientCertInfo
  244. )
  245. {
  246. DBG_ASSERT( pClientCertInfo != NULL );
  247. DBG_ASSERT( _pUlHttpRequest != NULL );
  248. DBG_ASSERT( _pUlHttpRequest->pSslInfo != NULL );
  249. _pUlHttpRequest->pSslInfo->pClientCertInfo = pClientCertInfo;
  250. }
  251. HTTP_RAW_CONNECTION_ID
  252. QueryRawConnectionId(
  253. VOID
  254. ) const
  255. {
  256. DBG_ASSERT( _pUlHttpRequest != NULL );
  257. return _pUlHttpRequest->RawConnectionId;
  258. }
  259. HRESULT
  260. GetRawUrl(
  261. STRA * pstrRawUrl
  262. )
  263. {
  264. if ( pstrRawUrl == NULL )
  265. {
  266. DBG_ASSERT( FALSE );
  267. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  268. }
  269. return pstrRawUrl->Copy( _pUlHttpRequest->pRawUrl,
  270. _pUlHttpRequest->RawUrlLength );
  271. }
  272. HRESULT
  273. GetRawUrl(
  274. PCHAR pszRawUrl,
  275. USHORT * pcbRawUrl
  276. )
  277. {
  278. if ( pcbRawUrl == NULL ||
  279. ( pszRawUrl == NULL && *pcbRawUrl > 0 ) )
  280. {
  281. DBG_ASSERT( FALSE );
  282. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  283. }
  284. if ( *pcbRawUrl < _pUlHttpRequest->RawUrlLength + 1 )
  285. {
  286. *pcbRawUrl = _pUlHttpRequest->RawUrlLength + 1;
  287. return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
  288. }
  289. *pcbRawUrl = _pUlHttpRequest->RawUrlLength + 1;
  290. memcpy( pszRawUrl,
  291. _pUlHttpRequest->pRawUrl,
  292. _pUlHttpRequest->RawUrlLength + 1);
  293. return NO_ERROR;
  294. }
  295. HRESULT
  296. GetOriginalFullUrl(
  297. STRU * pstrFullUrl,
  298. BOOL fIncludeQueryString = FALSE
  299. )
  300. {
  301. if ( pstrFullUrl == NULL )
  302. {
  303. DBG_ASSERT( FALSE );
  304. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  305. }
  306. if ( !fIncludeQueryString )
  307. {
  308. return pstrFullUrl->Copy( _pszOriginalFullUrl,
  309. _cchOriginalFullUrl );
  310. }
  311. else
  312. {
  313. return pstrFullUrl->Copy( _pszOriginalFullUrl );
  314. }
  315. }
  316. HRESULT
  317. GetFullUrl(
  318. STRU * pstrFullUrl
  319. )
  320. {
  321. if ( pstrFullUrl == NULL )
  322. {
  323. DBG_ASSERT( FALSE );
  324. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  325. }
  326. return pstrFullUrl->Copy( _pUlHttpRequest->CookedUrl.pFullUrl,
  327. _pUlHttpRequest->CookedUrl.FullUrlLength / sizeof(WCHAR) );
  328. }
  329. HRESULT
  330. GetAllHeaders(
  331. STRA * pstrHeaders,
  332. BOOL fISAPIStyle
  333. );
  334. BOOL
  335. IsSuspectUrl(
  336. VOID
  337. );
  338. HRESULT
  339. GetUrl(
  340. STRU * pstrUrl
  341. )
  342. {
  343. if ( pstrUrl == NULL )
  344. {
  345. DBG_ASSERT( FALSE );
  346. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  347. }
  348. return pstrUrl->Copy( _pUlHttpRequest->CookedUrl.pAbsPath,
  349. _pUlHttpRequest->CookedUrl.AbsPathLength / sizeof(WCHAR) );
  350. }
  351. VOID
  352. QueryUrl(
  353. WCHAR ** ppszUrl,
  354. USHORT * pcbUrl)
  355. {
  356. *ppszUrl = (PWSTR) _pUlHttpRequest->CookedUrl.pAbsPath;
  357. *pcbUrl = _pUlHttpRequest->CookedUrl.AbsPathLength;
  358. }
  359. HRESULT
  360. GetHostAddr(
  361. IN OUT STRU *pstrHostAddr
  362. )
  363. {
  364. WCHAR * pchTail;
  365. if ( pstrHostAddr == NULL )
  366. {
  367. DBG_ASSERT( FALSE );
  368. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  369. }
  370. if( _pUlHttpRequest->CookedUrl.pHost[0] == L'[' )
  371. {
  372. pchTail = wcspbrk( _pUlHttpRequest->CookedUrl.pHost, L"]" );
  373. if( pchTail != NULL )
  374. {
  375. return pstrHostAddr->Copy(
  376. _pUlHttpRequest->CookedUrl.pHost + 1,
  377. (DWORD)DIFF( pchTail - _pUlHttpRequest->CookedUrl.pHost - 1 ) );
  378. }
  379. else
  380. {
  381. DBG_ASSERT( FALSE );
  382. return E_FAIL;
  383. }
  384. }
  385. else
  386. {
  387. pchTail = wcspbrk( _pUlHttpRequest->CookedUrl.pHost, L":" );
  388. }
  389. if( !pchTail )
  390. {
  391. DBG_ASSERT( FALSE );
  392. return E_FAIL;
  393. }
  394. else
  395. {
  396. return pstrHostAddr->Copy( _pUlHttpRequest->CookedUrl.pHost,
  397. (DWORD)DIFF(pchTail - _pUlHttpRequest->CookedUrl.pHost) );
  398. }
  399. }
  400. BOOL
  401. QueryClientWantsDisconnect(
  402. VOID
  403. );
  404. HRESULT
  405. GetVerbString(
  406. STRA * pstrVerb
  407. );
  408. VOID
  409. QueryVerb(
  410. CHAR ** ppszVerb,
  411. USHORT * pcchVerb
  412. );
  413. HRESULT
  414. GetVersionString(
  415. STRA * pstrVersion
  416. );
  417. HRESULT
  418. GetAuthType(
  419. STRA * pstrAuthType
  420. );
  421. HRESULT
  422. GetRequestUserName(
  423. STRA * pstrUserName
  424. )
  425. {
  426. if ( pstrUserName == NULL )
  427. {
  428. DBG_ASSERT( FALSE );
  429. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  430. }
  431. return pstrUserName->Copy( _strRequestUserName );
  432. }
  433. HRESULT
  434. GetRequestPassword(
  435. STRA * pstrPassword
  436. )
  437. {
  438. if ( pstrPassword == NULL )
  439. {
  440. DBG_ASSERT( FALSE );
  441. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  442. }
  443. return pstrPassword->Copy( _strRequestPassword );
  444. }
  445. HRESULT
  446. SetRequestUserName(
  447. STRA & strUserName
  448. )
  449. {
  450. return _strRequestUserName.Copy( strUserName );
  451. }
  452. HRESULT
  453. SetRequestPassword(
  454. STRA & strPassword
  455. )
  456. {
  457. return _strRequestPassword.Copy( strPassword );
  458. }
  459. STRA *
  460. QueryRequestPassword(
  461. VOID
  462. )
  463. {
  464. return &_strRequestPassword;
  465. }
  466. STRA *
  467. QueryRequestUserName(
  468. VOID
  469. )
  470. {
  471. return &_strRequestUserName;
  472. }
  473. HTTP_VERSION
  474. QueryVersion(
  475. VOID
  476. )
  477. {
  478. return _pUlHttpRequest->Version;
  479. }
  480. HRESULT
  481. GetQueryString(
  482. STRU * pstrQueryString
  483. )
  484. {
  485. DBG_ASSERT ( pstrQueryString != NULL );
  486. if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
  487. {
  488. return pstrQueryString->Copy( _pUlHttpRequest->CookedUrl.pQueryString + 1,
  489. _pUlHttpRequest->CookedUrl.QueryStringLength / sizeof(WCHAR) - 1 );
  490. }
  491. else
  492. {
  493. return pstrQueryString->Copy( L"", 0 );
  494. }
  495. }
  496. HRESULT
  497. GetQueryStringA(
  498. STRA * pstrQueryString
  499. )
  500. {
  501. DBG_ASSERT ( pstrQueryString != NULL );
  502. if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
  503. {
  504. return pstrQueryString->CopyWTruncate( _pUlHttpRequest->CookedUrl.pQueryString + 1);
  505. }
  506. else
  507. {
  508. return pstrQueryString->Copy( "", 0 );
  509. }
  510. }
  511. HRESULT
  512. SetVerb(
  513. STRA & strVerb
  514. );
  515. HRESULT
  516. SetVersion(
  517. STRA & strVersion
  518. );
  519. HRESULT
  520. BuildFullUrl(
  521. STRA& strPath,
  522. STRA * pstrRedirect,
  523. BOOL fIncludeParameters = TRUE
  524. );
  525. HRESULT
  526. BuildFullUrl(
  527. STRU& strPath,
  528. STRU * pstrRedirect,
  529. BOOL fIncludeParameters = TRUE
  530. );
  531. HTTP_VERB
  532. QueryVerbType(
  533. VOID
  534. ) const
  535. {
  536. return _pUlHttpRequest->Verb;
  537. }
  538. VOID
  539. SetVerbType(
  540. HTTP_VERB NewVerb
  541. )
  542. {
  543. _pUlHttpRequest->Verb = NewVerb;
  544. }
  545. const CHAR *
  546. GetHeader(
  547. ULONG index,
  548. USHORT * pcchLength = NULL
  549. ) const
  550. {
  551. if (pcchLength)
  552. {
  553. *pcchLength = _pUlHttpRequest->Headers.KnownHeaders[ index ].RawValueLength;
  554. }
  555. return _pUlHttpRequest->Headers.KnownHeaders[ index ].pRawValue;
  556. }
  557. CHAR *
  558. GetHeader(
  559. CHAR * pszHeaderName
  560. );
  561. HRESULT
  562. GetHeader(
  563. STRA & strHeaderName,
  564. STRA * pstrValue,
  565. BOOL fIsUnknownHeader = FALSE
  566. )
  567. {
  568. return GetHeader( strHeaderName.QueryStr(),
  569. strHeaderName.QueryCCH(),
  570. pstrValue,
  571. fIsUnknownHeader );
  572. }
  573. HRESULT
  574. GetHeader(
  575. CHAR * pszHeaderName,
  576. DWORD cchHeaderName,
  577. STRA * pstrValue,
  578. BOOL fIsUnknownHeader = FALSE
  579. );
  580. HRESULT
  581. CloneRequest(
  582. DWORD dwCloneFlags,
  583. W3_REQUEST ** ppRequest
  584. );
  585. HRESULT
  586. DeleteHeader(
  587. CHAR * pszHeaderName
  588. );
  589. HRESULT
  590. DeleteKnownHeader(
  591. ULONG ulHeaderIndex
  592. );
  593. HRESULT
  594. SetHeader(
  595. STRA & strHeaderName,
  596. STRA & strHeaderValue,
  597. BOOL fAppend = FALSE
  598. );
  599. HRESULT
  600. SetKnownHeader(
  601. ULONG ulHeaderIndex,
  602. STRA & strHeaderValue,
  603. BOOL fAppend = FALSE
  604. );
  605. HRESULT
  606. SetHeadersByStream(
  607. CHAR * pszHeaderStream
  608. );
  609. const CHAR *
  610. QueryRawUrl(
  611. USHORT *pcchUrl
  612. ) const
  613. {
  614. *pcchUrl = _pUlHttpRequest->RawUrlLength;
  615. return _pUlHttpRequest->pRawUrl;
  616. }
  617. LPVOID
  618. QueryEntityBody(
  619. VOID
  620. )
  621. {
  622. if ( _pUlHttpRequest->EntityChunkCount == 0 )
  623. {
  624. return NULL;
  625. }
  626. //
  627. // we only expect one memory type chunk
  628. //
  629. DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
  630. DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
  631. return _pUlHttpRequest->pEntityChunks[0].FromMemory.pBuffer;
  632. }
  633. DWORD
  634. QueryAvailableBytes(
  635. VOID
  636. )
  637. {
  638. if ( _pUlHttpRequest->EntityChunkCount == 0 )
  639. {
  640. return 0;
  641. }
  642. //
  643. // we only expect one memory type chunk
  644. //
  645. DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
  646. DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
  647. return _pUlHttpRequest->pEntityChunks[0].FromMemory.BufferLength;
  648. }
  649. private:
  650. HRESULT
  651. BuildISAPIHeaderLine(
  652. LPCSTR pszHeaderName,
  653. DWORD cchHeaderName,
  654. LPCSTR pszHeaderValue,
  655. DWORD cchHeaderValue,
  656. STRA * pstrHeaderLine
  657. );
  658. HRESULT
  659. BuildRawHeaderLine(
  660. LPCSTR pszHeaderName,
  661. DWORD cchHeaderName,
  662. LPCSTR pszHeaderValue,
  663. DWORD cchHeaderValue,
  664. STRA * pstrHeaderLine
  665. );
  666. };
  667. //
  668. // Cloned request used for executing child requests
  669. //
  670. #define W3_REQUEST_CLONE_BASICS 0x01
  671. #define W3_REQUEST_CLONE_HEADERS 0x02
  672. #define W3_REQUEST_CLONE_ENTITY 0x04
  673. #define W3_REQUEST_CLONE_NO_PRECONDITION 0x08
  674. #define W3_REQUEST_CLONE_NO_DAV 0x10
  675. class W3_CLONE_REQUEST : public W3_REQUEST
  676. {
  677. public:
  678. W3_CLONE_REQUEST()
  679. {
  680. _pUlHttpRequest = &_ulHttpRequest;
  681. }
  682. virtual ~W3_CLONE_REQUEST()
  683. {
  684. }
  685. HRESULT
  686. CopyMinimum(
  687. HTTP_REQUEST * pRequestToClone
  688. );
  689. HRESULT
  690. CopyHeaders(
  691. HTTP_REQUEST * pRequestToClone
  692. );
  693. HRESULT
  694. CopyBasics(
  695. HTTP_REQUEST * pRequestToClone
  696. );
  697. HRESULT
  698. CopyEntity(
  699. HTTP_REQUEST * pRequestToClone
  700. );
  701. VOID
  702. RemoveConditionals(
  703. VOID
  704. );
  705. VOID *
  706. operator new(
  707. #if DBG
  708. size_t size
  709. #else
  710. size_t
  711. #endif
  712. )
  713. {
  714. DBG_ASSERT( size == sizeof( W3_CLONE_REQUEST ) );
  715. DBG_ASSERT( sm_pachCloneRequests != NULL );
  716. return sm_pachCloneRequests->Alloc();
  717. }
  718. VOID
  719. operator delete(
  720. VOID * pCloneRequest
  721. )
  722. {
  723. DBG_ASSERT( pCloneRequest != NULL );
  724. DBG_ASSERT( sm_pachCloneRequests != NULL );
  725. DBG_REQUIRE( sm_pachCloneRequests->Free( pCloneRequest ) );
  726. }
  727. static
  728. HRESULT
  729. Initialize(
  730. VOID
  731. );
  732. static
  733. VOID
  734. Terminate(
  735. VOID
  736. );
  737. private:
  738. HTTP_REQUEST _ulHttpRequest;
  739. //
  740. // Lookaside for main contexts
  741. //
  742. static ALLOC_CACHE_HANDLER * sm_pachCloneRequests;
  743. W3_CLONE_REQUEST(const W3_CLONE_REQUEST &);
  744. void operator=(const W3_CLONE_REQUEST &);
  745. };
  746. #endif