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;