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 CefPostDataElement;
|
||||
class CefRequest;
|
||||
class CefSchemeHandler;
|
||||
class CefSchemeHandlerFactory;
|
||||
class CefStreamReader;
|
||||
class CefStreamWriter;
|
||||
class CefV8Handler;
|
||||
|
@ -141,6 +143,16 @@ bool CefRegisterExtension(const std::wstring& extension_name,
|
|||
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
|
||||
// framework classes must implement the CefBase class.
|
||||
class CefBase
|
||||
|
@ -930,4 +942,47 @@ public:
|
|||
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
|
||||
|
|
|
@ -126,6 +126,13 @@ CEF_EXPORT void cef_do_message_loop_work();
|
|||
CEF_EXPORT int cef_register_extension(const wchar_t* extension_name,
|
||||
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
|
||||
{
|
||||
// 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);
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -373,6 +373,10 @@
|
|||
RelativePath=".\request_impl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scheme_impl.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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/v8value_cpptoc.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 "base/string_util.h"
|
||||
|
||||
|
@ -43,6 +45,8 @@ CEF_EXPORT void cef_shutdown()
|
|||
DCHECK(CefStreamWriterCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefV8ValueCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerFactoryCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefV8HandlerCToCpp::DebugObjCt == 0);
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
@ -107,3 +111,22 @@ CEF_EXPORT int cef_register_plugin(const cef_plugin_info_t* plugin_info)
|
|||
|
||||
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"
|
||||
>
|
||||
</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
|
||||
RelativePath=".\ctocpp\v8handler_ctocpp.cc"
|
||||
>
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "cef_nplugin.h"
|
||||
#include "cef_nplugin_capi.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 "../ctocpp/browser_ctocpp.h"
|
||||
#include "../ctocpp/post_data_ctocpp.h"
|
||||
|
@ -31,6 +33,8 @@ void CefShutdown()
|
|||
#ifdef _DEBUG
|
||||
// Check that all wrapper objects have been destroyed
|
||||
DCHECK(CefHandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefSchemeHandlerFactoryCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefV8HandlerCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefBrowserCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefRequestCToCpp::DebugObjCt == 0);
|
||||
|
@ -95,3 +99,11 @@ bool CefRegisterPlugin(const struct CefPluginInfo& plugin_info)
|
|||
|
||||
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"
|
||||
>
|
||||
</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
|
||||
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
|
||||
std::wstring StringToWString(const std::string& s)
|
||||
{
|
||||
std::wstring temp(s.length(),L' ');
|
||||
std::copy(s.begin(), s.end(), temp.begin());
|
||||
return temp;
|
||||
wchar_t* wch;
|
||||
UINT bytes = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size()+1, NULL, 0);
|
||||
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.
|
||||
class ClientV8ExtensionHandler : public CefThreadSafeBase<CefV8Handler>
|
||||
{
|
||||
|
@ -97,6 +193,123 @@ private:
|
|||
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,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPTSTR lpCmdLine,
|
||||
|
@ -156,6 +369,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|||
L"})();";
|
||||
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;
|
||||
HACCEL hAccelTable;
|
||||
|
||||
|
@ -260,26 +477,6 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|||
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"
|
||||
// function.
|
||||
class ClientV8FunctionHandler : public CefThreadSafeBase<CefV8Handler>
|
||||
|
@ -577,54 +774,10 @@ public:
|
|||
std::wstring url = request->GetURL();
|
||||
if(url == L"http://tests/request") {
|
||||
// Show the request contents
|
||||
std::wstringstream ss;
|
||||
|
||||
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();
|
||||
std::wstring dump;
|
||||
DumpRequestContents(request, dump);
|
||||
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";
|
||||
} else if(wcsstr(url.c_str(), L"logo.gif") != NULL) {
|
||||
// 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);
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -63,6 +63,7 @@ BEGIN
|
|||
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
||||
MENUITEM "Popup Window", ID_TESTS_POPUP
|
||||
MENUITEM "Request", ID_TESTS_REQUEST
|
||||
MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER
|
||||
END
|
||||
END
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define ID_TESTS_PLUGIN 32774
|
||||
#define ID_TESTS_POPUP 32775
|
||||
#define ID_TESTS_REQUEST 32776
|
||||
#define ID_TESTS_SCHEME_HANDLER 32777
|
||||
#define IDC_STATIC -1
|
||||
#define IDS_LOGO 1000
|
||||
|
||||
|
|
Loading…
Reference in New Issue