Author: gavincornwell
Date: Thu Dec 11 10:56:03 2014
New Revision: 1644593

URL: http://svn.apache.org/r1644593
Log:
First part of CMIS-874 (Switch from NSURLConnection to NSURLSession).

The CMISHttpXXX classes have been moved to use NSURLSession but they currently 
always use data tasks. To support background upload and download operations the 
appropriate task has to be used. A different session configuration object is 
also required to run in the background, the 2nd part will address these 
shortcomings.

Modified:
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.h
    
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISAuthenticationProvider.h
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h
    
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardAuthenticationProvider.m
    
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardUntrustedSSLAuthenticationProvider.m
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
    chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.h?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.h (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.h Thu Dec 
11 10:56:03 2014
@@ -22,7 +22,7 @@
 @class CMISOperationContext;
 @class CMISRequest;
 
-@interface CMISDocument : CMISFileableObject <NSURLConnectionDataDelegate>
+@interface CMISDocument : CMISFileableObject
 
 @property (nonatomic, strong, readonly) NSString *contentStreamId;
 @property (nonatomic, strong, readonly) NSString *contentStreamFileName;

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISAuthenticationProvider.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISAuthenticationProvider.h?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISAuthenticationProvider.h 
(original)
+++ 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISAuthenticationProvider.h 
Thu Dec 11 10:56:03 2014
@@ -51,4 +51,10 @@
  */
 - (void)didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge 
*)challenge;
 
+/**
+ * callback when authentication challenge was received using NSURLSession
+ */
+- (void)didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+          completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, 
NSURLCredential *))completionHandler;
+
 @end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h Thu Dec 11 
10:56:03 2014
@@ -106,7 +106,7 @@ extern NSString * const kCMISErrorDescri
  CMIS errors are created either 
  
  - directly. This is the case when an error is captured by one of the 
methods/classes in the CMIS library
- - indirectly. Errors have been created by classes/methods outside the CMIS 
library. Example errors created through NSURLConnection. In this case, the 
underlying error is copied into the CMIS error using the NSUnderlyingErrorKey 
in the userInfo Dictionary.
+ - indirectly. Errors have been created by classes/methods outside the CMIS 
library. Example errors created through NSURLSession. In this case, the 
underlying error is copied into the CMIS error using the NSUnderlyingErrorKey 
in the userInfo Dictionary.
  
  */
 @interface CMISErrors : NSObject

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardAuthenticationProvider.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardAuthenticationProvider.m?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardAuthenticationProvider.m
 (original)
+++ 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardAuthenticationProvider.m
 Thu Dec 11 10:56:03 2014
@@ -62,6 +62,10 @@
     return [NSDictionary dictionary];
 }
 
+- (void)updateWithHttpURLResponse:(NSHTTPURLResponse*)httpUrlResponse
+{
+    // nothing to do in the default implementation
+}
 
 - (BOOL)canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace 
*)protectionSpace
 {
@@ -108,11 +112,29 @@
     }
 }
 
-
-- (void)updateWithHttpURLResponse:(NSHTTPURLResponse*)httpUrlResponse
+- (void)didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+          completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, 
NSURLCredential *))completionHandler
 {
-    // nothing to do in the default implementation
+    if (challenge.previousFailureCount == 0) {
+        if ([challenge.protectionSpace.authenticationMethod 
isEqualToString:NSURLAuthenticationMethodClientCertificate] &&
+            self.credential.identity) {
+            CMISLogDebug(@"Authenticating with client certificate");
+            completionHandler(NSURLSessionAuthChallengeUseCredential, 
self.credential);
+        } else if ([challenge.protectionSpace.authenticationMethod 
isEqualToString:NSURLAuthenticationMethodHTTPBasic] &&
+                   self.credential.user && self.credential.hasPassword) {
+            CMISLogDebug(@"Authenticating with username and password");
+            completionHandler(NSURLSessionAuthChallengeUseCredential, 
self.credential);
+        } else if (challenge.proposedCredential) {
+            CMISLogDebug(@"Authenticating with proposed credential");
+            completionHandler(NSURLSessionAuthChallengeUseCredential, 
challenge.proposedCredential);
+        } else {
+            CMISLogDebug(@"Authenticating without credential");
+            completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, 
nil);
+        }
+    } else {
+        CMISLogDebug(@"Authentication failed, cancelling logon");
+        
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
+    }
 }
 
