ssl_error_handler.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#include "content/browser/ssl/ssl_error_handler.h" 6 7#include "base/bind.h" 8#include "content/browser/renderer_host/render_view_host_impl.h" 9#include "content/browser/ssl/ssl_cert_error_handler.h" 10#include "content/browser/web_contents/navigation_controller_impl.h" 11#include "content/browser/web_contents/web_contents_impl.h" 12#include "content/public/browser/browser_thread.h" 13#include "content/public/browser/resource_request_info.h" 14#include "net/base/net_errors.h" 15#include "net/url_request/url_request.h" 16 17using net::SSLInfo; 18 19namespace content { 20 21SSLErrorHandler::SSLErrorHandler(const base::WeakPtr<Delegate>& delegate, 22 const GlobalRequestID& id, 23 ResourceType::Type resource_type, 24 const GURL& url, 25 int render_process_id, 26 int render_view_id) 27 : manager_(NULL), 28 request_id_(id), 29 delegate_(delegate), 30 render_process_id_(render_process_id), 31 render_view_id_(render_view_id), 32 request_url_(url), 33 resource_type_(resource_type), 34 request_has_been_notified_(false) { 35 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 36 DCHECK(delegate); 37 38 // This makes sure we don't disappear on the IO thread until we've given an 39 // answer to the net::URLRequest. 40 // 41 // Release in CompleteCancelRequest, CompleteContinueRequest, or 42 // CompleteTakeNoAction. 43 AddRef(); 44} 45 46SSLErrorHandler::~SSLErrorHandler() {} 47 48void SSLErrorHandler::OnDispatchFailed() { 49 TakeNoAction(); 50} 51 52void SSLErrorHandler::OnDispatched() { 53 TakeNoAction(); 54} 55 56SSLCertErrorHandler* SSLErrorHandler::AsSSLCertErrorHandler() { 57 return NULL; 58} 59 60void SSLErrorHandler::Dispatch() { 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 62 63 WebContents* web_contents = NULL; 64 RenderViewHostImpl* render_view_host = 65 RenderViewHostImpl::FromID(render_process_id_, render_view_id_); 66 if (render_view_host) 67 web_contents = render_view_host->GetDelegate()->GetAsWebContents(); 68 69 if (!web_contents) { 70 // We arrived on the UI thread, but the tab we're looking for is no longer 71 // here. 72 OnDispatchFailed(); 73 return; 74 } 75 76 // Hand ourselves off to the SSLManager. 77 manager_ = 78 static_cast<NavigationControllerImpl*>(&web_contents->GetController())-> 79 ssl_manager(); 80 OnDispatched(); 81} 82 83void SSLErrorHandler::CancelRequest() { 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 85 86 // We need to complete this task on the IO thread. 87 BrowserThread::PostTask( 88 BrowserThread::IO, FROM_HERE, 89 base::Bind( 90 &SSLErrorHandler::CompleteCancelRequest, this, net::ERR_ABORTED)); 91} 92 93void SSLErrorHandler::DenyRequest() { 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 95 96 // We need to complete this task on the IO thread. 97 BrowserThread::PostTask( 98 BrowserThread::IO, FROM_HERE, 99 base::Bind( 100 &SSLErrorHandler::CompleteCancelRequest, this, 101 net::ERR_INSECURE_RESPONSE)); 102} 103 104void SSLErrorHandler::ContinueRequest() { 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 106 107 // We need to complete this task on the IO thread. 108 BrowserThread::PostTask( 109 BrowserThread::IO, FROM_HERE, 110 base::Bind(&SSLErrorHandler::CompleteContinueRequest, this)); 111} 112 113void SSLErrorHandler::TakeNoAction() { 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 115 116 // We need to complete this task on the IO thread. 117 BrowserThread::PostTask( 118 BrowserThread::IO, FROM_HERE, 119 base::Bind(&SSLErrorHandler::CompleteTakeNoAction, this)); 120} 121 122void SSLErrorHandler::CompleteCancelRequest(int error) { 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 124 125 // It is important that we notify the net::URLRequest only once. If we try 126 // to notify the request twice, it may no longer exist and |this| might have 127 // already have been deleted. 128 DCHECK(!request_has_been_notified_); 129 if (request_has_been_notified_) 130 return; 131 132 SSLCertErrorHandler* cert_error = AsSSLCertErrorHandler(); 133 const SSLInfo* ssl_info = NULL; 134 if (cert_error) 135 ssl_info = &cert_error->ssl_info(); 136 if (delegate_) 137 delegate_->CancelSSLRequest(request_id_, error, ssl_info); 138 request_has_been_notified_ = true; 139 140 // We're done with this object on the IO thread. 141 Release(); 142} 143 144void SSLErrorHandler::CompleteContinueRequest() { 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 146 147 // It is important that we notify the net::URLRequest only once. If we try to 148 // notify the request twice, it may no longer exist and |this| might have 149 // already have been deleted. 150 DCHECK(!request_has_been_notified_); 151 if (request_has_been_notified_) 152 return; 153 154 if (delegate_) 155 delegate_->ContinueSSLRequest(request_id_); 156 request_has_been_notified_ = true; 157 158 // We're done with this object on the IO thread. 159 Release(); 160} 161 162void SSLErrorHandler::CompleteTakeNoAction() { 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 164 165 // It is important that we notify the net::URLRequest only once. If we try to 166 // notify the request twice, it may no longer exist and |this| might have 167 // already have been deleted. 168 DCHECK(!request_has_been_notified_); 169 if (request_has_been_notified_) 170 return; 171 172 request_has_been_notified_ = true; 173 174 // We're done with this object on the IO thread. 175 Release(); 176} 177 178} // namespace content 179