1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_FRAME_URLMON_URL_REQUEST_PRIVATE_H_
6 #define CHROME_FRAME_URLMON_URL_REQUEST_PRIVATE_H_
13 #include "base/gtest_prod_util.h"
14 #include "base/threading/platform_thread.h"
15 #include "net/base/net_errors.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request_status.h"
19 class UrlmonUrlRequest
20 : public CComObjectRootEx
<CComMultiThreadModel
>,
21 public PluginUrlRequest
,
22 public IServiceProviderImpl
<UrlmonUrlRequest
>,
23 public IBindStatusCallback
,
24 public IHttpNegotiate
,
26 public IHttpSecurity
{
30 virtual bool Read(int bytes_to_read
);
32 // Special function needed by ActiveDocument::Load()
33 HRESULT
InitPending(const GURL
& url
, IMoniker
* moniker
, IBindCtx
* bind_ctx
,
34 bool enable_frame_busting
, bool privileged_mode
,
35 HWND notification_window
, IStream
* cache
);
37 // Used from "DownloadRequestInHost".
38 // Callback will be invoked either right away (if operation is finished) or
39 // from inside ::OnStopBinding() when it is safe to reuse the bind_context.
40 typedef base::Callback
<void(IMoniker
*, IBindCtx
*, IStream
*, const char*)>
41 TerminateBindCallback
;
42 void TerminateBind(const TerminateBindCallback
& callback
);
44 // Parent Window for UrlMon error dialogs
45 void set_parent_window(HWND parent_window
) {
46 parent_window_
= parent_window
;
49 // This function passes information on whether ChromeFrame is running in
51 void set_privileged_mode(bool privileged_mode
) {
52 privileged_mode_
= privileged_mode
;
55 // Returns a string in the form " id: %i Obj: %X URL: %s" which is useful
56 // to identify request objects in the log.
57 std::string
me() const;
63 BEGIN_COM_MAP(UrlmonUrlRequest
)
64 COM_INTERFACE_ENTRY(IHttpNegotiate
)
65 COM_INTERFACE_ENTRY(IServiceProvider
)
66 COM_INTERFACE_ENTRY(IBindStatusCallback
)
67 COM_INTERFACE_ENTRY(IWindowForBindingUI
)
68 COM_INTERFACE_ENTRY(IAuthenticate
)
69 COM_INTERFACE_ENTRY(IHttpSecurity
)
72 BEGIN_SERVICE_MAP(UrlmonUrlRequest
)
73 SERVICE_ENTRY(IID_IHttpNegotiate
);
76 // IBindStatusCallback implementation
77 STDMETHOD(OnStartBinding
)(DWORD reserved
, IBinding
* binding
);
78 STDMETHOD(GetPriority
)(LONG
* priority
);
79 STDMETHOD(OnLowResource
)(DWORD reserved
);
80 STDMETHOD(OnProgress
)(ULONG progress
, ULONG max_progress
,
81 ULONG status_code
, LPCWSTR status_text
);
82 STDMETHOD(OnStopBinding
)(HRESULT result
, LPCWSTR error
);
83 STDMETHOD(GetBindInfo
)(DWORD
* bind_flags
, BINDINFO
* bind_info
);
84 STDMETHOD(OnDataAvailable
)(DWORD flags
, DWORD size
, FORMATETC
* formatetc
,
86 STDMETHOD(OnObjectAvailable
)(REFIID iid
, IUnknown
* object
);
88 // IHttpNegotiate implementation
89 STDMETHOD(BeginningTransaction
)(const wchar_t* url
,
90 const wchar_t* current_headers
, DWORD reserved
,
91 wchar_t** additional_headers
);
92 STDMETHOD(OnResponse
)(DWORD dwResponseCode
, const wchar_t* response_headers
,
93 const wchar_t* request_headers
, wchar_t** additional_headers
);
95 // IWindowForBindingUI implementation. This interface is used typically to
96 // query the window handle which URLMON uses as the parent of error dialogs.
97 STDMETHOD(GetWindow
)(REFGUID guid_reason
, HWND
* parent_window
);
99 // IAuthenticate implementation. Used to return the parent window for the
100 // dialog displayed by IE for authenticating with a proxy.
101 STDMETHOD(Authenticate
)(HWND
* parent_window
, LPWSTR
* user_name
,
104 // IHttpSecurity implementation.
105 STDMETHOD(OnSecurityProblem
)(DWORD problem
);
107 void set_pending(bool pending
) {
111 bool pending() const {
115 bool terminate_requested() const {
116 return !terminate_bind_callback_
.is_null();
119 std::string
response_headers() {
120 return response_headers_
;
124 void ReleaseBindings();
126 HRESULT
StartAsyncDownload();
127 void NotifyDelegateAndDie();
128 void TerminateTransaction();
129 static net::Error
HresultToNetError(HRESULT hr
);
132 size_t SendDataToDelegate(size_t bytes
);
134 // This class simplifies tracking the progress of operation. We have 3 main
135 // states: DONE, WORKING and ABORTING.
136 // When in [DONE] or [ABORTING] state, there is additional information
137 // about the result of operation.
138 // Start(), SetRedirected(), Cancel() and Done() methods trigger the state
139 // change. See comments bellow.
142 enum State
{DONE
, ABORTING
, WORKING
};
144 Redirection() : http_code(0) { }
146 std::string utf8_url
;
149 Status() : state_(Status::DONE
) {
152 State
get_state() const {
156 // Switch from [DONE] to [WORKING].
158 DCHECK_EQ(state_
, DONE
);
162 // Save redirection information and switch to [ABORTING] state.
163 // Assumes binding_->Abort() will be called!
164 void SetRedirected(int http_code
, const std::string
& utf8_url
) {
165 DCHECK_EQ(state_
, WORKING
);
166 DCHECK_EQ(result_
.status(), net::URLRequestStatus::SUCCESS
);
167 redirect_
.utf8_url
= utf8_url
;
169 // At times we receive invalid redirect codes like 0, 200, etc. We
170 // default to 302 in this case.
171 redirect_
.http_code
= http_code
;
172 if (!net::HttpResponseHeaders::IsRedirectResponseCode(http_code
))
173 redirect_
.http_code
= 302;
178 // Set the result as net::URLRequestStatus::CANCELED.
179 // Switch to [ABORTING] state (if not already in that state).
184 if (state_
== WORKING
) {
187 // state_ == ABORTING
188 redirect_
.http_code
= 0;
189 redirect_
.utf8_url
.clear();
192 set_result(net::URLRequestStatus::CANCELED
, 0);
199 bool was_redirected() const {
200 return redirect_
.http_code
!= 0;
203 const Redirection
& get_redirection() const {
207 const net::URLRequestStatus
& get_result() const {
211 void set_result(net::URLRequestStatus::Status status
, int error
) {
212 result_
.set_status(status
);
213 result_
.set_error(error
);
216 void set_result(HRESULT hr
) {
217 result_
.set_status(FAILED(hr
)? net::URLRequestStatus::FAILED
:
218 net::URLRequestStatus::SUCCESS
);
219 result_
.set_error(HresultToNetError(hr
));
223 Redirection redirect_
;
225 net::URLRequestStatus result_
;
229 base::win::ScopedComPtr
<IBinding
> binding_
;
230 base::win::ScopedComPtr
<IMoniker
> moniker_
;
231 base::win::ScopedComPtr
<IBindCtx
> bind_context_
;
232 base::win::ScopedComPtr
<IStream
> cache_
;
233 base::win::ScopedComPtr
<IStream
> pending_data_
;
235 size_t pending_read_size_
;
236 base::PlatformThreadId thread_
;
238 bool headers_received_
;
239 int calling_delegate_
; // re-entrancy protection.
240 // Set to true if the ChromeFrame instance is running in privileged mode.
241 bool privileged_mode_
;
243 TerminateBindCallback terminate_bind_callback_
;
244 std::string response_headers_
;
245 // Defaults to true and indicates whether we want to keep the original
246 // transaction alive when we receive the last data notification from
248 bool is_expecting_download_
;
249 // Set to true if the Urlmon transaction object needs to be cleaned up
250 // when this object is destroyed. Happens if we return
251 // INET_E_TERMINATE_BIND from OnDataAvailable in the last data notification.
252 bool cleanup_transaction_
;
253 // Copy of the request headers.
254 std::string request_headers_
;
256 DISALLOW_COPY_AND_ASSIGN(UrlmonUrlRequest
);
259 #endif // CHROME_FRAME_URLMON_URL_REQUEST_PRIVATE_H_