-
 @end

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardUntrustedSSLAuthenticationProvider.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardUntrustedSSLAuthenticationProvider.m?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardUntrustedSSLAuthenticationProvider.m
 (original)
+++ 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISStandardUntrustedSSLAuthenticationProvider.m
 Thu Dec 11 10:56:03 2014
@@ -18,6 +18,7 @@
  */
 
 #import "CMISStandardUntrustedSSLAuthenticationProvider.h"
+#import "CMISLog.h"
 
 @implementation CMISStandardUntrustedSSLAuthenticationProvider
 
@@ -40,10 +41,24 @@
     if ((challenge.previousFailureCount == 0) &&
         ([challenge.protectionSpace.authenticationMethod 
isEqualToString:NSURLAuthenticationMethodServerTrust]))
     {
+        CMISLogWarning(@"Allowing self-signed certificate");
         [challenge.sender useCredential:[NSURLCredential 
credentialForTrust:challenge.protectionSpace.serverTrust] 
forAuthenticationChallenge:challenge];
     } else {
         [super didReceiveAuthenticationChallenge:challenge];
     }
 }
 
+- (void)didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+          completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, 
NSURLCredential *))completionHandler
+{
+    if ((challenge.previousFailureCount == 0) &&
+        ([challenge.protectionSpace.authenticationMethod 
isEqualToString:NSURLAuthenticationMethodServerTrust]))
+    {
+        CMISLogWarning(@"Allowing self-signed certificate");
+        completionHandler(NSURLSessionAuthChallengeUseCredential, 
[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    } else {
+        [super didReceiveChallenge:challenge 
completionHandler:completionHandler];
+    }
+}
+
 @end

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m 
Thu Dec 11 10:56:03 2014
@@ -105,54 +105,32 @@ authenticationProvider:(id<CMISAuthentic
     return self;
 }
 
+#pragma mark CMISCancellableRequest method
 
 - (void)cancel
 {
-    [self.outputStream close];
+    [super cancel];
     
+    // clean up
+    [self.outputStream close];
     self.progressBlock = nil;
-    
-    [super cancel];
 }
 
+#pragma mark Session delegate methods
 
-- (void)connection:(NSURLConnection *)connection 
didReceiveResponse:(NSURLResponse *)response
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error
 {
-    [super connection:connection didReceiveResponse:response];
-    
-    // update statistics
-    if (self.bytesExpected == 0 && response.expectedContentLength != 
NSURLResponseUnknownLength) {
-        self.bytesExpected = response.expectedContentLength;
-    }
-    self.bytesDownloaded = 0;
-
-    // set up output stream if available
-    if (self.outputStream) { // otherwise store data in memory in self.data
-        // create file for downloaded content
-        BOOL isStreamReady = self.outputStream.streamStatus == 
NSStreamStatusOpen;
-        if (!isStreamReady) {
-            [self.outputStream open];
-            isStreamReady = self.outputStream.streamStatus == 
NSStreamStatusOpen;
-        }
+    // clean up
+    [self.outputStream close];
+    self.progressBlock = nil;
     
-        if (!isStreamReady) {
-            [connection cancel];
-            
-            if (self.completionBlock)
-            {
-                NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeStorage
-                                                     
detailedDescription:@"Could not open output stream"];
-                self.completionBlock(nil, cmisError);
-            }
-        }
-    }
+    [super URLSession:session task:task didCompleteWithError:error];
 }
 
-
-- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask 
*)dataTask didReceiveData:(NSData *)data
 {
     if (self.outputStream == nil) { // if there is no outputStream then store 
data in memory in self.data
-        [super connection:connection didReceiveData:data];
+        [super URLSession:session dataTask:dataTask didReceiveData:data];
     } else {
         const uint8_t *bytes = data.bytes;
         NSUInteger length = data.length;
@@ -160,8 +138,8 @@ authenticationProvider:(id<CMISAuthentic
         do {
             NSUInteger written = [self.outputStream write:&bytes[offset] 
maxLength:length - offset];
             if (written <= 0) {
-                CMISLogError(@"Error while writing downloaded data to file");
-                [connection cancel];
+                CMISLogError(@"Error while writing downloaded data to stream");
+                [session invalidateAndCancel];
                 return;
             } else {
                 offset += written;
@@ -171,31 +149,52 @@ authenticationProvider:(id<CMISAuthentic
     
     // update statistics
     self.bytesDownloaded += data.length;
-    // pass progress to progressBlock
+    
+    // pass progress to progressBlock, on the main thread
     if (self.progressBlock) {
-        self.progressBlock(self.bytesDownloaded, self.bytesExpected);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (self.progressBlock) {
+                self.progressBlock(self.bytesDownloaded, self.bytesExpected);
+            }
+        });
     }
-    
 }
 
-
-- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError 
*)error
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask 
*)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void 
(^)(NSURLSessionResponseDisposition))completionHandler
 {
-    [self.outputStream close];
-
-    self.progressBlock = nil;
-
-    [super connection:connection didFailWithError:error];
-}
-
-
-- (void)connectionDidFinishLoading:(NSURLConnection *)connection
-{
-    [self.outputStream close];
-
-    self.progressBlock = nil;
-
-    [super connectionDidFinishLoading:connection];
+    // update statistics
+    if (self.bytesExpected == 0 && 
self.sessionTask.countOfBytesExpectedToReceive != 
NSURLSessionTransferSizeUnknown) {
+        self.bytesExpected = self.sessionTask.countOfBytesExpectedToReceive;
+    }
+    
+    self.bytesDownloaded = 0;
+    
+    // set up output stream if available
+    if (self.outputStream) { // otherwise store data in memory in self.data
+        // create file for downloaded content
+        BOOL isStreamReady = self.outputStream.streamStatus == 
NSStreamStatusOpen;
+        if (!isStreamReady) {
+            [self.outputStream open];
+            isStreamReady = self.outputStream.streamStatus == 
NSStreamStatusOpen;
+        }
+        
+        if (isStreamReady) {
+            [super URLSession:session dataTask:dataTask 
didReceiveResponse:response completionHandler:completionHandler];
+        } else {
+            [session invalidateAndCancel];
+            
+            if (self.completionBlock)
+            {
+                NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeStorage
+                                                     
detailedDescription:@"Could not open output stream"];
+                
+                // call the completion block on the main thread
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    self.completionBlock(nil, cmisError);
+                });
+            }
+        }
+    }
 }
 
 @end

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h Thu Dec 
11 10:56:03 2014
@@ -23,10 +23,11 @@
 #import "CMISRequest.h"
 @class CMISAuthenticationProvider;
 
