I have been working on an App that has a simple UIWebView in it that displays a Sharepoint site. I originally thought the NTLM authentication would be an issue but as it turns out that is really straight forward. However, ever since iOS8 my app has been spamming "Stream is sending an event before being opened" over and over again in my log to the point that the page really never can load.
I originally thought it was something I was doing so I created a small app (below) to remove any weirdness my other app may have had but unfortunately I get the same issue. I guess my main issue is I don't know where to even start to look to find an answer to this one. The Internet has some mention of this but no clear resolution like [webView dontDoThat]. :D
I am playing around with adding the connection to the run loop manually, you will see this in the code. I have tried every way I know how to create the connection but this is the most recent try.
I start out handing the SSL challenge because my cert is not valid for the domain, then I get the NTLM challenge and send in the hard coded username and pass as a test. It partially loads the site but finally gives up loading all the resources in what I assume is this error. Theories welcome.
//
// ViewController.m
//
// Created by Greg Frame on 10/2/14.
//
#import "ViewController.h"
#define APPURL @"https://mysharepoint.com"
#define USERNAME @"usernamehere"
#define PASSWORD @"passwordhere"
@interface ViewController ()
@end
@implementation ViewController
BOOL _Authenticated = NO;
BOOL _SSLAuthenticated = NO;
NSURLConnection *_Connection;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.webView.delegate = self;
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark UIWebViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(webView.loading){ //if url requests come through while its loading, its probably embedded content
return YES;
}
BOOL result = YES;
if (!_Authenticated || !_SSLAuthenticated) {
//I have tried a ton of different ways to create the NSURLConnection this is the latest
_Connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[_Connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[_Connection start];
result = NO;
}
return result;
}
#pragma mark NSURLConnection Delegate
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
if( [challenge previousFailureCount] == 0 ) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(@"SSL Challenge");
NSURL* baseURL = [NSURL URLWithString:APPURL];
if ([challenge.protectionSpace.host isEqualToString:baseURL.host]) {
NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else
NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);
} else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]) {
NSLog(@"NTLM Challenge");
_SSLAuthenticated = YES; //cant get here otherwise
//persistence:NSURLCredentialPersistenceForSession
NSURLCredential *cred = [NSURLCredential credentialWithUser:USERNAME password:PASSWORD persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
} else {
NSLog(@"Unsupported Challenge");
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
} else {
NSLog(@"Failed authentication");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)pResponse;
NSLog(@"Received response %ld", (long)[httpResponse statusCode]);
if( !_SSLAuthenticated && [httpResponse statusCode] == 200) {
NSLog(@"SSL GOOD");
_SSLAuthenticated = YES;
[_Connection cancel];
_Connection = nil;
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
return;
}
if( !_Authenticated && [httpResponse statusCode] == 200) {
NSLog(@"NTLM GOOD");
_Authenticated = YES;
[_Connection cancel];
[_Connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
[self.webView loadRequest:requestURL];
return;
}
NSLog(@"Connection Cancelled");
[_Connection cancel];
}
@end
Disclaimer: Parts and pieces were copied from others so I don't claim to have manually typed every line. Thanks to you all who had code that I put in this example.
Any help appreciated! - Greg Frame
Some log entries:
2014-10-06 15:12:31.110 sptest2[21405:2051411] SSL Challenge
2014-10-06 15:12:31.110 sptest2[21405:2051411] trusting connection to host xxxxx.xxxxx.com
2014-10-06 15:12:31.426 sptest2[21405:2051411] NTLM Challenge
2014-10-06 15:12:31.899 sptest2[21405:2051690] Stream 0x7c8d9070 is sending an event before being opened
2014-10-06 15:12:32.429 sptest2[21405:2051411] Received response 200
2014-10-06 15:12:32.429 sptest2[21405:2051411] NTLM GOOD
2014-10-06 15:12:33.184 sptest2[21405:2051723] Stream 0x7ca95210 is sending an event before being opened
2014-10-06 15:12:34.293 sptest2[21405:2051723] Stream 0x7bed9740 is sending an event before being opened
2014-10-06 15:12:34.465 sptest2[21405:2051723] Stream 0x7bee1120 is sending an event before being opened
2014-10-06 15:12:34.523 sptest2[21405:2051723] Stream 0x7caba9a0 is sending an event before being opened
2014-10-06 15:12:34.532 sptest2[21405:2051723] Stream 0x7f87e040 is sending an event before being opened
...