Add wxWebViewHandler::StartRequest()
The new method an associated classes allow for a more detailed handling in wxWebViewHandler instances. Most notibly post data and headers from the request can be processsed. The response can be send asynchronously.
This commit is contained in:
parent
0021241d78
commit
4500a48407
3 changed files with 230 additions and 44 deletions
|
|
@ -92,6 +92,37 @@ enum wxWebViewUserScriptInjectionTime
|
|||
wxWEBVIEW_INJECT_AT_DOCUMENT_END
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewHandlerRequest
|
||||
{
|
||||
public:
|
||||
virtual ~wxWebViewHandlerRequest() { }
|
||||
virtual wxString GetRawURI() const = 0;
|
||||
virtual wxString GetURI() const { return GetRawURI(); }
|
||||
virtual wxInputStream* GetData() const = 0;
|
||||
virtual wxString GetDataString(const wxMBConv& conv = wxConvUTF8) const;
|
||||
virtual wxString GetMethod() const = 0;
|
||||
virtual wxString GetHeader(const wxString& name) const = 0;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewHandlerResponseData
|
||||
{
|
||||
public:
|
||||
virtual ~wxWebViewHandlerResponseData() { }
|
||||
virtual wxInputStream* GetStream() = 0;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewHandlerResponse
|
||||
{
|
||||
public:
|
||||
virtual ~wxWebViewHandlerResponse() { }
|
||||
virtual void SetStatus(int status) = 0;
|
||||
virtual void SetContentType(const wxString& contentType) = 0;
|
||||
virtual void SetHeader(const wxString& name, const wxString& value) = 0;
|
||||
virtual void Finish(wxSharedPtr<wxWebViewHandlerResponseData> data) = 0;
|
||||
virtual void Finish(const wxString& text, const wxMBConv& conv = wxConvUTF8);
|
||||
virtual void FinishWithError() = 0;
|
||||
};
|
||||
|
||||
//Base class for custom scheme handlers
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewHandler
|
||||
{
|
||||
|
|
@ -100,12 +131,17 @@ public:
|
|||
: m_scheme(scheme), m_securityURL() {}
|
||||
virtual ~wxWebViewHandler() {}
|
||||
virtual wxString GetName() const { return m_scheme; }
|
||||
virtual wxFSFile* GetFile(const wxString &uri) = 0;
|
||||
virtual wxFSFile* GetFile(const wxString &uri);
|
||||
virtual void SetSecurityURL(const wxString& url) { m_securityURL = url; }
|
||||
virtual wxString GetSecurityURL() const { return m_securityURL; }
|
||||
virtual void SetVirtualHost(const wxString& host) { m_virtualHost = host; }
|
||||
virtual wxString GetVirtualHost() const;
|
||||
virtual void StartRequest(const wxWebViewHandlerRequest& request,
|
||||
wxSharedPtr<wxWebViewHandlerResponse> response);
|
||||
private:
|
||||
wxString m_scheme;
|
||||
wxString m_securityURL;
|
||||
wxString m_virtualHost;
|
||||
};
|
||||
|
||||
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewNameStr[];
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
|
||||
#include "wx/webview.h"
|
||||
#include "wx/filesys.h"
|
||||
#include "wx/mstream.h"
|
||||
|
||||
#if defined(__WXOSX__)
|
||||
#include "wx/osx/webview_webkit.h"
|
||||
|
|
@ -52,6 +54,92 @@ wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
|||
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_RESULT, wxWebViewEvent);
|
||||
|
||||
// wxWebViewHandlerRequest
|
||||
wxString wxWebViewHandlerRequest::GetDataString(const wxMBConv& conv) const
|
||||
{
|
||||
wxInputStream* data = GetData();
|
||||
if (!data)
|
||||
return wxString();
|
||||
|
||||
size_t length = data->GetLength();
|
||||
wxMemoryBuffer buffer;
|
||||
data->ReadAll(buffer.GetWriteBuf(length), length);
|
||||
wxString dataStr((const char*) buffer.GetData(), conv, length);
|
||||
return dataStr;
|
||||
}
|
||||
|
||||
// wxWebViewHandlerResponseDataStream
|
||||
class wxWebViewHandlerResponseDataString : public wxWebViewHandlerResponseData
|
||||
{
|
||||
public:
|
||||
wxWebViewHandlerResponseDataString(const wxCharBuffer& data): m_data(data)
|
||||
{
|
||||
m_stream = new wxMemoryInputStream(m_data, m_data.length());
|
||||
}
|
||||
|
||||
~wxWebViewHandlerResponseDataString() { delete m_stream; }
|
||||
|
||||
virtual wxInputStream* GetStream() wxOVERRIDE
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
wxCharBuffer m_data;
|
||||
wxInputStream* m_stream;
|
||||
};
|
||||
|
||||
// wxWebViewHandlerResponse
|
||||
void wxWebViewHandlerResponse::Finish(const wxString& text,
|
||||
const wxMBConv& conv)
|
||||
{
|
||||
Finish(wxSharedPtr<wxWebViewHandlerResponseData>(
|
||||
new wxWebViewHandlerResponseDataString(text.mb_str(conv))));
|
||||
}
|
||||
|
||||
// wxWebViewHandlerResponseDataFile
|
||||
class wxWebViewHandlerResponseDataFile : public wxWebViewHandlerResponseData
|
||||
{
|
||||
public:
|
||||
wxWebViewHandlerResponseDataFile(wxFSFile* file): m_file(file) { }
|
||||
|
||||
~wxWebViewHandlerResponseDataFile() { delete m_file; }
|
||||
|
||||
virtual wxInputStream* GetStream() wxOVERRIDE
|
||||
{ return m_file->GetStream(); }
|
||||
|
||||
wxFSFile* m_file;
|
||||
};
|
||||
|
||||
// wxWebViewHandler
|
||||
wxString wxWebViewHandler::GetVirtualHost() const
|
||||
{
|
||||
if (m_virtualHost.empty())
|
||||
return GetName() + ".wxsite";
|
||||
else
|
||||
return m_virtualHost;
|
||||
}
|
||||
|
||||
wxFSFile* wxWebViewHandler::GetFile(const wxString& WXUNUSED(uri))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void wxWebViewHandler::StartRequest(const wxWebViewHandlerRequest& request,
|
||||
wxSharedPtr<wxWebViewHandlerResponse> response)
|
||||
{
|
||||
wxFSFile* file = GetFile(request.GetURI());
|
||||
if (file)
|
||||
{
|
||||
response->SetContentType(file->GetMimeType());
|
||||
response->Finish(wxSharedPtr<wxWebViewHandlerResponseData>(
|
||||
new wxWebViewHandlerResponseDataFile(file)));
|
||||
}
|
||||
else
|
||||
response->FinishWithError();
|
||||
}
|
||||
|
||||
// wxWebView
|
||||
|
||||
wxStringWebViewFactoryMap wxWebView::m_factoryMap;
|
||||
|
||||
wxWebViewZoom wxWebView::GetZoom() const
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "wx/hashmap.h"
|
||||
#include "wx/filesys.h"
|
||||
#include "wx/msgdlg.h"
|
||||
#include "wx/mstream.h"
|
||||
#include "wx/textdlg.h"
|
||||
#include "wx/filedlg.h"
|
||||
|
||||
|
|
@ -847,6 +848,107 @@ wxString nsErrorToWxHtmlError(NSError* error, wxWebViewNavigationError* out)
|
|||
@end
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||
|
||||
class wxWebViewWebKitHandlerRequest: public wxWebViewHandlerRequest
|
||||
{
|
||||
public:
|
||||
wxWebViewWebKitHandlerRequest(NSURLRequest* request):
|
||||
m_data(NULL),
|
||||
m_request(request)
|
||||
{ }
|
||||
|
||||
~wxWebViewWebKitHandlerRequest()
|
||||
{ wxDELETE(m_data); }
|
||||
|
||||
virtual wxString GetRawURI() const wxOVERRIDE
|
||||
{ return wxCFStringRef::AsString(m_request.URL.absoluteString); }
|
||||
|
||||
virtual wxInputStream* GetData() const wxOVERRIDE
|
||||
{
|
||||
if (!m_data && m_request.HTTPBody)
|
||||
m_data = new wxMemoryInputStream(m_request.HTTPBody.bytes, m_request.HTTPBody.length);
|
||||
|
||||
return m_data;
|
||||
}
|
||||
|
||||
virtual wxString GetMethod() const wxOVERRIDE
|
||||
{ return wxCFStringRef::AsString(m_request.HTTPMethod); }
|
||||
|
||||
virtual wxString GetHeader(const wxString& name) const wxOVERRIDE
|
||||
{
|
||||
return wxCFStringRef::AsString(
|
||||
[m_request valueForHTTPHeaderField:wxCFStringRef(name).AsNSString()]);
|
||||
}
|
||||
|
||||
mutable wxInputStream* m_data;
|
||||
NSURLRequest* m_request;
|
||||
};
|
||||
|
||||
class API_AVAILABLE(macos(10.13)) wxWebViewWebkitHandlerResponse: public wxWebViewHandlerResponse
|
||||
{
|
||||
public:
|
||||
wxWebViewWebkitHandlerResponse(id<WKURLSchemeTask> task):
|
||||
m_status(200),
|
||||
m_task([task retain])
|
||||
{
|
||||
m_headers = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
~wxWebViewWebkitHandlerResponse()
|
||||
{
|
||||
[m_headers release];
|
||||
[m_task release];
|
||||
}
|
||||
|
||||
virtual void SetStatus(int status) wxOVERRIDE
|
||||
{ m_status = status; }
|
||||
|
||||
virtual void SetContentType(const wxString& contentType) wxOVERRIDE
|
||||
{ SetHeader("Content-Type", contentType); }
|
||||
|
||||
virtual void SetHeader(const wxString& name, const wxString& value) wxOVERRIDE
|
||||
{
|
||||
[m_headers setValue:wxCFStringRef(value).AsNSString()
|
||||
forKey:wxCFStringRef(name).AsNSString()];
|
||||
}
|
||||
|
||||
virtual void Finish(wxSharedPtr<wxWebViewHandlerResponseData> data) wxOVERRIDE
|
||||
{
|
||||
m_data = data;
|
||||
wxInputStream* stream = data->GetStream();
|
||||
size_t length = stream->GetLength();
|
||||
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:m_task.request.URL
|
||||
statusCode:m_status
|
||||
HTTPVersion:nil
|
||||
headerFields:m_headers];
|
||||
[m_task didReceiveResponse:response];
|
||||
[response release];
|
||||
|
||||
//Load the data, we malloc it so it is tidied up properly
|
||||
void* buffer = malloc(length);
|
||||
stream->Read(buffer, length);
|
||||
NSData *taskData = [[NSData alloc] initWithBytesNoCopy:buffer length:length];
|
||||
[m_task didReceiveData:taskData];
|
||||
[taskData release];
|
||||
|
||||
[m_task didFinish];
|
||||
}
|
||||
|
||||
virtual void FinishWithError() wxOVERRIDE
|
||||
{
|
||||
NSError *error = [[NSError alloc] initWithDomain:NSURLErrorDomain
|
||||
code:NSURLErrorFileDoesNotExist
|
||||
userInfo:nil];
|
||||
[m_task didFailWithError:error];
|
||||
[error release];
|
||||
}
|
||||
|
||||
int m_status;
|
||||
NSMutableDictionary* m_headers;
|
||||
id<WKURLSchemeTask> m_task;
|
||||
wxSharedPtr<wxWebViewHandlerResponseData> m_data;
|
||||
};
|
||||
|
||||
@implementation WebViewCustomProtocol
|
||||
|
||||
- (id)initWithHandler:(wxWebViewHandler *)handler
|
||||
|
|
@ -858,49 +960,9 @@ wxString nsErrorToWxHtmlError(NSError* error, wxWebViewNavigationError* out)
|
|||
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
|
||||
WX_API_AVAILABLE_MACOS(10, 13)
|
||||
{
|
||||
NSURLRequest *request = urlSchemeTask.request;
|
||||
NSString* path = [[request URL] absoluteString];
|
||||
|
||||
wxString wxpath = wxCFStringRef::AsString(path);
|
||||
|
||||
wxFSFile* file = m_handler->GetFile(wxpath);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
NSError *error = [[NSError alloc] initWithDomain:NSURLErrorDomain
|
||||
code:NSURLErrorFileDoesNotExist
|
||||
userInfo:nil];
|
||||
|
||||
[urlSchemeTask didFailWithError:error];
|
||||
|
||||
[error release];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
size_t length = file->GetStream()->GetLength();
|
||||
|
||||
|
||||
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[request URL]
|
||||
MIMEType:wxCFStringRef(file->GetMimeType()).AsNSString()
|
||||
expectedContentLength:length
|
||||
textEncodingName:nil];
|
||||
|
||||
//Load the data, we malloc it so it is tidied up properly
|
||||
void* buffer = malloc(length);
|
||||
file->GetStream()->Read(buffer, length);
|
||||
NSData *data = [[NSData alloc] initWithBytesNoCopy:buffer length:length];
|
||||
|
||||
//Set the data
|
||||
[urlSchemeTask didReceiveResponse:response];
|
||||
[urlSchemeTask didReceiveData:data];
|
||||
|
||||
//Notify that we have finished
|
||||
[urlSchemeTask didFinish];
|
||||
|
||||
[data release];
|
||||
|
||||
[response release];
|
||||
wxWebViewWebKitHandlerRequest request(urlSchemeTask.request);
|
||||
wxSharedPtr<wxWebViewHandlerResponse> response(new wxWebViewWebkitHandlerResponse(urlSchemeTask));
|
||||
m_handler->StartRequest(request, response);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue