mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 01:30:32 +08:00
[v2] Improve processRequest: Handle errors and behave more like a webserver
This also fixes that requests remain in "pending" state on darwin if e.g. a file is not found or an error occurs during loading of the file.
This commit is contained in:
parent
59d29dc12f
commit
d827aafe89
@ -41,7 +41,7 @@ void Quit(void*);
|
|||||||
const char* GetSize(void *ctx);
|
const char* GetSize(void *ctx);
|
||||||
const char* GetPos(void *ctx);
|
const char* GetPos(void *ctx);
|
||||||
|
|
||||||
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, void* data, int datalength);
|
void ProcessURLResponse(void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength);
|
||||||
|
|
||||||
/* Dialogs */
|
/* Dialogs */
|
||||||
|
|
||||||
|
@ -51,13 +51,13 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, void* data, int datalength) {
|
void ProcessURLResponse(void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength) {
|
||||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||||
NSString *nsurl = safeInit(url);
|
NSString *nsurl = safeInit(url);
|
||||||
NSString *nsContentType = safeInit(contentType);
|
NSString *nsContentType = safeInit(contentType);
|
||||||
NSData *nsdata = [NSData dataWithBytes:data length:datalength];
|
NSData *nsdata = [NSData dataWithBytes:data length:datalength];
|
||||||
|
|
||||||
[ctx processURLResponse:nsurl :nsContentType :nsdata];
|
[ctx processURLResponse:nsurl :statusCode :nsContentType :nsdata];
|
||||||
|
|
||||||
[nsdata release];
|
[nsdata release];
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
- (void) SaveFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(NSString*)filters;
|
- (void) SaveFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(NSString*)filters;
|
||||||
|
|
||||||
- (void) loadRequest:(NSString*)url;
|
- (void) loadRequest:(NSString*)url;
|
||||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData*)data;
|
- (void) processURLResponse:(NSString *)url :(int)statusCode :(NSString *)contentType :(NSData*)data;
|
||||||
- (void) ExecJS:(NSString*)script;
|
- (void) ExecJS:(NSString*)script;
|
||||||
- (NSScreen*) getCurrentScreen;
|
- (NSScreen*) getCurrentScreen;
|
||||||
|
|
||||||
|
@ -376,12 +376,14 @@
|
|||||||
[self.webview evaluateJavaScript:script completionHandler:nil];
|
[self.webview evaluateJavaScript:script completionHandler:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData *)data {
|
- (void) processURLResponse:(NSString *)url :(int)statusCode :(NSString *)contentType :(NSData *)data {
|
||||||
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
|
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
|
||||||
NSURL *nsurl = [NSURL URLWithString:url];
|
NSURL *nsurl = [NSURL URLWithString:url];
|
||||||
NSMutableDictionary *headerFields = [NSMutableDictionary new];
|
NSMutableDictionary *headerFields = [NSMutableDictionary new];
|
||||||
headerFields[@"content-type"] = contentType;
|
if ( ![contentType isEqualToString:@""] ) {
|
||||||
NSHTTPURLResponse *response = [[NSHTTPURLResponse new] initWithURL:nsurl statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
headerFields[@"content-type"] = contentType;
|
||||||
|
}
|
||||||
|
NSHTTPURLResponse *response = [[NSHTTPURLResponse new] initWithURL:nsurl statusCode:statusCode HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
||||||
[urlSchemeTask didReceiveResponse:response];
|
[urlSchemeTask didReceiveResponse:response];
|
||||||
[urlSchemeTask didReceiveData:data];
|
[urlSchemeTask didReceiveData:data];
|
||||||
[urlSchemeTask didFinish];
|
[urlSchemeTask didFinish];
|
||||||
|
@ -16,8 +16,10 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -272,21 +274,32 @@ func (f *Frontend) ExecJS(js string) {
|
|||||||
func (f *Frontend) processRequest(r *request) {
|
func (f *Frontend) processRequest(r *request) {
|
||||||
uri := C.GoString(r.url)
|
uri := C.GoString(r.url)
|
||||||
|
|
||||||
|
var _contents []byte
|
||||||
|
var _mimetype string
|
||||||
|
|
||||||
// Translate URI to file
|
// Translate URI to file
|
||||||
file, match, err := common.TranslateUriToFile(uri, "wails", "wails")
|
file, match, err := common.TranslateUriToFile(uri, "wails", "wails")
|
||||||
if err != nil {
|
if err == nil {
|
||||||
// TODO Handle errors
|
if !match {
|
||||||
return
|
// This should never happen on darwin, because we get only called for wails://
|
||||||
} else if !match {
|
panic("Unexpected host for request on wails:// scheme")
|
||||||
return
|
}
|
||||||
|
|
||||||
|
// Load file from asset store
|
||||||
|
_contents, _mimetype, err = f.assets.Load(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
_contents, _mimetype, err := f.assets.Load(file)
|
statusCode := 200
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.logger.Error(err.Error())
|
if os.IsNotExist(err) {
|
||||||
//TODO: Handle errors
|
statusCode = 404
|
||||||
return
|
} else {
|
||||||
|
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
statusCode = 500
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var data unsafe.Pointer
|
var data unsafe.Pointer
|
||||||
if _contents != nil {
|
if _contents != nil {
|
||||||
data = unsafe.Pointer(&_contents[0])
|
data = unsafe.Pointer(&_contents[0])
|
||||||
@ -294,7 +307,7 @@ func (f *Frontend) processRequest(r *request) {
|
|||||||
mimetype := C.CString(_mimetype)
|
mimetype := C.CString(_mimetype)
|
||||||
defer C.free(unsafe.Pointer(mimetype))
|
defer C.free(unsafe.Pointer(mimetype))
|
||||||
|
|
||||||
C.ProcessURLResponse(r.ctx, r.url, mimetype, data, C.int(len(_contents)))
|
C.ProcessURLResponse(r.ctx, r.url, C.int(statusCode), mimetype, data, C.int(len(_contents)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (f *Frontend) processSystemEvent(message string) {
|
//func (f *Frontend) processSystemEvent(message string) {
|
||||||
|
@ -333,7 +333,8 @@ func (f *Frontend) processRequest(request unsafe.Pointer) {
|
|||||||
// TODO Handle errors
|
// TODO Handle errors
|
||||||
return
|
return
|
||||||
} else if !match {
|
} else if !match {
|
||||||
return
|
// This should never happen on linux, because we get only called for wails://
|
||||||
|
panic("Unexpected host for request on wails:// scheme")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load file from asset store
|
// Load file from asset store
|
||||||
@ -342,6 +343,8 @@ func (f *Frontend) processRequest(request unsafe.Pointer) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO How to return 404/500 errors to webkit?
|
||||||
|
|
||||||
cContent := C.CString(string(content))
|
cContent := C.CString(string(content))
|
||||||
defer C.free(unsafe.Pointer(cContent))
|
defer C.free(unsafe.Pointer(cContent))
|
||||||
cMimeType := C.CString(mimeType)
|
cMimeType := C.CString(mimeType)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -336,26 +337,45 @@ func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, arg
|
|||||||
//Get the request
|
//Get the request
|
||||||
uri, _ := req.GetUri()
|
uri, _ := req.GetUri()
|
||||||
|
|
||||||
|
var content []byte
|
||||||
|
var mimeType string
|
||||||
|
|
||||||
|
// Translate URI to file
|
||||||
file, match, err := common.TranslateUriToFile(uri, "file", "wails")
|
file, match, err := common.TranslateUriToFile(uri, "file", "wails")
|
||||||
if err != nil {
|
if err == nil {
|
||||||
// TODO Handle errors
|
if !match {
|
||||||
return
|
// In this case we should let the WebView2 handle the request with it's default handler
|
||||||
} else if !match {
|
return
|
||||||
return
|
}
|
||||||
|
|
||||||
|
// Load file from asset store
|
||||||
|
content, mimeType, err = f.assets.Load(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load file from asset store
|
statusCode := 200
|
||||||
content, mimeType, err := f.assets.Load(file)
|
reasonPhrase := "OK"
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
if os.IsNotExist(err) {
|
||||||
|
statusCode = 404
|
||||||
|
reasonPhrase = "Not Found"
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
statusCode = 500
|
||||||
|
reasonPhrase = "Internal Server Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers := []string{}
|
||||||
|
if mimeType != "" {
|
||||||
|
headers = append(headers, "Content-Type: "+mimeType)
|
||||||
|
}
|
||||||
|
if content != nil && f.servingFromDisk {
|
||||||
|
headers = append(headers, "Pragma: no-cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
env := f.chromium.Environment()
|
env := f.chromium.Environment()
|
||||||
headers := "Content-Type: " + mimeType
|
response, err := env.CreateWebResourceResponse(content, statusCode, reasonPhrase, strings.Join(headers, "\n"))
|
||||||
if f.servingFromDisk {
|
|
||||||
headers += "\nPragma: no-cache"
|
|
||||||
}
|
|
||||||
response, err := env.CreateWebResourceResponse(content, 200, "OK", headers)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -366,7 +386,6 @@ func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, arg
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var edgeMap = map[string]uintptr{
|
var edgeMap = map[string]uintptr{
|
||||||
|
Loading…
Reference in New Issue
Block a user