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