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.

438 lines
13 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 bstrContentType);
  85. STDMETHOD_(void, OnResponseDataAvailable)(SAFEARRAY ** Data);
  86. STDMETHOD_(void, OnResponseFinished)();
  87. protected:
  88. union
  89. {
  90. IUnknown ** _ppUnk;
  91. IUnknown * _pUnk;
  92. };
  93. int _nSize;
  94. };
  95. #define _DEFAULT_VECTORLENGTH 4
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CWinHttpRequestEventsMarshaller
  98. class CWinHttpRequestEventsMarshaller : public IWinHttpRequestEvents
  99. {
  100. CSinkArray * _pSinkArray;
  101. HWND _hWnd;
  102. long _cRefs;
  103. bool _bFireEvents;
  104. CCritSec _cs;
  105. public:
  106. CWinHttpRequestEventsMarshaller(CSinkArray * pSinkArray, HWND hWnd);
  107. ~CWinHttpRequestEventsMarshaller();
  108. //---------------------------------------------------------------
  109. // IUnknown methods.
  110. //---------------------------------------------------------------
  111. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  112. STDMETHOD_(ULONG, AddRef)();
  113. STDMETHOD_(ULONG, Release)();
  114. //---------------------------------------------------------------
  115. // IWinHttpRequestEvents
  116. //---------------------------------------------------------------
  117. STDMETHOD_(void, OnResponseStart)(long Status, BSTR bstrContentType);
  118. STDMETHOD_(void, OnResponseDataAvailable)(SAFEARRAY ** Data);
  119. STDMETHOD_(void, OnResponseFinished)();
  120. CSinkArray * GetSinkArray()
  121. {
  122. return _pSinkArray;
  123. }
  124. static HRESULT Create(CSinkArray * pSinkArray,
  125. CWinHttpRequestEventsMarshaller ** ppSinkMarshaller);
  126. static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  127. void Shutdown();
  128. void FreezeEvents()
  129. {
  130. _bFireEvents = false;
  131. }
  132. void UnfreezeEvents()
  133. {
  134. _bFireEvents = true;
  135. }
  136. bool OkToFireEvents()
  137. {
  138. return _bFireEvents;
  139. }
  140. };
  141. #define WHREM_MSG_ON_RESPONSE_START (WM_USER + 1)
  142. #define WHREM_MSG_ON_RESPONSE_DATA_AVAILABLE (WM_USER + 2)
  143. #define WHREM_MSG_ON_RESPONSE_FINISHED (WM_USER + 3)
  144. /////////////////////////////////////////////////////////////////////////////
  145. // CHttpRequest
  146. class CHttpRequest : public IWinHttpRequest,
  147. public IProvideClassInfo2,
  148. public IConnectionPointContainer
  149. {
  150. public:
  151. CHttpRequest();
  152. ~CHttpRequest();
  153. DWORD SendAsync();
  154. inline LPCWSTR GetUserAgentString() const
  155. {
  156. return (_bstrUserAgent != NULL) ?
  157. _bstrUserAgent :
  158. WINHTTP_DEFAULT_USER_AGENT;
  159. }
  160. //---------------------------------------------------------------
  161. // IUnknown methods.
  162. //---------------------------------------------------------------
  163. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  164. STDMETHOD_(ULONG, AddRef)();
  165. STDMETHOD_(ULONG, Release)();
  166. //---------------------------------------------------------------
  167. // IDispatch methods.
  168. //---------------------------------------------------------------
  169. STDMETHOD(GetTypeInfoCount)(UINT * pctinfo);
  170. STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo);
  171. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR * rgszNames,
  172. UINT cNames,
  173. LCID lcid,
  174. DISPID * rgDispId);
  175. STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid,
  176. WORD wFlags,
  177. DISPPARAMS * pDispParams,
  178. VARIANT * pVarResult,
  179. EXCEPINFO * pExcepInfo,
  180. UINT * puArgErr);
  181. //---------------------------------------------------------------
  182. // IWinHttpRequest methods.
  183. //---------------------------------------------------------------
  184. STDMETHOD(SetProxy)(HTTPREQUEST_PROXY_SETTING ProxySetting,
  185. VARIANT varProxyServer,
  186. VARIANT varBypassList);
  187. STDMETHOD(SetCredentials)(BSTR bstrUserName,
  188. BSTR bstrPassword,
  189. HTTPREQUEST_SETCREDENTIALS_FLAGS Flags);
  190. STDMETHOD(Open)(BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync);
  191. STDMETHOD(SetRequestHeader)(BSTR bstrHeader, BSTR bstrValue);
  192. STDMETHOD(GetResponseHeader)(BSTR bstrHeader, BSTR * pbstrValue);
  193. STDMETHOD(GetAllResponseHeaders)(BSTR * pbstrHeaders);
  194. STDMETHOD(Send)(VARIANT varBody);
  195. STDMETHOD(get_Status)(long * plStatus);
  196. STDMETHOD(get_StatusText)(BSTR * pbstrStatus);
  197. STDMETHOD(get_ResponseText)(BSTR * pbstrBody);
  198. STDMETHOD(get_ResponseBody)(VARIANT * pvarBody);
  199. STDMETHOD(get_ResponseStream)(VARIANT * pvarBody);
  200. STDMETHOD(get_Option)(WinHttpRequestOption Option, VARIANT * Value);
  201. STDMETHOD(put_Option)(WinHttpRequestOption Option, VARIANT Value);
  202. STDMETHOD(WaitForResponse)(VARIANT Timeout, VARIANT_BOOL * pboolSucceeded);
  203. STDMETHOD(Abort)();
  204. STDMETHOD(SetTimeouts)(long ResolveTimeout, long ConnectTimeout, long SendTimeout, long ReceiveTimeout);
  205. //---------------------------------------------------------------
  206. // IProvideClassInfo methods.
  207. //---------------------------------------------------------------
  208. STDMETHOD(GetClassInfo)(ITypeInfo ** ppTI);
  209. //---------------------------------------------------------------
  210. // IProvideClassInfo2 methods.
  211. //---------------------------------------------------------------
  212. STDMETHOD(GetGUID)(DWORD dwGuidKind, GUID * pGUID);
  213. //---------------------------------------------------------------
  214. // IConnectionPointContainer methods.
  215. //---------------------------------------------------------------
  216. STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints ** ppEnum);
  217. STDMETHOD(FindConnectionPoint)(REFIID riid, IConnectionPoint ** ppCP);
  218. class CHttpRequestEventsCP : public IConnectionPoint
  219. {
  220. public:
  221. CSinkArray _SinkArray;
  222. CWinHttpRequestEventsMarshaller * _pSinkMarshaller;
  223. DWORD _cConnections;
  224. //---------------------------------------------------------------
  225. // IUnknown methods.
  226. //---------------------------------------------------------------
  227. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  228. STDMETHOD_(ULONG, AddRef)();
  229. STDMETHOD_(ULONG, Release)();
  230. //---------------------------------------------------------------
  231. // IConnectionPoint methods.
  232. //---------------------------------------------------------------
  233. STDMETHOD(GetConnectionInterface)(IID * pIID);
  234. STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer ** ppCPC);
  235. STDMETHOD(Advise)(IUnknown * pUnk, DWORD * pdwCookie);
  236. STDMETHOD(Unadvise)(DWORD dwCookie);
  237. STDMETHOD(EnumConnections)(IEnumConnections **);
  238. inline CHttpRequest * Px() const
  239. {
  240. return (CHttpRequest *)((BYTE *)this - offsetof(CHttpRequest, _CP));
  241. }
  242. void FireOnResponseStart(long Status, BSTR ContentType);
  243. void FireOnResponseDataAvailable(const BYTE * rgbData, DWORD cbData);
  244. void FireOnResponseFinished();
  245. CHttpRequestEventsCP()
  246. {
  247. _cConnections = 0;
  248. _pSinkMarshaller = NULL;
  249. }
  250. ~CHttpRequestEventsCP();
  251. inline IWinHttpRequestEvents * GetSink()
  252. {
  253. return (_pSinkMarshaller == NULL) ?
  254. static_cast<IWinHttpRequestEvents *>(&_SinkArray)
  255. : static_cast<IWinHttpRequestEvents *>(_pSinkMarshaller);
  256. }
  257. HRESULT CreateEventSinksMarshaller();
  258. void ShutdownEventSinksMarshaller();
  259. void ReleaseEventSinksMarshaller();
  260. void FreezeEvents();
  261. void UnfreezeEvents();
  262. };
  263. friend class CHttpRequestEventsCP;
  264. private:
  265. enum State
  266. {
  267. CREATED = 0,
  268. OPENED = 1,
  269. SENDING = 2,
  270. SENT = 3,
  271. RECEIVING = 4,
  272. RESPONSE = 5
  273. };
  274. long _cRefs;
  275. IUnknown * _pUnkSite;
  276. ITypeInfo * _pTypeInfo;
  277. BSTR _bstrUserAgent;
  278. DWORD _dwProxySetting;
  279. BSTR _bstrProxyServer;
  280. BSTR _bstrBypassList;
  281. State _eState;
  282. HINTERNET _hInet;
  283. HINTERNET _hConnection;
  284. HINTERNET _hHTTP;
  285. DWORD _ResolveTimeout;
  286. DWORD _ConnectTimeout;
  287. DWORD _SendTimeout;
  288. DWORD _ReceiveTimeout;
  289. BOOL _fAsync;
  290. HANDLE _hWorkerThread;
  291. DWORD _cRefsOnMainThread;
  292. DWORD _dwMainThreadId;
  293. HRESULT _hrAsyncResult;
  294. void * _hAbortedConnectObject;
  295. void * _hAbortedRequestObject;
  296. bool _bAborted;
  297. bool _bSetTimeouts;
  298. bool _bDisableRedirects;
  299. DWORD _dwCodePage;
  300. DWORD _dwEscapePercentFlag;
  301. DWORD _cbRequestBody;
  302. char * _szRequestBuffer;
  303. char * _szResponseBuffer;
  304. DWORD _cbResponseBuffer;
  305. DWORD _cbResponseBody;
  306. DWORD _dwSslIgnoreFlags;
  307. BSTR _bstrCertSubject;
  308. CHttpRequestEventsCP _CP;
  309. void Initialize();
  310. void ReleaseResources();
  311. void Recycle();
  312. void Reset();
  313. HRESULT GetHttpRequestTypeInfo(REFGUID guid, ITypeInfo ** ppTypeInfo);
  314. HRESULT ReadResponse();
  315. HRESULT SetRequiredRequestHeaders();
  316. HRESULT SetRequestBody(VARIANT varBody);
  317. void SetState(State state);
  318. HRESULT CreateStreamOnResponse(IStream ** ppStm);
  319. HRESULT _GetResponseHeader(OLECHAR * wszHeader, BSTR * pbstrValue);
  320. HRESULT CreateAsyncWorkerThread();
  321. static void SetErrorInfo(HRESULT hr);
  322. BOOL SelectCertificate();
  323. };
  324. /////////////////////////////////////////////////////////////////////////////
  325. // function prototypes
  326. STDMETHODIMP
  327. CreateHttpRequest(REFIID riid, void ** ppvObject);
  328. #ifdef WINHTTP_STATIC_LIBRARY
  329. STDAPI WinHttpCreateHttpRequestComponent(REFIID riid, void ** ppvObject);
  330. #endif
  331. BOOLAPI WinHttpCheckPlatform(void);
  332. BOOL RegisterWinHttpEventMarshallerWndClass();
  333. void CleanupWinHttpRequestGlobals();
  334. #endif //_HTTPREQUEST_HXX_