-@interface CMISHttpRequest : NSObject <NSURLConnectionDelegate, 
NSURLConnectionDataDelegate, CMISCancellableRequest>
+@interface CMISHttpRequest : NSObject <CMISCancellableRequest, 
NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
 
 @property (nonatomic, assign) CMISHttpRequestMethod requestMethod;
-@property (nonatomic, strong) NSURLConnection *connection;
+@property (nonatomic, strong) NSURLSession *urlSession;
+@property (nonatomic, strong) NSURLSessionTask *sessionTask;
 @property (nonatomic, strong) NSData *requestBody;
 @property (nonatomic, strong) NSMutableData *responseBody;
 @property (nonatomic, strong) NSDictionary *additionalHeaders;

Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m Thu Dec 
11 10:56:03 2014
@@ -101,20 +101,24 @@ NSString * const kCMISExceptionVersionin
         }
     }];
     
-    self.connection = [[NSURLConnection alloc] initWithRequest:urlRequest 
delegate:self startImmediately:NO];
+    // create session and task
+    self.urlSession = [NSURLSession 
sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
+                                                    delegate:self
+                                               delegateQueue:nil];
+    self.sessionTask = [self.urlSession dataTaskWithRequest:urlRequest];
+    
     CMISReachability *reachability = [CMISReachability networkReachability];
     
