Add HandleProtocolExecution event for unregistered protocols (issue #155).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@163 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2011-01-12 01:33:03 +00:00
parent bf02152631
commit 013c008775
13 changed files with 217 additions and 4 deletions

View File

@@ -40,6 +40,7 @@
#include "cef_context.h"
#include "cef_process.h"
#include "cef_process_io_thread.h"
#include "external_protocol_handler.h"
#include "request_impl.h"
#include "base/file_path.h"
@@ -281,8 +282,7 @@ class RequestProxy : public net::URLRequest::Delegate,
if (browser_.get()) {
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get())
{
if(handler.get()) {
// Build the request object for passing to the handler
CefRefPtr<CefRequest> request(new CefRequestImpl());
CefRequestImpl* requestimpl =
@@ -376,11 +376,29 @@ class RequestProxy : public net::URLRequest::Delegate,
OnReceivedResponse(info, false);
AsyncReadData();
}
if(!handled && ResourceType::IsFrame(params->request_type) &&
!net::URLRequest::IsHandledProtocol(params->url.scheme())) {
bool allow_os_execution = false;
CefHandler::RetVal rv = handler->HandleProtocolExecution(browser_,
params->url.spec(), &allow_os_execution);
if(rv == RV_CONTINUE && allow_os_execution &&
ExternalProtocolHandler::HandleExternalProtocol(params->url)) {
handled = true;
} else if(rv == RV_HANDLED) {
handled = true;
}
if (handled) {
OnCompletedRequest(
URLRequestStatus(URLRequestStatus::HANDLED_EXTERNALLY, net::OK),
std::string(), base::Time());
}
}
}
}
if(!handled)
{
if(!handled) {
// Might need to resolve the blob references in the upload data.
if (params->upload) {
_Context->request_context()->blob_storage_controller()->

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef _EXTERNAL_PROTOCOL_HANDLER_H
#define _EXTERNAL_PROTOCOL_HANDLER_H
#include <string>
class GURL;
namespace ExternalProtocolHandler {
// Returns true if the OS provides external support for the specified |scheme|.
bool HasExternalHandler(const std::string& scheme);
// Pass handling of the specified |gurl| to the OS.
bool HandleExternalProtocol(const GURL& gurl);
} // namespace ExternalProtocolHandler
#endif // _EXTERNAL_PROTOCOL_HANDLER_H

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "external_protocol_handler.h"
namespace ExternalProtocolHandler {
bool HasExternalHandler(const std::string& scheme) {
return false;
}
bool HandleExternalProtocol(const GURL& gurl) {
return false;
}
} // namespace ExternalProtocolHandler

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "external_protocol_handler.h"
namespace ExternalProtocolHandler {
bool HasExternalHandler(const std::string& scheme) {
return false;
}
bool HandleExternalProtocol(const GURL& gurl) {
return false;
}
} // namespace ExternalProtocolHandler

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "external_protocol_handler.h"
#include "base/utf_string_conversions.h"
#include "base/win/registry.h"
#include "googleurl/src/gurl.h"
#include <shellapi.h>
namespace ExternalProtocolHandler {
// According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp:
// "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in
// ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6
// support URLS of 2083 chars in length, 2K is safe."
const int kMaxAddressLengthChars = 2048;
bool HasExternalHandler(const std::string& scheme) {
base::win::RegKey key;
const std::wstring registry_path =
ASCIIToWide(scheme + "\\shell\\open\\command");
key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ);
if (key.Valid()) {
DWORD size = 0;
key.ReadValue(NULL, NULL, &size, NULL);
if (size > 2) {
// ShellExecute crashes the process when the command is empty.
// We check for "2" because it always returns the trailing NULL.
return true;
}
}
return false;
}
bool HandleExternalProtocol(const GURL& gurl) {
if (!HasExternalHandler(gurl.scheme()))
return false;
const std::string& address = gurl.spec();
if (address.length() > kMaxAddressLengthChars)
return false;
ShellExecuteA(NULL, "open", address.c_str(), NULL, NULL, SW_SHOWNORMAL);
return true;
}
} // namespace ExternalProtocolHandler