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.

1081 lines
20 KiB

  1. #ifndef _MAINCONTEXT_HXX_
  2. #define _MAINCONTEXT_HXX_
  3. class W3_CONNECTION;
  4. class RAW_CONNECTION;
  5. class W3_MAIN_CONTEXT;
  6. //
  7. // Different states
  8. //
  9. enum CONTEXT_STATE
  10. {
  11. CONTEXT_STATE_START,
  12. CONTEXT_STATE_URLINFO,
  13. CONTEXT_STATE_AUTHENTICATION,
  14. CONTEXT_STATE_AUTHORIZATION,
  15. CONTEXT_STATE_HANDLE_REQUEST,
  16. CONTEXT_STATE_RESPONSE,
  17. CONTEXT_STATE_LOG,
  18. CONTEXT_STATE_DONE,
  19. //
  20. // This should be the last value
  21. //
  22. STATE_COUNT
  23. };
  24. //
  25. // W3_CONNECTION_STATE - Abstract class representing state associated with
  26. // connection (W3_CONNECTION)
  27. //
  28. class W3_CONNECTION_STATE
  29. {
  30. public:
  31. virtual BOOL
  32. Cleanup(
  33. VOID
  34. ) = 0;
  35. };
  36. //
  37. // W3_CONTEXT_STATE - Abstract class representing context information for a
  38. // given state, stored for a given W3_MAIN_CONTEXT
  39. // At the end of the state machine, objects implementing
  40. // this class will be cleaned up (using Cleanup()).
  41. //
  42. class W3_MAIN_CONTEXT_STATE
  43. {
  44. public:
  45. virtual
  46. ~W3_MAIN_CONTEXT_STATE()
  47. {
  48. }
  49. virtual BOOL
  50. Cleanup(
  51. W3_MAIN_CONTEXT * pContext
  52. ) = 0;
  53. VOID *
  54. operator new(
  55. size_t uiSize,
  56. VOID * pPlacement
  57. );
  58. VOID
  59. operator delete(
  60. VOID * pContext
  61. );
  62. };
  63. //
  64. // W3_MAIN_CONTEXT
  65. //
  66. // This class represents the mainline (non-child) context representing the
  67. // the execution of a single HTTP request. This class contains and manages
  68. // the HTTP state machine
  69. //
  70. class W3_MAIN_CONTEXT : public W3_CONTEXT
  71. {
  72. private:
  73. //
  74. // Reference count used to manage fact that this context can be attached
  75. // to a RAW_CONNECTION
  76. //
  77. LONG _cRefs;
  78. //
  79. // Request information
  80. //
  81. W3_REQUEST _request;
  82. //
  83. // Response object (not necessarily used in sending a response)
  84. //
  85. W3_RESPONSE _response;
  86. //
  87. // The associated connection for this given request
  88. //
  89. W3_CONNECTION * _pConnection;
  90. BOOL _fAssociationChecked;
  91. //
  92. // The associated Site for this request
  93. //
  94. W3_SITE * _pSite;
  95. //
  96. // Metadata for request
  97. //
  98. URL_CONTEXT * _pUrlContext;
  99. //
  100. // User for the context. For now, the user cannot be reset for a child
  101. // context and is therefore stored only in the main context. That could
  102. // change later if we allow child requests to take on different
  103. // user identity
  104. //
  105. W3_USER_CONTEXT * _pUserContext;
  106. //
  107. // Did an authentication provider already handle sending
  108. // access denied headers?
  109. //
  110. BOOL _fProviderHandled;
  111. //
  112. // Do we need to check if Anonymous auth type is supported when
  113. // we call ANONYMOUS_AUTH_PROVIDER::DoAuthenticate
  114. //
  115. BOOL _fCheckAnonAuthTypeSupported;
  116. //
  117. // Certificate context representing client certificate if negotiated
  118. //
  119. CERTIFICATE_CONTEXT * _pCertificateContext;
  120. //
  121. // ULATQ context used to communicate with UL
  122. //
  123. ULATQ_CONTEXT _ulatqContext;
  124. //
  125. // Filter state
  126. //
  127. W3_FILTER_CONTEXT * _pFilterContext;
  128. //
  129. // Inline filter context used for almost all cases (except
  130. // when we need to persist filter context beyond
  131. // main context lifetime)
  132. //
  133. W3_FILTER_CONTEXT _FilterContext;
  134. //
  135. // State machine
  136. //
  137. DWORD _currentState;
  138. DWORD _nextState;
  139. //
  140. // State context objects
  141. //
  142. W3_MAIN_CONTEXT_STATE * _rgStateContexts[ STATE_COUNT ];
  143. //
  144. // Should we disconnect at the end of this request?
  145. //
  146. BOOL _fDisconnect;
  147. //
  148. // Are we done with compression for this request?
  149. //
  150. BOOL _fDoneWithCompression;
  151. //
  152. // The COMPRESSION_CONTEXT for the current request
  153. //
  154. COMPRESSION_CONTEXT *_pCompressionContext;
  155. //
  156. // Logging data to be passed on to UL
  157. //
  158. LOG_CONTEXT _LogContext;
  159. //
  160. // Do we need to send a final done?
  161. //
  162. BOOL _fNeedFinalDone;
  163. //
  164. // The current context to receive IO completions
  165. //
  166. W3_CONTEXT * _pCurrentContext;
  167. //
  168. // Is this response cacheble in UL?
  169. //
  170. BOOL _fIsUlCacheable;
  171. //
  172. // Access check (put here only since a child request cannot/should not
  173. // change the remote address)
  174. //
  175. ADDRESS_CHECK _IpAddressCheck;
  176. //
  177. // Keep track of available entity body to be read thru UL.
  178. //
  179. DWORD _cbRemainingEntityFromUL;
  180. //
  181. // Keep track of the entity that we've read so far so that
  182. // we can enforce MaxRequestEntityAllowed.
  183. //
  184. DWORD _cbEntityReadSoFar;
  185. //
  186. // For HEAD requests, UL will not send a content-length so we'll have
  187. // to do for HEAD requests. The reason we keep this state
  188. // is because filters/child-requests can reset the verb -> a resetting
  189. // which still doesn't change the fact that UL will not be setting
  190. // Content-Length
  191. //
  192. BOOL _fGenerateContentLength;
  193. //
  194. // Raw connection. Needed since we need to tell the raw connection when
  195. // it should no longer reference us
  196. //
  197. RAW_CONNECTION * _pRawConnection;
  198. //
  199. // List of *-ScriptMaps which do not want to be notified at all anymore
  200. // about this particular chain of request
  201. //
  202. MULTISZ _mszIgnoredInterceptors;
  203. //
  204. // Call information about last posted completion
  205. //
  206. CHAR * _pszLastPostFileName;
  207. DWORD _dwLastPostLineNumber;
  208. //
  209. // Handle for TIMER callback when a W3_MAIN_CONTEXT has existed for too long
  210. //
  211. HANDLE _hTimer;
  212. //
  213. // Per request trace log
  214. //
  215. W3_TRACE_LOG * _pTraceLog;
  216. //
  217. // Can we ignore the apppool check (done when WAS routes us to an
  218. // AppPool we aren't configured by URL-wise
  219. //
  220. BOOL _fIgnoreAppPoolCheck;
  221. //
  222. // static TraceLogFactory
  223. //
  224. static W3_TRACE_LOG_FACTORY * sm_pLogFactory;
  225. //
  226. // static File to trace to
  227. //
  228. static HANDLE sm_hTraceFile;
  229. static
  230. HRESULT
  231. SetupTraceLogging(
  232. VOID
  233. );
  234. static
  235. VOID
  236. CleanupTraceLogging(
  237. VOID
  238. );
  239. //
  240. // timeout in milliseconds before DebugBreak() is called
  241. // read from registry at static Initialization
  242. //
  243. static DWORD sm_dwTimeout;
  244. //
  245. // Callback function that does the DebugBreak for overtime W3_MAIN_CONTEXT
  246. //
  247. static
  248. VOID
  249. TimerCallback(
  250. PVOID pvParam,
  251. BOOLEAN fReason
  252. );
  253. W3_MAIN_CONTEXT(const W3_MAIN_CONTEXT &);
  254. void operator=(const W3_MAIN_CONTEXT &);
  255. public:
  256. //
  257. // Lookaside for main contexts
  258. //
  259. static ALLOC_CACHE_HANDLER * sm_pachMainContexts;
  260. //
  261. // The states
  262. //
  263. static W3_STATE * sm_pStates[ STATE_COUNT ];
  264. static SHORT sm_rgInline[ STATE_COUNT ];
  265. static USHORT sm_cbInlineBytes;
  266. W3_MAIN_CONTEXT(
  267. HTTP_REQUEST * pUlHttpRequest,
  268. ULATQ_CONTEXT pUlAtqContext
  269. );
  270. ~W3_MAIN_CONTEXT();
  271. VOID *
  272. operator new(
  273. size_t uiSize,
  274. VOID * pPlacement
  275. );
  276. VOID
  277. operator delete(
  278. VOID * pMainContext
  279. );
  280. VOID *
  281. AllocateFromInlineMemory(
  282. DWORD cbSize
  283. );
  284. //
  285. // Overridden W3_CONTEXT methods
  286. //
  287. ULATQ_CONTEXT
  288. QueryUlatqContext(
  289. VOID
  290. )
  291. {
  292. return _ulatqContext;
  293. }
  294. W3_REQUEST *
  295. QueryRequest(
  296. VOID
  297. )
  298. {
  299. return &_request;
  300. }
  301. W3_RESPONSE *
  302. QueryResponse(
  303. VOID
  304. )
  305. {
  306. return &_response;
  307. }
  308. BOOL
  309. QueryResponseSent(
  310. VOID
  311. )
  312. {
  313. return _response.QueryResponseSent();
  314. }
  315. BOOL
  316. QueryIsUlCacheable(
  317. VOID
  318. )
  319. {
  320. return _fIsUlCacheable;
  321. }
  322. VOID
  323. DisableUlCache(
  324. VOID
  325. )
  326. {
  327. _fIsUlCacheable = FALSE;
  328. }
  329. BOOL
  330. QueryProviderHandled(
  331. VOID
  332. )
  333. {
  334. return _fProviderHandled;
  335. }
  336. BOOL
  337. QueryNeedFinalDone(
  338. VOID
  339. )
  340. {
  341. return _fNeedFinalDone;
  342. }
  343. VOID
  344. SetNeedFinalDone(
  345. VOID
  346. )
  347. {
  348. _fNeedFinalDone = TRUE;
  349. }
  350. BOOL
  351. QueryCheckAnonAuthTypeSupported(
  352. VOID
  353. )
  354. {
  355. return _fCheckAnonAuthTypeSupported;
  356. }
  357. VOID
  358. SetCheckAnonAuthTypeSupported(
  359. BOOL fCheckAnonAuthTypeSupported
  360. )
  361. {
  362. _fCheckAnonAuthTypeSupported = fCheckAnonAuthTypeSupported;
  363. }
  364. BOOL
  365. QueryShouldGenerateContentLength(
  366. VOID
  367. ) const
  368. {
  369. return _fGenerateContentLength;
  370. }
  371. VOID
  372. SetShouldGenerateContentLength(
  373. BOOL fShouldGenerate
  374. )
  375. {
  376. _fGenerateContentLength = fShouldGenerate;
  377. }
  378. W3_USER_CONTEXT *
  379. QueryUserContext(
  380. VOID
  381. )
  382. {
  383. return _pUserContext;
  384. }
  385. W3_USER_CONTEXT *
  386. QueryConnectionUserContext(
  387. VOID
  388. );
  389. VOID
  390. SetConnectionUserContext(
  391. W3_USER_CONTEXT * pUserContext
  392. );
  393. VOID
  394. SetUserContext(
  395. W3_USER_CONTEXT * pUserContext
  396. )
  397. {
  398. // perf ctr
  399. if (pUserContext->QueryAuthType() == MD_AUTH_ANONYMOUS)
  400. {
  401. _pSite->IncAnonUsers();
  402. }
  403. else
  404. {
  405. _pSite->IncNonAnonUsers();
  406. }
  407. _pUserContext = pUserContext;
  408. }
  409. CERTIFICATE_CONTEXT *
  410. QueryCertificateContext(
  411. VOID
  412. ) const
  413. {
  414. return _pCertificateContext;
  415. }
  416. VOID
  417. UpdateSkipped(
  418. HTTP_DATA_CHUNK * pChunks,
  419. DWORD cChunks
  420. );
  421. VOID
  422. DetermineRemainingEntity(
  423. VOID
  424. );
  425. VOID
  426. SetCertificateContext(
  427. CERTIFICATE_CONTEXT * pCertificateContext
  428. )
  429. {
  430. _pCertificateContext = pCertificateContext;
  431. }
  432. W3_FILTER_CONTEXT *
  433. QueryFilterContext(
  434. BOOL fCreateIfNotFound = TRUE
  435. );
  436. URL_CONTEXT *
  437. QueryUrlContext(
  438. VOID
  439. )
  440. {
  441. return _pUrlContext;
  442. }
  443. W3_SITE *
  444. QuerySite(
  445. VOID
  446. )
  447. {
  448. return _pSite;
  449. }
  450. W3_CONTEXT *
  451. QueryCurrentContext(
  452. VOID
  453. )
  454. {
  455. return _pCurrentContext;
  456. }
  457. VOID
  458. PopCurrentContext(
  459. VOID
  460. )
  461. {
  462. _pCurrentContext = _pCurrentContext->QueryParentContext();
  463. if ( _pCurrentContext == NULL )
  464. {
  465. _pCurrentContext = this;
  466. }
  467. }
  468. VOID
  469. PushCurrentContext(
  470. W3_CONTEXT * pW3Context
  471. )
  472. {
  473. _pCurrentContext = pW3Context;
  474. }
  475. W3_CONTEXT *
  476. QueryParentContext(
  477. VOID
  478. )
  479. {
  480. return NULL;
  481. }
  482. W3_MAIN_CONTEXT *
  483. QueryMainContext(
  484. VOID
  485. )
  486. {
  487. return this;
  488. }
  489. BOOL
  490. QueryDisconnect(
  491. VOID
  492. );
  493. VOID
  494. SetDisconnect(
  495. BOOL fDisconnect
  496. )
  497. {
  498. _fDisconnect = fDisconnect;
  499. }
  500. VOID
  501. SetDeniedFlags(
  502. DWORD dwDeniedFlags
  503. )
  504. {
  505. if( _pFilterContext )
  506. {
  507. _pFilterContext->SetDeniedFlags( dwDeniedFlags );
  508. }
  509. }
  510. BOOL
  511. NotifyFilters(
  512. DWORD dwNotification,
  513. VOID * pvFilterInfo,
  514. BOOL * pfFinished
  515. );
  516. BOOL
  517. IsNotificationNeeded(
  518. DWORD dwNotification
  519. );
  520. //
  521. // W3_MAIN_CONTEXT specific methods. These methods are not callable
  522. // when we are in the state of invoking a handler
  523. //
  524. VOID
  525. ReferenceMainContext(
  526. VOID
  527. )
  528. {
  529. InterlockedIncrement( &_cRefs );
  530. }
  531. VOID
  532. DereferenceMainContext(
  533. VOID
  534. )
  535. {
  536. ULATQ_CONTEXT ulatqContext;
  537. if ( !InterlockedDecrement( &_cRefs ) )
  538. {
  539. //
  540. // Remember the ULATQ context. Once we've deleted the object
  541. // we will free the context
  542. //
  543. ulatqContext = _ulatqContext;
  544. delete this;
  545. UlAtqFreeContext( ulatqContext );
  546. }
  547. }
  548. BOOL
  549. QueryIgnoreAppPoolCheck(
  550. VOID
  551. ) const
  552. {
  553. return _fIgnoreAppPoolCheck;
  554. }
  555. VOID
  556. SetIgnoreAppPoolCheck(
  557. VOID
  558. )
  559. {
  560. _fIgnoreAppPoolCheck = TRUE;
  561. }
  562. RAW_CONNECTION *
  563. QueryRawConnection(
  564. VOID
  565. ) const
  566. {
  567. return _pRawConnection;
  568. }
  569. VOID
  570. SetRawConnection(
  571. RAW_CONNECTION * pRawConnection
  572. );
  573. VOID
  574. SetRawConnectionClientContext(
  575. DWORD dwCurrentFilter,
  576. VOID * pvContext
  577. );
  578. BOOL
  579. QueryRawConnectionNotificationChanged(
  580. VOID
  581. );
  582. BOOL
  583. IsRawConnectionDisableNotificationNeeded(
  584. DWORD dwFilter,
  585. DWORD dwNotification
  586. );
  587. BOOL
  588. QueryExpiry(
  589. LARGE_INTEGER * pExpiry
  590. );
  591. HRESULT
  592. ExecuteExpiredUrl(
  593. STRU & strExpUrl
  594. );
  595. HRESULT
  596. PasswdExpireNotify(
  597. VOID
  598. );
  599. HRESULT
  600. PasswdChangeExecute(
  601. VOID
  602. );
  603. HRESULT
  604. ReceiveEntityBody(
  605. BOOL fAsync,
  606. VOID * pBuffer,
  607. DWORD cbBuffer,
  608. DWORD * pBytesReceived
  609. );
  610. DWORD
  611. QueryRemainingEntityFromUl(
  612. VOID
  613. ) const
  614. {
  615. return _cbRemainingEntityFromUL;
  616. }
  617. VOID
  618. SetRemainingEntityFromUl(
  619. DWORD cbRemaining
  620. )
  621. {
  622. _cbRemainingEntityFromUL = cbRemaining;
  623. }
  624. HRESULT
  625. GetRemoteDNSName(
  626. STRA * pstrDNSName
  627. );
  628. ADDRESS_CHECK *
  629. QueryAddressCheck(
  630. VOID
  631. )
  632. {
  633. return &_IpAddressCheck;
  634. }
  635. VOID
  636. SetProviderHandled(
  637. BOOL fProviderHandled
  638. )
  639. {
  640. _fProviderHandled = fProviderHandled;
  641. }
  642. HRESULT
  643. OnAccessDenied(
  644. VOID
  645. )
  646. {
  647. return NO_ERROR;
  648. }
  649. VOID
  650. SetUrlContext(
  651. URL_CONTEXT * pUrlContext
  652. )
  653. {
  654. _pUrlContext = pUrlContext;
  655. }
  656. VOID
  657. AssociateSite(
  658. W3_SITE * site
  659. )
  660. {
  661. _pSite = site;
  662. }
  663. W3_CONNECTION *
  664. QueryConnection(
  665. BOOL fCreateIfNotFound = TRUE
  666. );
  667. //
  668. // Retrieve context for specified/current state
  669. //
  670. W3_MAIN_CONTEXT_STATE *
  671. QueryContextState(
  672. DWORD contextState = -1
  673. )
  674. {
  675. if ( contextState == -1 )
  676. {
  677. contextState = _currentState;
  678. }
  679. return _rgStateContexts[ contextState ];
  680. }
  681. //
  682. // Set context for current state
  683. //
  684. VOID
  685. SetContextState(
  686. W3_MAIN_CONTEXT_STATE * pStateContext
  687. )
  688. {
  689. _rgStateContexts[ _currentState ] = pStateContext;
  690. }
  691. W3_CONNECTION_STATE *
  692. QueryConnectionState(
  693. VOID
  694. );
  695. VOID
  696. SetConnectionState(
  697. W3_CONNECTION_STATE * pConnectionState
  698. );
  699. HRESULT AppendIgnoreInterceptor(STRU &strName)
  700. {
  701. if (!_mszIgnoredInterceptors.Append(strName))
  702. {
  703. return HRESULT_FROM_WIN32(GetLastError());
  704. }
  705. return S_OK;
  706. }
  707. BOOL IsIgnoredInterceptor(STRU &strName)
  708. {
  709. return _mszIgnoredInterceptors.FindString(strName);
  710. }
  711. VOID SetDoneWithCompression()
  712. {
  713. _fDoneWithCompression = TRUE;
  714. }
  715. BOOL QueryDoneWithCompression()
  716. {
  717. return _fDoneWithCompression;
  718. }
  719. VOID SetCompressionContext(IN COMPRESSION_CONTEXT *pCompressionContext)
  720. {
  721. DBG_ASSERT(_pCompressionContext == NULL);
  722. _pCompressionContext = pCompressionContext;
  723. }
  724. COMPRESSION_CONTEXT *QueryCompressionContext()
  725. {
  726. return _pCompressionContext;
  727. }
  728. HTTP_LOG_FIELDS_DATA *QueryUlLogData()
  729. {
  730. return _LogContext.QueryUlLogData();
  731. }
  732. LOG_CONTEXT *QueryLogContext()
  733. {
  734. return &_LogContext;
  735. }
  736. HRESULT CollectLoggingData(BOOL fCollectForULLogging);
  737. void SetLastIOPending(LAST_IO_PENDING ioPending)
  738. {
  739. _LogContext.m_ioPending = ioPending;
  740. }
  741. LAST_IO_PENDING QueryLastIOPending()
  742. {
  743. return _LogContext.m_ioPending;
  744. }
  745. VOID IncrementBytesRecvd(DWORD dwRecvd)
  746. {
  747. _LogContext.m_dwBytesRecvd += dwRecvd;
  748. _cbEntityReadSoFar += dwRecvd;
  749. }
  750. VOID IncrementBytesSent(DWORD dwSent)
  751. {
  752. _LogContext.m_dwBytesSent += dwSent;
  753. }
  754. VOID SetInitialEntityReadSize(DWORD dwBytes)
  755. {
  756. _cbEntityReadSoFar = dwBytes;
  757. }
  758. DWORD QueryEntityReadSoFar()
  759. {
  760. return _cbEntityReadSoFar;
  761. }
  762. VOID
  763. DoWork(
  764. DWORD cbCompletion,
  765. DWORD dwCompletionStatus,
  766. BOOL fIoCompletion
  767. );
  768. BOOL
  769. SetupContext(
  770. HTTP_REQUEST * pUlHttpRequest,
  771. ULATQ_CONTEXT pUlAtqContext
  772. );
  773. VOID
  774. CleanupContext(
  775. VOID
  776. );
  777. VOID
  778. SetFinishedResponse(
  779. VOID
  780. )
  781. {
  782. _nextState = CONTEXT_STATE_RESPONSE;
  783. }
  784. VOID
  785. SetDone(
  786. VOID
  787. )
  788. {
  789. _nextState = CONTEXT_STATE_LOG;
  790. }
  791. VOID
  792. BackupStateMachine(
  793. VOID
  794. );
  795. HRESULT
  796. SetupCertificateContext(
  797. HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo
  798. );
  799. DWORD
  800. QueryCurrentStarScriptMapIndex(
  801. VOID
  802. )
  803. {
  804. return 0;
  805. }
  806. static
  807. HRESULT
  808. SetupStateMachine(
  809. VOID
  810. );
  811. static
  812. VOID
  813. CleanupStateMachine(
  814. VOID
  815. );
  816. static
  817. HRESULT
  818. Initialize(
  819. VOID
  820. );
  821. static
  822. VOID
  823. Terminate(
  824. VOID
  825. );
  826. static
  827. VOID
  828. AddressResolutionCallback(
  829. ADDRCHECKARG pContext,
  830. BOOL fUnused,
  831. LPSTR pszUnused
  832. );
  833. //
  834. // Completion routines called from ULATQ
  835. //
  836. static
  837. VOID
  838. OnIoCompletion(
  839. PVOID pvContext,
  840. DWORD cbWritten,
  841. DWORD dwCompletionStatus,
  842. OVERLAPPED * lpo
  843. );
  844. static
  845. VOID
  846. OnNewRequest(
  847. ULATQ_CONTEXT pContext
  848. );
  849. static
  850. VOID
  851. OnPostedCompletion(
  852. DWORD dwCompletionStatus,
  853. DWORD cbWritten,
  854. LPOVERLAPPED lpo
  855. );
  856. static
  857. VOID
  858. PostMainCompletion(
  859. CHAR * pszFileName,
  860. DWORD dwLineNumber,
  861. W3_MAIN_CONTEXT * pMainContext
  862. );
  863. W3_TRACE_LOG*
  864. QueryTraceLog(
  865. VOID
  866. )
  867. {
  868. return _pTraceLog;
  869. }
  870. };
  871. #define POST_MAIN_COMPLETION(x) \
  872. W3_MAIN_CONTEXT::PostMainCompletion( __FILE__, __LINE__, (x) )
  873. #endif