OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ssl/ssl_error_handler.h" | 5 #include "chrome/browser/ssl/ssl_error_handler.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "chrome/browser/chrome_thread.h" |
8 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 8 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
9 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" | 9 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
10 #include "chrome/browser/ssl/ssl_cert_error_handler.h" | 10 #include "chrome/browser/ssl/ssl_cert_error_handler.h" |
11 #include "chrome/browser/tab_contents/tab_contents.h" | 11 #include "chrome/browser/tab_contents/tab_contents.h" |
12 #include "chrome/browser/tab_contents/tab_util.h" | 12 #include "chrome/browser/tab_contents/tab_util.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "net/url_request/url_request.h" | 14 #include "net/url_request/url_request.h" |
15 | 15 |
16 SSLErrorHandler::SSLErrorHandler(ResourceDispatcherHost* rdh, | 16 SSLErrorHandler::SSLErrorHandler(ResourceDispatcherHost* rdh, |
17 URLRequest* request, | 17 URLRequest* request, |
18 ResourceType::Type resource_type, | 18 ResourceType::Type resource_type, |
19 const std::string& frame_origin, | 19 const std::string& frame_origin, |
20 const std::string& main_frame_origin, | 20 const std::string& main_frame_origin) |
21 MessageLoop* ui_loop) | 21 : manager_(NULL), |
22 : ui_loop_(ui_loop), | |
23 io_loop_(MessageLoop::current()), | |
24 manager_(NULL), | |
25 request_id_(0, 0), | 22 request_id_(0, 0), |
26 resource_dispatcher_host_(rdh), | 23 resource_dispatcher_host_(rdh), |
27 request_url_(request->url()), | 24 request_url_(request->url()), |
28 resource_type_(resource_type), | 25 resource_type_(resource_type), |
29 frame_origin_(frame_origin), | 26 frame_origin_(frame_origin), |
30 main_frame_origin_(main_frame_origin), | 27 main_frame_origin_(main_frame_origin), |
31 request_has_been_notified_(false) { | 28 request_has_been_notified_(false) { |
32 DCHECK(MessageLoop::current() != ui_loop); | 29 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI)); |
33 | 30 |
34 ResourceDispatcherHostRequestInfo* info = | 31 ResourceDispatcherHostRequestInfo* info = |
35 ResourceDispatcherHost::InfoForRequest(request); | 32 ResourceDispatcherHost::InfoForRequest(request); |
36 request_id_.child_id = info->child_id(); | 33 request_id_.child_id = info->child_id(); |
37 request_id_.request_id = info->request_id(); | 34 request_id_.request_id = info->request_id(); |
38 | 35 |
39 if (!ResourceDispatcherHost::RenderViewForRequest(request, | 36 if (!ResourceDispatcherHost::RenderViewForRequest(request, |
40 &render_process_host_id_, | 37 &render_process_host_id_, |
41 &tab_contents_id_)) | 38 &tab_contents_id_)) |
42 NOTREACHED(); | 39 NOTREACHED(); |
43 | 40 |
44 // This makes sure we don't disappear on the IO thread until we've given an | 41 // This makes sure we don't disappear on the IO thread until we've given an |
45 // answer to the URLRequest. | 42 // answer to the URLRequest. |
46 // | 43 // |
47 // Release in CompleteCancelRequest, CompleteContinueRequest, | 44 // Release in CompleteCancelRequest, CompleteContinueRequest, |
48 // CompleteStartRequest or CompleteTakeNoAction. | 45 // CompleteStartRequest or CompleteTakeNoAction. |
49 AddRef(); | 46 AddRef(); |
50 } | 47 } |
51 | 48 |
52 void SSLErrorHandler::Dispatch() { | 49 void SSLErrorHandler::Dispatch() { |
53 DCHECK(MessageLoop::current() == ui_loop_); | 50 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
54 | 51 |
55 TabContents* tab_contents = GetTabContents(); | 52 TabContents* tab_contents = GetTabContents(); |
56 if (!tab_contents) { | 53 if (!tab_contents) { |
57 // We arrived on the UI thread, but the tab we're looking for is no longer | 54 // We arrived on the UI thread, but the tab we're looking for is no longer |
58 // here. | 55 // here. |
59 OnDispatchFailed(); | 56 OnDispatchFailed(); |
60 return; | 57 return; |
61 } | 58 } |
62 | 59 |
63 // Hand ourselves off to the SSLManager. | 60 // Hand ourselves off to the SSLManager. |
64 manager_ = tab_contents->controller().ssl_manager(); | 61 manager_ = tab_contents->controller().ssl_manager(); |
65 OnDispatched(); | 62 OnDispatched(); |
66 } | 63 } |
67 | 64 |
68 TabContents* SSLErrorHandler::GetTabContents() { | 65 TabContents* SSLErrorHandler::GetTabContents() { |
69 return tab_util::GetTabContentsByID(render_process_host_id_, | 66 return tab_util::GetTabContentsByID(render_process_host_id_, |
70 tab_contents_id_); | 67 tab_contents_id_); |
71 } | 68 } |
72 | 69 |
73 void SSLErrorHandler::CancelRequest() { | 70 void SSLErrorHandler::CancelRequest() { |
74 DCHECK(MessageLoop::current() == ui_loop_); | 71 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
75 | 72 |
76 // We need to complete this task on the IO thread. | 73 // We need to complete this task on the IO thread. |
77 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 74 ChromeThread::PostTask( |
78 this, &SSLErrorHandler::CompleteCancelRequest, | 75 ChromeThread::IO, FROM_HERE, |
79 net::ERR_ABORTED)); | 76 NewRunnableMethod( |
| 77 this, &SSLErrorHandler::CompleteCancelRequest, net::ERR_ABORTED)); |
80 } | 78 } |
81 | 79 |
82 void SSLErrorHandler::DenyRequest() { | 80 void SSLErrorHandler::DenyRequest() { |
83 DCHECK(MessageLoop::current() == ui_loop_); | 81 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
84 | 82 |
85 // We need to complete this task on the IO thread. | 83 // We need to complete this task on the IO thread. |
86 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 84 ChromeThread::PostTask( |
87 this, &SSLErrorHandler::CompleteCancelRequest, | 85 ChromeThread::IO, FROM_HERE, |
88 net::ERR_INSECURE_RESPONSE)); | 86 NewRunnableMethod( |
| 87 this, &SSLErrorHandler::CompleteCancelRequest, |
| 88 net::ERR_INSECURE_RESPONSE)); |
89 } | 89 } |
90 | 90 |
91 void SSLErrorHandler::ContinueRequest() { | 91 void SSLErrorHandler::ContinueRequest() { |
92 DCHECK(MessageLoop::current() == ui_loop_); | 92 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
93 | 93 |
94 // We need to complete this task on the IO thread. | 94 // We need to complete this task on the IO thread. |
95 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 95 ChromeThread::PostTask( |
96 this, &SSLErrorHandler::CompleteContinueRequest)); | 96 ChromeThread::IO, FROM_HERE, |
| 97 NewRunnableMethod(this, &SSLErrorHandler::CompleteContinueRequest)); |
97 } | 98 } |
98 | 99 |
99 void SSLErrorHandler::StartRequest(FilterPolicy::Type filter_policy) { | 100 void SSLErrorHandler::StartRequest(FilterPolicy::Type filter_policy) { |
100 DCHECK(MessageLoop::current() == ui_loop_); | 101 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
101 | 102 |
102 // We need to complete this task on the IO thread. | 103 // We need to complete this task on the IO thread. |
103 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 104 ChromeThread::PostTask( |
104 this, &SSLErrorHandler::CompleteStartRequest, filter_policy)); | 105 ChromeThread::IO, FROM_HERE, |
| 106 NewRunnableMethod( |
| 107 this, &SSLErrorHandler::CompleteStartRequest, filter_policy)); |
105 } | 108 } |
106 | 109 |
107 void SSLErrorHandler::TakeNoAction() { | 110 void SSLErrorHandler::TakeNoAction() { |
108 DCHECK(MessageLoop::current() == ui_loop_); | 111 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
109 | 112 |
110 // We need to complete this task on the IO thread. | 113 // We need to complete this task on the IO thread. |
111 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 114 ChromeThread::PostTask( |
112 this, &SSLErrorHandler::CompleteTakeNoAction)); | 115 ChromeThread::IO, FROM_HERE, |
| 116 NewRunnableMethod(this, &SSLErrorHandler::CompleteTakeNoAction)); |
113 } | 117 } |
114 | 118 |
115 void SSLErrorHandler::CompleteCancelRequest(int error) { | 119 void SSLErrorHandler::CompleteCancelRequest(int error) { |
116 DCHECK(MessageLoop::current() == io_loop_); | 120 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
117 | 121 |
118 // It is important that we notify the URLRequest only once. If we try to | 122 // It is important that we notify the URLRequest only once. If we try to |
119 // notify the request twice, it may no longer exist and |this| might have | 123 // notify the request twice, it may no longer exist and |this| might have |
120 // already have been deleted. | 124 // already have been deleted. |
121 DCHECK(!request_has_been_notified_); | 125 DCHECK(!request_has_been_notified_); |
122 if (request_has_been_notified_) | 126 if (request_has_been_notified_) |
123 return; | 127 return; |
124 | 128 |
125 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); | 129 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); |
126 if (request) { | 130 if (request) { |
127 // The request can be NULL if it was cancelled by the renderer (as the | 131 // The request can be NULL if it was cancelled by the renderer (as the |
128 // result of the user navigating to a new page from the location bar). | 132 // result of the user navigating to a new page from the location bar). |
129 DLOG(INFO) << "CompleteCancelRequest() url: " << request->url().spec(); | 133 DLOG(INFO) << "CompleteCancelRequest() url: " << request->url().spec(); |
130 SSLCertErrorHandler* cert_error = AsSSLCertErrorHandler(); | 134 SSLCertErrorHandler* cert_error = AsSSLCertErrorHandler(); |
131 if (cert_error) | 135 if (cert_error) |
132 request->SimulateSSLError(error, cert_error->ssl_info()); | 136 request->SimulateSSLError(error, cert_error->ssl_info()); |
133 else | 137 else |
134 request->SimulateError(error); | 138 request->SimulateError(error); |
135 } | 139 } |
136 request_has_been_notified_ = true; | 140 request_has_been_notified_ = true; |
137 | 141 |
138 // We're done with this object on the IO thread. | 142 // We're done with this object on the IO thread. |
139 Release(); | 143 Release(); |
140 } | 144 } |
141 | 145 |
142 void SSLErrorHandler::CompleteContinueRequest() { | 146 void SSLErrorHandler::CompleteContinueRequest() { |
143 DCHECK(MessageLoop::current() == io_loop_); | 147 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
144 | 148 |
145 // It is important that we notify the URLRequest only once. If we try to | 149 // It is important that we notify the URLRequest only once. If we try to |
146 // notify the request twice, it may no longer exist and |this| might have | 150 // notify the request twice, it may no longer exist and |this| might have |
147 // already have been deleted. | 151 // already have been deleted. |
148 DCHECK(!request_has_been_notified_); | 152 DCHECK(!request_has_been_notified_); |
149 if (request_has_been_notified_) | 153 if (request_has_been_notified_) |
150 return; | 154 return; |
151 | 155 |
152 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); | 156 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); |
153 if (request) { | 157 if (request) { |
154 // The request can be NULL if it was cancelled by the renderer (as the | 158 // The request can be NULL if it was cancelled by the renderer (as the |
155 // result of the user navigating to a new page from the location bar). | 159 // result of the user navigating to a new page from the location bar). |
156 DLOG(INFO) << "CompleteContinueRequest() url: " << request->url().spec(); | 160 DLOG(INFO) << "CompleteContinueRequest() url: " << request->url().spec(); |
157 request->ContinueDespiteLastError(); | 161 request->ContinueDespiteLastError(); |
158 } | 162 } |
159 request_has_been_notified_ = true; | 163 request_has_been_notified_ = true; |
160 | 164 |
161 // We're done with this object on the IO thread. | 165 // We're done with this object on the IO thread. |
162 Release(); | 166 Release(); |
163 } | 167 } |
164 | 168 |
165 void SSLErrorHandler::CompleteStartRequest(FilterPolicy::Type filter_policy) { | 169 void SSLErrorHandler::CompleteStartRequest(FilterPolicy::Type filter_policy) { |
166 DCHECK(MessageLoop::current() == io_loop_); | 170 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
167 | 171 |
168 // It is important that we notify the URLRequest only once. If we try to | 172 // It is important that we notify the URLRequest only once. If we try to |
169 // notify the request twice, it may no longer exist and |this| might have | 173 // notify the request twice, it may no longer exist and |this| might have |
170 // already have been deleted. | 174 // already have been deleted. |
171 DCHECK(!request_has_been_notified_); | 175 DCHECK(!request_has_been_notified_); |
172 if (request_has_been_notified_) | 176 if (request_has_been_notified_) |
173 return; | 177 return; |
174 | 178 |
175 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); | 179 URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); |
176 if (request) { | 180 if (request) { |
177 // The request can be NULL if it was cancelled by the renderer (as the | 181 // The request can be NULL if it was cancelled by the renderer (as the |
178 // result of the user navigating to a new page from the location bar). | 182 // result of the user navigating to a new page from the location bar). |
179 DLOG(INFO) << "CompleteStartRequest() url: " << request->url().spec(); | 183 DLOG(INFO) << "CompleteStartRequest() url: " << request->url().spec(); |
180 // The request should not have been started (SUCCESS is the initial state). | 184 // The request should not have been started (SUCCESS is the initial state). |
181 DCHECK(request->status().status() == URLRequestStatus::SUCCESS); | 185 DCHECK(request->status().status() == URLRequestStatus::SUCCESS); |
182 ResourceDispatcherHostRequestInfo* info = | 186 ResourceDispatcherHostRequestInfo* info = |
183 ResourceDispatcherHost::InfoForRequest(request); | 187 ResourceDispatcherHost::InfoForRequest(request); |
184 info->set_filter_policy(filter_policy); | 188 info->set_filter_policy(filter_policy); |
185 request->Start(); | 189 request->Start(); |
186 } | 190 } |
187 request_has_been_notified_ = true; | 191 request_has_been_notified_ = true; |
188 | 192 |
189 // We're done with this object on the IO thread. | 193 // We're done with this object on the IO thread. |
190 Release(); | 194 Release(); |
191 } | 195 } |
192 | 196 |
193 void SSLErrorHandler::CompleteTakeNoAction() { | 197 void SSLErrorHandler::CompleteTakeNoAction() { |
194 DCHECK(MessageLoop::current() == io_loop_); | 198 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
195 | 199 |
196 // It is important that we notify the URLRequest only once. If we try to | 200 // It is important that we notify the URLRequest only once. If we try to |
197 // notify the request twice, it may no longer exist and |this| might have | 201 // notify the request twice, it may no longer exist and |this| might have |
198 // already have been deleted. | 202 // already have been deleted. |
199 DCHECK(!request_has_been_notified_); | 203 DCHECK(!request_has_been_notified_); |
200 if (request_has_been_notified_) | 204 if (request_has_been_notified_) |
201 return; | 205 return; |
202 | 206 |
203 request_has_been_notified_ = true; | 207 request_has_been_notified_ = true; |
204 | 208 |
205 // We're done with this object on the IO thread. | 209 // We're done with this object on the IO thread. |
206 Release(); | 210 Release(); |
207 } | 211 } |
OLD | NEW |