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