-    if (self.connection && reachability.hasNetworkConnection) {
-        [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
forMode:NSRunLoopCommonModes];
-        [self.connection start];
+    if (self.sessionTask && reachability.hasNetworkConnection) {
+        [self.sessionTask resume];
         startedRequest = YES;
     } else if (!reachability.hasNetworkConnection) {
         NSError *noConnectionError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeNoNetworkConnection 
detailedDescription:kCMISErrorDescriptionNoNetworkConnection];
-        [self connection:self.connection didFailWithError:noConnectionError];
+        [self URLSession:self.urlSession task:self.sessionTask 
didCompleteWithError:noConnectionError];
     }
     else {
         if (self.completionBlock) {
-            NSString *detailedDescription = [NSString stringWithFormat:@"Could 
not create connection to %@", urlRequest.URL];
+            NSString *detailedDescription = [NSString stringWithFormat:@"Could 
not connect to %@", urlRequest.URL];
             NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeConnection 
detailedDescription:detailedDescription];
             self.completionBlock(nil, cmisError);
         }
@@ -123,96 +127,84 @@ NSString * const kCMISExceptionVersionin
     return startedRequest;
 }
 
+#pragma mark CMISCancellableRequest method
+
 - (void)cancel
 {
-    if (self.connection) {
+    if (self.urlSession) {
         void (^completionBlock)(CMISHttpResponse *httpResponse, NSError 
*error);
         completionBlock = self.completionBlock; // remember completion block 
in order to invoke it after the connection was cancelled
         
-        self.completionBlock = nil; // prevent potential NSURLConnection 
delegate callbacks to invoke the completion block redundantly
+        self.completionBlock = nil; // prevent potential NSURLSession delegate 
callbacks to invoke the completion block redundantly
         
-        [self.connection cancel];
+        [self.urlSession invalidateAndCancel];
         
-        self.connection = nil;
+        self.urlSession = nil;
         
         NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeCancelled detailedDescription:@"Request 
was cancelled"];
         completionBlock(nil, cmisError);
     }
 }
 
+#pragma mark Session delegate methods
 
-- (BOOL)connection:(NSURLConnection *)connection 
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error
 {
-    return [self.authenticationProvider 
canAuthenticateAgainstProtectionSpace:protectionSpace];
-}
-
+    [self.authenticationProvider updateWithHttpURLResponse:self.response];
 
-- (void)connection:(NSURLConnection *)connection 
didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
-{
-    [self.authenticationProvider didCancelAuthenticationChallenge:challenge];
+    if (self.completionBlock) {
+        
+        NSError *cmisError = nil;
+        CMISHttpResponse *httpResponse = nil;
+        
+        if (error) {
+            CMISErrorCodes cmisErrorCode = kCMISErrorCodeConnection;
+            
+            // swap error code if necessary
+            if (error.code == NSURLErrorCancelled) {
+                cmisErrorCode = kCMISErrorCodeCancelled;
+            } else if (error.code == kCMISErrorCodeNoNetworkConnection) {
+                cmisErrorCode = kCMISErrorCodeNoNetworkConnection;
+            }
+            
+            cmisError = [CMISErrors cmisError:error 
cmisErrorCode:cmisErrorCode];
+        } else {
+            // no error returned but we also need to check response code
+            httpResponse = [CMISHttpResponse 
responseUsingURLHTTPResponse:self.response data:self.responseBody];
+            if (![self checkStatusCodeForResponse:httpResponse 
httpRequestMethod:self.requestMethod error:&cmisError]) {
+                httpResponse = nil;
+            }
+        }
+        
+        // call the completion block on the main thread
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self.completionBlock(httpResponse, cmisError);
+        });
+    }
+    
+    // clean up
+    self.sessionTask = nil;
+    self.urlSession = nil;
 }
 
-
-- (void)connection:(NSURLConnection *)connection 
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask 
*)dataTask didReceiveData:(NSData *)data
 {
-    [self.authenticationProvider didReceiveAuthenticationChallenge:challenge];
+    [self.responseBody appendData:data];
 }
 
