Roll leveldb to r76.
[chromium-blink-merge.git] / chrome_frame / urlmon_url_request_private.h
bloba8ef99b4190a3515b5a5d4faedf9a53ac57dac67
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_
8 #include <atlbase.h>
9 #include <atlcom.h>
11 #include <string>
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,
25 public IAuthenticate,
26 public IHttpSecurity {
27 public:
28 virtual bool Start();
29 virtual void Stop();
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
50 // privileged mode.
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;
59 protected:
60 UrlmonUrlRequest();
61 ~UrlmonUrlRequest();
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)
70 END_COM_MAP()
72 BEGIN_SERVICE_MAP(UrlmonUrlRequest)
73 SERVICE_ENTRY(IID_IHttpNegotiate);
74 END_SERVICE_MAP()
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,
85 STGMEDIUM* storage);
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,
102 LPWSTR* password);
104 // IHttpSecurity implementation.
105 STDMETHOD(OnSecurityProblem)(DWORD problem);
107 void set_pending(bool pending) {
108 pending_ = pending;
111 bool pending() const {
112 return pending_;
115 bool terminate_requested() const {
116 return !terminate_bind_callback_.is_null();
119 std::string response_headers() {
120 return response_headers_;
123 protected:
124 void ReleaseBindings();
126 HRESULT StartAsyncDownload();
127 void NotifyDelegateAndDie();
128 void TerminateTransaction();
129 static net::Error HresultToNetError(HRESULT hr);
131 private:
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.
140 class Status {
141 public:
142 enum State {DONE, ABORTING, WORKING};
143 struct Redirection {
144 Redirection() : http_code(0) { }
145 int http_code;
146 std::string utf8_url;
149 Status() : state_(Status::DONE) {
152 State get_state() const {
153 return state_;
156 // Switch from [DONE] to [WORKING].
157 void Start() {
158 DCHECK_EQ(state_, DONE);
159 state_ = WORKING;
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;
175 state_ = ABORTING;
178 // Set the result as net::URLRequestStatus::CANCELED.
179 // Switch to [ABORTING] state (if not already in that state).
180 void Cancel() {
181 if (state_ == DONE)
182 return;
184 if (state_ == WORKING) {
185 state_ = ABORTING;
186 } else {
187 // state_ == ABORTING
188 redirect_.http_code = 0;
189 redirect_.utf8_url.clear();
192 set_result(net::URLRequestStatus::CANCELED, 0);
195 void Done() {
196 state_ = DONE;
199 bool was_redirected() const {
200 return redirect_.http_code != 0;
203 const Redirection& get_redirection() const {
204 return redirect_;
207 const net::URLRequestStatus& get_result() const {
208 return result_;
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));
222 private:
223 Redirection redirect_;
224 State state_;
225 net::URLRequestStatus result_;
228 Status status_;
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_;
237 HWND parent_window_;
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_;
242 bool pending_;
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
247 // urlmon.
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_