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.

627 lines
17 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: Request object
  6. File: Request.h
  7. Owner: CGrant, DGottner
  8. This file contains the header info for defining the Request object.
  9. Note: This was largely stolen from Kraig Brocjschmidt's Inside OLE2
  10. second edition, chapter 14 Beeper v5.
  11. ===================================================================*/
  12. #ifndef _Request_H
  13. #define _Request_H
  14. #include "debug.h"
  15. #include "util.h"
  16. #include "hashing.h"
  17. #include "dispatch.h"
  18. #include "strlist.h"
  19. #include "asptlb.h"
  20. #include "response.h"
  21. #include "memcls.h"
  22. #include "ftm.h"
  23. #ifdef USE_LOCALE
  24. extern DWORD g_dwTLS;
  25. #endif
  26. class CCookie;
  27. class CClCert;
  28. class CRequestHit;
  29. class CServVarsIterator;
  30. // Type for an object-destroyed callback
  31. typedef void (*PFNDESTROYED)(void);
  32. enum CollectionType {NONE, SERVERVARIABLE, QUERYSTRING, FORM, COOKIE, CLCERT };
  33. enum FormDataStatus {AVAILABLE, BINARYREADONLY, FORMCOLLECTIONONLY, ISTREAMONLY};
  34. class CRequest;
  35. #define NUM_REQUEST_HITS 32
  36. /*
  37. * C R e q u e s t H i t s A r r a y
  38. *
  39. * Base class for:
  40. * CQueryString
  41. * CFormInputs
  42. * CCookies
  43. * CClCerts
  44. *
  45. * Implements self-reallocating array of CRequestHit
  46. */
  47. class CRequestHitsArray
  48. {
  49. protected:
  50. DWORD m_dwCount; // How many Request hits there are
  51. DWORD m_dwHitMax; // Number of slots available to store Request hits
  52. CRequestHit** m_rgRequestHit; // Array of Request hits
  53. CRequestHitsArray();
  54. ~CRequestHitsArray();
  55. inline HRESULT Init()
  56. {
  57. m_dwCount = 0;
  58. m_dwHitMax = 0;
  59. m_rgRequestHit = NULL;
  60. return S_OK;
  61. }
  62. inline HRESULT ReInit()
  63. {
  64. m_dwCount = 0;
  65. return S_OK;
  66. }
  67. public:
  68. BOOL AddRequestHit(CRequestHit *pHit);
  69. };
  70. /*
  71. * C Q u e r y S t r i n g
  72. *
  73. * Implements the QueryString object (interface derived from IRequestDictionary)
  74. */
  75. class CQueryString : public IRequestDictionaryImpl, public CRequestHitsArray
  76. {
  77. private:
  78. IUnknown * m_punkOuter; // object to do ref count
  79. CRequest * m_pRequest; // pointer to parent object
  80. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  81. public:
  82. CQueryString(CRequest *, IUnknown *);
  83. // The Big Three
  84. STDMETHODIMP QueryInterface(const GUID &, void **);
  85. STDMETHODIMP_(ULONG) AddRef();
  86. STDMETHODIMP_(ULONG) Release();
  87. // OLE Automation Interface
  88. STDMETHODIMP get_Item(VARIANT varKey, VARIANT *pvarReturn);
  89. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  90. STDMETHODIMP get_Count(int *pcValues);
  91. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  92. HRESULT Init();
  93. HRESULT ReInit();
  94. ~CQueryString();
  95. };
  96. /*
  97. * C S e r v e r V a r i a b l e s
  98. *
  99. * Implements the ServerVariables object (interface derived from IRequestDictionary)
  100. */
  101. class CServerVariables : public IRequestDictionaryImpl
  102. {
  103. private:
  104. IUnknown * m_punkOuter; // object to do ref count
  105. CRequest * m_pRequest; // pointer to parent object
  106. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  107. CServVarsIterator * m_pIterator; // we use an iterator to support integer index
  108. public:
  109. CServerVariables(CRequest *, IUnknown *);
  110. HRESULT Init()
  111. {
  112. return S_OK;
  113. }
  114. // The Big Three
  115. STDMETHODIMP QueryInterface(const GUID &, void **);
  116. STDMETHODIMP_(ULONG) AddRef();
  117. STDMETHODIMP_(ULONG) Release();
  118. // OLE Automation Interface
  119. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  120. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  121. STDMETHODIMP get_Count(int *pcValues);
  122. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  123. // We've added a destructor, but didn't want to change the
  124. // order of the existing vtbl entries.
  125. ~CServerVariables();
  126. };
  127. /*
  128. * C F o r m I n p u t s
  129. *
  130. * Implements the Form object (interface derived from IRequestDictionary)
  131. */
  132. class CFormInputs : public IRequestDictionaryImpl, public CRequestHitsArray
  133. {
  134. private:
  135. IUnknown * m_punkOuter; // object to do ref count
  136. CRequest * m_pRequest; // pointer to parent object
  137. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  138. public:
  139. CFormInputs(CRequest *, IUnknown *);
  140. HRESULT Init();
  141. HRESULT ReInit();
  142. // The Big Three
  143. STDMETHODIMP QueryInterface(const GUID &, void **);
  144. STDMETHODIMP_(ULONG) AddRef();
  145. STDMETHODIMP_(ULONG) Release();
  146. // OLE Automation Interface
  147. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  148. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  149. STDMETHODIMP get_Count(int *pcValues);
  150. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  151. ~CFormInputs();
  152. };
  153. /*
  154. * C C o o k i e s
  155. *
  156. * Implements the Cookies object (interface derived from IRequestDictionary)
  157. */
  158. class CCookies : public IRequestDictionaryImpl, public CRequestHitsArray
  159. {
  160. friend CResponseCookies;
  161. private:
  162. IUnknown * m_punkOuter; // object to do ref count
  163. CRequest * m_pRequest; // pointer to parent object
  164. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  165. CCookie * m_pEmptyCookie; // for when the cookie is not there
  166. public:
  167. CCookies(CRequest *, IUnknown *);
  168. ~CCookies();
  169. HRESULT Init();
  170. HRESULT ReInit();
  171. // The Big Three
  172. STDMETHODIMP QueryInterface(const GUID &, void **);
  173. STDMETHODIMP_(ULONG) AddRef();
  174. STDMETHODIMP_(ULONG) Release();
  175. // OLE Automation Interface
  176. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  177. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  178. STDMETHODIMP get_Count(int *pcValues);
  179. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  180. };
  181. /*
  182. * C C l C e r t s
  183. *
  184. * Implements the ClCerts object (interface derived from IRequestDictionary)
  185. */
  186. class CClCerts : public IRequestDictionaryImpl, public CRequestHitsArray
  187. {
  188. private:
  189. IUnknown * m_punkOuter; // object to do ref count
  190. CRequest * m_pRequest; // pointer to parent object
  191. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  192. CClCert * m_pEmptyClCert; // for when the clcert is not there
  193. public:
  194. CClCerts(CRequest *, IUnknown *);
  195. ~CClCerts();
  196. HRESULT Init();
  197. HRESULT ReInit();
  198. // The Big Three
  199. STDMETHODIMP QueryInterface(const GUID &, void **);
  200. STDMETHODIMP_(ULONG) AddRef();
  201. STDMETHODIMP_(ULONG) Release();
  202. // OLE Automation Interface
  203. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  204. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  205. STDMETHODIMP get_Count(int *pcValues);
  206. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  207. };
  208. /*
  209. * C R e q u e s t H i t
  210. *
  211. * Implements the RequestHit object
  212. */
  213. class CRequestHit : private CLinkElem
  214. {
  215. friend class CRequest;
  216. friend class CRequestData;
  217. friend class CQueryString;
  218. friend class CFormInputs;
  219. friend class CCookies;
  220. friend class CClCerts;
  221. friend class CCertRequest;
  222. friend class CResponseCookies;
  223. friend class CRequestIterator;
  224. private:
  225. BOOL m_fInited:1;
  226. BOOL m_fDuplicate:1;
  227. CStringList *m_pQueryData, *m_pFormData;
  228. CCookie *m_pCookieData;
  229. CClCert *m_pClCertData;
  230. public:
  231. CRequestHit();
  232. ~CRequestHit();
  233. HRESULT Init(char *szName, BOOL fDuplicate = FALSE);
  234. HRESULT AddValue(CollectionType source, char *szValue, CIsapiReqInfo *, UINT lCodePage);
  235. HRESULT AddCertValue(VARENUM ve, LPBYTE pValue, UINT cLen );
  236. HRESULT AddKeyAndValue(CollectionType source, char *szKey, char *szValue, CIsapiReqInfo *, UINT lCodePage);
  237. // Cache on per-class basis
  238. ACACHE_INCLASS_DEFINITIONS()
  239. };
  240. /*
  241. * C R e q u e s t D a t a
  242. *
  243. * Structure that holds the intrinsic's properties.
  244. * The instrinsic keeps pointer to it (NULL when lightweight)
  245. */
  246. class CRequestData : public IUnknown
  247. {
  248. friend class CRequest;
  249. friend class CResponse;
  250. friend class CQueryString;
  251. friend class CServerVariables;
  252. friend class CFormInputs;
  253. friend class CCookies;
  254. friend class CClCerts;
  255. friend class CResponseCookies;
  256. friend class CRequestIterator;
  257. friend class CCertRequest;
  258. private:
  259. // constructor to pass params to members and init members
  260. CRequestData(CRequest *pRequest);
  261. ~CRequestData();
  262. HRESULT Init();
  263. HRESULT ReInit(CIsapiReqInfo *pIReq, CHitObj *pHitObj);
  264. HRESULT GetEmptyStringList(IDispatch **ppdisp);
  265. CSupportErrorInfo m_ISupportErrImp; // Implementation of ISupportErrorInfo for this object
  266. CIsapiReqInfo * m_pIReq; // CIsapiReqInfo block for HTTP info
  267. CHitObj * m_pHitObj; // pointer to hitobj for this request
  268. CHashTableMBStr m_mpszStrings; // map sz's to string lists
  269. BOOL m_fLoadForm:1; // do we need to load the body?
  270. BOOL m_fLoadQuery:1; // do we need to load QueryString?
  271. BOOL m_fLoadCookies:1; // do we need to load Cookies?
  272. BOOL m_fLoadClCerts:1; // do we need to load ClCerts?
  273. FormDataStatus m_FormDataStatus; // Is form data available for BinaryRead or Form Collection?
  274. BYTE * m_pbAvailableData; // pointer to available data in CIsapiReqInfo
  275. size_t m_cbAvailable; // number of bytes available in CIsapiReqInfo
  276. size_t m_cbTotal; // Total number of bytes remaining in request
  277. char * m_szFormData; // pointer to form data (allocted or CIsapiReqInfo)
  278. size_t m_cbFormData; // number of bytes allocated for form data
  279. char * m_szFormClone; // clone of form data (LoadVariables clobbers)
  280. char * m_szCookie; // clone of cookie data (this one gets trashed)
  281. size_t m_cbCookie; // number of bytes allocated for the cookie data
  282. char * m_szClCert; // clone of clcert data (this one gets trashed)
  283. size_t m_cbClCert; // number of bytes allocated for the clcert data
  284. char * m_szQueryString; // query string data
  285. CStringList * m_pEmptyString; // all empty results share the same object
  286. CQueryString m_QueryString; // pointer to the "QueryString" object
  287. CServerVariables m_ServerVariables; // pointer to the "ServerVariables" object
  288. CFormInputs m_FormInputs; // pointer to the "Form" object
  289. CCookies m_Cookies; // pointer to the "Cookies" object
  290. CClCerts m_ClCerts; // pointer to the "ClCert" object
  291. ULONG m_cRefs; // ref count
  292. public:
  293. STDMETHODIMP QueryInterface(const GUID &, void **);
  294. STDMETHODIMP_(ULONG) AddRef();
  295. STDMETHODIMP_(ULONG) Release();
  296. // Cache on per-class basis
  297. ACACHE_INCLASS_DEFINITIONS()
  298. };
  299. /*
  300. * C R e q u e s t
  301. *
  302. * Implements the Request object
  303. */
  304. class CRequest : public IRequestImpl, public CFTMImplementation, public IStream
  305. {
  306. friend class CQueryString;
  307. friend class CServerVariables;
  308. friend class CFormInputs;
  309. friend class CCookies;
  310. friend class CClCerts;
  311. friend class CResponseCookies;
  312. friend class CRequestIterator;
  313. friend class CCertRequest;
  314. private:
  315. // Flags
  316. DWORD m_fInited : 1; // Is initialized?
  317. DWORD m_fDiagnostics : 1; // Display ref count in debug output
  318. DWORD m_fOuterUnknown : 1; // Ref count outer unknown?
  319. // Ref count / Outer unknown
  320. union
  321. {
  322. DWORD m_cRefs;
  323. IUnknown *m_punkOuter;
  324. };
  325. // Properties
  326. CRequestData *m_pData; // pointer to structure that holds
  327. // CRequest properties
  328. UINT GetCodePage();
  329. HRESULT LoadVariables(CollectionType Source, char *szURL, UINT lCodePage);
  330. HRESULT LoadCookies(char *szCookies);
  331. HRESULT LoadClCerts(char *szClCerts, UINT lCodePage);
  332. HRESULT LoadCertList( LPSTR pszPrefix, LPSTR* pszCertList);
  333. HRESULT CopyClientData();
  334. HRESULT GetRequestEnumerator(CollectionType, IUnknown **ppEnumReturn);
  335. // Added support for chunked Transfer in Request.form
  336. HRESULT CopyChunkedClientData();
  337. HRESULT CopyNonChunkedClientData();
  338. #ifdef DBG
  339. inline void TurnDiagsOn() { m_fDiagnostics = TRUE; }
  340. inline void TurnDiagsOff() { m_fDiagnostics = FALSE; }
  341. void AssertValid() const;
  342. #else
  343. inline void TurnDiagsOn() {}
  344. inline void TurnDiagsOff() {}
  345. inline void AssertValid() const {}
  346. #endif
  347. public:
  348. CRequest(IUnknown *punkOuter = NULL);
  349. ~CRequest();
  350. HRESULT CleanUp();
  351. HRESULT Init();
  352. HRESULT UnInit();
  353. HRESULT ReInit(CIsapiReqInfo *pIReq, CHitObj *pHitObj);
  354. inline CIsapiReqInfo *GetIReq()
  355. {
  356. Assert(m_fInited);
  357. Assert(m_pData);
  358. return m_pData->m_pIReq;
  359. }
  360. inline CLinkElem* CertStoreFindElem(LPSTR pV, int cV)
  361. {
  362. Assert(m_fInited);
  363. Assert(m_pData);
  364. return m_pData->m_mpszStrings.FindElem( pV, cV );
  365. }
  366. inline CLinkElem* CertStoreAddElem(CLinkElem* pH)
  367. {
  368. Assert(m_fInited);
  369. Assert(m_pData);
  370. return m_pData->m_mpszStrings.AddElem( pH );
  371. }
  372. inline LPSTR GetCertStoreBuf()
  373. {
  374. Assert(m_fInited);
  375. Assert(m_pData);
  376. return m_pData->m_szClCert;
  377. }
  378. inline size_t GetCertStoreSize()
  379. {
  380. Assert(m_fInited);
  381. Assert(m_pData);
  382. return m_pData->m_cbClCert;
  383. }
  384. inline void SetCertStore(LPSTR p, size_t s)
  385. {
  386. Assert(m_fInited);
  387. Assert(m_pData);
  388. m_pData->m_szClCert = p;
  389. m_pData->m_cbClCert = s;
  390. }
  391. inline CHashTable *GetStrings()
  392. {
  393. Assert(m_fInited);
  394. Assert(m_pData);
  395. return &(m_pData->m_mpszStrings);
  396. }
  397. // Non-delegating object IUnknown
  398. //
  399. STDMETHODIMP QueryInterface(const IID &Iid, void **ppvObj);
  400. STDMETHODIMP_(ULONG) AddRef();
  401. STDMETHODIMP_(ULONG) Release();
  402. // Tombstone stub
  403. HRESULT CheckForTombstone();
  404. // IRequest functions
  405. //
  406. STDMETHODIMP get_Item(BSTR bstrVar, IDispatch **ppDispReturn);
  407. STDMETHODIMP get_QueryString(IRequestDictionary **ppDictReturn);
  408. STDMETHODIMP get_Form(IRequestDictionary **ppDictReturn);
  409. STDMETHODIMP get_Body(IRequestDictionary **ppDictReturn);
  410. STDMETHODIMP get_ServerVariables(IRequestDictionary **ppDictReturn);
  411. STDMETHODIMP get_ClientCertificate(IRequestDictionary **ppDictReturn);
  412. STDMETHODIMP get_Cookies(IRequestDictionary **ppDictReturn);
  413. STDMETHODIMP get_TotalBytes(long *pcbTotal);
  414. STDMETHODIMP BinaryRead(VARIANT *pvarCount, VARIANT *pvarReturn);
  415. // IStream implementation
  416. STDMETHODIMP Read(void *pv, ULONG cb, ULONG *pcbRead);
  417. STDMETHODIMP Write(const void *pv, ULONG cb, ULONG *pcbWritten);
  418. STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
  419. ULARGE_INTEGER *plibNewPosition);
  420. STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize);
  421. STDMETHODIMP CopyTo(IStream *pstm, ULARGE_INTEGER cb,
  422. ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
  423. STDMETHODIMP Commit(DWORD grfCommitFlags);
  424. STDMETHODIMP Revert();
  425. STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  426. DWORD dwLockType);
  427. STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  428. DWORD dwLockType);
  429. STDMETHODIMP Stat(STATSTG *pstatstg, DWORD grfStatFlag);
  430. STDMETHODIMP Clone(IStream **ppstm);
  431. // Cache on per-class basis
  432. ACACHE_INCLASS_DEFINITIONS()
  433. };
  434. /*===================================================================
  435. ITERATORS:
  436. There are two iterators used for Request - a general purpose
  437. iterator which will iterate through the keys of Cookies, QueryString,
  438. Form. A special iterator is used for ServerVariables
  439. ===================================================================*/
  440. /*
  441. * C S e r v V a r s I t e r a t o r
  442. *
  443. * IEnumVariant implementation for Request.ServerVariables
  444. */
  445. class CServVarsIterator : public IEnumVARIANT
  446. {
  447. friend CServerVariables;
  448. public:
  449. CServVarsIterator();
  450. ~CServVarsIterator();
  451. HRESULT Init(CIsapiReqInfo *pIReq);
  452. // The Big Three
  453. STDMETHODIMP QueryInterface(const GUID &, void **);
  454. STDMETHODIMP_(ULONG) AddRef();
  455. STDMETHODIMP_(ULONG) Release();
  456. // standard methods for iterators
  457. STDMETHODIMP Clone(IEnumVARIANT **ppEnumReturn);
  458. STDMETHODIMP Next(unsigned long cElements, VARIANT *rgVariant, unsigned long *pcElementsFetched);
  459. STDMETHODIMP Skip(unsigned long cElements);
  460. STDMETHODIMP Reset();
  461. private:
  462. ULONG m_cRefs; // reference count
  463. wchar_t **m_rgwszKeys; // array of ISAPI keys
  464. wchar_t **m_pwszKey; // current key in gm_rgwszKeys
  465. wchar_t *m_pwchAllHttp; // extra keys in ALL_HTTP server variable
  466. ULONG m_cKeys; // total number of keys
  467. void CreateKeys(wchar_t *pwchKeys, int *pcwchAlloc, int *pcRequestHeaders);
  468. };
  469. /*
  470. * C R e q u e s t I t e r a t o r
  471. *
  472. * IEnumVariant implementation for all Request collections except
  473. * ServerVariables
  474. */
  475. class CRequestIterator : public IEnumVARIANT
  476. {
  477. public:
  478. CRequestIterator(CRequest *, CollectionType);
  479. ~CRequestIterator();
  480. HRESULT Init();
  481. // The Big Three
  482. STDMETHODIMP QueryInterface(const GUID &, void **);
  483. STDMETHODIMP_(ULONG) AddRef();
  484. STDMETHODIMP_(ULONG) Release();
  485. // standard methods for iterators
  486. STDMETHODIMP Clone(IEnumVARIANT **ppEnumReturn);
  487. STDMETHODIMP Next(unsigned long cElements, VARIANT *rgVariant, unsigned long *pcElementsFetched);
  488. STDMETHODIMP Skip(unsigned long cElements);
  489. STDMETHODIMP Reset();
  490. private:
  491. ULONG m_cRefs; // reference count
  492. CollectionType m_Collection; // which collection to iterate over?
  493. CRequest *m_pRequest; // pointer to the request object
  494. CRequestHit *m_pRequestHit; // current bookmark for iteration
  495. };
  496. BOOL RequestSupportInit();
  497. VOID RequestSupportTerminate();
  498. #endif //_Request_H