-
-- (void)connection:(NSURLConnection *)connection 
didReceiveResponse:(NSURLResponse *)response
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask 
*)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void 
(^)(NSURLSessionResponseDisposition))completionHandler
 {
     self.responseBody = [[NSMutableData alloc] init];
     if ([response isKindOfClass:NSHTTPURLResponse.class]) {
         self.response = (NSHTTPURLResponse*)response;
     }
-}
-
-
-- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
-{
-    [self.responseBody appendData:data];
-}
-
-
-- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError 
*)error
-{
-    [self.authenticationProvider updateWithHttpURLResponse:self.response];
-
-    if (self.completionBlock) {
-        CMISErrorCodes cmisErrorCode = kCMISErrorCodeConnection;
-        
-        // swap error code if necessary
-        if (error.code == NSURLErrorCancelled) {
-            cmisErrorCode = kCMISErrorCodeCancelled;
-        } else if (error.code == kCMISErrorCodeNoNetworkConnection) {
-            cmisErrorCode = kCMISErrorCodeNoNetworkConnection;
-        }
-        
-        NSError *cmisError = [CMISErrors cmisError:error 
cmisErrorCode:cmisErrorCode];
-        self.completionBlock(nil, cmisError);
-    }
     
-    self.completionBlock = nil;
-    self.connection = nil;
+    completionHandler(NSURLSessionResponseAllow);
 }
 
-
-- (void)connectionDidFinishLoading:(NSURLConnection *)connection
+- (void)URLSession:(NSURLSession *)session 
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, 
NSURLCredential *))completionHandler
 {
-    [self.authenticationProvider updateWithHttpURLResponse:self.response];
-    
-    if (self.completionBlock) {
-        NSError *cmisError = nil;
-        CMISHttpResponse *httpResponse = [CMISHttpResponse 
responseUsingURLHTTPResponse:self.response data:self.responseBody];
-        if ([self checkStatusCodeForResponse:httpResponse 
httpRequestMethod:self.requestMethod error:&cmisError]) {
-            self.completionBlock(httpResponse, nil);
-        } else {
-            self.completionBlock(nil, cmisError);
-        }
-    }
-    
-    self.completionBlock = nil;
-    self.connection = nil;
+    [self.authenticationProvider didReceiveChallenge:challenge 
completionHandler:completionHandler];
 }
 
 - (BOOL)checkStatusCodeForResponse:(CMISHttpResponse *)response 
httpRequestMethod:(CMISHttpRequestMethod)httpRequestMethod error:(NSError 
**)error

