diff --git a/QiniuSDK/Http/QNHttpManager.h b/QiniuSDK/Http/QNHttpManager.h index 3b45be74..9ecf4752 100644 --- a/QiniuSDK/Http/QNHttpManager.h +++ b/QiniuSDK/Http/QNHttpManager.h @@ -9,9 +9,12 @@ #import #import "QNhttpDelegate.h" +#import "QNConfiguration.h" + @interface QNHttpManager : NSObject -- (instancetype)initWithTimeout:(UInt32)timeout; +- (instancetype)initWithTimeout:(UInt32)timeout + urlConverter:(QNUrlConvert)converter; - (void)multipartPost:(NSString *)url withData:(NSData *)data diff --git a/QiniuSDK/Http/QNHttpManager.m b/QiniuSDK/Http/QNHttpManager.m index 701756ca..e3303fd0 100644 --- a/QiniuSDK/Http/QNHttpManager.m +++ b/QiniuSDK/Http/QNHttpManager.m @@ -16,22 +16,25 @@ @interface QNHttpManager () @property (nonatomic) AFHTTPRequestOperationManager *httpManager; @property UInt32 timeout; +@property (nonatomic, strong) QNUrlConvert converter; @end @implementation QNHttpManager -- (instancetype)initWithTimeout:(UInt32)timeout { +- (instancetype)initWithTimeout:(UInt32)timeout + urlConverter:(QNUrlConvert)converter { if (self = [super init]) { _httpManager = [[AFHTTPRequestOperationManager alloc] init]; _httpManager.responseSerializer = [AFJSONResponseSerializer serializer]; _timeout = timeout; + _converter = converter; } return self; } - (instancetype)init { - return [self initWithTimeout:60]; + return [self initWithTimeout:60 urlConverter:nil]; } + (QNResponseInfo *)buildResponseInfo:(AFHTTPRequestOperation *)operation @@ -102,6 +105,9 @@ - (void)multipartPost:(NSString *)url withCompleteBlock:(QNCompleteBlock)completeBlock withProgressBlock:(QNInternalProgressBlock)progressBlock withCancelBlock:(QNCancelBlock)cancelBlock { + if (_converter != nil) { + url = _converter(url); + } NSMutableURLRequest *request = [_httpManager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:url @@ -123,6 +129,10 @@ - (void) post:(NSString *)url withCompleteBlock:(QNCompleteBlock)completeBlock withProgressBlock:(QNInternalProgressBlock)progressBlock withCancelBlock:(QNCancelBlock)cancelBlock { + if (_converter != nil) { + url = _converter(url); + } + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; if (headers) { [request setAllHTTPHeaderFields:headers]; diff --git a/QiniuSDK/Http/QNSessionManager.h b/QiniuSDK/Http/QNSessionManager.h index 689c8e60..0127e918 100644 --- a/QiniuSDK/Http/QNSessionManager.h +++ b/QiniuSDK/Http/QNSessionManager.h @@ -1,12 +1,15 @@ #import #import "QNHttpDelegate.h" +#import "QNConfiguration.h" + #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) @interface QNSessionManager : NSObject - (instancetype)initWithProxy:(NSDictionary *)proxyDict - timeout:(UInt32)timeout; + timeout:(UInt32)timeout + urlConverter:(QNUrlConvert)converter; - (void)multipartPost:(NSString *)url withData:(NSData *)data diff --git a/QiniuSDK/Http/QNSessionManager.m b/QiniuSDK/Http/QNSessionManager.m index ad2a10a1..79f656ae 100644 --- a/QiniuSDK/Http/QNSessionManager.m +++ b/QiniuSDK/Http/QNSessionManager.m @@ -54,18 +54,14 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N @interface QNSessionManager () @property (nonatomic) AFHTTPSessionManager *httpManager; @property UInt32 timeout; +@property (nonatomic, strong) QNUrlConvert converter; @end -static NSString *userAgent = nil; - @implementation QNSessionManager -+ (void)initialize { - userAgent = QNUserAgent(); -} - - (instancetype)initWithProxy:(NSDictionary *)proxyDict - timeout:(UInt32)timeout { + timeout:(UInt32)timeout + urlConverter:(QNUrlConvert)converter { if (self = [super init]) { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; if (proxyDict != nil) { @@ -74,13 +70,14 @@ - (instancetype)initWithProxy:(NSDictionary *)proxyDict _httpManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration]; _httpManager.responseSerializer = [AFHTTPResponseSerializer serializer]; _timeout = timeout; + _converter = converter; } return self; } - (instancetype)init { - return [self initWithProxy:nil timeout:60]; + return [self initWithProxy:nil timeout:60 urlConverter:nil]; } + (QNResponseInfo *)buildResponseInfo:(NSHTTPURLResponse *)response @@ -153,7 +150,7 @@ - (void) sendRequest:(NSMutableURLRequest *)request [request setTimeoutInterval:_timeout]; - [request setValue:userAgent forHTTPHeaderField:@"User-Agent"]; + [request setValue:QNUserAgent() forHTTPHeaderField:@"User-Agent"]; [request setValue:nil forHTTPHeaderField:@"Accept-Language"]; [uploadTask resume]; } @@ -166,6 +163,10 @@ - (void)multipartPost:(NSString *)url withCompleteBlock:(QNCompleteBlock)completeBlock withProgressBlock:(QNInternalProgressBlock)progressBlock withCancelBlock:(QNCancelBlock)cancelBlock { + if (_converter != nil) { + url = _converter(url); + } + NSMutableURLRequest *request = [_httpManager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:url @@ -187,6 +188,10 @@ - (void) post:(NSString *)url withCompleteBlock:(QNCompleteBlock)completeBlock withProgressBlock:(QNInternalProgressBlock)progressBlock withCancelBlock:(QNCancelBlock)cancelBlock { + if (_converter != nil) { + url = _converter(url); + } + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; if (headers) { [request setAllHTTPHeaderFields:headers]; diff --git a/QiniuSDK/Http/QNUserAgent.m b/QiniuSDK/Http/QNUserAgent.m index 527d5d92..263b6fed 100644 --- a/QiniuSDK/Http/QNUserAgent.m +++ b/QiniuSDK/Http/QNUserAgent.m @@ -24,9 +24,14 @@ } NSString *QNUserAgent(void) { + static NSString *ua = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ #if __IPHONE_OS_VERSION_MIN_REQUIRED - return [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], clientId()]; + ua = [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], clientId()]; #else - return [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], clientId()]; + ua = [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], clientId()]; #endif + }); + return ua; } diff --git a/QiniuSDK/Storage/QNConfiguration.h b/QiniuSDK/Storage/QNConfiguration.h index 9eccef43..c467535c 100644 --- a/QiniuSDK/Storage/QNConfiguration.h +++ b/QiniuSDK/Storage/QNConfiguration.h @@ -15,6 +15,14 @@ */ extern const UInt32 kQNBlockSize; +/** + * 转换为用户需要的url + * + * @param url 上传url + * + * @return 根据上传url算出代理url + */ +typedef NSString *(^QNUrlConvert)(NSString *url); @class QNConfigurationBuilder; @@ -63,13 +71,14 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); */ @property (readonly) UInt32 timeoutInterval; - @property (nonatomic, readonly) id recorder; @property (nonatomic, readonly) QNRecorderKeyGenerator recorderKeyGen; @property (nonatomic, readonly) NSDictionary *proxy; +@property (nonatomic, readonly) QNUrlConvert converter; + + (instancetype)build:(QNConfigurationBuilderBlock)block; @end @@ -155,5 +164,6 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); @property (nonatomic, assign) NSDictionary *proxy; +@property (nonatomic, assign) QNUrlConvert converter; @end diff --git a/QiniuSDK/Storage/QNConfiguration.m b/QiniuSDK/Storage/QNConfiguration.m index 2e2680e0..9deafb3b 100644 --- a/QiniuSDK/Storage/QNConfiguration.m +++ b/QiniuSDK/Storage/QNConfiguration.m @@ -32,6 +32,8 @@ - (instancetype)initWithBuilder:(QNConfigurationBuilder *)builder { _recorderKeyGen = builder.recorderKeyGen; _proxy = builder.proxy; + + _converter = builder.converter; } return self; } @@ -47,6 +49,12 @@ - (instancetype)init { _putThreshold = 512 * 1024; _retryMax = 5; _timeoutInterval = 60; + + _recorder = nil; + _recorderKeyGen = nil; + + _proxy = nil; + _converter = nil; } return self; } diff --git a/QiniuSDK/Storage/QNUploadManager.m b/QiniuSDK/Storage/QNUploadManager.m index 41bf531a..98c04d4b 100644 --- a/QiniuSDK/Storage/QNUploadManager.m +++ b/QiniuSDK/Storage/QNUploadManager.m @@ -58,6 +58,7 @@ - (instancetype)initWithConfiguration:(QNConfiguration *)config { config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { }]; } + _config = config; #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) BOOL lowVersion = NO; #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) @@ -73,15 +74,15 @@ - (instancetype)initWithConfiguration:(QNConfiguration *)config { } #endif if (lowVersion) { - _httpManager = [[QNHttpManager alloc] initWithTimeout:_config.timeoutInterval]; + _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter]; } else { - _httpManager = [[QNSessionManager alloc] initWithProxy:config.proxy timeout:_config.timeoutInterval]; + _httpManager = [[QNSessionManager alloc] initWithProxy:config.proxy timeout:config.timeoutInterval + urlConverter:config.converter]; } #else - _httpManager = [[QNHttpManager alloc] initWithTimeout:_config.timeoutInterval]; + _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter]; #endif - _config = config; } return self; } diff --git a/QiniuSDKTests/QNFormUploadTest.m b/QiniuSDKTests/QNFormUploadTest.m index e4cd307f..99ecd6a7 100644 --- a/QiniuSDKTests/QNFormUploadTest.m +++ b/QiniuSDKTests/QNFormUploadTest.m @@ -198,4 +198,35 @@ - (void)testProxy { XCTAssert([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); } +- (void)testUrlConvert { + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + __block NSString *key = nil; + + QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { + builder.converter = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + builder.zone = [[QNZone alloc] initWithUpHost:@"upnono.qiniu.com" upHostBackup:@"" upIp:@""]; + }]; + + QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; + + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [upManager putData:data key:nil token:g_token complete: ^(QNResponseInfo *info, NSString *k, NSDictionary *resp) { + key = k; + testInfo = info; + testResp = resp; + } option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + NSLog(@"%@", testResp); + XCTAssert(key == nil, @"Pass"); + XCTAssert(testInfo.isOK, @"Pass"); + XCTAssert(testInfo.reqId, @"Pass"); + XCTAssert([testInfo.host isEqual:@"up.qiniu.com"], @"Pass"); + XCTAssert([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); +} + @end diff --git a/QiniuSDKTests/QNResumeUploadTest.m b/QiniuSDKTests/QNResumeUploadTest.m index 2add1372..db1a44c2 100644 --- a/QiniuSDKTests/QNResumeUploadTest.m +++ b/QiniuSDKTests/QNResumeUploadTest.m @@ -147,7 +147,7 @@ - (void)testProxy { QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; - int size = 6 * 1024; + int size = 600; NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; NSString *keyUp = [NSString stringWithFormat:@"%dkproxy", size]; __block QNResponseInfo *info = nil; @@ -165,5 +165,33 @@ - (void)testProxy { [QNTempFile removeTempfile:tempFile]; } +- (void)testUrlConvert { + QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { + builder.converter = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + builder.zone = [[QNZone alloc] initWithUpHost:@"upnono.qiniu.com" upHostBackup:@"" upIp:@""]; + }]; + + QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; + + int size = 600; + NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; + NSString *keyUp = [NSString stringWithFormat:@"%dkconvert", size]; + __block QNResponseInfo *info = nil; + __block NSString *key = nil; + [upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } option:nil]; + + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.isOK, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + XCTAssert([info.host isEqual:@"up.qiniu.com"], @"Pass"); + [QNTempFile removeTempfile:tempFile]; +} + #endif @end diff --git a/QiniuSDKTests/QNSessionTest.m b/QiniuSDKTests/QNSessionTest.m index 1029366e..a1899a44 100644 --- a/QiniuSDKTests/QNSessionTest.m +++ b/QiniuSDKTests/QNSessionTest.m @@ -15,6 +15,8 @@ #import "QNSessionManager.h" #import "QNResponseInfo.h" +#import "QNConfiguration.h" + @interface QNSessionTest : XCTestCase @property QNSessionManager *httpManager; @end @@ -90,7 +92,7 @@ - (void)testProxy { (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, }; - QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:proxyDict timeout:60]; + QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:proxyDict timeout:60 urlConverter:nil]; NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; __block QNResponseInfo *testInfo = nil; [httpManager post:@"http://up123.qiniu.com" withData:data withParams:nil withHeaders:nil withCompleteBlock: ^(QNResponseInfo *info, NSDictionary *resp) { @@ -102,6 +104,24 @@ - (void)testProxy { XCTAssert(testInfo.reqId, @"Pass"); } +- (void)testUrlConvert { + QNUrlConvert c = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + + QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:nil timeout:60 urlConverter:c]; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + __block QNResponseInfo *testInfo = nil; + [httpManager post:@"http://upnono.qiniu.com" withData:data withParams:nil withHeaders:nil withCompleteBlock: ^(QNResponseInfo *info, NSDictionary *resp) { + testInfo = info; + } withProgressBlock:nil withCancelBlock:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.reqId, @"Pass"); + XCTAssert([testInfo.host isEqual:@"up.qiniu.com"], @"Pass"); +} + @end #endif