Skip to content

Commit

Permalink
fix: Add more server checks before loading urls or reloading
Browse files Browse the repository at this point in the history
Add  more server ckecks before loading urls or reloading, also check for socket
  • Loading branch information
jcesarmobile committed Nov 9, 2018
1 parent 9c0eeea commit 90e21d3
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 22 deletions.
74 changes: 56 additions & 18 deletions src/ios/CDVWKWebViewEngine.m
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ @interface CDVWKWebViewEngine ()
@property (nonatomic, readwrite) CGRect frame;
@property (nonatomic, strong) NSString *userAgentCreds;
@property (nonatomic, assign) BOOL internalConnectionsOnly;

@property (nonatomic, readwrite) NSString *CDV_LOCAL_SERVER;
@end

Expand Down Expand Up @@ -353,6 +354,14 @@ - (void)pluginInitialize
addObserver:self
selector:@selector(onAppWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onSocketError:)
name:@"socketUnknownError" object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onSocketError:)
name:@"socketInUseError" object:nil];

NSLog(@"Using Ionic WKWebView");

Expand Down Expand Up @@ -417,7 +426,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
if (context == KVOContext) {
if (object == [self webView] && [keyPath isEqualToString: @"URL"] && [object valueForKeyPath:keyPath] == nil){
NSLog(@"URL is nil. Reloading WKWebView");
[(WKWebView*)_engineWebView reload];
if ([self.webServer isRunning]) {
[(WKWebView*)_engineWebView reload];
} else {
[self loadErrorPage:nil];
}
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
Expand All @@ -426,11 +439,19 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N

- (void)onAppWillEnterForeground:(NSNotification *)notification {
if ([self shouldReloadWebView]) {
NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
[(WKWebView*)_engineWebView reload];
if ([self.webServer isRunning]) {
NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
[(WKWebView*)_engineWebView reload];
} else {
[self loadErrorPage:nil];
}
}
}

- (void)onSocketError:(NSNotification *)notification {
[self loadErrorPage:nil];
}

- (BOOL)shouldReloadWebView
{
WKWebView* wkWebView = (WKWebView*)_engineWebView;
Expand Down Expand Up @@ -475,17 +496,25 @@ - (id)loadRequest:(NSURLRequest *)request
if ([self.webServer isRunning]) {
return [(WKWebView*)_engineWebView loadRequest:request];
} else {
NSString* errorHtml = [NSString stringWithFormat:
@"<html>"
@"<head><title>Error</title></head>"
@" <div style='font-size:2em'>"
@" <p>The App Server is not running.</p>"
@" <p>Close other apps and try again.</p>"
@" </div>"
@"</html>"
];
return [self loadHTMLString:errorHtml baseURL:request.URL];
return [self loadErrorPage:request];
}
}

- (id)loadErrorPage:(NSURLRequest *)request
{
if (!request) {
request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
}
NSString* errorHtml = [NSString stringWithFormat:
@"<html>"
@"<head><title>Error</title></head>"
@" <div style='font-size:2em'>"
@" <p><b>Error</b></p>"
@" <p>Unable to load app.</p>"
@" </div>"
@"</html>"
];
return [self loadHTMLString:errorHtml baseURL:request.URL];
}

- (id)loadHTMLString:(NSString *)string baseURL:(NSURL*)baseURL
Expand Down Expand Up @@ -744,7 +773,11 @@ - (void)webView:(WKWebView*)theWebView didFailNavigation:(WKNavigation*)navigati

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
[webView reload];
if ([self.webServer isRunning]) {
[webView reload];
} else {
[self loadErrorPage:nil];
}
}

- (BOOL)defaultResourcePolicyForURL:(NSURL*)url
Expand Down Expand Up @@ -815,14 +848,19 @@ - (void) webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigat

-(void)getServerBasePath:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
}

-(void)setServerBasePath:(CDVInvokedUrlCommand*)command
{
NSString * path = [command argumentAtIndex:0];
[self setServerPath:path];
[(WKWebView*)_engineWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]]];
NSString * path = [command argumentAtIndex:0];
[self setServerPath:path];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
if ([self.webServer isRunning]) {
[(WKWebView*)_engineWebView loadRequest:request];
} else {
[self loadErrorPage:request];
}
}

-(void)setServerPath:(NSString *) path
Expand Down
33 changes: 29 additions & 4 deletions src/ios/GCDWebServer/Core/GCDWebServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ - (int)_createListeningSocket:(BOOL)useIPv6
*error = GCDWebServerMakePosixError(errno);
}
GWS_LOG_ERROR(@"Failed binding %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketInUseError" object:nil]];
close(listeningSocket);
}

Expand Down Expand Up @@ -713,20 +714,38 @@ - (BOOL)hasSocketError:(int)socket {
int error = 0;
socklen_t len = sizeof(error);
int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);

if (retval != 0 ) {
/* there was a problem getting the error code */
GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
return YES;
}

if (error != 0) {
GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
return YES;
}
return NO;
}

- (int)socketError:(int)socket {
int error = 0;
socklen_t len = sizeof(error);
int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);

if (retval != 0 ) {
/* there was a problem getting the error code */
GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
return retval;
}

if (error != 0) {
GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
return error;
}
return 0;
}

- (void)_didEnterBackground:(NSNotification*)notification {
GWS_DCHECK([NSThread isMainThread]);
GWS_LOG_DEBUG(@"Did enter background");
Expand All @@ -744,8 +763,14 @@ - (void)_willEnterForeground:(NSNotification*)notification {
}

if ([self isRunning] && ([self hasSocketError:ipv4ListeningSocket] || [self hasSocketError:ipv6ListeningSocket])) {
[self _stop];
[self _start:nil];
// If error is -1 (unknown) its probably because of port being used by other app, so don't restart in this case as it will fail
if ([self socketError:ipv4ListeningSocket] != -1 && [self socketError:ipv6ListeningSocket] != -1) {
[self _stop];
[self _start:nil];
} else {
_options = nil;
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketUnknownError" object:nil]];
}
}
}

Expand Down

0 comments on commit 90e21d3

Please sign in to comment.