Add custom handler support.

This commit is contained in:
Haojian Wu 2014-07-03 19:27:07 +08:00 committed by Tobias Taschner
parent e3026f9e8b
commit aaaefbbecf
No known key found for this signature in database
GPG key ID: AE6ECD71294F87FD
2 changed files with 116 additions and 3 deletions

View file

@ -11,7 +11,6 @@
#include "wx/webview.h"
#include "wx/sharedptr.h"
#include "wx/vector.h"
#include "wx/timer.h"
#ifdef __VISUALC__
#pragma warning(push)
@ -20,6 +19,7 @@
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "include/cef_scheme.h"
#ifdef __VISUALC__
#pragma warning(pop)
@ -112,11 +112,55 @@ private:
IMPLEMENT_REFCOUNTING(ClientHandler);
};
class SchemeHandler : public CefResourceHandler
{
public:
SchemeHandler(const wxSharedPtr<wxWebViewHandler>& handler) : offset_(0), m_handler(handler) {}
// CefResourceHandler methods
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback);
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl);
virtual bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback);
virtual void Cancel() {}
private:
wxSharedPtr<wxWebViewHandler> m_handler;
std::string data_;
std::string mime_type_;
size_t offset_;
IMPLEMENT_REFCOUNTING(SchemeHandler);
IMPLEMENT_LOCKING(SchemeHandler);
};
class SchemeHandlerFactory : public CefSchemeHandlerFactory
{
public:
SchemeHandlerFactory(wxSharedPtr<wxWebViewHandler> handler): m_handler(handler) {}
// Return a new scheme handler instance to handle the request.
virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& scheme_name,
CefRefPtr<CefRequest> request)
{
return new SchemeHandler( m_handler );
}
IMPLEMENT_REFCOUNTING(SchemeHandlerFactory);
private:
wxSharedPtr<wxWebViewHandler> m_handler;
};
class WXDLLIMPEXP_WEBVIEW wxWebViewChromium : public wxWebView
{
public:
wxWebViewChromium() {}
wxWebViewChromium(wxWindow* parent,

View file

@ -436,7 +436,8 @@ bool wxWebViewChromium::CanSetZoomType(wxWebViewZoomType type) const
void wxWebViewChromium::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
{
// We currently don't support custom scheme handlers
CefRegisterSchemeHandlerFactory( handler->GetName().ToStdWstring(), "",
new SchemeHandlerFactory(handler) );
}
#ifdef __WXMSW__
@ -727,3 +728,71 @@ void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
}
m_loadErrorCode = type;
}
bool SchemeHandler::ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback)
{
bool handled = false;
AutoLock lock_scope( this );
std::string url = request->GetURL();
wxFSFile* file = m_handler->GetFile( url );
if ( file )
{
mime_type_ = (file->GetMimeType()).ToStdString();
size_t size = file->GetStream()->GetLength();
char* buf = new char[size];
file->GetStream()->Read( buf, size );
data_ = std::string( buf, buf+size );
delete[] buf;
handled = true;
}
if ( handled )
{
// Indicate the headers are available.
callback->Continue();
return true;
}
return false;
}
void SchemeHandler::GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl)
{
response->SetMimeType( mime_type_ );
response->SetStatus( 200 );
// Set the resulting response length
response_length = data_.length();
}
bool SchemeHandler::ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback)
{
bool has_data = false;
bytes_read = 0;
AutoLock lock_scope( this );
if ( offset_ < data_.length() )
{
// Copy the next block of data into the buffer.
int transfer_size =
std::min( bytes_to_read, static_cast<int>( data_.length() - offset_ ) );
memcpy( data_out, data_.c_str() + offset_, transfer_size );
offset_ += transfer_size;
bytes_read = transfer_size;
has_data = true;
}
return has_data;
}