Modified: 
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
URL: 
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m?rev=1644593&r1=1644592&r2=1644593&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m 
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m 
Thu Dec 11 10:56:03 2014
@@ -42,7 +42,7 @@ const NSUInteger kRawBufferSize = 24576;
 
 /**
  A category that extends the NSStream class in order to pair an inputstream 
with an outputstream.
- The input stream will be used by NSURLConnection via the HTTPBodyStream 
property of the URL request.
+ The input stream will be used by NSURLSession via the HTTPBodyStream property 
of the URL request.
  The paired output stream will buffer base64 encoded as well as XML data.
  
  NOTE: the original sample code also provides a method for backward 
compatibility w.r.t  iOS versions below 5.0
@@ -207,7 +207,8 @@ authenticationProvider:(id<CMISAuthentic
     return startSuccess;
 }
 
-#pragma CMISCancellableRequest method
+#pragma mark CMISCancellableRequest method
+
 - (void)cancel
 {
     self.progressBlock = nil;
@@ -218,68 +219,52 @@ authenticationProvider:(id<CMISAuthentic
     }
 }
 
-#pragma NSURLConnectionDataDelegate methods
-- (void)connection:(NSURLConnection *)connection 
didReceiveResponse:(NSURLResponse *)response
+#pragma mark Session delegate methods
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error
 {
-    [super connection:connection didReceiveResponse:response];
+    [super URLSession:session task:task didCompleteWithError:error];
+    
+    if (self.useCombinedInputStream) {
+        if (error) {
+            [self stopSendWithStatus:@"connection is being terminated with 
error."];
+        } else {
+            [self stopSendWithStatus:@"Connection finished as expected."];
+        }
+    }
     
+    self.progressBlock = nil;
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask 
*)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void 
(^)(NSURLSessionResponseDisposition))completionHandler
+{
     self.bytesUploaded = 0;
+    
+    [super URLSession:session dataTask:dataTask didReceiveResponse:response 
completionHandler:completionHandler];
 }
 
-- (void)connection:(NSURLConnection *)connection
-   didSendBodyData:(NSInteger)bytesWritten
- totalBytesWritten:(NSInteger)totalBytesWritten
-totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent 
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
 {
     if (self.progressBlock) {
         if (self.useCombinedInputStream && self.base64Encoding) {
             // Show the actual transmitted raw data size to the user, not the 
base64 encoded size
-            totalBytesWritten = [CMISHttpUploadRequest 
rawEncodedLength:totalBytesWritten];
-            if (totalBytesWritten > totalBytesExpectedToWrite) {
-                totalBytesWritten = totalBytesExpectedToWrite;
+            totalBytesSent = [CMISHttpUploadRequest 
rawEncodedLength:totalBytesSent];
+            if (totalBytesSent > totalBytesExpectedToSend) {
+                totalBytesSent = totalBytesExpectedToSend;
             }
         }
         
         if (self.bytesExpected == 0) {
-            self.progressBlock((unsigned long long)totalBytesWritten, 
(unsigned long long)totalBytesExpectedToWrite);
+            self.progressBlock((unsigned long long)totalBytesSent, (unsigned 
long long)totalBytesExpectedToSend);
         } else {
-            self.progressBlock((unsigned long long)totalBytesWritten, 
self.bytesExpected);
+            self.progressBlock((unsigned long long)totalBytesSent, 
self.bytesExpected);
         }
     }
 }
 
+#pragma mark NSStreamDelegate method
 
 /**
- In addition to closing the connection we also have to close/reset all streams 
used in this class.
- This is for base64 encoding only
- */
-- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError 
*)error
-{
-    [super connection:connection didFailWithError:error];
-    
-    if (self.useCombinedInputStream) {
-        [self stopSendWithStatus:@"connection is being terminated with 
error."];
-    }
-    self.progressBlock = nil;
-}
-
-
-/**
- In addition to closing the connection we also have to close/reset all streams 
used in this class.
- This is for base64 encoding only
- */
-- (void)connectionDidFinishLoading:(NSURLConnection *)connection
-{
-    [super connectionDidFinishLoading:connection];
-    if (self.useCombinedInputStream) {
-        [self stopSendWithStatus:@"Connection finished as expected."];
-    }
-    
-    self.progressBlock = nil;
-}
-
-#pragma NSStreamDelegate method
-/**
  For encoding base64 data - this is the meat of this class.
  The action is in the case where the eventCode == 
NSStreamEventHasSpaceAvailable
  
@@ -393,7 +378,7 @@ totalBytesExpectedToWrite:(NSInteger)tot
                 if (bytesWritten <= 0) {
                     [self stopSendWithStatus:@"Network write error"];
                     NSError *cmisError = [CMISErrors 
createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:@"Network 
write error"];
-                    [self connection:nil didFailWithError:cmisError];
+                    [self URLSession:nil task:nil 
didCompleteWithError:cmisError];
                 } else {
                     self.bufferOffset += bytesWritten;
                 }
@@ -417,7 +402,7 @@ totalBytesExpectedToWrite:(NSInteger)tot
 }
 
 
-#pragma private methods
+#pragma mark Private methods
 
 - (void)prepareStreams
 {
@@ -468,13 +453,13 @@ totalBytesExpectedToWrite:(NSInteger)tot
     return 4 * adjustedThirdPartOfSize;
 }
 
-+ (NSUInteger)rawEncodedLength:(NSUInteger)base64EncodedSize
++ (unsigned long long)rawEncodedLength:(unsigned long long)base64EncodedSize
 {
     if (0 == base64EncodedSize) {
         return 0;
     }
     
-    NSUInteger adjustedFourthPartOfSize = (base64EncodedSize / 4) + ( (0 == 
base64EncodedSize % 4 ) ? 0 : 1 );
+    unsigned long long adjustedFourthPartOfSize = (base64EncodedSize / 4) + ( 
(0 == base64EncodedSize % 4 ) ? 0 : 1 );
     return 3 * adjustedFourthPartOfSize;
 }
 
@@ -486,9 +471,9 @@ totalBytesExpectedToWrite:(NSInteger)tot
     self.bufferOffset = 0;
     self.bufferLimit  = 0;
     self.dataBuffer = nil;
-    if (self.connection != nil) {
-        [self.connection cancel];
-        self.connection = nil;
+    if (self.urlSession != nil) {
+        [self.urlSession invalidateAndCancel];
+        self.urlSession = nil;
     }
     if (self.encoderStream != nil) {
         self.encoderStream.delegate = nil;


Reply via email to