Author: gavincornwell
Date: Fri Dec 12 10:39:06 2014
New Revision: 1644858
URL: http://svn.apache.org/r1644858
Log:
Second part of CMIS-874 (Switch from NSURLConnection to NSURLSession).
The most appropriate task is now used for the request i.e. if a filePath is
provided a NSURLSessionDownloadTask is used, uploads are now always done using
an NSURLSessionUploadTask and all other requests use NSURLSessionDataTask.
Support for background sessions is going to need some further re-factoring so
that will follow in another commit.
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/AtomPub/CMISAtomPubObjectService.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/Browser/CMISBrowserObjectService.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISSession.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISNetworkProvider.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISDefaultNetworkProvider.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.h
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.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/AtomPub/CMISAtomPubObjectService.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/AtomPub/CMISAtomPubObjectService.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
---
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/AtomPub/CMISAtomPubObjectService.m
(original)
+++
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/AtomPub/CMISAtomPubObjectService.m
Fri Dec 12 10:39:06 2014
@@ -87,17 +87,44 @@
completionBlock:(void (^)(NSError
*error))completionBlock
progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock
{
- return [self downloadContentOfObject:objectId
- streamId:streamId
- toFile:filePath
- offset:nil
- length:nil
- completionBlock:completionBlock
- progressBlock:^(unsigned long long bytesDownloaded,
unsigned long long bytesTotal) {
- if (progressBlock) {
- progressBlock(bytesDownloaded, bytesTotal);
- }
- }];
+ CMISRequest *request = [[CMISRequest alloc] init];
+
+ [self retrieveObjectInternal:objectId cmisRequest:request
completionBlock:^(CMISObjectData *objectData, NSError *error) {
+ if (error) {
+ if (completionBlock) {
+ completionBlock([CMISErrors cmisError:error
cmisErrorCode:kCMISErrorCodeObjectNotFound]);
+ }
+ } else {
+ NSURL *contentUrl = objectData.contentUrl;
+
+ if (contentUrl) {
+ if (streamId != nil) {
+ contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISParameterStreamId value:streamId
url:contentUrl];
+ }
+
+ unsigned long long streamLength =
[[[objectData.properties.propertiesDictionary
objectForKey:kCMISPropertyContentStreamLength] firstValue]
unsignedLongLongValue];
+
+ [self.bindingSession.networkProvider invoke:contentUrl
+ httpMethod:HTTP_GET
+ session:self.bindingSession
+ outputFilePath:filePath
+ bytesExpected:streamLength
+ cmisRequest:request
+ completionBlock:^(CMISHttpResponse
*httpResponse, NSError *error) {
+ if (completionBlock) {
+ completionBlock(error);
+ }
+ } progressBlock:progressBlock];
+
+ } else {
+ if (completionBlock) {
+ completionBlock(nil);
+ }
+ }
+ }
+ }];
+
+ return request;
}
- (CMISRequest*)downloadContentOfObject:(NSString *)objectId
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/Browser/CMISBrowserObjectService.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/Browser/CMISBrowserObjectService.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
---
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/Browser/CMISBrowserObjectService.m
(original)
+++
chemistry/objectivecmis/trunk/ObjectiveCMIS/Bindings/Browser/CMISBrowserObjectService.m
Fri Dec 12 10:39:06 2014
@@ -122,17 +122,28 @@
completionBlock:(void (^)(NSError
*error))completionBlock
progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock
{
- return [self downloadContentOfObject:objectId
- streamId:streamId
- toFile:filePath
- offset:nil
- length:nil
- completionBlock:completionBlock
- progressBlock:^(unsigned long long bytesDownloaded,
unsigned long long bytesTotal) {
- if (progressBlock) {
- progressBlock(bytesDownloaded, bytesTotal);
- }
- }];
+ CMISRequest *request = [[CMISRequest alloc] init];
+
+ NSString *rootUrl = [self.bindingSession
objectForKey:kCMISBrowserBindingSessionKeyRootFolderUrl];
+
+ NSString *contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISParameterStreamId value:streamId
urlString:rootUrl];
+ contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISParameterObjectId value:objectId
urlString:contentUrl];
+ contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISBrowserJSONParameterSelector
value:kCMISBrowserJSONSelectorContent urlString:contentUrl];
+
+ [self.bindingSession.networkProvider invoke:[NSURL
URLWithString:contentUrl]
+ httpMethod:HTTP_GET
+ session:self.bindingSession
+ outputFilePath:filePath
+ bytesExpected:0
+ cmisRequest:request
+ completionBlock:^(CMISHttpResponse
*httpResponse, NSError *error)
+ {
+ if (completionBlock) {
+ completionBlock(error);
+ }
+ } progressBlock:progressBlock];
+
+ return request;
}
- (CMISRequest*)downloadContentOfObject:(NSString *)objectId
@@ -188,13 +199,11 @@
contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISParameterObjectId value:objectId
urlString:contentUrl];
contentUrl = [CMISURLUtil
urlStringByAppendingParameter:kCMISBrowserJSONParameterSelector
value:kCMISBrowserJSONSelectorContent urlString:contentUrl];
- unsigned long long streamLength = 0; //TODO do we need this?
-
[self.bindingSession.networkProvider invoke:[NSURL
URLWithString:contentUrl]
httpMethod:HTTP_GET
session:self.bindingSession
outputStream:outputStream
- bytesExpected:streamLength
+ bytesExpected:0
offset:offset
length:length
cmisRequest:request
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.m (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISDocument.m Fri Dec
12 10:39:06 2014
@@ -156,15 +156,11 @@
completionBlock:(void (^)(NSError *error))completionBlock
progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock
{
- return [self downloadContentToFile:filePath
- offset:nil
- length:nil
- completionBlock:completionBlock
- progressBlock:^(unsigned long long bytesDownloaded,
unsigned long long bytesTotal) {
- if (progressBlock) {
- progressBlock(bytesDownloaded, bytesTotal);
- }
- }];
+ return [self.binding.objectService downloadContentOfObject:self.identifier
+ streamId:nil
+ toFile:filePath
+ completionBlock:completionBlock
+ progressBlock:progressBlock];
}
@@ -176,11 +172,7 @@
offset:nil
length:nil
completionBlock:completionBlock
- progressBlock:^(unsigned long long
bytesDownloaded, unsigned long long bytesTotal) {
- if (progressBlock) {
- progressBlock(bytesDownloaded,
bytesTotal);
- }
- }];
+ progressBlock:progressBlock];
}
- (CMISRequest*)downloadContentToFile:(NSString *)filePath
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISSession.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISSession.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISSession.m (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Client/CMISSession.m Fri Dec 12
10:39:06 2014
@@ -582,12 +582,11 @@
completionBlock:(void (^)(NSError
*error))completionBlock
progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock
{
- return [self downloadContentOfCMISObject:objectId
- toFile:filePath
- offset:nil
- length:nil
- completionBlock:completionBlock
- progressBlock:progressBlock];
+ return [self.binding.objectService downloadContentOfObject:objectId
+ streamId:nil
+ toFile:filePath
+ completionBlock:completionBlock
+ progressBlock:progressBlock];
}
- (CMISRequest*)downloadContentOfCMISObject:(NSString *)objectId
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.h Fri Dec
12 10:39:06 2014
@@ -137,11 +137,15 @@ extern NSString * const kCMISParameterVa
// Common Media Types
extern NSString * const kCMISMediaTypeOctetStream;
-//ContentStreamAllowed enum values
+// ContentStreamAllowed enum values
extern NSString * const kCMISContentStreamAllowedValueRequired;
extern NSString * const kCMISContentStreamAllowedValueAllowed;
extern NSString * const kCMISContentStreamAllowedValueNotAllowed;
+// Background network default values
+extern NSString * const kCMISDefaultBackgroundNetworkSessionId;
+extern NSString * const kCMISDefaultBackgroundNetworkSessionSharedContainerId;
+
+ (NSSet *)repositoryCapabilityKeys;
+ (NSSet *)repositoryCapabilityNewTypeSettableAttributesKeys;
+ (NSSet *)repositoryCapabilityCreateablePropertyTypesKeys;
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISConstants.m Fri Dec
12 10:39:06 2014
@@ -149,11 +149,15 @@ NSString * const kCMISParameterValueRetu
// Common Media Types
NSString * const kCMISMediaTypeOctetStream = @"application/octet-stream";
-//ContentStreamAllowed enum values
+// ContentStreamAllowed enum values
NSString * const kCMISContentStreamAllowedValueRequired = @"required";
NSString * const kCMISContentStreamAllowedValueAllowed = @"allowed";
NSString * const kCMISContentStreamAllowedValueNotAllowed = @"notallowed";
+// Background network default values
+NSString * const kCMISDefaultBackgroundNetworkSessionId = @"ObjectiveCMIS";
+NSString * const kCMISDefaultBackgroundNetworkSessionSharedContainerId =
@"ObjectiveCMISContainer";
+
+ (NSSet *)repositoryCapabilityKeys
{
if(!_repositoryCapabilityKeys) {
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISNetworkProvider.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISNetworkProvider.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISNetworkProvider.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISNetworkProvider.h
Fri Dec 12 10:39:06 2014
@@ -124,9 +124,28 @@ useBase64Encoding:(BOOL)useBase64Encodin
completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
progressBlock:(void (^)(unsigned long long bytesDownloaded, unsigned long
long bytesTotal))progressBlock;
+/**
+ * Invoke method used for downloads to a file.
+ * @param url the RESTful API URL to be used
+ * @param httpRequestMethod
+ * @param session
+ * @param outputFilePath the location of the file to write the response to
+ * @param bytesExpected the size of the content to be downloaded (optional)
+ * @param cmisRequest a handle to the CMISRequest allowing this HTTP request
to be cancelled
+ * @param completionBlock returns an instance of the HTTPResponse if
successful or nil otherwise
+ * @param progressBlock
+ */
+- (void)invoke:(NSURL *)url
+ httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ session:(CMISBindingSession *)session
+outputFilePath:(NSString *)outputFilePath
+ bytesExpected:(unsigned long long)bytesExpected
+ cmisRequest:(CMISRequest *)cmisRequest
+completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
+ progressBlock:(void (^)(unsigned long long bytesDownloaded, unsigned long
long bytesTotal))progressBlock;
/**
- * Invoke method used for downloads,
+ * Invoke method used for downloads to an output stream.
* @param url the RESTful API URL to be used
* @param httpRequestMethod
* @param session
@@ -154,7 +173,7 @@ completionBlock:(void (^)(CMISHttpRespon
* @param outputStream the stream pointing to the destination. Must be an
instance or extension of NSOutputStream
* @param bytesExpected the size of the content to be downloaded
* @param offset the offset of the stream or null to read the stream from the
beginning
- * @param legnth the maximum length of the stream or null to read to the end
of the stream
+ * @param length the maximum length of the stream or null to read to the end
of the stream
* @param completionBlock returns an instance of the HTTPResponse if
successful or nil otherwise
* @param progressBlock
* @param requestObject a handle to the CMISRequest allowing this HTTP request
to be cancelled
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.h
Fri Dec 12 10:39:06 2014
@@ -52,6 +52,37 @@ extern NSString * const kCMISSessionPara
*/
extern NSString * const kCMISSessionParameterSendCookies;
+/**
+ * Key for setting whether network reachability checks should be made
+ * before making a newtork call. Default is YES.
+ */
+extern NSString * const kCMISSessionParameterCheckNetworkReachability;
+
+/**
+ * Key for setting the timeout interval (in seconds) for a network request,
default is 60.
+ */
+extern NSString * const kCMISSessionParameterRequestTimeout;
+
+/**
+ * Key for setting whether a background session should be used for network
calls,
+ * default is NO.
+ * This will cause downloads and uploads to occur in a separate process.
+ */
+extern NSString * const kCMISSessionParameterUseBackgroundNetworkSession;
+
+/**
+ * Key for setting the identifier to use for the background session, ignored
unless
+ * kCMISSessionParameterUseBackgroundNetworkSession is set to YES.
+ * If not set, background sessions will use an identifier of "ObjectiveCMIS".
+ */
+extern NSString * const kCMISSessionParameterBackgroundNetworkSessionId;
+
+/**
+ * Key for setting the shared container identifier used by the background
network session.
+ * If not set, an identifier of "ObjectiveCMISContainer" will be used.
+ */
+extern NSString * const
kCMISSessionParameterBackgroundNetworkSessionSharedContainerId;
+
@interface CMISSessionParameters : NSObject
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISSessionParameters.m
Fri Dec 12 10:39:06 2014
@@ -25,6 +25,12 @@ NSString * const kCMISSessionParameterLi
NSString * const kCMISSessionParameterTypeDefinitionCacheSize =
@"session_param_cache_size_type_definition";
NSString * const kCMISSessionParameterSendCookies =
@"session_param_send_cookies";
+NSString * const kCMISSessionParameterCheckNetworkReachability =
@"session_param_check_network_reachability";
+NSString * const kCMISSessionParameterRequestTimeout =
@"session_param_request_timeout";
+NSString * const kCMISSessionParameterUseBackgroundNetworkSession =
@"session_param_use_background_session";
+NSString * const kCMISSessionParameterBackgroundNetworkSessionId =
@"session_param_background_session_id";
+NSString * const
kCMISSessionParameterBackgroundNetworkSessionSharedContainerId =
@"session_param_background_session_shared_container_id";
+
@interface CMISSessionParameters ()
@property (nonatomic, assign, readwrite) CMISBindingType bindingType;
@property (nonatomic, strong, readwrite) NSMutableDictionary *sessionData;
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISDefaultNetworkProvider.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISDefaultNetworkProvider.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
---
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISDefaultNetworkProvider.m
(original)
+++
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISDefaultNetworkProvider.m
Fri Dec 12 10:39:06 2014
@@ -170,17 +170,55 @@ completionBlock:(void (^)(CMISHttpRespon
- (void)invoke:(NSURL *)url
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
session:(CMISBindingSession *)session
- outputStream:(NSOutputStream *)outputStream
+outputFilePath:(NSString *)outputFilePath
bytesExpected:(unsigned long long)bytesExpected
cmisRequest:(CMISRequest *)cmisRequest
completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
progressBlock:(void (^)(unsigned long long bytesDownloaded, unsigned long
long bytesTotal))progressBlock
{
- [self invoke:url httpMethod:httpRequestMethod session:session
outputStream:outputStream bytesExpected:bytesExpected offset:nil length:nil
cmisRequest:cmisRequest completionBlock:completionBlock
progressBlock:^(unsigned long long bytesDownloaded, unsigned long long
bytesTotal) {
- if (progressBlock) {
- progressBlock(bytesDownloaded, bytesTotal);
+ if (!cmisRequest.isCancelled) {
+ NSMutableURLRequest *urlRequest = [CMISDefaultNetworkProvider
createRequestForUrl:url
+
httpMethod:HTTP_GET
+
session:session];
+
+ CMISHttpDownloadRequest* request = [CMISHttpDownloadRequest
startRequest:urlRequest
+
httpMethod:httpRequestMethod
+
outputFilePath:outputFilePath
+
bytesExpected:bytesExpected
+
authenticationProvider:session.authenticationProvider
+
completionBlock:completionBlock
+
progressBlock:progressBlock];
+ if (request) {
+ cmisRequest.httpRequest = request;
}
- }];
+ } else {
+ if (completionBlock) {
+ completionBlock(nil, [CMISErrors
createCMISErrorWithCode:kCMISErrorCodeCancelled
+ detailedDescription:@"Request
was cancelled"]);
+
+ }
+ }
+}
+
+- (void)invoke:(NSURL *)url
+ httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ session:(CMISBindingSession *)session
+ outputStream:(NSOutputStream *)outputStream
+ bytesExpected:(unsigned long long)bytesExpected
+ cmisRequest:(CMISRequest *)cmisRequest
+completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
+ progressBlock:(void (^)(unsigned long long bytesDownloaded, unsigned long
long bytesTotal))progressBlock
+{
+ [self invoke:url
+ httpMethod:httpRequestMethod
+ session:session
+ outputStream:outputStream
+ bytesExpected:bytesExpected
+ offset:nil
+ length:nil
+ cmisRequest:cmisRequest
+ completionBlock:completionBlock
+ progressBlock:progressBlock];
}
- (void)invoke:(NSURL *)url
@@ -285,9 +323,11 @@ completionBlock:(void (^)(CMISHttpRespon
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
session:(CMISBindingSession *)session
{
+ NSNumber *timeout = [session
objectForKey:kCMISSessionParameterRequestTimeout defaultValue:@(60)];
+
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
- timeoutInterval:60];
+
timeoutInterval:[timeout doubleValue]];
NSString *httpMethod;
switch (httpRequestMethod) {
case HTTP_GET:
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.h
Fri Dec 12 10:39:06 2014
@@ -19,7 +19,11 @@
#import "CMISHttpRequest.h"
-@interface CMISHttpDownloadRequest : CMISHttpRequest
+@interface CMISHttpDownloadRequest : CMISHttpRequest
<NSURLSessionDownloadDelegate>
+
+// The file path to write the response body to.
+// This will force the use of a download task internally.
+@property (nonatomic, strong) NSString *outputFilePath;
// the outputStream should be unopened but if it is already open it will not
be reset but used as is;
// it is closed on completion; if no outputStream is provided, download goes
to httpResponse.data
@@ -33,7 +37,7 @@
/** starts a URL request for download. Data are written to the provided output
stream
* completionBlock returns a CMISHttpResponse object or nil if unsuccessful
*/
-+ (id)startRequest:(NSMutableURLRequest*)urlRequest
++ (id)startRequest:(NSMutableURLRequest *)urlRequest
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
outputStream:(NSOutputStream*)outputStream
bytesExpected:(unsigned long long)bytesExpected
@@ -53,5 +57,16 @@
authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock;
+
+/** starts a URL request for download. Data is written to the provided file
path.
+ * completionBlock returns a CMISHttpResponse object or nil if unsuccessful
+ */
++ (id)startRequest:(NSMutableURLRequest *)urlRequest
+
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ outputFilePath:(NSString *)outputFilePath
+ bytesExpected:(unsigned long long)bytesExpected
+ authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
+ completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
+ progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock;
@end
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
Fri Dec 12 10:39:06 2014
@@ -26,6 +26,7 @@
@property (nonatomic, copy) void (^progressBlock)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal);
@property (nonatomic, assign) unsigned long long bytesDownloaded;
@property (nonatomic, assign) BOOL cancelled;
+@property (nonatomic, strong) NSError *fileCopyError;
- (id)initWithHttpMethod:(CMISHttpRequestMethod)httpRequestMethod
completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
@@ -37,17 +38,19 @@
@implementation CMISHttpDownloadRequest
+ (id)startRequest:(NSMutableURLRequest *)urlRequest
- httpMethod:(CMISHttpRequestMethod)httpRequestMethod
- outputStream:(NSOutputStream*)outputStream
- bytesExpected:(unsigned long long)bytesExpected
-authenticationProvider:(id<CMISAuthenticationProvider>) authenticationProvider
- completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
- progressBlock:(void (^)(unsigned long long bytesDownloaded, unsigned long
long bytesTotal))progressBlock
+
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ outputStream:(NSOutputStream*)outputStream
+ bytesExpected:(unsigned long long)bytesExpected
+ authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
+ completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
+ progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock
{
return [CMISHttpDownloadRequest startRequest:urlRequest
httpMethod:httpRequestMethod
outputStream:outputStream
bytesExpected:bytesExpected
+ offset:nil
+ length:nil
authenticationProvider:authenticationProvider
completionBlock:completionBlock
progressBlock:progressBlock];
@@ -92,6 +95,27 @@ authenticationProvider:(id<CMISAuthentic
return httpRequest;
}
++ (id)startRequest:(NSMutableURLRequest *)urlRequest
+
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ outputFilePath:(NSString *)outputFilePath
+ bytesExpected:(unsigned long long)bytesExpected
+ authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
+ completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
+ progressBlock:(void (^)(unsigned long long
bytesDownloaded, unsigned long long bytesTotal))progressBlock;
+{
+ CMISHttpDownloadRequest *httpRequest = [[self alloc]
initWithHttpMethod:httpRequestMethod
+
completionBlock:completionBlock
+
progressBlock:progressBlock];
+ httpRequest.outputFilePath = outputFilePath;
+ httpRequest.bytesExpected = bytesExpected;
+ httpRequest.authenticationProvider = authenticationProvider;
+
+ if (![httpRequest startRequest:urlRequest]) {
+ httpRequest = nil;
+ };
+
+ return httpRequest;
+}
- (id)initWithHttpMethod:(CMISHttpRequestMethod)httpRequestMethod
completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
@@ -105,6 +129,15 @@ authenticationProvider:(id<CMISAuthentic
return self;
}
+- (NSURLSessionTask *)taskForRequest:(NSURLRequest *)request
+{
+ if (self.outputFilePath) {
+ return [self.urlSession downloadTaskWithRequest:request];
+ } else {
+ return [super taskForRequest:request];
+ }
+}
+
#pragma mark CMISCancellableRequest method
- (void)cancel
@@ -124,6 +157,15 @@ authenticationProvider:(id<CMISAuthentic
[self.outputStream close];
self.progressBlock = nil;
+ if (self.outputFilePath) {
+ // download tasks don't return the response via delegate methods so
get it from the task
+ self.response = (NSHTTPURLResponse *)task.response;
+
+ if (self.fileCopyError) {
+ error = self.fileCopyError;
+ }
+ }
+
[super URLSession:session task:task didCompleteWithError:error];
}
@@ -197,4 +239,45 @@ authenticationProvider:(id<CMISAuthentic
}
}
+- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes
+{
+ // TODO: Add support for resuming download tasks
+}
+
+- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
+{
+ // create URL representation of destination
+ NSURL *destinationURL = [NSURL fileURLWithPath:self.outputFilePath];
+
+ // remove the current file, if it exists
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ [fileManager removeItemAtURL:destinationURL error:nil];
+
+ // copy the temporary file to the requested file path
+ if ([fileManager copyItemAtURL:location toURL:destinationURL error:nil]) {
+ CMISLogDebug(@"Copied downloaded file from %@ to %@", location,
self.outputFilePath);
+ } else {
+ self.fileCopyError = [CMISErrors
createCMISErrorWithCode:kCMISErrorCodeStorage
+ detailedDescription:[NSString
stringWithFormat:@"Could not copy temporary file to %@", self.outputFilePath]];
+ }
+}
+
+- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
+{
+ // pass progress to progressBlock, on the main thread
+ if (self.progressBlock) {
+ unsigned long long totalBytesExpected = totalBytesExpectedToWrite;
+
+ if (totalBytesExpected == NSURLSessionTransferSizeUnknown &&
self.bytesExpected != 0) {
+ totalBytesExpected = self.bytesExpected;
+ }
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (self.progressBlock) {
+ self.progressBlock(totalBytesWritten, totalBytesExpected);
+ }
+ });
+ }
+}
+
@end
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.h Fri Dec
12 10:39:06 2014
@@ -58,4 +58,7 @@
/// starts the URL request
- (BOOL)startRequest:(NSMutableURLRequest*)urlRequest;
+/// Creates an appropriate task for the given request object.
+- (NSURLSessionTask *)taskForRequest:(NSURLRequest *)request;
+
@end
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m Fri Dec
12 10:39:06 2014
@@ -105,7 +105,7 @@ NSString * const kCMISExceptionVersionin
self.urlSession = [NSURLSession
sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self
delegateQueue:nil];
- self.sessionTask = [self.urlSession dataTaskWithRequest:urlRequest];
+ self.sessionTask = [self taskForRequest:urlRequest];
CMISReachability *reachability = [CMISReachability networkReachability];
@@ -127,6 +127,11 @@ NSString * const kCMISExceptionVersionin
return startedRequest;
}
+- (NSURLSessionTask *)taskForRequest:(NSURLRequest *)request
+{
+ return [self.urlSession dataTaskWithRequest:request];
+}
+
#pragma mark CMISCancellableRequest method
- (void)cancel
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.h?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.h
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.h
Fri Dec 12 10:39:06 2014
@@ -30,28 +30,28 @@
* completionBlock returns CMISHttpResponse instance or nil if unsuccessful
*/
+ (id)startRequest:(NSMutableURLRequest *)urlRequest
- httpMethod:(CMISHttpRequestMethod)httpRequestMethod
- inputStream:(NSInputStream*)inputStream
- headers:(NSDictionary*)additionalHeaders
- bytesExpected:(unsigned long long)bytesExpected
- authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
- completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
- progressBlock:(void (^)(unsigned long long
bytesUploaded, unsigned long long bytesTotal))progressBlock;
+
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ inputStream:(NSInputStream*)inputStream
+ headers:(NSDictionary*)additionalHeaders
+ bytesExpected:(unsigned long long)bytesExpected
+ authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
+ completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
+ progressBlock:(void (^)(unsigned long long
bytesUploaded, unsigned long long bytesTotal))progressBlock;
/**
* starts a URL request with a provided input stream. The input stream has to
point to the raw NON-encoded data set. This method will first write the
* provided start data, afterwards the content of the input stream (optionally
encoding it as base64) and then the provided end data.
*/
+ (id)startRequest:(NSMutableURLRequest *)urlRequest
- httpMethod:(CMISHttpRequestMethod)httpRequestMethod
- inputStream:(NSInputStream*)sourceInputStream
- headers:(NSDictionary*)additionalHeaders
- bytesExpected:(unsigned long long)bytesExpected
-authenticationProvider:(id<CMISAuthenticationProvider>) authenticationProvider
- startData:(NSData *)startData
- endData:(NSData *)endData
- useBase64Encoding:(BOOL)useBase64Encoding
- completionBlock:(void (^)(CMISHttpResponse *httpResponse, NSError
*error))completionBlock
- progressBlock:(void (^)(unsigned long long bytesUploaded, unsigned long
long bytesTotal))progressBlock;
+
httpMethod:(CMISHttpRequestMethod)httpRequestMethod
+ inputStream:(NSInputStream*)sourceInputStream
+ headers:(NSDictionary*)additionalHeaders
+ bytesExpected:(unsigned long long)bytesExpected
+ authenticationProvider:(id<CMISAuthenticationProvider>)
authenticationProvider
+ startData:(NSData *)startData
+ endData:(NSData *)endData
+ useBase64Encoding:(BOOL)useBase64Encoding
+ completionBlock:(void (^)(CMISHttpResponse
*httpResponse, NSError *error))completionBlock
+ progressBlock:(void (^)(unsigned long long
bytesUploaded, unsigned long long bytesTotal))progressBlock;
@end
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
Fri Dec 12 10:39:06 2014
@@ -174,7 +174,6 @@ authenticationProvider:(id<CMISAuthentic
return self;
}
-
/**
if we are using on-the-go base64 encoding, we will use the
combinedInputStream in URL connections/request.
In this case a little extra work is required: i.e. we need to provide the
length of the encoded data stream (including
@@ -182,24 +181,14 @@ authenticationProvider:(id<CMISAuthentic
*/
- (BOOL)startRequest:(NSMutableURLRequest*)urlRequest
{
- if (self.useCombinedInputStream)
- {
- if (self.combinedInputStream) {
- urlRequest.HTTPBodyStream = self.combinedInputStream;
- if(self.base64Encoding) {
- NSMutableDictionary *headers = [NSMutableDictionary
dictionaryWithDictionary:self.additionalHeaders];
- [headers setValue:[NSString stringWithFormat:@"%llu",
self.encodedLength] forKey:@"Content-Length"];
- self.additionalHeaders = [NSDictionary
dictionaryWithDictionary:headers];
- }
- }
- }
- else
- {
- if (self.inputStream) {
- urlRequest.HTTPBodyStream = self.inputStream;
- }
+ if (self.useCombinedInputStream && self.combinedInputStream &&
self.base64Encoding) {
+ NSMutableDictionary *headers = [NSMutableDictionary
dictionaryWithDictionary:self.additionalHeaders];
+ [headers setValue:[NSString stringWithFormat:@"%llu",
self.encodedLength] forKey:@"Content-Length"];
+ self.additionalHeaders = [NSDictionary
dictionaryWithDictionary:headers];
}
+
BOOL startSuccess = [super startRequest:urlRequest];
+
if (self.useCombinedInputStream) {
[self.encoderStream open];
}
@@ -207,6 +196,11 @@ authenticationProvider:(id<CMISAuthentic
return startSuccess;
}
+- (NSURLSessionTask *)taskForRequest:(NSURLRequest *)request
+{
+ return [self.urlSession uploadTaskWithStreamedRequest:request];
+}
+
#pragma mark CMISCancellableRequest method
- (void)cancel
@@ -221,6 +215,15 @@ authenticationProvider:(id<CMISAuthentic
#pragma mark Session delegate methods
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
needNewBodyStream:(void (^)(NSInputStream *))completionHandler
+{
+ if (self.combinedInputStream) {
+ completionHandler(self.combinedInputStream);
+ } else {
+ completionHandler(self.inputStream);
+ }
+}
+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
[super URLSession:session task:task didCompleteWithError:error];
Modified: chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m?rev=1644858&r1=1644857&r2=1644858&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMISTests/ObjectiveCMISTests.m Fri
Dec 12 10:39:06 2014
@@ -415,7 +415,7 @@
CMISLogDebug(@"Fetching content stream for document %@",
randomDoc.name);
// Writing content of CMIS document to local file
- NSString *filePath = [NSString
stringWithFormat:@"%@/testfile", NSTemporaryDirectory()];
+ NSString *filePath = [NSString stringWithFormat:@"%@testfile",
NSTemporaryDirectory()];
// NSString *filePath = @"testfile";
[randomDoc downloadContentToFile:filePath
completionBlock:^(NSError *error) {
@@ -443,7 +443,6 @@
- (void)testCancelDownload
{
[self runTest:^ {
- __block BOOL cancelPossible = YES;
[self.session
retrieveObjectByPath:@"/ios-test/millenium-dome-exif.jpg"
completionBlock:^(CMISObject *object, NSError *error) {
CMISDocument *document = (CMISDocument *)object;
XCTAssertNil(error, @"Error while retrieving object: %@", [error
description]);
@@ -454,29 +453,22 @@
completionBlock:^(NSError *error) {
XCTAssertNotNil(error, @"Could not cancel download");
XCTAssertTrue(error.code == kCMISErrorCodeCancelled,
@"Unexpected error: %@", [error description]);
- // Assert File exists and check file length
- XCTAssertTrue([[NSFileManager defaultManager]
fileExistsAtPath:filePath], @"File does not exist");
- NSError *fileError = nil;
- NSDictionary *fileAttributes = [[NSFileManager
defaultManager] attributesOfItemAtPath:filePath error:&fileError];
- XCTAssertNil(fileError, @"Could not verify attributes of file
%@: %@", filePath, [fileError description]);
- XCTAssertTrue([fileAttributes fileSize] > 0, @"Expected at
least some bytes but found an empty file");
-
- // if we managed to cancel check we don't have the whole file
- if (cancelPossible)
+
+ // Assert requested file path does not exist
+ if ([[NSFileManager defaultManager]
fileExistsAtPath:filePath])
{
- XCTAssertTrue([fileAttributes fileSize] <
document.contentStreamLength, @"Cancel was successful so expected smaller file
size");
+ XCTFail(@"File exists despite being cancelled");
+
+ // remove the temp file
+ NSError *fileError = nil;
+ [[NSFileManager defaultManager] removeItemAtPath:filePath
error:&fileError];
+ XCTAssertNil(fileError, @"Could not remove file %@: %@",
filePath, [fileError description]);
}
-
- // Nice boys clean up after themselves
- [[NSFileManager defaultManager] removeItemAtPath:filePath
error:&fileError];
- XCTAssertNil(fileError, @"Could not remove file %@: %@",
filePath, [fileError description]);
-
self.testCompleted = YES;
} progressBlock:^(unsigned long long bytesDownloaded, unsigned
long long bytesTotal) {
CMISLogDebug(@"download progress %llu/%llu", bytesDownloaded,
bytesTotal);
if (bytesDownloaded == bytesTotal)
{
- cancelPossible = NO;
CMISLogWarning(@"whole file was recieved in one chunk!");
}
if (bytesDownloaded > 0) { // as soon as some data was
downloaded cancel the request