libcef:
- Add support for custom scheme handlers (entry #49, initial version by heshiming). cefclient: - Add custom scheme handler test. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@37 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
f341b9f439
commit
087319efdb
|
@ -50,6 +50,8 @@ class CefHandler;
|
||||||
class CefPostData;
|
class CefPostData;
|
||||||
class CefPostDataElement;
|
class CefPostDataElement;
|
||||||
class CefRequest;
|
class CefRequest;
|
||||||
|
class CefSchemeHandler;
|
||||||
|
class CefSchemeHandlerFactory;
|
||||||
class CefStreamReader;
|
class CefStreamReader;
|
||||||
class CefStreamWriter;
|
class CefStreamWriter;
|
||||||
class CefV8Handler;
|
class CefV8Handler;
|
||||||
|
@ -141,6 +143,16 @@ bool CefRegisterExtension(const std::wstring& extension_name,
|
||||||
CefRefPtr<CefV8Handler> handler);
|
CefRefPtr<CefV8Handler> handler);
|
||||||
|
|
||||||
|
|
||||||
|
// Register a custom scheme handler factory for the specified |scheme_name| and
|
||||||
|
// |host_name|. All URLs beginning with scheme_name://host_name/ can be handled
|
||||||
|
// by CefSchemeHandler instances returned by the factory. Specify an empty
|
||||||
|
// |host_name| value to match all host names.
|
||||||
|
/*--cef()--*/
|
||||||
|
bool CefRegisterScheme(const std::wstring& scheme_name,
|
||||||
|
const std::wstring& host_name,
|
||||||
|
CefRefPtr<CefSchemeHandlerFactory> factory);
|
||||||
|
|
||||||
|
|
||||||
// Interface defining the the reference count implementation methods. All
|
// Interface defining the the reference count implementation methods. All
|
||||||
// framework classes must implement the CefBase class.
|
// framework classes must implement the CefBase class.
|
||||||
class CefBase
|
class CefBase
|
||||||
|
@ -930,4 +942,47 @@ public:
|
||||||
std::wstring& exception) =0;
|
std::wstring& exception) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class that creates CefSchemeHandler instances.
|
||||||
|
/*--cef(source=client)--*/
|
||||||
|
class CefSchemeHandlerFactory : public CefBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Return a new scheme handler instance to handle the request.
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual CefRefPtr<CefSchemeHandler> Create() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class used to represent a custom scheme handler interface.
|
||||||
|
/*--cef(source=client)--*/
|
||||||
|
class CefSchemeHandler : public CefBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Process the request. All response generation should take place in this
|
||||||
|
// method. If there is no response set |response_length| to zero and
|
||||||
|
// ReadResponse() will not be called. If the response length is not known then
|
||||||
|
// set |response_length| to -1 and ReadResponse() will be called until it
|
||||||
|
// returns false or until the value of |bytes_read| is set to 0. Otherwise,
|
||||||
|
// set |response_length| to a positive value and ReadResponse() will be called
|
||||||
|
// until it returns false, the value of |bytes_read| is set to 0 or the
|
||||||
|
// specified number of bytes have been read. If there is a response set
|
||||||
|
// |mime_type| to the mime type for the response.
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||||
|
std::wstring& mime_type, int* response_length) =0;
|
||||||
|
|
||||||
|
// Cancel processing of the request.
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void Cancel() =0;
|
||||||
|
|
||||||
|
// Copy up to |bytes_to_read| bytes into |data_out|. If the copy succeeds
|
||||||
|
// set |bytes_read| to the number of bytes copied and return true. If the
|
||||||
|
// copy fails return false and ReadResponse() will not be called again.
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool ReadResponse(void* data_out, int bytes_to_read,
|
||||||
|
int* bytes_read) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // _CEF_H
|
#endif // _CEF_H
|
||||||
|
|
|
@ -126,6 +126,13 @@ CEF_EXPORT void cef_do_message_loop_work();
|
||||||
CEF_EXPORT int cef_register_extension(const wchar_t* extension_name,
|
CEF_EXPORT int cef_register_extension(const wchar_t* extension_name,
|
||||||
const wchar_t* javascript_code, struct _cef_v8handler_t* handler);
|
const wchar_t* javascript_code, struct _cef_v8handler_t* handler);
|
||||||
|
|
||||||
|
// Register a custom scheme handler factory for the specified |scheme_name| and
|
||||||
|
// |host_name|. All URLs beginning with scheme_name://host_name/ can be handled
|
||||||
|
// by cef_scheme_handler_t instances returned by the factory. Specify an NULL
|
||||||
|
// |host_name| value to match all host names.
|
||||||
|
CEF_EXPORT int cef_register_scheme(const wchar_t* scheme_name,
|
||||||
|
const wchar_t* host_name, struct _cef_scheme_handler_factory_t* factory);
|
||||||
|
|
||||||
typedef struct _cef_base_t
|
typedef struct _cef_base_t
|
||||||
{
|
{
|
||||||
// Size of the data structure.
|
// Size of the data structure.
|
||||||
|
@ -769,6 +776,50 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_function(const wchar_t* name,
|
||||||
cef_v8handler_t* handler);
|
cef_v8handler_t* handler);
|
||||||
|
|
||||||
|
|
||||||
|
// Structure that creates cef_scheme_handler_t instances.
|
||||||
|
typedef struct _cef_scheme_handler_factory_t
|
||||||
|
{
|
||||||
|
// Base structure.
|
||||||
|
cef_base_t base;
|
||||||
|
|
||||||
|
// Return a new scheme handler instance to handle the request.
|
||||||
|
struct _cef_scheme_handler_t* (CEF_CALLBACK *create)(
|
||||||
|
struct _cef_scheme_handler_factory_t* self);
|
||||||
|
|
||||||
|
} cef_scheme_handler_factory_t;
|
||||||
|
|
||||||
|
|
||||||
|
// Structure used to represent a custom scheme handler structure.
|
||||||
|
typedef struct _cef_scheme_handler_t
|
||||||
|
{
|
||||||
|
// Base structure.
|
||||||
|
cef_base_t base;
|
||||||
|
|
||||||
|
// Process the request. All response generation should take place in this
|
||||||
|
// function. If there is no response set |response_length| to zero and
|
||||||
|
// read_response() will not be called. If the response length is not known
|
||||||
|
// then set |response_length| to -1 and read_response() will be called until
|
||||||
|
// it returns false (0) or until the value of |bytes_read| is set to 0.
|
||||||
|
// Otherwise, set |response_length| to a positive value and read_response()
|
||||||
|
// will be called until it returns false (0), the value of |bytes_read| is set
|
||||||
|
// to 0 or the specified number of bytes have been read. If there is a
|
||||||
|
// response set |mime_type| to the mime type for the response.
|
||||||
|
int (CEF_CALLBACK *process_request)(struct _cef_scheme_handler_t* self,
|
||||||
|
struct _cef_request_t* request, cef_string_t* mime_type,
|
||||||
|
int* response_length);
|
||||||
|
|
||||||
|
// Cancel processing of the request.
|
||||||
|
void (CEF_CALLBACK *cancel)(struct _cef_scheme_handler_t* self);
|
||||||
|
|
||||||
|
// Copy up to |bytes_to_read| bytes into |data_out|. If the copy succeeds set
|
||||||
|
// |bytes_read| to the number of bytes copied and return true (1). If the copy
|
||||||
|
// fails return false (0) and read_response() will not be called again.
|
||||||
|
int (CEF_CALLBACK *read_response)(struct _cef_scheme_handler_t* self,
|
||||||
|
void* data_out, int bytes_to_read, int* bytes_read);
|
||||||
|
|
||||||
|
} cef_scheme_handler_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -373,6 +373,10 @@
|
||||||
RelativePath=".\request_impl.h"
|
RelativePath=".\request_impl.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\scheme_impl.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\simple_clipboard_impl.cc"
|
RelativePath=".\simple_clipboard_impl.cc"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,411 @@
|
||||||
|
// Copyright (c) 2009 The Chromium Embedded Framework Authors.
|
||||||
|
// Portions copyright (c) 2006-2009 The Chromium 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 "precompiled_libcef.h"
|
||||||
|
#include "base/lazy_instance.h"
|
||||||
|
#include "base/message_loop.h"
|
||||||
|
#include "base/string_util.h"
|
||||||
|
#include "base/worker_pool.h"
|
||||||
|
#include "net/base/completion_callback.h"
|
||||||
|
#include "net/base/io_buffer.h"
|
||||||
|
#include "net/base/upload_data.h"
|
||||||
|
#include "net/http/http_util.h"
|
||||||
|
#include "net/url_request/url_request.h"
|
||||||
|
#include "net/url_request/url_request_filter.h"
|
||||||
|
#include "net/url_request/url_request_job.h"
|
||||||
|
|
||||||
|
#include "include/cef.h"
|
||||||
|
#include "tracker.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "request_impl.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
// Memory manager.
|
||||||
|
|
||||||
|
base::LazyInstance<CefTrackManager> g_scheme_tracker(base::LINKER_INITIALIZED);
|
||||||
|
|
||||||
|
class TrackBase : public CefTrackObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TrackBase(CefBase* base) { base_ = base; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CefRefPtr<CefBase> base_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void TrackAdd(CefTrackObject* object)
|
||||||
|
{
|
||||||
|
g_scheme_tracker.Pointer()->Add(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TrackDelete(CefTrackObject* object)
|
||||||
|
{
|
||||||
|
g_scheme_tracker.Pointer()->Delete(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// URLRequestJob implementation.
|
||||||
|
|
||||||
|
class CefUrlRequestJob : public URLRequestJob {
|
||||||
|
public:
|
||||||
|
CefUrlRequestJob(URLRequest* request, CefRefPtr<CefSchemeHandler> handler)
|
||||||
|
: URLRequestJob(request),
|
||||||
|
url_(request->url()),
|
||||||
|
handler_(handler),
|
||||||
|
response_length_(0),
|
||||||
|
remaining_bytes_(0) { }
|
||||||
|
|
||||||
|
virtual ~CefUrlRequestJob(){}
|
||||||
|
|
||||||
|
virtual void Start()
|
||||||
|
{
|
||||||
|
handler_->Cancel();
|
||||||
|
// Continue asynchronously.
|
||||||
|
DCHECK(!async_resolver_);
|
||||||
|
async_resolver_ = new AsyncResolver(this);
|
||||||
|
WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(
|
||||||
|
async_resolver_.get(), &AsyncResolver::Resolve, url_), true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Kill()
|
||||||
|
{
|
||||||
|
if (async_resolver_) {
|
||||||
|
async_resolver_->Cancel();
|
||||||
|
async_resolver_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
URLRequestJob::Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool ReadRawData(net::IOBuffer* dest, int dest_size, int *bytes_read)
|
||||||
|
{
|
||||||
|
DCHECK_NE(dest_size, 0);
|
||||||
|
DCHECK(bytes_read);
|
||||||
|
|
||||||
|
// When remaining_bytes_>=0, it means the handler knows the content size
|
||||||
|
// before hand. We continue to read until
|
||||||
|
if (remaining_bytes_>=0) {
|
||||||
|
if (remaining_bytes_ < dest_size)
|
||||||
|
dest_size = static_cast<int>(remaining_bytes_);
|
||||||
|
|
||||||
|
// If we should copy zero bytes because |remaining_bytes_| is zero, short
|
||||||
|
// circuit here.
|
||||||
|
if (!dest_size) {
|
||||||
|
*bytes_read = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remaining_bytes > 0
|
||||||
|
bool rv = handler_->ReadResponse(dest->data(), dest_size, bytes_read);
|
||||||
|
remaining_bytes_ -= *bytes_read;
|
||||||
|
if (!rv) {
|
||||||
|
// handler indicated no further data to read
|
||||||
|
*bytes_read = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The handler returns -1 for GetResponseLength, this means the handler
|
||||||
|
// doesn't know the content size before hand. We do basically the same
|
||||||
|
// thing, except for checking the return value for handler_->ReadResponse,
|
||||||
|
// which is an indicator for no further data to be read.
|
||||||
|
bool rv = handler_->ReadResponse(dest->data(), dest_size, bytes_read);
|
||||||
|
if (!rv)
|
||||||
|
// handler indicated no further data to read
|
||||||
|
*bytes_read = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool IsRedirectResponse(GURL* location, int* http_status_code)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetContentEncodings(
|
||||||
|
std::vector<Filter::FilterType>* encoding_types)
|
||||||
|
{
|
||||||
|
DCHECK(encoding_types->empty());
|
||||||
|
|
||||||
|
return !encoding_types->empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetMimeType(std::string* mime_type) const
|
||||||
|
{
|
||||||
|
DCHECK(request_);
|
||||||
|
// call handler to get mime type
|
||||||
|
*mime_type = mime_type_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void SetExtraRequestHeaders(const std::string& headers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefSchemeHandler> handler_;
|
||||||
|
std::string mime_type_;
|
||||||
|
int response_length_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GURL url_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DidResolve(const GURL& url)
|
||||||
|
{
|
||||||
|
async_resolver_ = NULL;
|
||||||
|
|
||||||
|
// We may have been orphaned...
|
||||||
|
if (!request_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
remaining_bytes_ = response_length_;
|
||||||
|
if (remaining_bytes_>0)
|
||||||
|
set_expected_content_size(remaining_bytes_);
|
||||||
|
NotifyHeadersComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 remaining_bytes_;
|
||||||
|
std::string m_response;
|
||||||
|
|
||||||
|
class AsyncResolver :
|
||||||
|
public base::RefCountedThreadSafe<AsyncResolver> {
|
||||||
|
public:
|
||||||
|
explicit AsyncResolver(CefUrlRequestJob* owner)
|
||||||
|
: owner_(owner), owner_loop_(MessageLoop::current()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resolve(const GURL& url) {
|
||||||
|
AutoLock locked(lock_);
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// safe to perform long operation here
|
||||||
|
CefRefPtr<CefRequest> req(CefRequest::CreateRequest());
|
||||||
|
req->SetURL(UTF8ToWide(url.spec()));
|
||||||
|
req->SetMethod(UTF8ToWide(owner_->request()->method()));
|
||||||
|
|
||||||
|
// check to see if we have post data
|
||||||
|
net::UploadData* data = owner_->request()->get_upload();
|
||||||
|
if (data) {
|
||||||
|
CefRefPtr<CefPostData> postdata(CefPostData::CreatePostData());
|
||||||
|
static_cast<CefPostDataImpl*>(postdata.get())->Set(*data);
|
||||||
|
req->SetPostData(postdata);
|
||||||
|
}
|
||||||
|
owner_->handler_->Cancel();
|
||||||
|
std::wstring mime_type;
|
||||||
|
int response_length = 0;
|
||||||
|
// handler should complete content generation in ProcessRequest
|
||||||
|
bool res = owner_->handler_->ProcessRequest(req, mime_type,
|
||||||
|
&response_length);
|
||||||
|
if (res) {
|
||||||
|
owner_->mime_type_ = WideToUTF8(mime_type);
|
||||||
|
owner_->response_length_ = response_length;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
if (owner_loop_) {
|
||||||
|
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
|
||||||
|
this, &AsyncResolver::ReturnResults, url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cancel() {
|
||||||
|
owner_->handler_->Cancel();
|
||||||
|
|
||||||
|
owner_ = NULL;
|
||||||
|
|
||||||
|
AutoLock locked(lock_);
|
||||||
|
owner_loop_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ReturnResults(const GURL& url) {
|
||||||
|
if (owner_)
|
||||||
|
owner_->DidResolve(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
CefUrlRequestJob* owner_;
|
||||||
|
|
||||||
|
Lock lock_;
|
||||||
|
MessageLoop* owner_loop_;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class AsyncResolver;
|
||||||
|
scoped_refptr<AsyncResolver> async_resolver_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CefUrlRequestJob);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// URLRequestFilter clone that manages the CefSchemeHandlerFactory pointers.
|
||||||
|
|
||||||
|
class CefUrlRequestFilter {
|
||||||
|
public:
|
||||||
|
// scheme,hostname -> ProtocolFactory
|
||||||
|
typedef std::map<std::pair<std::string, std::string>,
|
||||||
|
CefSchemeHandlerFactory*> HandlerMap;
|
||||||
|
|
||||||
|
// Singleton instance for use.
|
||||||
|
static CefUrlRequestFilter* GetInstance()
|
||||||
|
{
|
||||||
|
if (!shared_instance_)
|
||||||
|
shared_instance_ = new CefUrlRequestFilter;
|
||||||
|
return shared_instance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static URLRequestJob* Factory(URLRequest* request,
|
||||||
|
const std::string& scheme)
|
||||||
|
{
|
||||||
|
// Returning null here just means that the built-in handler will be used.
|
||||||
|
return GetInstance()->FindRequestHandler(request, scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddHostnameHandler(const std::string& scheme,
|
||||||
|
const std::string& hostname,
|
||||||
|
CefSchemeHandlerFactory* factory)
|
||||||
|
{
|
||||||
|
handler_map_[make_pair(scheme, hostname)] = factory;
|
||||||
|
|
||||||
|
// Register with the ProtocolFactory.
|
||||||
|
URLRequest::RegisterProtocolFactory(scheme,
|
||||||
|
&CefUrlRequestFilter::Factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveHostnameHandler(const std::string& scheme,
|
||||||
|
const std::string& hostname)
|
||||||
|
{
|
||||||
|
HandlerMap::iterator iter =
|
||||||
|
handler_map_.find(make_pair(scheme, hostname));
|
||||||
|
DCHECK(iter != handler_map_.end());
|
||||||
|
|
||||||
|
handler_map_.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all the existing URL handlers and unregister with the
|
||||||
|
// ProtocolFactory. Resets the hit count.
|
||||||
|
void ClearHandlers()
|
||||||
|
{
|
||||||
|
// Unregister with the ProtocolFactory.
|
||||||
|
std::set<std::string> schemes;
|
||||||
|
for (HandlerMap::const_iterator i = handler_map_.begin();
|
||||||
|
i != handler_map_.end(); ++i) {
|
||||||
|
schemes.insert(i->first.first);
|
||||||
|
}
|
||||||
|
for (std::set<std::string>::const_iterator scheme = schemes.begin();
|
||||||
|
scheme != schemes.end(); ++scheme) {
|
||||||
|
URLRequest::RegisterProtocolFactory(*scheme, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler_map_.clear();
|
||||||
|
hit_count_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefSchemeHandlerFactory* FindRequestHandlerFactory(URLRequest* request,
|
||||||
|
const std::string& scheme)
|
||||||
|
{
|
||||||
|
CefSchemeHandlerFactory* factory = NULL;
|
||||||
|
if (request->url().is_valid()) {
|
||||||
|
// Check for a map with a hostname first.
|
||||||
|
const std::string& hostname = request->url().host();
|
||||||
|
|
||||||
|
HandlerMap::iterator i = handler_map_.find(make_pair(scheme, hostname));
|
||||||
|
if (i != handler_map_.end())
|
||||||
|
factory = i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!factory) {
|
||||||
|
// Check for a map with no specified hostname.
|
||||||
|
HandlerMap::iterator i =
|
||||||
|
handler_map_.find(make_pair(scheme, std::string()));
|
||||||
|
if (i != handler_map_.end())
|
||||||
|
factory = i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the number of times a handler was used to service a request.
|
||||||
|
int hit_count() const { return hit_count_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CefUrlRequestFilter() : hit_count_(0) { }
|
||||||
|
|
||||||
|
// Helper method that looks up the request in the handler_map_.
|
||||||
|
URLRequestJob* FindRequestHandler(URLRequest* request,
|
||||||
|
const std::string& scheme)
|
||||||
|
{
|
||||||
|
URLRequestJob* job = NULL;
|
||||||
|
CefSchemeHandlerFactory* factory =
|
||||||
|
FindRequestHandlerFactory(request, scheme);
|
||||||
|
if (factory) {
|
||||||
|
CefRefPtr<CefSchemeHandler> handler = factory->Create();
|
||||||
|
if (handler.get())
|
||||||
|
job = new CefUrlRequestJob(request, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (job) {
|
||||||
|
DLOG(INFO) << "URLRequestFilter hit for " << request->url().spec();
|
||||||
|
hit_count_++;
|
||||||
|
}
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maps hostnames to factories. Hostnames take priority over URLs.
|
||||||
|
HandlerMap handler_map_;
|
||||||
|
|
||||||
|
int hit_count_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Singleton instance.
|
||||||
|
static CefUrlRequestFilter* shared_instance_;
|
||||||
|
|
||||||
|
DISALLOW_EVIL_CONSTRUCTORS(CefUrlRequestFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
CefUrlRequestFilter* CefUrlRequestFilter::shared_instance_ = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
class SchemeRequestJobWrapper {
|
||||||
|
public:
|
||||||
|
SchemeRequestJobWrapper(const std::string& scheme_name,
|
||||||
|
const std::string& host_name,
|
||||||
|
CefSchemeHandlerFactory* factory)
|
||||||
|
: factory_(factory), scheme_name_(scheme_name), host_name_(host_name)
|
||||||
|
{
|
||||||
|
// The reference will be released when the application exits.
|
||||||
|
TrackAdd(new TrackBase(factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterScheme()
|
||||||
|
{
|
||||||
|
// we need to store the pointer of this handler because
|
||||||
|
// we can't pass it as a parameter to the factory method
|
||||||
|
CefUrlRequestFilter::GetInstance()->AddHostnameHandler(
|
||||||
|
scheme_name_, host_name_, factory_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddRef() {}
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CefSchemeHandlerFactory* factory_;
|
||||||
|
std::string scheme_name_;
|
||||||
|
std::string host_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CefRegisterScheme(const std::wstring& scheme_name,
|
||||||
|
const std::wstring& host_name,
|
||||||
|
CefRefPtr<CefSchemeHandlerFactory> factory)
|
||||||
|
{
|
||||||
|
// Verify that the context is already initialized
|
||||||
|
if(!_Context.get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SchemeRequestJobWrapper* wrapper = new SchemeRequestJobWrapper(
|
||||||
|
WideToUTF8(scheme_name), WideToUTF8(host_name), factory);
|
||||||
|
|
||||||
|
PostTask(FROM_HERE, NewRunnableMethod(wrapper,
|
||||||
|
&SchemeRequestJobWrapper::RegisterScheme));
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// A portion of this file was generated by the CEF translator tool. When
|
||||||
|
// making changes by hand only do so within the body of existing function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../precompiled_libcef.h"
|
||||||
|
#include "cpptoc/scheme_handler_cpptoc.h"
|
||||||
|
#include "ctocpp/request_ctocpp.h"
|
||||||
|
#include "../transfer_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
int CEF_CALLBACK scheme_handler_process_request(
|
||||||
|
struct _cef_scheme_handler_t* self, cef_request_t* request,
|
||||||
|
cef_string_t* mime_type, int* response_length)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
DCHECK(request);
|
||||||
|
DCHECK(mime_type);
|
||||||
|
DCHECK(response_length);
|
||||||
|
if(!self || !request || !mime_type || !response_length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::wstring mimeTypeStr;
|
||||||
|
if(*mime_type)
|
||||||
|
mimeTypeStr = *mime_type;
|
||||||
|
|
||||||
|
bool rv = CefSchemeHandlerCppToC::Get(self)->ProcessRequest(
|
||||||
|
CefRequestCToCpp::Wrap(request), mimeTypeStr, response_length);
|
||||||
|
|
||||||
|
transfer_string_contents(mimeTypeStr, mime_type);
|
||||||
|
|
||||||
|
return rv?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK scheme_handler_cancel(struct _cef_scheme_handler_t* self)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
if(!self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefSchemeHandlerCppToC::Get(self)->Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CEF_CALLBACK scheme_handler_read_response(
|
||||||
|
struct _cef_scheme_handler_t* self, void* data_out, int bytes_to_read,
|
||||||
|
int* bytes_read)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
DCHECK(data_out);
|
||||||
|
DCHECK(bytes_read);
|
||||||
|
if(!self || !data_out || !bytes_read)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bool rv = CefSchemeHandlerCppToC::Get(self)->ReadResponse(
|
||||||
|
data_out, bytes_to_read, bytes_read);
|
||||||
|
|
||||||
|
return rv?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSchemeHandlerCppToC::CefSchemeHandlerCppToC(CefSchemeHandler* cls)
|
||||||
|
: CefCppToC<CefSchemeHandlerCppToC, CefSchemeHandler, cef_scheme_handler_t>(
|
||||||
|
cls)
|
||||||
|
{
|
||||||
|
struct_.struct_.process_request = scheme_handler_process_request;
|
||||||
|
struct_.struct_.cancel = scheme_handler_cancel;
|
||||||
|
struct_.struct_.read_response = scheme_handler_read_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
long CefCppToC<CefSchemeHandlerCppToC, CefSchemeHandler,
|
||||||
|
cef_scheme_handler_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
#ifndef _SCHEMEHANDLER_CPPTOC_H
|
||||||
|
#define _SCHEMEHANDLER_CPPTOC_H
|
||||||
|
|
||||||
|
#ifndef USING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
|
||||||
|
#else // USING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "cef.h"
|
||||||
|
#include "cef_capi.h"
|
||||||
|
#include "cpptoc.h"
|
||||||
|
|
||||||
|
// Wrap a C++ class with a C structure.
|
||||||
|
// This class may be instantiated and accessed wrapper-side only.
|
||||||
|
class CefSchemeHandlerCppToC
|
||||||
|
: public CefCppToC<CefSchemeHandlerCppToC, CefSchemeHandler,
|
||||||
|
cef_scheme_handler_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CefSchemeHandlerCppToC(CefSchemeHandler* cls);
|
||||||
|
virtual ~CefSchemeHandlerCppToC() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // USING_CEF_SHARED
|
||||||
|
#endif // _SCHEMEHANDLER_CPPTOC_H
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// A portion of this file was generated by the CEF translator tool. When
|
||||||
|
// making changes by hand only do so within the body of existing function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../precompiled_libcef.h"
|
||||||
|
#include "cpptoc/scheme_handler_cpptoc.h"
|
||||||
|
#include "cpptoc/scheme_handler_factory_cpptoc.h"
|
||||||
|
|
||||||
|
|
||||||
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
struct _cef_scheme_handler_t* CEF_CALLBACK scheme_handler_factory_create(
|
||||||
|
struct _cef_scheme_handler_factory_t* self)
|
||||||
|
{
|
||||||
|
CefRefPtr<CefSchemeHandler> rv =
|
||||||
|
CefSchemeHandlerFactoryCppToC::Get(self)->Create();
|
||||||
|
|
||||||
|
return CefSchemeHandlerCppToC::Wrap(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefSchemeHandlerFactoryCppToC::CefSchemeHandlerFactoryCppToC(
|
||||||
|
CefSchemeHandlerFactory* cls)
|
||||||
|
: CefCppToC<CefSchemeHandlerFactoryCppToC, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>(cls)
|
||||||
|
{
|
||||||
|
struct_.struct_.create = scheme_handler_factory_create;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
long CefCppToC<CefSchemeHandlerFactoryCppToC, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
#ifndef _SCHEMEHANDLERFACTORY_CPPTOC_H
|
||||||
|
#define _SCHEMEHANDLERFACTORY_CPPTOC_H
|
||||||
|
|
||||||
|
#ifndef USING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
|
||||||
|
#else // USING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "cef.h"
|
||||||
|
#include "cef_capi.h"
|
||||||
|
#include "cpptoc.h"
|
||||||
|
|
||||||
|
// Wrap a C++ class with a C structure.
|
||||||
|
// This class may be instantiated and accessed wrapper-side only.
|
||||||
|
class CefSchemeHandlerFactoryCppToC
|
||||||
|
: public CefCppToC<CefSchemeHandlerFactoryCppToC, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CefSchemeHandlerFactoryCppToC(CefSchemeHandlerFactory* cls);
|
||||||
|
virtual ~CefSchemeHandlerFactoryCppToC() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // USING_CEF_SHARED
|
||||||
|
#endif // _SCHEMEHANDLERFACTORY_CPPTOC_H
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// A portion of this file was generated by the CEF translator tool. When
|
||||||
|
// making changes by hand only do so within the body of existing static and
|
||||||
|
// virtual method implementations. See the translator.README.txt file in the
|
||||||
|
// tools directory for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../precompiled_libcef.h"
|
||||||
|
#include "cpptoc/request_cpptoc.h"
|
||||||
|
#include "ctocpp/scheme_handler_ctocpp.h"
|
||||||
|
#include "../transfer_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
// VIRTUAL METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
bool CefSchemeHandlerCToCpp::ProcessRequest(CefRefPtr<CefRequest> request,
|
||||||
|
std::wstring& mime_type, int* response_length)
|
||||||
|
{
|
||||||
|
if(CEF_MEMBER_MISSING(struct_, process_request))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cef_string_t mimeTypeRet = NULL;
|
||||||
|
if(!mime_type.empty())
|
||||||
|
mimeTypeRet = cef_string_alloc(mime_type.c_str());
|
||||||
|
|
||||||
|
int rv = struct_->process_request(struct_, CefRequestCppToC::Wrap(request),
|
||||||
|
&mimeTypeRet, response_length);
|
||||||
|
|
||||||
|
transfer_string_contents(mimeTypeRet, mime_type, true);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefSchemeHandlerCToCpp::Cancel()
|
||||||
|
{
|
||||||
|
if(CEF_MEMBER_MISSING(struct_, cancel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct_->cancel(struct_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CefSchemeHandlerCToCpp::ReadResponse(void* data_out, int bytes_to_read,
|
||||||
|
int* bytes_read)
|
||||||
|
{
|
||||||
|
if(CEF_MEMBER_MISSING(struct_, read_response))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return struct_->read_response(struct_, data_out, bytes_to_read, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
long CefCToCpp<CefSchemeHandlerCToCpp, CefSchemeHandler,
|
||||||
|
cef_scheme_handler_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _SCHEMEHANDLER_CTOCPP_H
|
||||||
|
#define _SCHEMEHANDLER_CTOCPP_H
|
||||||
|
|
||||||
|
#ifndef BUILDING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||||
|
#else // BUILDING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "cef.h"
|
||||||
|
#include "cef_capi.h"
|
||||||
|
#include "ctocpp.h"
|
||||||
|
|
||||||
|
// Wrap a C structure with a C++ class.
|
||||||
|
// This class may be instantiated and accessed DLL-side only.
|
||||||
|
class CefSchemeHandlerCToCpp
|
||||||
|
: public CefCToCpp<CefSchemeHandlerCToCpp, CefSchemeHandler,
|
||||||
|
cef_scheme_handler_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CefSchemeHandlerCToCpp(cef_scheme_handler_t* str)
|
||||||
|
: CefCToCpp<CefSchemeHandlerCToCpp, CefSchemeHandler,
|
||||||
|
cef_scheme_handler_t>(str) {}
|
||||||
|
virtual ~CefSchemeHandlerCToCpp() {}
|
||||||
|
|
||||||
|
// CefSchemeHandler methods
|
||||||
|
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||||
|
std::wstring& mime_type, int* response_length);
|
||||||
|
virtual void Cancel();
|
||||||
|
virtual bool ReadResponse(void* data_out, int bytes_to_read, int* bytes_read);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUILDING_CEF_SHARED
|
||||||
|
#endif // _SCHEMEHANDLER_CTOCPP_H
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// A portion of this file was generated by the CEF translator tool. When
|
||||||
|
// making changes by hand only do so within the body of existing static and
|
||||||
|
// virtual method implementations. See the translator.README.txt file in the
|
||||||
|
// tools directory for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../precompiled_libcef.h"
|
||||||
|
#include "ctocpp/scheme_handler_ctocpp.h"
|
||||||
|
#include "ctocpp/scheme_handler_factory_ctocpp.h"
|
||||||
|
|
||||||
|
|
||||||
|
// VIRTUAL METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
CefRefPtr<CefSchemeHandler> CefSchemeHandlerFactoryCToCpp::Create()
|
||||||
|
{
|
||||||
|
if(CEF_MEMBER_MISSING(struct_, create))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_cef_scheme_handler_t* rv = struct_->create(struct_);
|
||||||
|
|
||||||
|
return CefSchemeHandlerCToCpp::Wrap(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
long CefCToCpp<CefSchemeHandlerFactoryCToCpp, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2009 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.
|
||||||
|
//
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _SCHEMEHANDLERFACTORY_CTOCPP_H
|
||||||
|
#define _SCHEMEHANDLERFACTORY_CTOCPP_H
|
||||||
|
|
||||||
|
#ifndef BUILDING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||||
|
#else // BUILDING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "cef.h"
|
||||||
|
#include "cef_capi.h"
|
||||||
|
#include "ctocpp.h"
|
||||||
|
|
||||||
|
// Wrap a C structure with a C++ class.
|
||||||
|
// This class may be instantiated and accessed DLL-side only.
|
||||||
|
class CefSchemeHandlerFactoryCToCpp
|
||||||
|
: public CefCToCpp<CefSchemeHandlerFactoryCToCpp, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CefSchemeHandlerFactoryCToCpp(cef_scheme_handler_factory_t* str)
|
||||||
|
: CefCToCpp<CefSchemeHandlerFactoryCToCpp, CefSchemeHandlerFactory,
|
||||||
|
cef_scheme_handler_factory_t>(str) {}
|
||||||
|
virtual ~CefSchemeHandlerFactoryCToCpp() {}
|
||||||
|
|
||||||
|
// CefSchemeHandlerFactory methods
|
||||||
|
virtual CefRefPtr<CefSchemeHandler> Create();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUILDING_CEF_SHARED
|
||||||
|
#endif // _SCHEMEHANDLERFACTORY_CTOCPP_H
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "cpptoc/stream_writer_cpptoc.h"
|
#include "cpptoc/stream_writer_cpptoc.h"
|
||||||
#include "cpptoc/v8value_cpptoc.h"
|
#include "cpptoc/v8value_cpptoc.h"
|
||||||
#include "ctocpp/handler_ctocpp.h"
|
#include "ctocpp/handler_ctocpp.h"
|
||||||
|
#include "ctocpp/scheme_handler_ctocpp.h"
|
||||||
|
#include "ctocpp/scheme_handler_factory_ctocpp.h"
|
||||||
#include "ctocpp/v8handler_ctocpp.h"
|
#include "ctocpp/v8handler_ctocpp.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
|
|
||||||
|
@ -43,6 +45,8 @@ CEF_EXPORT void cef_shutdown()
|
||||||
DCHECK(CefStreamWriterCppToC::DebugObjCt == 0);
|
DCHECK(CefStreamWriterCppToC::DebugObjCt == 0);
|
||||||
DCHECK(CefV8ValueCppToC::DebugObjCt == 0);
|
DCHECK(CefV8ValueCppToC::DebugObjCt == 0);
|
||||||
DCHECK(CefHandlerCToCpp::DebugObjCt == 0);
|
DCHECK(CefHandlerCToCpp::DebugObjCt == 0);
|
||||||
|
DCHECK(CefSchemeHandlerCToCpp::DebugObjCt == 0);
|
||||||
|
DCHECK(CefSchemeHandlerFactoryCToCpp::DebugObjCt == 0);
|
||||||
DCHECK(CefV8HandlerCToCpp::DebugObjCt == 0);
|
DCHECK(CefV8HandlerCToCpp::DebugObjCt == 0);
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
}
|
}
|
||||||
|
@ -107,3 +111,22 @@ CEF_EXPORT int cef_register_plugin(const cef_plugin_info_t* plugin_info)
|
||||||
|
|
||||||
return CefRegisterPlugin(pluginInfo);
|
return CefRegisterPlugin(pluginInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CEF_EXPORT int cef_register_scheme(const wchar_t* scheme_name,
|
||||||
|
const wchar_t* host_name, struct _cef_scheme_handler_factory_t* factory)
|
||||||
|
{
|
||||||
|
DCHECK(scheme_name);
|
||||||
|
DCHECK(factory);
|
||||||
|
if(!scheme_name || !factory)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::wstring nameStr, codeStr;
|
||||||
|
|
||||||
|
if(scheme_name)
|
||||||
|
nameStr = scheme_name;
|
||||||
|
if(host_name)
|
||||||
|
codeStr = host_name;
|
||||||
|
|
||||||
|
return CefRegisterScheme(nameStr, codeStr,
|
||||||
|
CefSchemeHandlerFactoryCToCpp::Wrap(factory));
|
||||||
|
}
|
||||||
|
|
|
@ -430,6 +430,54 @@
|
||||||
RelativePath=".\ctocpp\handler_ctocpp.h"
|
RelativePath=".\ctocpp\handler_ctocpp.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ctocpp\scheme_handler_ctocpp.cc"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PrecompiledHeaderThrough="../precompiled_libcef.h"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PrecompiledHeaderThrough="../precompiled_libcef.h"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ctocpp\scheme_handler_ctocpp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ctocpp\scheme_handler_factory_ctocpp.cc"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PrecompiledHeaderThrough="../precompiled_libcef.h"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PrecompiledHeaderThrough="../precompiled_libcef.h"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ctocpp\scheme_handler_factory_ctocpp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\ctocpp\v8handler_ctocpp.cc"
|
RelativePath=".\ctocpp\v8handler_ctocpp.cc"
|
||||||
>
|
>
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "cef_nplugin.h"
|
#include "cef_nplugin.h"
|
||||||
#include "cef_nplugin_capi.h"
|
#include "cef_nplugin_capi.h"
|
||||||
#include "../cpptoc/handler_cpptoc.h"
|
#include "../cpptoc/handler_cpptoc.h"
|
||||||
|
#include "../cpptoc/scheme_handler_cpptoc.h"
|
||||||
|
#include "../cpptoc/scheme_handler_factory_cpptoc.h"
|
||||||
#include "../cpptoc/v8handler_cpptoc.h"
|
#include "../cpptoc/v8handler_cpptoc.h"
|
||||||
#include "../ctocpp/browser_ctocpp.h"
|
#include "../ctocpp/browser_ctocpp.h"
|
||||||
#include "../ctocpp/post_data_ctocpp.h"
|
#include "../ctocpp/post_data_ctocpp.h"
|
||||||
|
@ -31,6 +33,8 @@ void CefShutdown()
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// Check that all wrapper objects have been destroyed
|
// Check that all wrapper objects have been destroyed
|
||||||
DCHECK(CefHandlerCppToC::DebugObjCt == 0);
|
DCHECK(CefHandlerCppToC::DebugObjCt == 0);
|
||||||
|
DCHECK(CefSchemeHandlerCppToC::DebugObjCt == 0);
|
||||||
|
DCHECK(CefSchemeHandlerFactoryCppToC::DebugObjCt == 0);
|
||||||
DCHECK(CefV8HandlerCppToC::DebugObjCt == 0);
|
DCHECK(CefV8HandlerCppToC::DebugObjCt == 0);
|
||||||
DCHECK(CefBrowserCToCpp::DebugObjCt == 0);
|
DCHECK(CefBrowserCToCpp::DebugObjCt == 0);
|
||||||
DCHECK(CefRequestCToCpp::DebugObjCt == 0);
|
DCHECK(CefRequestCToCpp::DebugObjCt == 0);
|
||||||
|
@ -95,3 +99,11 @@ bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info)
|
||||||
|
|
||||||
return (cef_register_plugin(&pluginInfo) ? true : false);
|
return (cef_register_plugin(&pluginInfo) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CefRegisterScheme(const std::wstring& scheme_name,
|
||||||
|
const std::wstring& host_name,
|
||||||
|
CefRefPtr<CefSchemeHandlerFactory> factory)
|
||||||
|
{
|
||||||
|
return cef_register_scheme(scheme_name.c_str(), host_name.c_str(),
|
||||||
|
CefSchemeHandlerFactoryCppToC::Wrap(factory));
|
||||||
|
}
|
||||||
|
|
|
@ -141,6 +141,22 @@
|
||||||
RelativePath="..\cpptoc\handler_cpptoc.h"
|
RelativePath="..\cpptoc\handler_cpptoc.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\cpptoc\scheme_handler_cpptoc.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\cpptoc\scheme_handler_cpptoc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\cpptoc\scheme_handler_factory_cpptoc.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\cpptoc\scheme_handler_factory_cpptoc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\cpptoc\v8handler_cpptoc.cc"
|
RelativePath="..\cpptoc\v8handler_cpptoc.cc"
|
||||||
>
|
>
|
||||||
|
|
|
@ -33,11 +33,107 @@ INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
|
||||||
// Convert a std::string to a std::wstring
|
// Convert a std::string to a std::wstring
|
||||||
std::wstring StringToWString(const std::string& s)
|
std::wstring StringToWString(const std::string& s)
|
||||||
{
|
{
|
||||||
std::wstring temp(s.length(),L' ');
|
wchar_t* wch;
|
||||||
std::copy(s.begin(), s.end(), temp.begin());
|
UINT bytes = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size()+1, NULL, 0);
|
||||||
return temp;
|
wch = new wchar_t[bytes];
|
||||||
|
if(wch)
|
||||||
|
bytes = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size()+1, wch, bytes);
|
||||||
|
std::wstring str = wch;
|
||||||
|
delete [] wch;
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a std::wstring to a std::string
|
||||||
|
std::string WStringToString(const std::wstring& s)
|
||||||
|
{
|
||||||
|
char* ch;
|
||||||
|
UINT bytes = WideCharToMultiByte(CP_ACP, 0, s.c_str(), s.size()+1, NULL, 0,
|
||||||
|
NULL, NULL);
|
||||||
|
ch = new char[bytes];
|
||||||
|
if(ch)
|
||||||
|
bytes = WideCharToMultiByte(CP_ACP, 0, s.c_str(), s.size()+1, ch, bytes,
|
||||||
|
NULL, NULL);
|
||||||
|
std::string str = ch;
|
||||||
|
delete [] ch;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a resource of type BINARY
|
||||||
|
bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes)
|
||||||
|
{
|
||||||
|
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(binaryId),
|
||||||
|
MAKEINTRESOURCE(256));
|
||||||
|
if(hRes)
|
||||||
|
{
|
||||||
|
HGLOBAL hGlob = LoadResource(hInst, hRes);
|
||||||
|
if(hGlob)
|
||||||
|
{
|
||||||
|
dwSize = SizeofResource(hInst, hRes);
|
||||||
|
pBytes = (LPBYTE)LockResource(hGlob);
|
||||||
|
if(dwSize > 0 && pBytes)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump the contents of the request into a string.
|
||||||
|
void DumpRequestContents(CefRefPtr<CefRequest> request, std::wstring& str)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
|
||||||
|
ss << L"URL: " << request->GetURL();
|
||||||
|
ss << L"\nMethod: " << request->GetMethod();
|
||||||
|
|
||||||
|
CefRequest::HeaderMap headerMap;
|
||||||
|
request->GetHeaderMap(headerMap);
|
||||||
|
if(headerMap.size() > 0) {
|
||||||
|
ss << L"\nHeaders:";
|
||||||
|
CefRequest::HeaderMap::const_iterator it = headerMap.begin();
|
||||||
|
for(; it != headerMap.end(); ++it) {
|
||||||
|
ss << L"\n\t" << (*it).first << L": " << (*it).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefPostData> postData = request->GetPostData();
|
||||||
|
if(postData.get()) {
|
||||||
|
CefPostData::ElementVector elements;
|
||||||
|
postData->GetElements(elements);
|
||||||
|
if(elements.size() > 0) {
|
||||||
|
ss << L"\nPost Data:";
|
||||||
|
CefRefPtr<CefPostDataElement> element;
|
||||||
|
CefPostData::ElementVector::const_iterator it = elements.begin();
|
||||||
|
for(; it != elements.end(); ++it) {
|
||||||
|
element = (*it);
|
||||||
|
if(element->GetType() == PDE_TYPE_BYTES) {
|
||||||
|
// the element is composed of bytes
|
||||||
|
ss << L"\n\tBytes: ";
|
||||||
|
if(element->GetBytesCount() == 0)
|
||||||
|
ss << L"(empty)";
|
||||||
|
else {
|
||||||
|
// retrieve the data.
|
||||||
|
size_t size = element->GetBytesCount();
|
||||||
|
char* bytes = new char[size];
|
||||||
|
element->GetBytes(size, bytes);
|
||||||
|
ss << StringToWString(std::string(bytes, size));
|
||||||
|
delete [] bytes;
|
||||||
|
}
|
||||||
|
} else if(element->GetType() == PDE_TYPE_FILE) {
|
||||||
|
ss << L"\n\tFile: " << element->GetFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Implementation of the V8 handler class for the "cef.test" extension.
|
// Implementation of the V8 handler class for the "cef.test" extension.
|
||||||
class ClientV8ExtensionHandler : public CefThreadSafeBase<CefV8Handler>
|
class ClientV8ExtensionHandler : public CefThreadSafeBase<CefV8Handler>
|
||||||
{
|
{
|
||||||
|
@ -97,6 +193,123 @@ private:
|
||||||
std::wstring test_param_;
|
std::wstring test_param_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Implementation of the schema handler for client:// requests.
|
||||||
|
class ClientSchemeHandler : public CefThreadSafeBase<CefSchemeHandler>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientSchemeHandler() : size_(0), offset_(0), bytes_(NULL) {}
|
||||||
|
|
||||||
|
// Process the request. All response generation should take place in this
|
||||||
|
// method. If there is no response set |response_length| to zero and
|
||||||
|
// ReadResponse() will not be called. If the response length is not known then
|
||||||
|
// set |response_length| to -1 and ReadResponse() will be called until it
|
||||||
|
// returns false or until the value of |bytes_read| is set to 0. Otherwise,
|
||||||
|
// set |response_length| to a positive value and ReadResponse() will be called
|
||||||
|
// until it returns false, the value of |bytes_read| is set to 0 or the
|
||||||
|
// specified number of bytes have been read. If there is a response set
|
||||||
|
// |mime_type| to the mime type for the response.
|
||||||
|
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||||
|
std::wstring& mime_type, int* response_length)
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
std::wstring url = request->GetURL();
|
||||||
|
if(wcsstr(url.c_str(), L"handler.html") != NULL) {
|
||||||
|
// Build the response html
|
||||||
|
html_ = "<html><head><title>Client Scheme Handler</title></head><body>"
|
||||||
|
"This contents of this page page are served by the "
|
||||||
|
"ClientSchemeHandler class handling the client:// protocol."
|
||||||
|
"<br>You should see an image:"
|
||||||
|
"<br/><img src=\"client://tests/client.gif\"><pre>";
|
||||||
|
|
||||||
|
// Output a string representation of the request
|
||||||
|
std::wstring dump;
|
||||||
|
DumpRequestContents(request, dump);
|
||||||
|
html_.append(WStringToString(dump));
|
||||||
|
|
||||||
|
html_.append("</pre><br>Try the test form:"
|
||||||
|
"<form method=\"POST\" action=\"handler.html\">"
|
||||||
|
"<input type=\"text\" name=\"field1\">"
|
||||||
|
"<input type=\"text\" name=\"field2\">"
|
||||||
|
"<input type=\"submit\">"
|
||||||
|
"</form></body></html>");
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
size_ = html_.size();
|
||||||
|
bytes_ = (LPBYTE)html_.c_str();
|
||||||
|
|
||||||
|
// Set the resulting mime type
|
||||||
|
mime_type = L"text/html";
|
||||||
|
}
|
||||||
|
else if(wcsstr(url.c_str(), L"client.gif") != NULL) {
|
||||||
|
// Load the response image
|
||||||
|
if(LoadBinaryResource(IDS_LOGO, size_, bytes_)) {
|
||||||
|
handled = true;
|
||||||
|
// Set the resulting mime type
|
||||||
|
mime_type = L"image/jpg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the resulting response length
|
||||||
|
*response_length = size_;
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel processing of the request.
|
||||||
|
virtual void Cancel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy up to |bytes_to_read| bytes into |data_out|. If the copy succeeds
|
||||||
|
// set |bytes_read| to the number of bytes copied and return true. If the
|
||||||
|
// copy fails return false and ReadResponse() will not be called again.
|
||||||
|
virtual bool ReadResponse(void* data_out, int bytes_to_read,
|
||||||
|
int* bytes_read)
|
||||||
|
{
|
||||||
|
bool has_data = false;
|
||||||
|
*bytes_read = 0;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
if(offset_ < size_) {
|
||||||
|
// Copy the next block of data into the buffer.
|
||||||
|
int transfer_size = min(bytes_to_read, static_cast<int>(size_ - offset_));
|
||||||
|
memcpy(data_out, bytes_ + offset_, transfer_size);
|
||||||
|
offset_ += transfer_size;
|
||||||
|
|
||||||
|
*bytes_read = transfer_size;
|
||||||
|
has_data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
return has_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DWORD size_, offset_;
|
||||||
|
LPBYTE bytes_;
|
||||||
|
std::string html_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation of the factory for for creating schema handlers.
|
||||||
|
class ClientSchemeHandlerFactory :
|
||||||
|
public CefThreadSafeBase<CefSchemeHandlerFactory>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Return a new scheme handler instance to handle the request.
|
||||||
|
virtual CefRefPtr<CefSchemeHandler> Create()
|
||||||
|
{
|
||||||
|
return new ClientSchemeHandler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Program entry point function.
|
||||||
int APIENTRY _tWinMain(HINSTANCE hInstance,
|
int APIENTRY _tWinMain(HINSTANCE hInstance,
|
||||||
HINSTANCE hPrevInstance,
|
HINSTANCE hPrevInstance,
|
||||||
LPTSTR lpCmdLine,
|
LPTSTR lpCmdLine,
|
||||||
|
@ -156,6 +369,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
||||||
L"})();";
|
L"})();";
|
||||||
CefRegisterExtension(L"v8/test", code, new ClientV8ExtensionHandler());
|
CefRegisterExtension(L"v8/test", code, new ClientV8ExtensionHandler());
|
||||||
|
|
||||||
|
// Register the scheme handler factory for requests using the client://
|
||||||
|
// protocol in the tests domain.
|
||||||
|
CefRegisterScheme(L"client", L"tests", new ClientSchemeHandlerFactory());
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
HACCEL hAccelTable;
|
HACCEL hAccelTable;
|
||||||
|
|
||||||
|
@ -260,26 +477,6 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a resource of type BINARY
|
|
||||||
bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes)
|
|
||||||
{
|
|
||||||
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(binaryId),
|
|
||||||
MAKEINTRESOURCE(256));
|
|
||||||
if(hRes)
|
|
||||||
{
|
|
||||||
HGLOBAL hGlob = LoadResource(hInst, hRes);
|
|
||||||
if(hGlob)
|
|
||||||
{
|
|
||||||
dwSize = SizeofResource(hInst, hRes);
|
|
||||||
pBytes = (LPBYTE)LockResource(hGlob);
|
|
||||||
if(dwSize > 0 && pBytes)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation of the V8 handler class for the "window.cef_test.Dump"
|
// Implementation of the V8 handler class for the "window.cef_test.Dump"
|
||||||
// function.
|
// function.
|
||||||
class ClientV8FunctionHandler : public CefThreadSafeBase<CefV8Handler>
|
class ClientV8FunctionHandler : public CefThreadSafeBase<CefV8Handler>
|
||||||
|
@ -577,54 +774,10 @@ public:
|
||||||
std::wstring url = request->GetURL();
|
std::wstring url = request->GetURL();
|
||||||
if(url == L"http://tests/request") {
|
if(url == L"http://tests/request") {
|
||||||
// Show the request contents
|
// Show the request contents
|
||||||
std::wstringstream ss;
|
std::wstring dump;
|
||||||
|
DumpRequestContents(request, dump);
|
||||||
ss << L"URL: " << url;
|
|
||||||
ss << L"\nMethod: " << request->GetMethod();
|
|
||||||
|
|
||||||
CefRequest::HeaderMap headerMap;
|
|
||||||
request->GetHeaderMap(headerMap);
|
|
||||||
if(headerMap.size() > 0) {
|
|
||||||
ss << L"\nHeaders:";
|
|
||||||
CefRequest::HeaderMap::const_iterator it = headerMap.begin();
|
|
||||||
for(; it != headerMap.end(); ++it) {
|
|
||||||
ss << L"\n\t" << (*it).first << L": " << (*it).second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CefRefPtr<CefPostData> postData = request->GetPostData();
|
|
||||||
if(postData.get()) {
|
|
||||||
CefPostData::ElementVector elements;
|
|
||||||
postData->GetElements(elements);
|
|
||||||
if(elements.size() > 0) {
|
|
||||||
ss << L"\nPost Data:";
|
|
||||||
CefRefPtr<CefPostDataElement> element;
|
|
||||||
CefPostData::ElementVector::const_iterator it = elements.begin();
|
|
||||||
for(; it != elements.end(); ++it) {
|
|
||||||
element = (*it);
|
|
||||||
if(element->GetType() == PDE_TYPE_BYTES) {
|
|
||||||
// the element is composed of bytes
|
|
||||||
ss << L"\n\tBytes: ";
|
|
||||||
if(element->GetBytesCount() == 0)
|
|
||||||
ss << L"(empty)";
|
|
||||||
else {
|
|
||||||
// retrieve the data.
|
|
||||||
size_t size = element->GetBytesCount();
|
|
||||||
char* bytes = new char[size];
|
|
||||||
element->GetBytes(size, bytes);
|
|
||||||
ss << StringToWString(std::string(bytes, size));
|
|
||||||
delete [] bytes;
|
|
||||||
}
|
|
||||||
} else if(element->GetType() == PDE_TYPE_FILE) {
|
|
||||||
ss << L"\n\tFile: " << element->GetFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring str = ss.str();
|
|
||||||
resourceStream = CefStreamReader::CreateForData(
|
resourceStream = CefStreamReader::CreateForData(
|
||||||
(void*)str.c_str(), str.size() * sizeof(wchar_t));
|
(void*)dump.c_str(), dump.size() * sizeof(wchar_t));
|
||||||
mimeType = L"text/plain";
|
mimeType = L"text/plain";
|
||||||
} else if(wcsstr(url.c_str(), L"logo.gif") != NULL) {
|
} else if(wcsstr(url.c_str(), L"logo.gif") != NULL) {
|
||||||
// Any time we find "logo.gif" in the URL substitute in our own image
|
// Any time we find "logo.gif" in the URL substitute in our own image
|
||||||
|
@ -1110,6 +1263,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
browser->GetMainFrame()->LoadRequest(request);
|
browser->GetMainFrame()->LoadRequest(request);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
case ID_TESTS_SCHEME_HANDLER: // Test the scheme handler
|
||||||
|
if(browser.get())
|
||||||
|
browser->GetMainFrame()->LoadURL(L"client://tests/handler.html");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -63,6 +63,7 @@ BEGIN
|
||||||
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
||||||
MENUITEM "Popup Window", ID_TESTS_POPUP
|
MENUITEM "Popup Window", ID_TESTS_POPUP
|
||||||
MENUITEM "Request", ID_TESTS_REQUEST
|
MENUITEM "Request", ID_TESTS_REQUEST
|
||||||
|
MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define ID_TESTS_PLUGIN 32774
|
#define ID_TESTS_PLUGIN 32774
|
||||||
#define ID_TESTS_POPUP 32775
|
#define ID_TESTS_POPUP 32775
|
||||||
#define ID_TESTS_REQUEST 32776
|
#define ID_TESTS_REQUEST 32776
|
||||||
|
#define ID_TESTS_SCHEME_HANDLER 32777
|
||||||
#define IDC_STATIC -1
|
#define IDC_STATIC -1
|
||||||
#define IDS_LOGO 1000
|
#define IDS_LOGO 1000
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue