Skip to content

Commit 60eff2f

Browse files
jcesarmobilemlynch
authored andcommittedNov 9, 2018
fix: Add more server checks before loading urls or reloading (ionic-team#211)
Add more server ckecks before loading urls or reloading, also check for socket
1 parent 9c0eeea commit 60eff2f

File tree

2 files changed

+85
-22
lines changed

2 files changed

+85
-22
lines changed
 

‎src/ios/CDVWKWebViewEngine.m

+56-18
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ @interface CDVWKWebViewEngine ()
107107
@property (nonatomic, readwrite) CGRect frame;
108108
@property (nonatomic, strong) NSString *userAgentCreds;
109109
@property (nonatomic, assign) BOOL internalConnectionsOnly;
110+
110111
@property (nonatomic, readwrite) NSString *CDV_LOCAL_SERVER;
111112
@end
112113

@@ -353,6 +354,14 @@ - (void)pluginInitialize
353354
addObserver:self
354355
selector:@selector(onAppWillEnterForeground:)
355356
name:UIApplicationWillEnterForegroundNotification object:nil];
357+
[[NSNotificationCenter defaultCenter]
358+
addObserver:self
359+
selector:@selector(onSocketError:)
360+
name:@"socketUnknownError" object:nil];
361+
[[NSNotificationCenter defaultCenter]
362+
addObserver:self
363+
selector:@selector(onSocketError:)
364+
name:@"socketInUseError" object:nil];
356365

357366
NSLog(@"Using Ionic WKWebView");
358367

@@ -417,7 +426,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
417426
if (context == KVOContext) {
418427
if (object == [self webView] && [keyPath isEqualToString: @"URL"] && [object valueForKeyPath:keyPath] == nil){
419428
NSLog(@"URL is nil. Reloading WKWebView");
420-
[(WKWebView*)_engineWebView reload];
429+
if ([self.webServer isRunning]) {
430+
[(WKWebView*)_engineWebView reload];
431+
} else {
432+
[self loadErrorPage:nil];
433+
}
421434
}
422435
} else {
423436
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
@@ -426,11 +439,19 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
426439

427440
- (void)onAppWillEnterForeground:(NSNotification *)notification {
428441
if ([self shouldReloadWebView]) {
429-
NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
430-
[(WKWebView*)_engineWebView reload];
442+
if ([self.webServer isRunning]) {
443+
NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
444+
[(WKWebView*)_engineWebView reload];
445+
} else {
446+
[self loadErrorPage:nil];
447+
}
431448
}
432449
}
433450

451+
- (void)onSocketError:(NSNotification *)notification {
452+
[self loadErrorPage:nil];
453+
}
454+
434455
- (BOOL)shouldReloadWebView
435456
{
436457
WKWebView* wkWebView = (WKWebView*)_engineWebView;
@@ -475,17 +496,25 @@ - (id)loadRequest:(NSURLRequest *)request
475496
if ([self.webServer isRunning]) {
476497
return [(WKWebView*)_engineWebView loadRequest:request];
477498
} else {
478-
NSString* errorHtml = [NSString stringWithFormat:
479-
@"<html>"
480-
@"<head><title>Error</title></head>"
481-
@" <div style='font-size:2em'>"
482-
@" <p>The App Server is not running.</p>"
483-
@" <p>Close other apps and try again.</p>"
484-
@" </div>"
485-
@"</html>"
486-
];
487-
return [self loadHTMLString:errorHtml baseURL:request.URL];
499+
return [self loadErrorPage:request];
500+
}
501+
}
502+
503+
- (id)loadErrorPage:(NSURLRequest *)request
504+
{
505+
if (!request) {
506+
request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
488507
}
508+
NSString* errorHtml = [NSString stringWithFormat:
509+
@"<html>"
510+
@"<head><title>Error</title></head>"
511+
@" <div style='font-size:2em'>"
512+
@" <p><b>Error</b></p>"
513+
@" <p>Unable to load app.</p>"
514+
@" </div>"
515+
@"</html>"
516+
];
517+
return [self loadHTMLString:errorHtml baseURL:request.URL];
489518
}
490519

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

745774
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
746775
{
747-
[webView reload];
776+
if ([self.webServer isRunning]) {
777+
[webView reload];
778+
} else {
779+
[self loadErrorPage:nil];
780+
}
748781
}
749782

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

816849
-(void)getServerBasePath:(CDVInvokedUrlCommand*)command
817850
{
818-
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
851+
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
819852
}
820853

821854
-(void)setServerBasePath:(CDVInvokedUrlCommand*)command
822855
{
823-
NSString * path = [command argumentAtIndex:0];
824-
[self setServerPath:path];
825-
[(WKWebView*)_engineWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]]];
856+
NSString * path = [command argumentAtIndex:0];
857+
[self setServerPath:path];
858+
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
859+
if ([self.webServer isRunning]) {
860+
[(WKWebView*)_engineWebView loadRequest:request];
861+
} else {
862+
[self loadErrorPage:request];
863+
}
826864
}
827865

828866
-(void)setServerPath:(NSString *) path

‎src/ios/GCDWebServer/Core/GCDWebServer.m

+29-4
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ - (int)_createListeningSocket:(BOOL)useIPv6
461461
*error = GCDWebServerMakePosixError(errno);
462462
}
463463
GWS_LOG_ERROR(@"Failed binding %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
464+
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketInUseError" object:nil]];
464465
close(listeningSocket);
465466
}
466467

@@ -713,20 +714,38 @@ - (BOOL)hasSocketError:(int)socket {
713714
int error = 0;
714715
socklen_t len = sizeof(error);
715716
int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
716-
717+
717718
if (retval != 0 ) {
718719
/* there was a problem getting the error code */
719720
GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
720721
return YES;
721722
}
722-
723+
723724
if (error != 0) {
724725
GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
725726
return YES;
726727
}
727728
return NO;
728729
}
729730

731+
- (int)socketError:(int)socket {
732+
int error = 0;
733+
socklen_t len = sizeof(error);
734+
int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
735+
736+
if (retval != 0 ) {
737+
/* there was a problem getting the error code */
738+
GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
739+
return retval;
740+
}
741+
742+
if (error != 0) {
743+
GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
744+
return error;
745+
}
746+
return 0;
747+
}
748+
730749
- (void)_didEnterBackground:(NSNotification*)notification {
731750
GWS_DCHECK([NSThread isMainThread]);
732751
GWS_LOG_DEBUG(@"Did enter background");
@@ -744,8 +763,14 @@ - (void)_willEnterForeground:(NSNotification*)notification {
744763
}
745764

746765
if ([self isRunning] && ([self hasSocketError:ipv4ListeningSocket] || [self hasSocketError:ipv6ListeningSocket])) {
747-
[self _stop];
748-
[self _start:nil];
766+
// 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
767+
if ([self socketError:ipv4ListeningSocket] != -1 && [self socketError:ipv6ListeningSocket] != -1) {
768+
[self _stop];
769+
[self _start:nil];
770+
} else {
771+
_options = nil;
772+
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketUnknownError" object:nil]];
773+
}
749774
}
750775
}
751776

0 commit comments

Comments
 (0)
Failed to load comments.