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.

501 lines
16 KiB

  1. /*
  2. * HttpRequest.hxx
  3. *
  4. * WinHttp HttpRequest COM component
  5. *
  6. * Copyright (C) 2000 Microsoft Corporation. All rights reserved. *
  7. *
  8. *
  9. */
  10. #ifndef _HTTPREQUEST_HXX_
  11. #define _HTTPREQUEST_HXX_
  12. #include <httprequest.h>
  13. #include <httprequestid.h>
  14. #include <ocidl.h>
  15. typedef INTERNETAPI WINHTTP_STATUS_CALLBACK InternetSetStatusCallbackFunc(
  16. IN HINTERNET hInternet,
  17. IN WINHTTP_STATUS_CALLBACK lpfnInternetCallback
  18. );
  19. #define WINHTTP_DEFAULT_USER_AGENT L"Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)"
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CClassFactory for CHttpRequest
  22. class CClassFactory : public IClassFactory
  23. {
  24. public:
  25. //---------------------------------------------------------------
  26. // IUnknown methods.
  27. //---------------------------------------------------------------
  28. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  29. STDMETHOD_(ULONG, AddRef)();
  30. STDMETHOD_(ULONG, Release)();
  31. //---------------------------------------------------------------
  32. // IClassFactory methods.
  33. //---------------------------------------------------------------
  34. STDMETHOD(CreateInstance)(IUnknown * pUnkOuter, REFIID riid, void ** ppv);
  35. STDMETHOD(LockServer)(BOOL fLock);
  36. CClassFactory();
  37. private:
  38. long _cRefs;
  39. };
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CSinkArray
  42. class CSinkArray : public IWinHttpRequestEvents
  43. {
  44. public:
  45. CSinkArray()
  46. {
  47. _nSize = 0;
  48. _ppUnk = NULL;
  49. }
  50. ~CSinkArray()
  51. {
  52. if (_nSize > 1)
  53. FREE_FIXED_MEMORY(_ppUnk);
  54. }
  55. DWORD Add(IUnknown* pUnk);
  56. BOOL Remove(DWORD dwCookie);
  57. void ReleaseAll();
  58. IUnknown * GetUnknown(DWORD dwCookie)
  59. {
  60. ULONG iIndex;
  61. if (dwCookie == 0)
  62. return NULL;
  63. iIndex = dwCookie-1;
  64. return begin()[iIndex];
  65. }
  66. IUnknown ** begin()
  67. {
  68. return (_nSize < 2) ? &_pUnk : _ppUnk;
  69. }
  70. IUnknown ** end()
  71. {
  72. return (_nSize < 2) ? (&_pUnk)+_nSize : &_ppUnk[_nSize];
  73. }
  74. //---------------------------------------------------------------
  75. // IUnknown methods.
  76. //---------------------------------------------------------------
  77. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  78. STDMETHOD_(ULONG, AddRef)();
  79. STDMETHOD_(ULONG, Release)();
  80. //---------------------------------------------------------------
  81. // IWinHttpRequestEvents
  82. //---------------------------------------------------------------
  83. // These could fail when out of memory
  84. STDMETHOD_(void, OnResponseStart)(long Status, BSTR ContentType);
  85. STDMETHOD_(void, OnResponseDataAvailable)(SAFEARRAY ** Data);
  86. STDMETHOD_(void, OnResponseFinished)();
  87. STDMETHOD_(void, OnError)(long ErrorNumber, BSTR ErrorDescription);
  88. protected:
  89. union
  90. {
  91. IUnknown ** _ppUnk;
  92. IUnknown * _pUnk;
  93. };
  94. int _nSize;
  95. };
  96. #define _DEFAULT_VECTORLENGTH 4
  97. /////////////////////////////////////////////////////////////////////////////
  98. // CWinHttpRequestEventsMarshaller
  99. class CWinHttpRequestEventsMarshaller : public IWinHttpRequestEvents
  100. {
  101. CSinkArray * _pSinkArray;
  102. HWND _hWnd;
  103. long _cRefs;
  104. bool _bFireEvents;
  105. CCritSec _cs;
  106. public:
  107. CWinHttpRequestEventsMarshaller(CSinkArray * pSinkArray, HWND hWnd);
  108. ~CWinHttpRequestEventsMarshaller();
  109. //---------------------------------------------------------------
  110. // IUnknown methods.
  111. //---------------------------------------------------------------
  112. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  113. STDMETHOD_(ULONG, AddRef)();
  114. STDMETHOD_(ULONG, Release)();
  115. //---------------------------------------------------------------
  116. // IWinHttpRequestEvents
  117. //---------------------------------------------------------------
  118. STDMETHOD_(void, OnResponseStart)(long Status, BSTR bstrContentType);
  119. STDMETHOD_(void, OnResponseDataAvailable)(SAFEARRAY ** Data);
  120. STDMETHOD_(void, OnResponseFinished)();
  121. STDMETHOD_(void, OnError)(long ErrorNumber, BSTR ErrorDescription);
  122. CSinkArray * GetSinkArray() const
  123. {
  124. return _pSinkArray;
  125. }
  126. static HRESULT Create(CSinkArray * pSinkArray,
  127. CWinHttpRequestEventsMarshaller ** ppSinkMarshaller);
  128. static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  129. void Shutdown();
  130. void FreezeEvents()
  131. {
  132. _bFireEvents = false;
  133. }
  134. void UnfreezeEvents()
  135. {
  136. _bFireEvents = true;
  137. }
  138. bool OkToFireEvents() const
  139. {
  140. return _bFireEvents;
  141. }
  142. };
  143. #define WHREM_MSG_ON_RESPONSE_START (WM_USER + 1)
  144. #define WHREM_MSG_ON_RESPONSE_DATA_AVAILABLE (WM_USER + 2)
  145. #define WHREM_MSG_ON_RESPONSE_FINISHED (WM_USER + 3)
  146. #define WHREM_MSG_ON_ERROR (WM_USER + 4)
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CHttpRequest
  149. class CHttpRequest : public IWinHttpRequest,
  150. public ISupportErrorInfo,
  151. public IProvideClassInfo2,
  152. public IConnectionPointContainer
  153. {
  154. public:
  155. CHttpRequest();
  156. ~CHttpRequest();
  157. #if !defined(TRUE_ASYNC)
  158. DWORD SendAsync();
  159. #endif//!TRUE_ASYNC
  160. inline LPCWSTR GetUserAgentString() const
  161. {
  162. return (_bstrUserAgent != NULL) ?
  163. _bstrUserAgent :
  164. WINHTTP_DEFAULT_USER_AGENT;
  165. }
  166. //---------------------------------------------------------------
  167. // IUnknown methods.
  168. //---------------------------------------------------------------
  169. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  170. STDMETHOD_(ULONG, AddRef)();
  171. STDMETHOD_(ULONG, Release)();
  172. //---------------------------------------------------------------
  173. // IDispatch methods.
  174. //---------------------------------------------------------------
  175. STDMETHOD(GetTypeInfoCount)(UINT * pctinfo);
  176. STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo);
  177. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR * rgszNames,
  178. UINT cNames,
  179. LCID lcid,
  180. DISPID * rgDispId);
  181. STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid,
  182. WORD wFlags,
  183. DISPPARAMS * pDispParams,
  184. VARIANT * pVarResult,
  185. EXCEPINFO * pExcepInfo,
  186. UINT * puArgErr);
  187. //---------------------------------------------------------------
  188. // IWinHttpRequest methods.
  189. //---------------------------------------------------------------
  190. STDMETHOD(SetProxy)(HTTPREQUEST_PROXY_SETTING ProxySetting,
  191. VARIANT varProxyServer,
  192. VARIANT varBypassList);
  193. STDMETHOD(SetCredentials)(BSTR bstrUserName,
  194. BSTR bstrPassword,
  195. HTTPREQUEST_SETCREDENTIALS_FLAGS Flags);
  196. STDMETHOD(Open)(BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync);
  197. STDMETHOD(SetRequestHeader)(BSTR bstrHeader, BSTR bstrValue);
  198. STDMETHOD(GetResponseHeader)(BSTR bstrHeader, BSTR * pbstrValue);
  199. STDMETHOD(GetAllResponseHeaders)(BSTR * pbstrHeaders);
  200. STDMETHOD(Send)(VARIANT varBody);
  201. STDMETHOD(get_Status)(long * plStatus);
  202. STDMETHOD(get_StatusText)(BSTR * pbstrStatus);
  203. STDMETHOD(get_ResponseText)(BSTR * pbstrBody);
  204. STDMETHOD(get_ResponseBody)(VARIANT * pvarBody);
  205. STDMETHOD(get_ResponseStream)(VARIANT * pvarBody);
  206. STDMETHOD(get_Option)(WinHttpRequestOption Option, VARIANT * Value);
  207. STDMETHOD(put_Option)(WinHttpRequestOption Option, VARIANT Value);
  208. STDMETHOD(WaitForResponse)(VARIANT Timeout, VARIANT_BOOL * pboolSucceeded);
  209. STDMETHOD(Abort)();
  210. STDMETHOD(SetTimeouts)(long ResolveTimeout, long ConnectTimeout, long SendTimeout, long ReceiveTimeout);
  211. STDMETHOD(SetClientCertificate)(BSTR ClientCertificate);
  212. STDMETHOD(SetAutoLogonPolicy)(WinHttpRequestAutoLogonPolicy AutoLogonPolicy);
  213. //---------------------------------------------------------------
  214. // ISupportErrorInfo methods.
  215. //---------------------------------------------------------------
  216. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  217. //---------------------------------------------------------------
  218. // IProvideClassInfo methods.
  219. //---------------------------------------------------------------
  220. STDMETHOD(GetClassInfo)(ITypeInfo ** ppTI);
  221. //---------------------------------------------------------------
  222. // IProvideClassInfo2 methods.
  223. //---------------------------------------------------------------
  224. STDMETHOD(GetGUID)(DWORD dwGuidKind, GUID * pGUID);
  225. //---------------------------------------------------------------
  226. // IConnectionPointContainer methods.
  227. //---------------------------------------------------------------
  228. STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints ** ppEnum);
  229. STDMETHOD(FindConnectionPoint)(REFIID riid, IConnectionPoint ** ppCP);
  230. class CHttpRequestEventsCP : public IConnectionPoint
  231. {
  232. public:
  233. CSinkArray _SinkArray;
  234. CWinHttpRequestEventsMarshaller * _pSinkMarshaller;
  235. DWORD _cConnections;
  236. BOOL _bOnErrorDisabled;
  237. //---------------------------------------------------------------
  238. // IUnknown methods.
  239. //---------------------------------------------------------------
  240. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  241. STDMETHOD_(ULONG, AddRef)();
  242. STDMETHOD_(ULONG, Release)();
  243. //---------------------------------------------------------------
  244. // IConnectionPoint methods.
  245. //---------------------------------------------------------------
  246. STDMETHOD(GetConnectionInterface)(IID * pIID);
  247. STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer ** ppCPC);
  248. STDMETHOD(Advise)(IUnknown * pUnk, DWORD * pdwCookie);
  249. STDMETHOD(Unadvise)(DWORD dwCookie);
  250. STDMETHOD(EnumConnections)(IEnumConnections **);
  251. inline CHttpRequest * Px() const
  252. {
  253. return (CHttpRequest *)((BYTE *)this - offsetof(CHttpRequest, _CP));
  254. }
  255. void FireOnResponseStart(long Status, BSTR ContentType);
  256. void FireOnResponseDataAvailable(const BYTE * rgbData, DWORD cbData);
  257. void FireOnResponseFinished();
  258. void FireOnError(HRESULT hr);
  259. CHttpRequestEventsCP()
  260. {
  261. _cConnections = 0;
  262. _pSinkMarshaller = NULL;
  263. _bOnErrorDisabled = FALSE;
  264. }
  265. ~CHttpRequestEventsCP();
  266. inline IWinHttpRequestEvents * GetSink()
  267. {
  268. return (_pSinkMarshaller == NULL) ?
  269. static_cast<IWinHttpRequestEvents *>(&_SinkArray)
  270. : static_cast<IWinHttpRequestEvents *>(_pSinkMarshaller);
  271. }
  272. inline void DisableOnError() { _bOnErrorDisabled = TRUE; }
  273. HRESULT CreateEventSinksMarshaller();
  274. void ShutdownEventSinksMarshaller();
  275. void ReleaseEventSinksMarshaller();
  276. void FreezeEvents();
  277. void UnfreezeEvents();
  278. };
  279. friend class CHttpRequestEventsCP;
  280. private:
  281. enum State
  282. {
  283. CREATED = 0,
  284. OPENED = 1,
  285. SENDING = 2,
  286. SENT = 3,
  287. RECEIVING = 4,
  288. RESPONSE = 5
  289. };
  290. long _cRefs;
  291. IUnknown * _pUnkSite;
  292. ITypeInfo * _pTypeInfo;
  293. BSTR _bstrUserAgent;
  294. DWORD _dwProxySetting;
  295. BSTR _bstrProxyServer;
  296. BSTR _bstrBypassList;
  297. State _eState;
  298. HINTERNET _hInet;
  299. HINTERNET _hConnection;
  300. HINTERNET _hHTTP;
  301. DWORD _ResolveTimeout;
  302. DWORD _ConnectTimeout;
  303. DWORD _SendTimeout;
  304. DWORD _ReceiveTimeout;
  305. BOOL _fAsync;
  306. #ifdef TRUE_ASYNC
  307. DWORD _dwNumberOfBytesAvailable;
  308. DWORD _cbNumberOfBytesRead;
  309. HANDLE _hCompleteEvent;
  310. BOOL _bRetriedWithCert;
  311. DWORD _dwContentLength;
  312. BYTE * _Buffer;
  313. #else
  314. HANDLE _hWorkerThread;
  315. #endif
  316. DWORD _cRefsOnMainThread;
  317. DWORD _dwMainThreadId;
  318. HRESULT _hrAsyncResult;
  319. void * _hAbortedConnectObject;
  320. void * _hAbortedRequestObject;
  321. bool _bAborted;
  322. bool _bSetTimeouts;
  323. bool _bSetUtf8Charset;
  324. DWORD _dwCodePage;
  325. DWORD _dwEscapeFlag;
  326. DWORD _cbRequestBody;
  327. char * _szRequestBuffer;
  328. DWORD _cbResponseBody;
  329. IStream * _pResponseStream;
  330. BOOL _fCheckForRevocation;
  331. DWORD _dwSslIgnoreFlags;
  332. BOOL _fCertLocalMachine;
  333. BSTR _bstrCertStore;
  334. BSTR _bstrCertSubject;
  335. DWORD _dwSecureProtocols;
  336. HRESULT _hrSecureFailure;
  337. BOOL _bEnableSslImpersonation;
  338. BOOL _bMethodGET;
  339. BOOL _bHttp1_1Mode;
  340. DWORD _dwAutoLogonPolicy;
  341. DWORD _dwRedirectPolicy;
  342. LONG _lMaxAutomaticRedirects;
  343. LONG _lMaxResponseHeaderSize;
  344. LONG _lMaxResponseDrainSize;
  345. DWORD _dwPassportConfig;
  346. CHttpRequestEventsCP _CP;
  347. void Initialize();
  348. void ReleaseResources();
  349. void Recycle();
  350. void Reset();
  351. HRESULT GetHttpRequestTypeInfo(REFGUID guid, ITypeInfo ** ppTypeInfo);
  352. HRESULT ReadResponse();
  353. HRESULT SetRequiredRequestHeaders();
  354. HRESULT SetRequestBody(VARIANT varBody);
  355. void SetState(State state);
  356. HRESULT CreateStreamOnResponse(IStream ** ppStm);
  357. #if !defined(TRUE_ASYNC)
  358. HRESULT _GetResponseHeader(OLECHAR * wszHeader, BSTR * pbstrValue);
  359. HRESULT CreateAsyncWorkerThread();
  360. #else
  361. HRESULT _GetResponseHeader(OLECHAR * wszHeader, BSTR * pbstrValue);
  362. static HRESULT _GetResponseHeader2(OLECHAR * wszHeader, BSTR * pbstrValue, HINTERNET hInternet);
  363. #endif//!TRUE_ASYNC
  364. static IErrorInfo * CreateErrorObject(HRESULT hr);
  365. static void SetErrorInfo(HRESULT hr);
  366. BOOL SelectCertificate();
  367. #ifdef TRUE_ASYNC
  368. HRESULT StartAsyncSend();
  369. HRESULT PrepareToReadData(HINTERNET);
  370. void CompleteDataRead(bool bNotAborted, HINTERNET);
  371. static void CALLBACK AsyncCallback(HINTERNET hInternet,
  372. DWORD_PTR dwContext,
  373. DWORD dwInternetStatus,
  374. LPVOID lpvStatusInformation,
  375. DWORD dwStatusInformationLength);
  376. #endif//TRUE_ASYNC
  377. static void CALLBACK SyncCallback(HINTERNET hInternet,
  378. DWORD_PTR dwContext,
  379. DWORD dwInternetStatus,
  380. LPVOID lpvStatusInformation,
  381. DWORD dwStatusInformationLength);
  382. };
  383. /////////////////////////////////////////////////////////////////////////////
  384. // function prototypes
  385. STDMETHODIMP
  386. CreateHttpRequest(REFIID riid, void ** ppvObject);
  387. #ifdef WINHTTP_STATIC_LIBRARY
  388. STDAPI WinHttpCreateHttpRequestComponent(REFIID riid, void ** ppvObject);
  389. #endif
  390. BOOLAPI WinHttpCheckPlatform(void);
  391. BOOL RegisterWinHttpEventMarshallerWndClass();
  392. void CleanupWinHttpRequestGlobals();
  393. #endif //_HTTPREQUEST_HXX_