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:
parent
bf02152631
commit
013c008775
4
cef.gyp
4
cef.gyp
|
@ -524,6 +524,7 @@
|
|||
'libcef/dom_storage_context.h',
|
||||
'libcef/dom_storage_namespace.cc',
|
||||
'libcef/dom_storage_namespace.h',
|
||||
'libcef/external_protocol_handler.h',
|
||||
'libcef/request_impl.cc',
|
||||
'libcef/request_impl.h',
|
||||
'libcef/scheme_impl.cc',
|
||||
|
@ -556,6 +557,7 @@
|
|||
'libcef/browser_webkit_glue_win.cc',
|
||||
'libcef/browser_webview_delegate_win.cc',
|
||||
'libcef/cef_process_ui_thread_win.cc',
|
||||
'libcef/external_protocol_handler_win.cc',
|
||||
'libcef/printing/print_settings.cc',
|
||||
'libcef/printing/print_settings.h',
|
||||
'libcef/printing/win_printing_context.cc',
|
||||
|
@ -574,6 +576,7 @@
|
|||
'libcef/browser_webview_mac.h',
|
||||
'libcef/browser_webview_mac.mm',
|
||||
'libcef/cef_process_ui_thread_mac.mm',
|
||||
'libcef/external_protocol_handler_mac.mm',
|
||||
'libcef/webview_host_mac.mm',
|
||||
'libcef/webwidget_host_mac.mm',
|
||||
],
|
||||
|
@ -586,6 +589,7 @@
|
|||
'libcef/browser_webkit_glue_gtk.cc',
|
||||
'libcef/browser_webview_delegate_gtk.cc',
|
||||
'libcef/cef_process_ui_thread_gtk.cc',
|
||||
'libcef/external_protocol_handler_gtk.cc',
|
||||
'libcef/webview_host_gtk.cc',
|
||||
'libcef/webwidget_host_gtk.cc',
|
||||
],
|
||||
|
|
|
@ -642,6 +642,20 @@ public:
|
|||
CefString& mimeType,
|
||||
int loadFlags) =0;
|
||||
|
||||
// Called to handle requests for URLs with an unknown protocol component.
|
||||
// Return RV_HANDLED to indicate that the request should succeed because it
|
||||
// was externally handled. Set |allow_os_execution| to true and return
|
||||
// RV_CONTINUE to attempt execution via the registered OS protocol handler,
|
||||
// if any. If RV_CONTINUE is returned and either |allow_os_execution| is false
|
||||
// or OS protocol handler execution fails then the request will fail with an
|
||||
// error condition.
|
||||
// SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED
|
||||
// ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
|
||||
/*--cef()--*/
|
||||
virtual RetVal HandleProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url,
|
||||
bool* allow_os_execution) =0;
|
||||
|
||||
// Called when a server indicates via the 'Content-Disposition' header that a
|
||||
// response represents a file to download. |mimeType| is the mime type for
|
||||
// the download, |fileName| is the suggested target file name and
|
||||
|
|
|
@ -453,6 +453,19 @@ typedef struct _cef_handler_t
|
|||
struct _cef_stream_reader_t** resourceStream, cef_string_t* mimeType,
|
||||
int loadFlags);
|
||||
|
||||
// Called to handle requests for URLs with an unknown protocol component.
|
||||
// Return RV_HANDLED to indicate that the request should succeed because it
|
||||
// was externally handled. Set |allow_os_execution| to true (1) and return
|
||||
// RV_CONTINUE to attempt execution via the registered OS protocol handler, if
|
||||
// any. If RV_CONTINUE is returned and either |allow_os_execution| is false
|
||||
// (0) or OS protocol handler execution fails then the request will fail with
|
||||
// an error condition. SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE
|
||||
// RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS
|
||||
// EXECUTION.
|
||||
enum cef_retval_t (CEF_CALLBACK *handle_protocol_execution)(
|
||||
struct _cef_handler_t* self, struct _cef_browser_t* browser,
|
||||
const cef_string_t* url, int* allow_os_execution);
|
||||
|
||||
// Called when a server indicates via the 'Content-Disposition' header that a
|
||||
// response represents a file to download. |mimeType| is the mime type for the
|
||||
// download, |fileName| is the suggested target file name and |contentLength|
|
||||
|
|
|
@ -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()->
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -215,6 +215,22 @@ enum cef_retval_t CEF_CALLBACK handler_handle_before_resource_load(
|
|||
return rv;
|
||||
}
|
||||
|
||||
enum cef_retval_t CEF_CALLBACK handler_handle_protocol_execution(
|
||||
struct _cef_handler_t* self, cef_browser_t* browser,
|
||||
const cef_string_t* url, int* allow_os_execution)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(browser);
|
||||
if(!self || !browser)
|
||||
return RV_CONTINUE;
|
||||
|
||||
bool allowExec = *allow_os_execution?true:false;
|
||||
enum cef_retval_t rv = CefHandlerCppToC::Get(self)->HandleProtocolExecution(
|
||||
CefBrowserCToCpp::Wrap(browser), CefString(url), &allowExec);
|
||||
*allow_os_execution = allowExec?true:false;
|
||||
return rv;
|
||||
}
|
||||
|
||||
enum cef_retval_t CEF_CALLBACK handler_handle_download_response(
|
||||
struct _cef_handler_t* self, cef_browser_t* browser,
|
||||
const cef_string_t* mimeType, const cef_string_t* fileName,
|
||||
|
@ -533,6 +549,7 @@ CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls)
|
|||
struct_.struct_.handle_load_error = handler_handle_load_error;
|
||||
struct_.struct_.handle_before_resource_load =
|
||||
handler_handle_before_resource_load;
|
||||
struct_.struct_.handle_protocol_execution = handler_handle_protocol_execution;
|
||||
struct_.struct_.handle_download_response = handler_handle_download_response;
|
||||
struct_.struct_.handle_authentication_request =
|
||||
handler_handle_authentication_request;
|
||||
|
|
|
@ -160,6 +160,20 @@ CefHandler::RetVal CefHandlerCToCpp::HandleBeforeResourceLoad(
|
|||
return rv;
|
||||
}
|
||||
|
||||
CefHandler::RetVal CefHandlerCToCpp::HandleProtocolExecution(
|
||||
CefRefPtr<CefBrowser> browser, const CefString& url,
|
||||
bool* allow_os_execution)
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, handle_protocol_execution))
|
||||
return RV_CONTINUE;
|
||||
|
||||
int allowExec = *allow_os_execution?1:0;
|
||||
cef_retval_t rv = struct_->handle_protocol_execution(struct_,
|
||||
CefBrowserCppToC::Wrap(browser), url.GetStruct(), &allowExec);
|
||||
*allow_os_execution = allowExec?true:false;
|
||||
return rv;
|
||||
}
|
||||
|
||||
CefHandler::RetVal CefHandlerCToCpp::HandleDownloadResponse(
|
||||
CefRefPtr<CefBrowser> browser, const CefString& mimeType,
|
||||
const CefString& fileName, int64 contentLength,
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
CefRefPtr<CefRequest> request, CefString& redirectUrl,
|
||||
CefRefPtr<CefStreamReader>& resourceStream, CefString& mimeType,
|
||||
int loadFlags);
|
||||
virtual RetVal HandleProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url, bool* allow_os_execution);
|
||||
virtual RetVal HandleDownloadResponse(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& mimeType, const CefString& fileName,
|
||||
int64 contentLength, CefRefPtr<CefDownloadHandler>& handler);
|
||||
|
|
|
@ -115,6 +115,22 @@ public:
|
|||
CefString& mimeType,
|
||||
int loadFlags);
|
||||
|
||||
// Called to handle requests for URLs with an unknown protocol component.
|
||||
// Return RV_HANDLED to indicate that the request should succeed because it
|
||||
// was externally handled. Set |allow_os_execution| to true and return
|
||||
// RV_CONTINUE to attempt execution via the registered OS protocol handler,
|
||||
// if any. If RV_CONTINUE is returned and either |allow_os_execution| is false
|
||||
// or OS protocol handler execution fails then the request will fail with an
|
||||
// error condition.
|
||||
// SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED
|
||||
// ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION.
|
||||
virtual RetVal HandleProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url,
|
||||
bool* allow_os_execution)
|
||||
{
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
// Called when a server indicates via the 'Content-Disposition' header that a
|
||||
// response represents a file to download. |mime_type| is the mime type for
|
||||
// the download, |file_name| is the suggested target file name and
|
||||
|
|
|
@ -114,6 +114,13 @@ public:
|
|||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
virtual RetVal HandleProtocolExecution(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url,
|
||||
bool* allow_os_execution)
|
||||
{
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
virtual RetVal HandleDownloadResponse(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& mimeType,
|
||||
const CefString& fileName,
|
||||
|
|
Loading…
Reference in New Issue