From 5a4d3e487e8a95cef96df1428fdbb40f745129da Mon Sep 17 00:00:00 2001 From: longbai Date: Thu, 21 Apr 2016 15:51:15 +0800 Subject: [PATCH] format --- .clang-format | 71 ++ QiniuDemo/QiniuDemo/AppDelegate.h | 2 - QiniuDemo/QiniuDemo/AppDelegate.m | 1 - QiniuDemo/QiniuDemo/ViewController.h | 9 +- QiniuDemo/QiniuDemo/ViewController.m | 129 ++- QiniuDemo/QiniuDemo/main.m | 4 +- QiniuDemo/QiniuDemoUITests/QiniuDemoUITests.m | 6 +- QiniuSDK/Common/GTM_Base64.m | 949 +++++++++--------- QiniuSDK/Common/QNALAssetFile.m | 49 +- QiniuSDK/Common/QNAsyncRun.m | 14 +- QiniuSDK/Common/QNCrc32.m | 44 +- QiniuSDK/Common/QNEtag.m | 77 +- QiniuSDK/Common/QNFile.h | 2 +- QiniuSDK/Common/QNFile.m | 116 +-- QiniuSDK/Common/QNFileDelegate.h | 1 - QiniuSDK/Common/QNPHAssetFile.h | 2 +- QiniuSDK/Common/QNPHAssetFile.m | 82 +- QiniuSDK/Common/QNPHAssetResource.h | 3 +- QiniuSDK/Common/QNPHAssetResource.m | 90 +- QiniuSDK/Common/QNSystem.m | 46 +- QiniuSDK/Common/QNUrlSafeBase64.m | 8 +- QiniuSDK/Http/QNDns.m | 80 +- QiniuSDK/Http/QNHttpDelegate.h | 31 +- QiniuSDK/Http/QNHttpManager.h | 32 +- QiniuSDK/Http/QNHttpManager.m | 382 ++++--- QiniuSDK/Http/QNResponseInfo.h | 8 +- QiniuSDK/Http/QNResponseInfo.m | 141 ++- QiniuSDK/Http/QNSessionManager.h | 38 +- QiniuSDK/Http/QNSessionManager.m | 451 ++++----- QiniuSDK/Http/QNUserAgent.m | 44 +- QiniuSDK/QiniuSDK.h | 8 +- QiniuSDK/Recorder/QNFileRecorder.h | 3 +- QiniuSDK/Recorder/QNFileRecorder.m | 84 +- QiniuSDK/Recorder/QNRecorderDelegate.h | 3 +- QiniuSDK/Storage/QNConfiguration.h | 19 +- QiniuSDK/Storage/QNConfiguration.m | 193 ++-- QiniuSDK/Storage/QNFormUpload.h | 19 +- QiniuSDK/Storage/QNFormUpload.m | 181 ++-- QiniuSDK/Storage/QNResumeUpload.h | 24 +- QiniuSDK/Storage/QNResumeUpload.m | 414 ++++---- QiniuSDK/Storage/QNUpToken.m | 67 +- QiniuSDK/Storage/QNUploadManager.h | 59 +- QiniuSDK/Storage/QNUploadManager.m | 438 ++++---- QiniuSDK/Storage/QNUploadOption+Private.h | 2 +- QiniuSDK/Storage/QNUploadOption.m | 56 +- QiniuSDKTests/QNBase64Test.m | 8 +- QiniuSDKTests/QNCrc32Test.m | 18 +- QiniuSDKTests/QNDnsTest.m | 16 +- QiniuSDKTests/QNEtagTest.m | 18 +- QiniuSDKTests/QNFileRecorderTest.m | 161 +-- QiniuSDKTests/QNFormUploadTest.m | 457 +++++---- QiniuSDKTests/QNHttpTest.m | 196 ++-- QiniuSDKTests/QNResumeUploadTest.m | 391 ++++---- QiniuSDKTests/QNSessionTest.m | 212 ++-- QiniuSDKTests/QNTempFile.m | 16 +- QiniuSDKTests/QNUpTokenTest.m | 37 +- format.sh | 5 + 57 files changed, 3030 insertions(+), 2987 deletions(-) create mode 100644 .clang-format create mode 100644 format.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..bdf01dc7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,71 @@ +# Copyright (c) 2015-present, Parse, LLC. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +--- +Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: true +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: false +AlwaysBreakTemplateDeclarations: false +AlwaysBreakBeforeMultilineStrings: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BinPackParameters: true +BinPackArguments: true +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +DerivePointerAlignment: true +ExperimentalAutoDetectBinPacking: true +IndentCaseLabels: true +IndentWrappedFunctionNames: true +IndentFunctionDeclarationAfterType: true +MaxEmptyLinesToKeep: 1 +KeepEmptyLinesAtTheStartOfBlocks: true +NamespaceIndentation: None +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 140 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 120 +PointerAlignment: Right +SpacesBeforeTrailingComments: 1 +Cpp11BracedListStyle: true +Standard: Cpp11 +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +BreakBeforeBraces: Attach +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpaceAfterCStyleCast: false +SpacesInContainerLiterals: true +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +SpaceBeforeParens: ControlStatements +DisableFormat: false +... diff --git a/QiniuDemo/QiniuDemo/AppDelegate.h b/QiniuDemo/QiniuDemo/AppDelegate.h index 55cfa4d8..c68b8b05 100644 --- a/QiniuDemo/QiniuDemo/AppDelegate.h +++ b/QiniuDemo/QiniuDemo/AppDelegate.h @@ -12,6 +12,4 @@ @property (strong, nonatomic) UIWindow *window; - @end - diff --git a/QiniuDemo/QiniuDemo/AppDelegate.m b/QiniuDemo/QiniuDemo/AppDelegate.m index 9d0f7c6f..adc99d86 100644 --- a/QiniuDemo/QiniuDemo/AppDelegate.m +++ b/QiniuDemo/QiniuDemo/AppDelegate.m @@ -14,7 +14,6 @@ @interface AppDelegate () @implementation AppDelegate - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; diff --git a/QiniuDemo/QiniuDemo/ViewController.h b/QiniuDemo/QiniuDemo/ViewController.h index 5a2be30c..07326fe2 100644 --- a/QiniuDemo/QiniuDemo/ViewController.h +++ b/QiniuDemo/QiniuDemo/ViewController.h @@ -6,14 +6,13 @@ // Copyright © 2016年 Aaron. All rights reserved. // -#import #import +#import @interface ViewController : UIViewController -@property (nonatomic, weak) IBOutlet UIButton * chooseBtn; -@property (nonatomic, weak) IBOutlet UIButton * uploadBtn; -@property (nonatomic, weak) IBOutlet UIImageView * preViewImage; +@property (nonatomic, weak) IBOutlet UIButton* chooseBtn; +@property (nonatomic, weak) IBOutlet UIButton* uploadBtn; +@property (nonatomic, weak) IBOutlet UIImageView* preViewImage; @end - diff --git a/QiniuDemo/QiniuDemo/ViewController.m b/QiniuDemo/QiniuDemo/ViewController.m index 17616665..a73c1f44 100644 --- a/QiniuDemo/QiniuDemo/ViewController.m +++ b/QiniuDemo/QiniuDemo/ViewController.m @@ -10,11 +10,11 @@ #import "AFNetworking.h" #import "UIImageView+AFNetworking.h" -@interface ViewController () +@interface ViewController () -@property (nonatomic, strong) NSString * token; -@property (nonatomic, strong) NSString * domain; -@property (nonatomic, strong) UIImage * pickImage; +@property (nonatomic, strong) NSString *token; +@property (nonatomic, strong) NSString *domain; +@property (nonatomic, strong) UIImage *pickImage; @end @@ -26,128 +26,115 @@ - (void)viewDidLoad { self.title = @"七牛云上传"; } -- (IBAction)chooseAction:(id)sender -{ +- (IBAction)chooseAction:(id)sender { [self gotoImageLibrary]; } -- (IBAction)uploadAction:(id)sender -{ +- (IBAction)uploadAction:(id)sender { if (self.pickImage == nil) { UIAlertView *alert = [[UIAlertView alloc] - initWithTitle:@"还未选择图片" - message:@"" - delegate:nil - cancelButtonTitle:@"OK!" - otherButtonTitles:nil]; + initWithTitle:@"还未选择图片" + message:@"" + delegate:nil + cancelButtonTitle:@"OK!" + otherButtonTitles:nil]; [alert show]; - }else - { - [self getTokenFromQN]; + } else { + [self getTokenFromQN]; } } -- (void)getTokenFromQN -{ +- (void)getTokenFromQN { //1.管理器 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; - -// //2.设置登录参数 -// NSDictionary *dict = @{ @"username":@"xn", @"password":@"123" }; - + + // //2.设置登录参数 + // NSDictionary *dict = @{ @"username":@"xn", @"password":@"123" }; + //3.请求 - [manager POST:@"http://115.231.183.102:9090/api/quick_start/simple_image_example_token.php" parameters:nil success: ^(AFHTTPRequestOperation *operation, id responseObject) { + [manager POST:@"http://115.231.183.102:9090/api/quick_start/simple_image_example_token.php" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { self.domain = responseObject[@"domain"]; self.token = responseObject[@"uptoken"]; [self uploadImageToQNFilePath:[self getImagePath:self.pickImage]]; - } failure: ^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"%@", error); - }]; + } + failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"%@", error); + }]; } --(void)uploadImageToQNFilePath:(NSString *)filePath -{ +- (void)uploadImageToQNFilePath:(NSString *)filePath { QNUploadManager *upManager = [[QNUploadManager alloc] init]; - QNUploadOption * uploadOption = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { - NSLog(@"percent == %.2f",percent); - } params:nil checkCrc:NO cancellationSignal:nil]; - [upManager putFile:filePath key: nil token:self.token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + QNUploadOption *uploadOption = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { + NSLog(@"percent == %.2f", percent); + } + params:nil + checkCrc:NO + cancellationSignal:nil]; + [upManager putFile:filePath key:nil token:self.token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { NSLog(@"info ===== %@", info); NSLog(@"resp ===== %@", resp); - NSLog(@"%@/%@",self.domain,resp[@"key"]); - [self.preViewImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",self.domain,resp[@"key"]]] placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]]; - - } option:uploadOption]; - -} + NSLog(@"%@/%@", self.domain, resp[@"key"]); + [self.preViewImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", self.domain, resp[@"key"]]] placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]]; + } + option:uploadOption]; +} -- (void)gotoImageLibrary -{ - if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) - { +- (void)gotoImageLibrary { + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self presentViewController:picker animated:YES completion:nil]; - }else { + } else { UIAlertView *alert = [[UIAlertView alloc] - initWithTitle:@"访问图片库错误" - message:@"" - delegate:nil - cancelButtonTitle:@"OK!" - otherButtonTitles:nil]; + initWithTitle:@"访问图片库错误" + message:@"" + delegate:nil + cancelButtonTitle:@"OK!" + otherButtonTitles:nil]; [alert show]; } } - - //再调用以下委托: #pragma mark UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker - didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo -{ + didFinishPickingImage:(UIImage *)image + editingInfo:(NSDictionary *)editingInfo { self.pickImage = image; //imageView为自己定义的UIImageView [picker dismissViewControllerAnimated:YES completion:^{ }]; - - } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [picker dismissViewControllerAnimated:YES completion:nil]; - } //照片获取本地路径转换 --(NSString *)getImagePath:(UIImage *)Image -{ - NSString * filePath = nil; - NSData * data = nil; - if (UIImagePNGRepresentation(Image) == nil) - { +- (NSString *)getImagePath:(UIImage *)Image { + NSString *filePath = nil; + NSData *data = nil; + if (UIImagePNGRepresentation(Image) == nil) { data = UIImageJPEGRepresentation(Image, 1.0); - } - else - { + } else { data = UIImagePNGRepresentation(Image); } - + //图片保存的路径 //这里将图片放在沙盒的documents文件夹中 - NSString * DocumentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; - + NSString *DocumentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; + //文件管理器 NSFileManager *fileManager = [NSFileManager defaultManager]; - + //把刚刚图片转换的data对象拷贝至沙盒中 [fileManager createDirectoryAtPath:DocumentsPath withIntermediateDirectories:YES attributes:nil error:nil]; - NSString * ImagePath = [[NSString alloc]initWithFormat:@"/theFirstImage.png"]; + NSString *ImagePath = [[NSString alloc] initWithFormat:@"/theFirstImage.png"]; [fileManager createFileAtPath:[DocumentsPath stringByAppendingString:ImagePath] contents:data attributes:nil]; - + //得到选择后沙盒中图片的完整路径 - filePath = [[NSString alloc]initWithFormat:@"%@%@",DocumentsPath,ImagePath]; + filePath = [[NSString alloc] initWithFormat:@"%@%@", DocumentsPath, ImagePath]; return filePath; } diff --git a/QiniuDemo/QiniuDemo/main.m b/QiniuDemo/QiniuDemo/main.m index 5e501091..0ff59f50 100644 --- a/QiniuDemo/QiniuDemo/main.m +++ b/QiniuDemo/QiniuDemo/main.m @@ -6,10 +6,10 @@ // Copyright © 2016年 Aaron. All rights reserved. // -#import #import "AppDelegate.h" +#import -int main(int argc, char * argv[]) { +int main(int argc, char* argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } diff --git a/QiniuDemo/QiniuDemoUITests/QiniuDemoUITests.m b/QiniuDemo/QiniuDemoUITests/QiniuDemoUITests.m index d2ec9290..bf7677d0 100644 --- a/QiniuDemo/QiniuDemoUITests/QiniuDemoUITests.m +++ b/QiniuDemo/QiniuDemoUITests/QiniuDemoUITests.m @@ -16,14 +16,14 @@ @implementation QiniuDemoUITests - (void)setUp { [super setUp]; - + // Put setup code here. This method is called before the invocation of each test method in the class. - + // In UI tests it is usually best to stop immediately when a failure occurs. self.continueAfterFailure = NO; // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. [[[XCUIApplication alloc] init] launch]; - + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } diff --git a/QiniuSDK/Common/GTM_Base64.m b/QiniuSDK/Common/GTM_Base64.m index d3fc766f..f1f91f2e 100644 --- a/QiniuSDK/Common/GTM_Base64.m +++ b/QiniuSDK/Common/GTM_Base64.m @@ -24,127 +24,124 @@ static const char kBase64InvalidChar = 99; static const char kBase64DecodeChars[] = { - // This array was generated by the following code: - // #include - // #include - // #include - // main() - // { - // static const char Base64[] = - // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - // char *pos; - // int idx, i, j; - // printf(" "); - // for (i = 0; i < 255; i += 8) { - // for (j = i; j < i + 8; j++) { - // pos = strchr(Base64, j); - // if ((pos == NULL) || (j == 0)) - // idx = 99; - // else - // idx = pos - Base64; - // if (idx == 99) - // printf(" %2d, ", idx); - // else - // printf(" %2d/*%c*/,", idx, j); - // } - // printf("\n "); - // } - // } - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 62 /*+*/, 99, 99, 99, 63 /*/ */, - 52 /*0*/, 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, - 60 /*8*/, 61 /*9*/, 99, 99, 99, 99, 99, 99, - 99, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, 5 /*F*/, 6 /*G*/, - 7 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, 12 /*M*/, 13 /*N*/, 14 /*O*/, - 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, - 23 /*X*/, 24 /*Y*/, 25 /*Z*/, 99, 99, 99, 99, 99, - 99, 26 /*a*/, 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, - 33 /*h*/, 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, - 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, 48 /*w*/, - 49 /*x*/, 50 /*y*/, 51 /*z*/, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; + // This array was generated by the following code: + // #include + // #include + // #include + // main() + // { + // static const char Base64[] = + // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + // char *pos; + // int idx, i, j; + // printf(" "); + // for (i = 0; i < 255; i += 8) { + // for (j = i; j < i + 8; j++) { + // pos = strchr(Base64, j); + // if ((pos == NULL) || (j == 0)) + // idx = 99; + // else + // idx = pos - Base64; + // if (idx == 99) + // printf(" %2d, ", idx); + // else + // printf(" %2d/*%c*/,", idx, j); + // } + // printf("\n "); + // } + // } + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 62 /*+*/, 99, 99, 99, 63 /*/ */, + 52 /*0*/, 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, + 60 /*8*/, 61 /*9*/, 99, 99, 99, 99, 99, 99, + 99, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, 5 /*F*/, 6 /*G*/, + 7 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, 12 /*M*/, 13 /*N*/, 14 /*O*/, + 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, + 23 /*X*/, 24 /*Y*/, 25 /*Z*/, 99, 99, 99, 99, 99, + 99, 26 /*a*/, 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, + 33 /*h*/, 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, + 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, 48 /*w*/, + 49 /*x*/, 50 /*y*/, 51 /*z*/, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99}; static const char kWebSafeBase64DecodeChars[] = { - // This array was generated by the following code: - // #include - // #include - // #include - // main() - // { - // static const char Base64[] = - // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - // char *pos; - // int idx, i, j; - // printf(" "); - // for (i = 0; i < 255; i += 8) { - // for (j = i; j < i + 8; j++) { - // pos = strchr(Base64, j); - // if ((pos == NULL) || (j == 0)) - // idx = 99; - // else - // idx = pos - Base64; - // if (idx == 99) - // printf(" %2d, ", idx); - // else - // printf(" %2d/*%c*/,", idx, j); - // } - // printf("\n "); - // } - // } - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 62 /*-*/, 99, 99, - 52 /*0*/, 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, - 60 /*8*/, 61 /*9*/, 99, 99, 99, 99, 99, 99, - 99, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, 5 /*F*/, 6 /*G*/, - 7 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, 12 /*M*/, 13 /*N*/, 14 /*O*/, - 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, - 23 /*X*/, 24 /*Y*/, 25 /*Z*/, 99, 99, 99, 99, 63 /*_*/, - 99, 26 /*a*/, 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, - 33 /*h*/, 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, - 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, 48 /*w*/, - 49 /*x*/, 50 /*y*/, 51 /*z*/, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; - + // This array was generated by the following code: + // #include + // #include + // #include + // main() + // { + // static const char Base64[] = + // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + // char *pos; + // int idx, i, j; + // printf(" "); + // for (i = 0; i < 255; i += 8) { + // for (j = i; j < i + 8; j++) { + // pos = strchr(Base64, j); + // if ((pos == NULL) || (j == 0)) + // idx = 99; + // else + // idx = pos - Base64; + // if (idx == 99) + // printf(" %2d, ", idx); + // else + // printf(" %2d/*%c*/,", idx, j); + // } + // printf("\n "); + // } + // } + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 62 /*-*/, 99, 99, + 52 /*0*/, 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, + 60 /*8*/, 61 /*9*/, 99, 99, 99, 99, 99, 99, + 99, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, 5 /*F*/, 6 /*G*/, + 7 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, 12 /*M*/, 13 /*N*/, 14 /*O*/, + 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, + 23 /*X*/, 24 /*Y*/, 25 /*Z*/, 99, 99, 99, 99, 63 /*_*/, + 99, 26 /*a*/, 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, + 33 /*h*/, 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, + 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, 48 /*w*/, + 49 /*x*/, 50 /*y*/, 51 /*z*/, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99}; // Tests a character to see if it's a whitespace character. // @@ -153,37 +150,37 @@ // NO if the character is not a whitespace character. // BOOL IsSpace(unsigned char c) { - // we use our own mapping here because we don't want anything w/ locale - // support. - static BOOL kSpaces[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0-9 - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 10-19 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-29 - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 30-39 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-49 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-59 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60-69 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70-79 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-89 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-99 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 100-109 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 110-119 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 120-129 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130-139 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140-149 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150-159 - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-169 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170-179 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180-189 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190-199 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200-209 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210-219 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 220-229 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 230-239 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-249 - 0, 0, 0, 0, 0, 1, // 250-255 - }; - return kSpaces[c]; + // we use our own mapping here because we don't want anything w/ locale + // support. + static BOOL kSpaces[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0-9 + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 10-19 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-29 + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 30-39 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-49 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-59 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60-69 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70-79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-89 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-99 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 100-109 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 110-119 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 120-129 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130-139 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140-149 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150-159 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-169 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170-179 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180-189 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190-199 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200-209 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210-219 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 220-229 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 230-239 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-249 + 0, 0, 0, 0, 0, 1, // 250-255 + }; + return kSpaces[c]; } // Calculate how long the data will be once it's base64 encoded. @@ -192,12 +189,12 @@ BOOL IsSpace(unsigned char c) { // The guessed encoded length for a source length // NSUInteger CalcEncodedLength(NSUInteger srcLen, BOOL padded) { - NSUInteger intermediate_result = 8 * srcLen + 5; - NSUInteger len = intermediate_result / 6; - if (padded) { - len = ((len + 3) / 4) * 4; - } - return len; + NSUInteger intermediate_result = 8 * srcLen + 5; + NSUInteger len = intermediate_result / 6; + if (padded) { + len = ((len + 3) / 4) * 4; + } + return len; } // Tries to calculate how long the data will be once it's base64 decoded. @@ -208,7 +205,7 @@ NSUInteger CalcEncodedLength(NSUInteger srcLen, BOOL padded) { // The guessed decoded length for a source length // NSUInteger GuessDecodedLength(NSUInteger srcLen) { - return (srcLen + 3) / 4 * 3; + return (srcLen + 3) / 4 * 3; } @interface GTM_Base64 (PrivateMethods) @@ -239,7 +236,6 @@ + (NSUInteger)baseDecode:(const char *)srcBytes @end - @implementation GTM_Base64 // @@ -247,69 +243,69 @@ @implementation GTM_Base64 // + (NSData *)encodeData:(NSData *)data { - return [self baseEncode:[data bytes] - length:[data length] - charset:kBase64EncodeChars - padded:YES]; + return [self baseEncode:[data bytes] + length:[data length] + charset:kBase64EncodeChars + padded:YES]; } + (NSData *)decodeData:(NSData *)data { - return [self baseDecode:[data bytes] - length:[data length] - charset:kBase64DecodeChars - requirePadding:YES]; + return [self baseDecode:[data bytes] + length:[data length] + charset:kBase64DecodeChars + requirePadding:YES]; } + (NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length { - return [self baseEncode:bytes - length:length - charset:kBase64EncodeChars - padded:YES]; + return [self baseEncode:bytes + length:length + charset:kBase64EncodeChars + padded:YES]; } + (NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length { - return [self baseDecode:bytes - length:length - charset:kBase64DecodeChars - requirePadding:YES]; + return [self baseDecode:bytes + length:length + charset:kBase64DecodeChars + requirePadding:YES]; } + (NSString *)stringByEncodingData:(NSData *)data { - NSString *result = nil; - NSData *converted = [self baseEncode:[data bytes] - length:[data length] - charset:kBase64EncodeChars - padded:YES]; - if (converted) { - result = [[NSString alloc] initWithData:converted - encoding:NSASCIIStringEncoding]; - } - return result; + NSString *result = nil; + NSData *converted = [self baseEncode:[data bytes] + length:[data length] + charset:kBase64EncodeChars + padded:YES]; + if (converted) { + result = [[NSString alloc] initWithData:converted + encoding:NSASCIIStringEncoding]; + } + return result; } + (NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length { - NSString *result = nil; - NSData *converted = [self baseEncode:bytes - length:length - charset:kBase64EncodeChars - padded:YES]; - if (converted) { - result = [[NSString alloc] initWithData:converted - encoding:NSASCIIStringEncoding]; - } - return result; + NSString *result = nil; + NSData *converted = [self baseEncode:bytes + length:length + charset:kBase64EncodeChars + padded:YES]; + if (converted) { + result = [[NSString alloc] initWithData:converted + encoding:NSASCIIStringEncoding]; + } + return result; } + (NSData *)decodeString:(NSString *)string { - NSData *result = nil; - NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding]; - if (data) { - result = [self baseDecode:[data bytes] - length:[data length] - charset:kBase64DecodeChars - requirePadding:YES]; - } - return result; + NSData *result = nil; + NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding]; + if (data) { + result = [self baseDecode:[data bytes] + length:[data length] + charset:kBase64DecodeChars + requirePadding:YES]; + } + return result; } // @@ -323,74 +319,74 @@ + (NSData *)decodeString:(NSString *)string { + (NSData *)webSafeEncodeData:(NSData *)data padded:(BOOL)padded { - return [self baseEncode:[data bytes] - length:[data length] - charset:kWebSafeBase64EncodeChars - padded:padded]; + return [self baseEncode:[data bytes] + length:[data length] + charset:kWebSafeBase64EncodeChars + padded:padded]; } + (NSData *)webSafeDecodeData:(NSData *)data { - return [self baseDecode:[data bytes] - length:[data length] - charset:kWebSafeBase64DecodeChars - requirePadding:NO]; + return [self baseDecode:[data bytes] + length:[data length] + charset:kWebSafeBase64DecodeChars + requirePadding:NO]; } + (NSData *)webSafeEncodeBytes:(const void *)bytes length:(NSUInteger)length padded:(BOOL)padded { - return [self baseEncode:bytes - length:length - charset:kWebSafeBase64EncodeChars - padded:padded]; + return [self baseEncode:bytes + length:length + charset:kWebSafeBase64EncodeChars + padded:padded]; } + (NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length { - return [self baseDecode:bytes - length:length - charset:kWebSafeBase64DecodeChars - requirePadding:NO]; + return [self baseDecode:bytes + length:length + charset:kWebSafeBase64DecodeChars + requirePadding:NO]; } + (NSString *)stringByWebSafeEncodingData:(NSData *)data padded:(BOOL)padded { - NSString *result = nil; - NSData *converted = [self baseEncode:[data bytes] - length:[data length] - charset:kWebSafeBase64EncodeChars - padded:padded]; - if (converted) { - result = [[NSString alloc] initWithData:converted - encoding:NSASCIIStringEncoding]; - } - return result; + NSString *result = nil; + NSData *converted = [self baseEncode:[data bytes] + length:[data length] + charset:kWebSafeBase64EncodeChars + padded:padded]; + if (converted) { + result = [[NSString alloc] initWithData:converted + encoding:NSASCIIStringEncoding]; + } + return result; } + (NSString *)stringByWebSafeEncodingBytes:(const void *)bytes length:(NSUInteger)length padded:(BOOL)padded { - NSString *result = nil; - NSData *converted = [self baseEncode:bytes - length:length - charset:kWebSafeBase64EncodeChars - padded:padded]; - if (converted) { - result = [[NSString alloc] initWithData:converted - encoding:NSASCIIStringEncoding]; - } - return result; + NSString *result = nil; + NSData *converted = [self baseEncode:bytes + length:length + charset:kWebSafeBase64EncodeChars + padded:padded]; + if (converted) { + result = [[NSString alloc] initWithData:converted + encoding:NSASCIIStringEncoding]; + } + return result; } + (NSData *)webSafeDecodeString:(NSString *)string { - NSData *result = nil; - NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding]; - if (data) { - result = [self baseDecode:[data bytes] - length:[data length] - charset:kWebSafeBase64DecodeChars - requirePadding:NO]; - } - return result; + NSData *result = nil; + NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding]; + if (data) { + result = [self baseDecode:[data bytes] + length:[data length] + charset:kWebSafeBase64DecodeChars + requirePadding:NO]; + } + return result; } @end @@ -412,26 +408,25 @@ + (NSData *)baseEncode:(const void *)bytes length:(NSUInteger)length charset:(const char *)charset padded:(BOOL)padded { - // how big could it be? - NSUInteger maxLength = CalcEncodedLength(length, padded); - // make space - NSMutableData *result = [NSMutableData data]; - [result setLength:maxLength]; - // do it - NSUInteger finalLength = [self baseEncode:bytes - srcLen:length - destBytes:[result mutableBytes] - destLen:[result length] - charset:charset - padded:padded]; - if (finalLength) { -// _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?"); - } - else { - // shouldn't happen, this means we ran out of space - result = nil; - } - return result; + // how big could it be? + NSUInteger maxLength = CalcEncodedLength(length, padded); + // make space + NSMutableData *result = [NSMutableData data]; + [result setLength:maxLength]; + // do it + NSUInteger finalLength = [self baseEncode:bytes + srcLen:length + destBytes:[result mutableBytes] + destLen:[result length] + charset:charset + padded:padded]; + if (finalLength) { + // _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?"); + } else { + // shouldn't happen, this means we ran out of space + result = nil; + } + return result; } // @@ -449,29 +444,28 @@ + (NSData *)baseDecode:(const void *)bytes length:(NSUInteger)length charset:(const char *)charset requirePadding:(BOOL)requirePadding { - // could try to calculate what it will end up as - NSUInteger maxLength = GuessDecodedLength(length); - // make space - NSMutableData *result = [NSMutableData data]; - [result setLength:maxLength]; - // do it - NSUInteger finalLength = [self baseDecode:bytes - srcLen:length - destBytes:[result mutableBytes] - destLen:[result length] - charset:charset - requirePadding:requirePadding]; - if (finalLength) { - if (finalLength != maxLength) { - // resize down to how big it was - [result setLength:finalLength]; - } - } - else { - // either an error in the args, or we ran out of space - result = nil; - } - return result; + // could try to calculate what it will end up as + NSUInteger maxLength = GuessDecodedLength(length); + // make space + NSMutableData *result = [NSMutableData data]; + [result setLength:maxLength]; + // do it + NSUInteger finalLength = [self baseDecode:bytes + srcLen:length + destBytes:[result mutableBytes] + destLen:[result length] + charset:charset + requirePadding:requirePadding]; + if (finalLength) { + if (finalLength != maxLength) { + // resize down to how big it was + [result setLength:finalLength]; + } + } else { + // either an error in the args, or we ran out of space + result = nil; + } + return result; } // @@ -491,69 +485,69 @@ + (NSUInteger)baseEncode:(const char *)srcBytes destLen:(NSUInteger)destLen charset:(const char *)charset padded:(BOOL)padded { - if (!srcLen || !destLen || !srcBytes || !destBytes) { - return 0; - } - - char *curDest = destBytes; - const unsigned char *curSrc = (const unsigned char *)(srcBytes); - - // Three bytes of data encodes to four characters of cyphertext. - // So we can pump through three-byte chunks atomically. - while (srcLen > 2) { - // space? -// _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong"); - curDest[0] = charset[curSrc[0] >> 2]; - curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)]; - curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)]; - curDest[3] = charset[curSrc[2] & 0x3f]; - - curDest += 4; - curSrc += 3; - srcLen -= 3; - destLen -= 4; - } - - // now deal with the tail (<=2 bytes) - switch (srcLen) { - case 0: - // Nothing left; nothing more to do. - break; - - case 1: - // One byte left: this encodes to two characters, and (optionally) - // two pad characters to round out the four-character cypherblock. -// _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong"); - curDest[0] = charset[curSrc[0] >> 2]; - curDest[1] = charset[(curSrc[0] & 0x03) << 4]; - curDest += 2; - destLen -= 2; - if (padded) { -// _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong"); - curDest[0] = kBase64PaddingChar; - curDest[1] = kBase64PaddingChar; - curDest += 2; - } - break; - - case 2: - // Two bytes left: this encodes to three characters, and (optionally) - // one pad character to round out the four-character cypherblock. -// _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong"); - curDest[0] = charset[curSrc[0] >> 2]; - curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)]; - curDest[2] = charset[(curSrc[1] & 0x0f) << 2]; - curDest += 3; - destLen -= 3; - if (padded) { -// _GTMDevAssert(destLen >= 1, @"our calc for encoded length was wrong"); - curDest[0] = kBase64PaddingChar; - curDest += 1; - } - break; - } - // return the length - return (curDest - destBytes); + if (!srcLen || !destLen || !srcBytes || !destBytes) { + return 0; + } + + char *curDest = destBytes; + const unsigned char *curSrc = (const unsigned char *)(srcBytes); + + // Three bytes of data encodes to four characters of cyphertext. + // So we can pump through three-byte chunks atomically. + while (srcLen > 2) { + // space? + // _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong"); + curDest[0] = charset[curSrc[0] >> 2]; + curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)]; + curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)]; + curDest[3] = charset[curSrc[2] & 0x3f]; + + curDest += 4; + curSrc += 3; + srcLen -= 3; + destLen -= 4; + } + + // now deal with the tail (<=2 bytes) + switch (srcLen) { + case 0: + // Nothing left; nothing more to do. + break; + + case 1: + // One byte left: this encodes to two characters, and (optionally) + // two pad characters to round out the four-character cypherblock. + // _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong"); + curDest[0] = charset[curSrc[0] >> 2]; + curDest[1] = charset[(curSrc[0] & 0x03) << 4]; + curDest += 2; + destLen -= 2; + if (padded) { + // _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong"); + curDest[0] = kBase64PaddingChar; + curDest[1] = kBase64PaddingChar; + curDest += 2; + } + break; + + case 2: + // Two bytes left: this encodes to three characters, and (optionally) + // one pad character to round out the four-character cypherblock. + // _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong"); + curDest[0] = charset[curSrc[0] >> 2]; + curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)]; + curDest[2] = charset[(curSrc[1] & 0x0f) << 2]; + curDest += 3; + destLen -= 3; + if (padded) { + // _GTMDevAssert(destLen >= 1, @"our calc for encoded length was wrong"); + curDest[0] = kBase64PaddingChar; + curDest += 1; + } + break; + } + // return the length + return (curDest - destBytes); } // @@ -572,131 +566,128 @@ + (NSUInteger)baseDecode:(const char *)srcBytes destLen:(NSUInteger)destLen charset:(const char *)charset requirePadding:(BOOL)requirePadding { - if (!srcLen || !destLen || !srcBytes || !destBytes) { - return 0; - } - - int decode; - NSUInteger destIndex = 0; - int state = 0; - char ch = 0; - while (srcLen-- && (ch = *srcBytes++) != 0) { - if (IsSpace(ch)) // Skip whitespace - continue; - - if (ch == kBase64PaddingChar) - break; - - decode = charset[(unsigned int)ch]; - if (decode == kBase64InvalidChar) - return 0; - - // Four cyphertext characters decode to three bytes. - // Therefore we can be in one of four states. - switch (state) { - case 0: - // We're at the beginning of a four-character cyphertext block. - // This sets the high six bits of the first byte of the - // plaintext block. -// _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong"); - destBytes[destIndex] = decode << 2; - state = 1; - break; - - case 1: - // We're one character into a four-character cyphertext block. - // This sets the low two bits of the first plaintext byte, - // and the high four bits of the second plaintext byte. -// _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong"); - destBytes[destIndex] |= decode >> 4; - destBytes[destIndex + 1] = (decode & 0x0f) << 4; - destIndex++; - state = 2; - break; - - case 2: - // We're two characters into a four-character cyphertext block. - // This sets the low four bits of the second plaintext - // byte, and the high two bits of the third plaintext byte. - // However, if this is the end of data, and those two - // bits are zero, it could be that those two bits are - // leftovers from the encoding of data that had a length - // of two mod three. -// _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong"); - destBytes[destIndex] |= decode >> 2; - destBytes[destIndex + 1] = (decode & 0x03) << 6; - destIndex++; - state = 3; - break; - - case 3: - // We're at the last character of a four-character cyphertext block. - // This sets the low six bits of the third plaintext byte. -// _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong"); - destBytes[destIndex] |= decode; - destIndex++; - state = 0; - break; - } - } - - // We are done decoding Base-64 chars. Let's see if we ended - // on a byte boundary, and/or with erroneous trailing characters. - if (ch == kBase64PaddingChar) { // We got a pad char - if ((state == 0) || (state == 1)) { - return 0; // Invalid '=' in first or second position - } - if (srcLen == 0) { - if (state == 2) { // We run out of input but we still need another '=' - return 0; - } - // Otherwise, we are in state 3 and only need this '=' - } - else { - if (state == 2) { // need another '=' - while ((ch = *srcBytes++) && (srcLen-- > 0)) { - if (!IsSpace(ch)) - break; - } - if (ch != kBase64PaddingChar) { - return 0; - } - } - // state = 1 or 2, check if all remain padding is space - while ((ch = *srcBytes++) && (srcLen-- > 0)) { - if (!IsSpace(ch)) { - return 0; - } - } - } - } - else { - // We ended by seeing the end of the string. - - if (requirePadding) { - // If we require padding, then anything but state 0 is an error. - if (state != 0) { - return 0; - } - } - else { - // Make sure we have no partial bytes lying around. Note that we do not - // require trailing '=', so states 2 and 3 are okay too. - if (state == 1) { - return 0; - } - } - } - - // If then next piece of output was valid and got written to it means we got a - // very carefully crafted input that appeared valid but contains some trailing - // bits past the real length, so just toss the thing. - if ((destIndex < destLen) && - (destBytes[destIndex] != 0)) { - return 0; - } - - return destIndex; + if (!srcLen || !destLen || !srcBytes || !destBytes) { + return 0; + } + + int decode; + NSUInteger destIndex = 0; + int state = 0; + char ch = 0; + while (srcLen-- && (ch = *srcBytes++) != 0) { + if (IsSpace(ch)) // Skip whitespace + continue; + + if (ch == kBase64PaddingChar) + break; + + decode = charset[(unsigned int)ch]; + if (decode == kBase64InvalidChar) + return 0; + + // Four cyphertext characters decode to three bytes. + // Therefore we can be in one of four states. + switch (state) { + case 0: + // We're at the beginning of a four-character cyphertext block. + // This sets the high six bits of the first byte of the + // plaintext block. + // _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong"); + destBytes[destIndex] = decode << 2; + state = 1; + break; + + case 1: + // We're one character into a four-character cyphertext block. + // This sets the low two bits of the first plaintext byte, + // and the high four bits of the second plaintext byte. + // _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong"); + destBytes[destIndex] |= decode >> 4; + destBytes[destIndex + 1] = (decode & 0x0f) << 4; + destIndex++; + state = 2; + break; + + case 2: + // We're two characters into a four-character cyphertext block. + // This sets the low four bits of the second plaintext + // byte, and the high two bits of the third plaintext byte. + // However, if this is the end of data, and those two + // bits are zero, it could be that those two bits are + // leftovers from the encoding of data that had a length + // of two mod three. + // _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong"); + destBytes[destIndex] |= decode >> 2; + destBytes[destIndex + 1] = (decode & 0x03) << 6; + destIndex++; + state = 3; + break; + + case 3: + // We're at the last character of a four-character cyphertext block. + // This sets the low six bits of the third plaintext byte. + // _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong"); + destBytes[destIndex] |= decode; + destIndex++; + state = 0; + break; + } + } + + // We are done decoding Base-64 chars. Let's see if we ended + // on a byte boundary, and/or with erroneous trailing characters. + if (ch == kBase64PaddingChar) { // We got a pad char + if ((state == 0) || (state == 1)) { + return 0; // Invalid '=' in first or second position + } + if (srcLen == 0) { + if (state == 2) { // We run out of input but we still need another '=' + return 0; + } + // Otherwise, we are in state 3 and only need this '=' + } else { + if (state == 2) { // need another '=' + while ((ch = *srcBytes++) && (srcLen-- > 0)) { + if (!IsSpace(ch)) + break; + } + if (ch != kBase64PaddingChar) { + return 0; + } + } + // state = 1 or 2, check if all remain padding is space + while ((ch = *srcBytes++) && (srcLen-- > 0)) { + if (!IsSpace(ch)) { + return 0; + } + } + } + } else { + // We ended by seeing the end of the string. + + if (requirePadding) { + // If we require padding, then anything but state 0 is an error. + if (state != 0) { + return 0; + } + } else { + // Make sure we have no partial bytes lying around. Note that we do not + // require trailing '=', so states 2 and 3 are okay too. + if (state == 1) { + return 0; + } + } + } + + // If then next piece of output was valid and got written to it means we got a + // very carefully crafted input that appeared valid but contains some trailing + // bits past the real length, so just toss the thing. + if ((destIndex < destLen) && + (destBytes[destIndex] != 0)) { + return 0; + } + + return destIndex; } @end diff --git a/QiniuSDK/Common/QNALAssetFile.m b/QiniuSDK/Common/QNALAssetFile.m index db84b914..af9408da 100644 --- a/QiniuSDK/Common/QNALAssetFile.m +++ b/QiniuSDK/Common/QNALAssetFile.m @@ -17,57 +17,56 @@ @interface QNALAssetFile () @property (nonatomic) ALAsset *asset; -@property (readonly) int64_t fileSize; +@property (readonly) int64_t fileSize; -@property (readonly) int64_t fileModifyTime; +@property (readonly) int64_t fileModifyTime; @end @implementation QNALAssetFile - (instancetype)init:(ALAsset *)asset error:(NSError *__autoreleasing *)error { - if (self = [super init]) { - NSDate *createTime = [asset valueForProperty:ALAssetPropertyDate]; - int64_t t = 0; - if (createTime != nil) { - t = [createTime timeIntervalSince1970]; - } - _fileModifyTime = t; - _fileSize = asset.defaultRepresentation.size; - _asset = asset; - } - - return self; + if (self = [super init]) { + NSDate *createTime = [asset valueForProperty:ALAssetPropertyDate]; + int64_t t = 0; + if (createTime != nil) { + t = [createTime timeIntervalSince1970]; + } + _fileModifyTime = t; + _fileSize = asset.defaultRepresentation.size; + _asset = asset; + } + + return self; } - (NSData *)read:(long)offset size:(long)size { - ALAssetRepresentation *rep = [self.asset defaultRepresentation]; - Byte *buffer = (Byte *)malloc(size); - NSUInteger buffered = [rep getBytes:buffer fromOffset:offset length:size error:nil]; + ALAssetRepresentation *rep = [self.asset defaultRepresentation]; + Byte *buffer = (Byte *)malloc(size); + NSUInteger buffered = [rep getBytes:buffer fromOffset:offset length:size error:nil]; - return [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; + return [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; } - (NSData *)readAll { - return [self read:0 size:(long)_fileSize]; + return [self read:0 size:(long)_fileSize]; } - (void)close { } --(NSString *)path { - ALAssetRepresentation *rep = [self.asset defaultRepresentation]; - return [rep url].path; +- (NSString *)path { + ALAssetRepresentation *rep = [self.asset defaultRepresentation]; + return [rep url].path; } - (int64_t)modifyTime { - return _fileModifyTime; + return _fileModifyTime; } - (int64_t)size { - return _fileSize; + return _fileSize; } @end #endif - diff --git a/QiniuSDK/Common/QNAsyncRun.m b/QiniuSDK/Common/QNAsyncRun.m index 6eed0fd8..ea745de1 100644 --- a/QiniuSDK/Common/QNAsyncRun.m +++ b/QiniuSDK/Common/QNAsyncRun.m @@ -6,17 +6,17 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import #import "QNAsyncRun.h" +#import void QNAsyncRun(QNRun run) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { - run(); - }); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + run(); + }); } void QNAsyncRunInMain(QNRun run) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - run(); - }); + dispatch_async(dispatch_get_main_queue(), ^(void) { + run(); + }); } diff --git a/QiniuSDK/Common/QNCrc32.m b/QiniuSDK/Common/QNCrc32.m index 974861ea..2632fc75 100644 --- a/QiniuSDK/Common/QNCrc32.m +++ b/QiniuSDK/Common/QNCrc32.m @@ -8,38 +8,38 @@ #import -#import "QNCrc32.h" #import "QNConfiguration.h" +#import "QNCrc32.h" @implementation QNCrc32 + (UInt32)data:(NSData *)data { - uLong crc = crc32(0L, Z_NULL, 0); + uLong crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, [data bytes], (uInt)[data length]); - return (UInt32)crc; + crc = crc32(crc, [data bytes], (uInt)[data length]); + return (UInt32)crc; } + (UInt32)file:(NSString *)filePath error:(NSError **)error { - @autoreleasepool { - NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error]; - if (*error != nil) { - return 0; - } - - int len = (int)[data length]; - int count = (len + kQNBlockSize - 1) / kQNBlockSize; - - uLong crc = crc32(0L, Z_NULL, 0); - for (int i = 0; i < count; i++) { - int offset = i * kQNBlockSize; - int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset); - NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; - crc = crc32(crc, [d bytes], (uInt)[d length]); - } - return (UInt32)crc; - } + @autoreleasepool { + NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error]; + if (*error != nil) { + return 0; + } + + int len = (int)[data length]; + int count = (len + kQNBlockSize - 1) / kQNBlockSize; + + uLong crc = crc32(0L, Z_NULL, 0); + for (int i = 0; i < count; i++) { + int offset = i * kQNBlockSize; + int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset); + NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; + crc = crc32(crc, [d bytes], (uInt)[d length]); + } + return (UInt32)crc; + } } @end diff --git a/QiniuSDK/Common/QNEtag.m b/QiniuSDK/Common/QNEtag.m index a95ea8b9..36ecfe82 100644 --- a/QiniuSDK/Common/QNEtag.m +++ b/QiniuSDK/Common/QNEtag.m @@ -8,54 +8,53 @@ #include -#import "QNEtag.h" #import "QNConfiguration.h" +#import "QNEtag.h" #import "QNUrlSafeBase64.h" @implementation QNEtag + (NSString *)file:(NSString *)filePath error:(NSError **)error { - @autoreleasepool { - NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error]; - if (*error != nil) { - return 0; - } - return [QNEtag data:data]; - } + @autoreleasepool { + NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error]; + if (*error != nil) { + return 0; + } + return [QNEtag data:data]; + } } + (NSString *)data:(NSData *)data { - if (data == nil || [data length] == 0) { - return @"Fto5o-5ea0sNMlW_75VgGJCv2AcJ"; - } - int len = (int)[data length]; - int count = (len + kQNBlockSize - 1) / kQNBlockSize; - - NSMutableData *retData = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH + 1]; - UInt8 *ret = [retData mutableBytes]; - - NSMutableData *blocksSha1 = nil; - UInt8 *pblocksSha1 = ret + 1; - if (count > 1) { - blocksSha1 = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH * count]; - pblocksSha1 = [blocksSha1 mutableBytes]; - } - - for (int i = 0; i < count; i++) { - int offset = i * kQNBlockSize; - int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset); - NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; - CC_SHA1([d bytes], (CC_LONG)size, pblocksSha1 + i * CC_SHA1_DIGEST_LENGTH); - } - if (count == 1) { - ret[0] = 0x16; - } - else { - ret[0] = 0x96; - CC_SHA1(pblocksSha1, (CC_LONG)CC_SHA1_DIGEST_LENGTH * count, ret + 1); - } - - return [QNUrlSafeBase64 encodeData:retData]; + if (data == nil || [data length] == 0) { + return @"Fto5o-5ea0sNMlW_75VgGJCv2AcJ"; + } + int len = (int)[data length]; + int count = (len + kQNBlockSize - 1) / kQNBlockSize; + + NSMutableData *retData = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH + 1]; + UInt8 *ret = [retData mutableBytes]; + + NSMutableData *blocksSha1 = nil; + UInt8 *pblocksSha1 = ret + 1; + if (count > 1) { + blocksSha1 = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH * count]; + pblocksSha1 = [blocksSha1 mutableBytes]; + } + + for (int i = 0; i < count; i++) { + int offset = i * kQNBlockSize; + int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset); + NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; + CC_SHA1([d bytes], (CC_LONG)size, pblocksSha1 + i * CC_SHA1_DIGEST_LENGTH); + } + if (count == 1) { + ret[0] = 0x16; + } else { + ret[0] = 0x96; + CC_SHA1(pblocksSha1, (CC_LONG)CC_SHA1_DIGEST_LENGTH * count, ret + 1); + } + + return [QNUrlSafeBase64 encodeData:retData]; } @end diff --git a/QiniuSDK/Common/QNFile.h b/QiniuSDK/Common/QNFile.h index fdebdb94..4cabf379 100644 --- a/QiniuSDK/Common/QNFile.h +++ b/QiniuSDK/Common/QNFile.h @@ -6,8 +6,8 @@ // Copyright (c) 2015年 Qiniu. All rights reserved. // -#import #import "QNFileDelegate.h" +#import @interface QNFile : NSObject /** diff --git a/QiniuSDK/Common/QNFile.m b/QiniuSDK/Common/QNFile.m index 645d3d9f..255a9d37 100644 --- a/QiniuSDK/Common/QNFile.m +++ b/QiniuSDK/Common/QNFile.m @@ -15,9 +15,9 @@ @interface QNFile () @property (nonatomic) NSData *data; -@property (readonly) int64_t fileSize; +@property (readonly) int64_t fileSize; -@property (readonly) int64_t fileModifyTime; +@property (readonly) int64_t fileModifyTime; @property (nonatomic) NSFileHandle *file; @@ -27,80 +27,80 @@ @implementation QNFile - (instancetype)init:(NSString *)path error:(NSError *__autoreleasing *)error { - if (self = [super init]) { - _filepath = path; - NSError *error2 = nil; - NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error2]; - if (error2 != nil) { - if (error != nil) { - *error = error2; - } - return self; - } - _fileSize = [fileAttr fileSize]; - NSDate *modifyTime = fileAttr[NSFileModificationDate]; - int64_t t = 0; - if (modifyTime != nil) { - t = [modifyTime timeIntervalSince1970]; - } - _fileModifyTime = t; - NSFileHandle *f = nil; - NSData *d = nil; - //[NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error] 不能用在大于 200M的文件上,改用filehandle - // 参见 https://issues.apache.org/jira/browse/CB-5790 - if (_fileSize > 16*1024*1024) { - f = [NSFileHandle fileHandleForReadingAtPath:path]; - if (f == nil) { - if (error != nil) { - *error =[[NSError alloc] initWithDomain:path code:kQNFileError userInfo:nil]; - } - return self; - } - }else{ - d = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:&error2]; - if (error2 != nil) { - if (error != nil) { - *error = error2; - } - return self; - } - } - _file = f; - _data = d; - } - - return self; + if (self = [super init]) { + _filepath = path; + NSError *error2 = nil; + NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error2]; + if (error2 != nil) { + if (error != nil) { + *error = error2; + } + return self; + } + _fileSize = [fileAttr fileSize]; + NSDate *modifyTime = fileAttr[NSFileModificationDate]; + int64_t t = 0; + if (modifyTime != nil) { + t = [modifyTime timeIntervalSince1970]; + } + _fileModifyTime = t; + NSFileHandle *f = nil; + NSData *d = nil; + //[NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error] 不能用在大于 200M的文件上,改用filehandle + // 参见 https://issues.apache.org/jira/browse/CB-5790 + if (_fileSize > 16 * 1024 * 1024) { + f = [NSFileHandle fileHandleForReadingAtPath:path]; + if (f == nil) { + if (error != nil) { + *error = [[NSError alloc] initWithDomain:path code:kQNFileError userInfo:nil]; + } + return self; + } + } else { + d = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:&error2]; + if (error2 != nil) { + if (error != nil) { + *error = error2; + } + return self; + } + } + _file = f; + _data = d; + } + + return self; } - (NSData *)read:(long)offset size:(long)size { - if (_data != nil) { - return [_data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; - } - [_file seekToFileOffset:offset]; - return [_file readDataOfLength:size]; + if (_data != nil) { + return [_data subdataWithRange:NSMakeRange(offset, (unsigned int)size)]; + } + [_file seekToFileOffset:offset]; + return [_file readDataOfLength:size]; } - (NSData *)readAll { - return [self read:0 size:(long)_fileSize]; + return [self read:0 size:(long)_fileSize]; } - (void)close { - if (_file != nil) { - [_file closeFile]; - } + if (_file != nil) { + [_file closeFile]; + } } --(NSString *)path { - return _filepath; +- (NSString *)path { + return _filepath; } - (int64_t)modifyTime { - return _fileModifyTime; + return _fileModifyTime; } - (int64_t)size { - return _fileSize; + return _fileSize; } @end diff --git a/QiniuSDK/Common/QNFileDelegate.h b/QiniuSDK/Common/QNFileDelegate.h index c3b611e5..e6cbeb84 100644 --- a/QiniuSDK/Common/QNFileDelegate.h +++ b/QiniuSDK/Common/QNFileDelegate.h @@ -8,7 +8,6 @@ #import - /** * 文件处理接口,支持ALAsset, NSFileHandle, NSData */ diff --git a/QiniuSDK/Common/QNPHAssetFile.h b/QiniuSDK/Common/QNPHAssetFile.h index 846c9254..0ac62936 100644 --- a/QiniuSDK/Common/QNPHAssetFile.h +++ b/QiniuSDK/Common/QNPHAssetFile.h @@ -12,7 +12,7 @@ #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) @class PHAsset; -@interface QNPHAssetFile : NSObject +@interface QNPHAssetFile : NSObject /** * 打开指定文件 * diff --git a/QiniuSDK/Common/QNPHAssetFile.m b/QiniuSDK/Common/QNPHAssetFile.m index 771a4759..9e0f9992 100644 --- a/QiniuSDK/Common/QNPHAssetFile.m +++ b/QiniuSDK/Common/QNPHAssetFile.m @@ -8,9 +8,9 @@ #import "QNPHAssetFile.h" -#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) -#import +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) #import +#import enum { kAMASSETMETADATA_PENDINGREADS = 1, kAMASSETMETADATA_ALLFINISHED = 0 @@ -18,12 +18,11 @@ #import "QNResponseInfo.h" -@interface QNPHAssetFile () -{ +@interface QNPHAssetFile () { BOOL _hasGotInfo; } -@property (nonatomic) PHAsset * phAsset; +@property (nonatomic) PHAsset *phAsset; @property (readonly) int64_t fileSize; @@ -37,8 +36,7 @@ @interface QNPHAssetFile () @implementation QNPHAssetFile -- (instancetype)init:(PHAsset *)phAsset error:(NSError *__autoreleasing *)error -{ +- (instancetype)init:(PHAsset *)phAsset error:(NSError *__autoreleasing *)error { if (self = [super init]) { NSDate *createTime = phAsset.creationDate; int64_t t = 0; @@ -48,19 +46,17 @@ - (instancetype)init:(PHAsset *)phAsset error:(NSError *__autoreleasing *)error _fileModifyTime = t; _phAsset = phAsset; [self getInfo]; - } return self; } -- (NSData *)read:(long)offset size:(long)size -{ +- (NSData *)read:(long)offset size:(long)size { NSRange subRange = NSMakeRange(offset, size); if (!self.assetData) { self.assetData = [self fetchDataFromAsset:self.phAsset]; } NSData *subData = [self.assetData subdataWithRange:subRange]; - + return subData; } @@ -71,7 +67,7 @@ - (NSData *)readAll { - (void)close { } --(NSString *)path { +- (NSString *)path { return self.assetURL.path; } @@ -83,39 +79,36 @@ - (int64_t)size { return _fileSize; } -- (void)getInfo -{ +- (void)getInfo { if (!_hasGotInfo) { _hasGotInfo = YES; - + if (PHAssetMediaTypeImage == self.phAsset.mediaType) { PHImageRequestOptions *request = [PHImageRequestOptions new]; request.version = PHImageRequestOptionsVersionCurrent; request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; request.resizeMode = PHImageRequestOptionsResizeModeNone; request.synchronous = YES; - + [[PHImageManager defaultManager] requestImageDataForAsset:self.phAsset options:request resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { _fileSize = imageData.length; _assetURL = [NSURL URLWithString:self.phAsset.localIdentifier]; - } - ]; - } - else if (PHAssetMediaTypeVideo == self.phAsset.mediaType) { + }]; + } else if (PHAssetMediaTypeVideo == self.phAsset.mediaType) { PHVideoRequestOptions *request = [PHVideoRequestOptions new]; request.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic; request.version = PHVideoRequestOptionsVersionCurrent; - - NSConditionLock* assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; + + NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; [[PHImageManager defaultManager] requestPlayerItemForVideo:self.phAsset options:request resultHandler:^(AVPlayerItem *playerItem, NSDictionary *info) { AVURLAsset *urlAsset = (AVURLAsset *)playerItem.asset; NSNumber *fileSize = nil; [urlAsset.URL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil]; _fileSize = [fileSize unsignedLongLongValue]; _assetURL = urlAsset.URL; - + [assetReadLock lock]; [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED]; }]; @@ -124,13 +117,11 @@ - (void)getInfo assetReadLock = nil; } } - } -- (NSData *)fetchDataFromAsset:(PHAsset *)asset -{ +- (NSData *)fetchDataFromAsset:(PHAsset *)asset { __block NSData *tmpData = [NSData data]; - + // Image if (asset.mediaType == PHAssetMediaTypeImage) { PHImageRequestOptions *request = [PHImageRequestOptions new]; @@ -138,41 +129,40 @@ - (NSData *)fetchDataFromAsset:(PHAsset *)asset request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; request.resizeMode = PHImageRequestOptionsResizeModeNone; request.synchronous = YES; - + [[PHImageManager defaultManager] requestImageDataForAsset:asset options:request resultHandler: - ^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { - tmpData = [NSData dataWithData:imageData]; - }]; + ^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { + tmpData = [NSData dataWithData:imageData]; + }]; } // Video - else { - + else { + PHVideoRequestOptions *request = [PHVideoRequestOptions new]; request.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic; request.version = PHVideoRequestOptionsVersionCurrent; - + NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; - - + [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:request resultHandler: - ^(AVAsset* asset, AVAudioMix* audioMix, NSDictionary* info) { - AVURLAsset *urlAsset = (AVURLAsset *)asset; - NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL]; - tmpData = [NSData dataWithData:videoData]; - - [assetReadLock lock]; - [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED]; - }]; - + ^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) { + AVURLAsset *urlAsset = (AVURLAsset *)asset; + NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL]; + tmpData = [NSData dataWithData:videoData]; + + [assetReadLock lock]; + [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED]; + }]; + [assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED]; [assetReadLock unlock]; assetReadLock = nil; } - + return tmpData; } diff --git a/QiniuSDK/Common/QNPHAssetResource.h b/QiniuSDK/Common/QNPHAssetResource.h index 678c994f..709de634 100644 --- a/QiniuSDK/Common/QNPHAssetResource.h +++ b/QiniuSDK/Common/QNPHAssetResource.h @@ -14,7 +14,7 @@ @class PHAssetResource; -@interface QNPHAssetResource : NSObject +@interface QNPHAssetResource : NSObject /** * 打开指定文件 @@ -29,4 +29,3 @@ @end #endif - diff --git a/QiniuSDK/Common/QNPHAssetResource.m b/QiniuSDK/Common/QNPHAssetResource.m index 781862d2..d0458a0d 100644 --- a/QiniuSDK/Common/QNPHAssetResource.m +++ b/QiniuSDK/Common/QNPHAssetResource.m @@ -8,8 +8,8 @@ #import "QNPHAssetResource.h" #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100) -#import #import +#import enum { kAMASSETMETADATA_PENDINGREADS = 1, @@ -18,17 +18,17 @@ #import "QNResponseInfo.h" -@interface QNPHAssetResource() +@interface QNPHAssetResource () -{ + { BOOL _hasGotInfo; } -@property (nonatomic) PHAsset * phAsset; +@property (nonatomic) PHAsset *phAsset; -@property (nonatomic) PHLivePhoto * phLivePhoto; +@property (nonatomic) PHLivePhoto *phLivePhoto; -@property (nonatomic) PHAssetResource * phAssetResource; +@property (nonatomic) PHAssetResource *phAssetResource; @property (readonly) int64_t fileSize; @@ -42,10 +42,9 @@ @interface QNPHAssetResource() @implementation QNPHAssetResource - (instancetype)init:(PHAssetResource *)phAssetResource - error:(NSError *__autoreleasing *)error -{ + error:(NSError *__autoreleasing *)error { if (self = [super init]) { - PHAsset * phasset = [PHAsset fetchAssetsWithBurstIdentifier:self.phAssetResource.assetLocalIdentifier options:nil][0]; + PHAsset *phasset = [PHAsset fetchAssetsWithBurstIdentifier:self.phAssetResource.assetLocalIdentifier options:nil][0]; NSDate *createTime = phasset.creationDate; int64_t t = 0; if (createTime != nil) { @@ -54,20 +53,17 @@ - (instancetype)init:(PHAssetResource *)phAssetResource _fileModifyTime = t; _phAssetResource = phAssetResource; [self getInfo]; - } return self; } - -- (NSData *)read:(long)offset size:(long)size -{ +- (NSData *)read:(long)offset size:(long)size { NSRange subRange = NSMakeRange(offset, size); if (!self.assetData) { self.assetData = [self fetchDataFromAsset:self.phAssetResource]; } NSData *subData = [self.assetData subdataWithRange:subRange]; - + return subData; } @@ -78,7 +74,7 @@ - (NSData *)readAll { - (void)close { } --(NSString *)path { +- (NSString *)path { return self.assetURL.path; } @@ -90,98 +86,90 @@ - (int64_t)size { return _fileSize; } -- (void)getInfo -{ +- (void)getInfo { if (!_hasGotInfo) { _hasGotInfo = YES; - NSConditionLock* assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; - + NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; + NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:self.phAssetResource.originalFilename]; NSURL *localpath = [NSURL fileURLWithPath:pathToWrite]; PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new]; options.networkAccessAllowed = YES; - [[PHAssetResourceManager defaultManager] writeDataForAssetResource:self.phAssetResource toFile:localpath options:options completionHandler:^(NSError * _Nullable error) { + [[PHAssetResourceManager defaultManager] writeDataForAssetResource:self.phAssetResource toFile:localpath options:options completionHandler:^(NSError *_Nullable error) { if (error == nil) { - AVURLAsset * urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil]; + AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil]; NSNumber *fileSize = nil; [urlAsset.URL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil]; _fileSize = [fileSize unsignedLongLongValue]; _assetURL = urlAsset.URL; self.assetData = [NSData dataWithData:[NSData dataWithContentsOfURL:urlAsset.URL]]; - }else - { - NSLog(@"%@",error); + } else { + NSLog(@"%@", error); } - - BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:pathToWrite]; + + BOOL blHave = [[NSFileManager defaultManager] fileExistsAtPath:pathToWrite]; if (!blHave) { NSLog(@"no have"); - return ; - }else { + return; + } else { NSLog(@" have"); - BOOL blDele= [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil]; + BOOL blDele = [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil]; if (blDele) { NSLog(@"dele success"); - }else { + } else { NSLog(@"dele fail"); } } [assetReadLock lock]; [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED]; }]; - + [assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED]; [assetReadLock unlock]; assetReadLock = nil; - } - } -- (NSData *)fetchDataFromAsset:(PHAssetResource *)videoResource -{ +- (NSData *)fetchDataFromAsset:(PHAssetResource *)videoResource { __block NSData *tmpData = [NSData data]; - + NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS]; - + NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:videoResource.originalFilename]; NSURL *localpath = [NSURL fileURLWithPath:pathToWrite]; PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new]; options.networkAccessAllowed = YES; - [[PHAssetResourceManager defaultManager] writeDataForAssetResource:videoResource toFile:localpath options:options completionHandler:^(NSError * _Nullable error) { + [[PHAssetResourceManager defaultManager] writeDataForAssetResource:videoResource toFile:localpath options:options completionHandler:^(NSError *_Nullable error) { if (error == nil) { - AVURLAsset * urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil]; + AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil]; NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL]; tmpData = [NSData dataWithData:videoData]; - }else - { - NSLog(@"%@",error); + } else { + NSLog(@"%@", error); } - BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:pathToWrite]; + BOOL blHave = [[NSFileManager defaultManager] fileExistsAtPath:pathToWrite]; if (!blHave) { NSLog(@"no have"); - return ; - }else { + return; + } else { NSLog(@" have"); - BOOL blDele= [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil]; + BOOL blDele = [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil]; if (blDele) { NSLog(@"dele success"); - }else { + } else { NSLog(@"dele fail"); } } [assetReadLock lock]; [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED]; }]; - + [assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED]; [assetReadLock unlock]; assetReadLock = nil; - - + return tmpData; } @end #endif - diff --git a/QiniuSDK/Common/QNSystem.m b/QiniuSDK/Common/QNSystem.m index 1082b36e..92ab1411 100644 --- a/QiniuSDK/Common/QNSystem.m +++ b/QiniuSDK/Common/QNSystem.m @@ -15,48 +15,48 @@ #import #endif -BOOL hasNSURLSession(){ +BOOL hasNSURLSession() { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) - float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; - if (sysVersion < 7.0) { - return NO; - } + float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; + if (sysVersion < 7.0) { + return NO; + } #else - NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; - if ((sysVersion.majorVersion <= 10 && sysVersion.minorVersion < 9)) { - return NO; - } + NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + if ((sysVersion.majorVersion <= 10 && sysVersion.minorVersion < 9)) { + return NO; + } #endif - return YES; + return YES; } -BOOL hasAts(){ +BOOL hasAts() { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) - float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; - if (sysVersion < 9.0) { - return NO; - } + float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; + if (sysVersion < 9.0) { + return NO; + } #else - NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; - if ((sysVersion.majorVersion <= 10 && sysVersion.minorVersion < 11)) { - return NO; - } + if ((sysVersion.majorVersion <= 10 && sysVersion.minorVersion < 11)) { + return NO; + } #endif - return YES; + return YES; } -BOOL allowsArbitraryLoads(){ +BOOL allowsArbitraryLoads() { if (!hasAts()) { return YES; } - + // for unit test NSDictionary* d = [[NSBundle mainBundle] infoDictionary]; if (d == nil || d.count == 0) { return YES; } - + NSDictionary* sec = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSAppTransportSecurity"]; if (sec == nil) { return NO; diff --git a/QiniuSDK/Common/QNUrlSafeBase64.m b/QiniuSDK/Common/QNUrlSafeBase64.m index f2ddd87b..73f22aec 100644 --- a/QiniuSDK/Common/QNUrlSafeBase64.m +++ b/QiniuSDK/Common/QNUrlSafeBase64.m @@ -14,16 +14,16 @@ @implementation QNUrlSafeBase64 + (NSString *)encodeString:(NSString *)sourceString { - NSData *data = [NSData dataWithBytes:[sourceString UTF8String] length:[sourceString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; - return [self encodeData:data]; + NSData *data = [NSData dataWithBytes:[sourceString UTF8String] length:[sourceString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; + return [self encodeData:data]; } + (NSString *)encodeData:(NSData *)data { - return [GTM_Base64 stringByWebSafeEncodingData:data padded:YES]; + return [GTM_Base64 stringByWebSafeEncodingData:data padded:YES]; } + (NSData *)decodeString:(NSString *)data { - return [GTM_Base64 webSafeDecodeString:data]; + return [GTM_Base64 webSafeDecodeString:data]; } @end diff --git a/QiniuSDK/Http/QNDns.m b/QiniuSDK/Http/QNDns.m index 4685c5e0..13ac10fe 100644 --- a/QiniuSDK/Http/QNDns.m +++ b/QiniuSDK/Http/QNDns.m @@ -12,62 +12,62 @@ #import "QNDns.h" static NSArray *getAddresses(CFHostRef hostRef) { - Boolean lookup = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); - if (!lookup) { - return nil; - } - CFArrayRef addresses = CFHostGetAddressing(hostRef, &lookup); - if (!lookup) { - return nil; - } + Boolean lookup = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); + if (!lookup) { + return nil; + } + CFArrayRef addresses = CFHostGetAddressing(hostRef, &lookup); + if (!lookup) { + return nil; + } - char buf[32]; - __block NSMutableArray *ret = [[NSMutableArray alloc] init]; + char buf[32]; + __block NSMutableArray *ret = [[NSMutableArray alloc] init]; - // Iterate through the records to extract the address information - struct sockaddr_in *remoteAddr; - for (int i = 0; i < CFArrayGetCount(addresses); i++) { - CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i); - remoteAddr = (struct sockaddr_in *)CFDataGetBytePtr(saData); + // Iterate through the records to extract the address information + struct sockaddr_in *remoteAddr; + for (int i = 0; i < CFArrayGetCount(addresses); i++) { + CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i); + remoteAddr = (struct sockaddr_in *)CFDataGetBytePtr(saData); - if (remoteAddr != NULL) { - const char *p = inet_ntop(AF_INET, &(remoteAddr->sin_addr), buf, 32); - NSString *ip = [NSString stringWithUTF8String:p]; - [ret addObject:ip]; -// NSLog(@"Resolved %u->%@", i, ip); - } - } - return ret; + if (remoteAddr != NULL) { + const char *p = inet_ntop(AF_INET, &(remoteAddr->sin_addr), buf, 32); + NSString *ip = [NSString stringWithUTF8String:p]; + [ret addObject:ip]; + // NSLog(@"Resolved %u->%@", i, ip); + } + } + return ret; } @implementation QNDns + (NSArray *)getAddresses:(NSString *)hostName { - // Convert the hostname into a StringRef - CFStringRef hostNameRef = CFStringCreateWithCString(kCFAllocatorDefault, [hostName UTF8String], kCFStringEncodingASCII); + // Convert the hostname into a StringRef + CFStringRef hostNameRef = CFStringCreateWithCString(kCFAllocatorDefault, [hostName UTF8String], kCFStringEncodingASCII); - CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostNameRef); - NSArray *ret = getAddresses(hostRef); + CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostNameRef); + NSArray *ret = getAddresses(hostRef); - CFRelease(hostRef); - CFRelease(hostNameRef); - return ret; + CFRelease(hostRef); + CFRelease(hostNameRef); + return ret; } + (NSString *)getAddress:(NSString *)hostName { - NSArray *result = [QNDns getAddresses:hostName]; - if (result == nil || result.count == 0) { - return @""; - } - return result[0]; + NSArray *result = [QNDns getAddresses:hostName]; + if (result == nil || result.count == 0) { + return @""; + } + return result[0]; } + (NSString *)getAddressesString:(NSString *)hostName { - NSArray *result = [QNDns getAddresses:hostName]; - if (result == nil || result.count == 0) { - return @""; - } - return [result componentsJoinedByString:@";"]; + NSArray *result = [QNDns getAddresses:hostName]; + if (result == nil || result.count == 0) { + return @""; + } + return [result componentsJoinedByString:@";"]; } @end diff --git a/QiniuSDK/Http/QNHttpDelegate.h b/QiniuSDK/Http/QNHttpDelegate.h index d7f496f4..0c9897d1 100644 --- a/QiniuSDK/Http/QNHttpDelegate.h +++ b/QiniuSDK/Http/QNHttpDelegate.h @@ -11,22 +11,21 @@ typedef BOOL (^QNCancelBlock)(void); */ @protocol QNHttpDelegate -- (void) multipartPost:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withFileName:(NSString *)key - withMimeType:(NSString *)mime - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; +- (void)multipartPost:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withFileName:(NSString *)key + withMimeType:(NSString *)mime + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; - -- (void) post:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withHeaders:(NSDictionary *)headers - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; +- (void)post:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withHeaders:(NSDictionary *)headers + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; @end diff --git a/QiniuSDK/Http/QNHttpManager.h b/QiniuSDK/Http/QNHttpManager.h index eccddc9f..78593a6e 100644 --- a/QiniuSDK/Http/QNHttpManager.h +++ b/QiniuSDK/Http/QNHttpManager.h @@ -6,8 +6,8 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import #import "QNHttpDelegate.h" +#import #import "QNConfiguration.h" @@ -17,21 +17,21 @@ urlConverter:(QNUrlConvert)converter dns:(QNDnsManager *)dns; -- (void) multipartPost:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withFileName:(NSString *)key - withMimeType:(NSString *)mime - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; +- (void)multipartPost:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withFileName:(NSString *)key + withMimeType:(NSString *)mime + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; -- (void) post:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withHeaders:(NSDictionary *)headers - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; +- (void)post:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withHeaders:(NSDictionary *)headers + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; @end diff --git a/QiniuSDK/Http/QNHttpManager.m b/QiniuSDK/Http/QNHttpManager.m index 42c14af8..7d282767 100644 --- a/QiniuSDK/Http/QNHttpManager.m +++ b/QiniuSDK/Http/QNHttpManager.m @@ -8,12 +8,12 @@ #import "AFNetworking.h" +#import "HappyDNS.h" #import "QNConfiguration.h" +#import "QNDns.h" #import "QNHttpManager.h" -#import "QNUserAgent.h" #import "QNResponseInfo.h" -#import "QNDns.h" -#import "HappyDNS.h" +#import "QNUserAgent.h" @interface QNHttpManager () @property (nonatomic) AFHTTPRequestOperationManager *httpManager; @@ -24,21 +24,21 @@ @interface QNHttpManager () const int kQNRetryConnectTimes = 3; -static NSURL *buildUrl(NSString *host, NSNumber *port, NSString *path){ - port = port == nil ?[NSNumber numberWithInt:80] : port; - NSString *p = [[NSString alloc] initWithFormat:@"http://%@:%@%@", host, port, path]; - return [[NSURL alloc] initWithString:p]; +static NSURL *buildUrl(NSString *host, NSNumber *port, NSString *path) { + port = port == nil ? [NSNumber numberWithInt:80] : port; + NSString *p = [[NSString alloc] initWithFormat:@"http://%@:%@%@", host, port, path]; + return [[NSURL alloc] initWithString:p]; } -static BOOL needRetry(AFHTTPRequestOperation *op, NSError *error){ - if (error != nil) { - return error.code < -1000; - } - if (op == nil) { - return YES; - } - int status = (int)[op.response statusCode]; - return status >= 500 && status < 600 && status != 579; +static BOOL needRetry(AFHTTPRequestOperation *op, NSError *error) { + if (error != nil) { + return error.code < -1000; + } + if (op == nil) { + return YES; + } + int status = (int)[op.response statusCode]; + return status >= 500 && status < 600 && status != 579; } @implementation QNHttpManager @@ -46,19 +46,19 @@ @implementation QNHttpManager - (instancetype)initWithTimeout:(UInt32)timeout urlConverter:(QNUrlConvert)converter dns:(QNDnsManager *)dns { - if (self = [super init]) { - _httpManager = [[AFHTTPRequestOperationManager alloc] init]; - _httpManager.responseSerializer = [AFJSONResponseSerializer serializer]; - _timeout = timeout; - _converter = converter; - _dns = dns; - } - - return self; + if (self = [super init]) { + _httpManager = [[AFHTTPRequestOperationManager alloc] init]; + _httpManager.responseSerializer = [AFJSONResponseSerializer serializer]; + _timeout = timeout; + _converter = converter; + _dns = dns; + } + + return self; } - (instancetype)init { - return [self initWithTimeout:60 urlConverter:nil dns:nil]; + return [self initWithTimeout:60 urlConverter:nil dns:nil]; } + (QNResponseInfo *)buildResponseInfo:(AFHTTPRequestOperation *)operation @@ -66,181 +66,177 @@ + (QNResponseInfo *)buildResponseInfo:(AFHTTPRequestOperation *)operation withDuration:(double)duration withResponse:(id)responseObject withIp:(NSString *)ip { - QNResponseInfo *info; - NSString *host = operation.request.URL.host; - - if (operation.response) { - int status = (int)[operation.response statusCode]; - NSDictionary *headers = [operation.response allHeaderFields]; - NSString *reqId = headers[@"X-Reqid"]; - NSString *xlog = headers[@"X-Log"]; - NSString *xvia = headers[@"X-Via"]; - if (xvia == nil) { - xvia = headers[@"X-Px"]; - } - info = [[QNResponseInfo alloc] init:status withReqId:reqId withXLog:xlog withXVia:xvia withHost:host withIp:ip withDuration:duration withBody:responseObject]; - } - else { - info = [QNResponseInfo responseInfoWithNetError:error host:host duration:duration]; - } - return info; + QNResponseInfo *info; + NSString *host = operation.request.URL.host; + + if (operation.response) { + int status = (int)[operation.response statusCode]; + NSDictionary *headers = [operation.response allHeaderFields]; + NSString *reqId = headers[@"X-Reqid"]; + NSString *xlog = headers[@"X-Log"]; + NSString *xvia = headers[@"X-Via"]; + if (xvia == nil) { + xvia = headers[@"X-Px"]; + } + info = [[QNResponseInfo alloc] init:status withReqId:reqId withXLog:xlog withXVia:xvia withHost:host withIp:ip withDuration:duration withBody:responseObject]; + } else { + info = [QNResponseInfo responseInfoWithNetError:error host:host duration:duration]; + } + return info; } -- (void) sendRequest2:(NSMutableURLRequest *)request - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock - withIpArray:(NSArray*)ips - withIndex:(int)index - withDomain:(NSString *)domain - withRetryTimes:(int)times - withStartTime:(NSDate *)startTime { - - NSURL *url = request.URL; - __block NSString *ip = nil; - if(ips != nil) { - ip = [ips objectAtIndex:(index%ips.count)]; - NSString *path = url.path; - if (path == nil || [@"" isEqualToString:path]) { - path = @"/"; - } - url = buildUrl(ip, url.port, path); - [request setValue:domain forHTTPHeaderField:@"Host"]; - - - } - - request.URL = url; - - [request setTimeoutInterval:_timeout]; - - [request setValue:[[QNUserAgent sharedInstance] description] forHTTPHeaderField:@"User-Agent"]; - [request setValue:nil forHTTPHeaderField:@"Accept-Language"]; - - - AFHTTPRequestOperation *operation = [_httpManager - HTTPRequestOperationWithRequest:request - success: ^(AFHTTPRequestOperation *operation, id responseObject) { - double duration = [[NSDate date] timeIntervalSinceDate:startTime]; - QNResponseInfo *info = [QNHttpManager buildResponseInfo:operation withError:nil withDuration:duration withResponse:operation.responseData withIp:ip]; - NSDictionary *resp = nil; - if (info.isOK) { - resp = responseObject; - } - completeBlock(info, resp); - } failure: ^(AFHTTPRequestOperation *operation, NSError *error) { - if (_converter != nil && (index+1 < ips.count || times>0) && needRetry(operation, error)) { - - NSLog(@"idx: %d, count: %lu", index, (unsigned long)ips.count); - int nindex = index; - if (ips.count != 0) - nindex = (index + 1) % ips.count; - - [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:nindex withDomain:domain withRetryTimes:times -1 withStartTime:startTime]; - return; - } - double duration = [[NSDate date] timeIntervalSinceDate:startTime]; - QNResponseInfo *info = [QNHttpManager buildResponseInfo:operation withError:error withDuration:duration withResponse:operation.responseData withIp:ip]; - NSLog(@"failure %@", info); - completeBlock(info, nil); - } - ]; - - __block AFHTTPRequestOperation *op = nil; - if (cancelBlock) { - op = operation; - } - - [operation setUploadProgressBlock: ^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { - - if (progressBlock) { - progressBlock(totalBytesWritten, totalBytesExpectedToWrite); - } - if (cancelBlock) { - if (cancelBlock()) { - [op cancel]; - } - op = nil; - } - }]; - - [_httpManager.operationQueue addOperation:operation]; +- (void)sendRequest2:(NSMutableURLRequest *)request + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock + withIpArray:(NSArray *)ips + withIndex:(int)index + withDomain:(NSString *)domain + withRetryTimes:(int)times + withStartTime:(NSDate *)startTime { + + NSURL *url = request.URL; + __block NSString *ip = nil; + if (ips != nil) { + ip = [ips objectAtIndex:(index % ips.count)]; + NSString *path = url.path; + if (path == nil || [@"" isEqualToString:path]) { + path = @"/"; + } + url = buildUrl(ip, url.port, path); + [request setValue:domain forHTTPHeaderField:@"Host"]; + } + + request.URL = url; + + [request setTimeoutInterval:_timeout]; + + [request setValue:[[QNUserAgent sharedInstance] description] forHTTPHeaderField:@"User-Agent"]; + [request setValue:nil forHTTPHeaderField:@"Accept-Language"]; + + AFHTTPRequestOperation *operation = [_httpManager + HTTPRequestOperationWithRequest:request + success:^(AFHTTPRequestOperation *operation, id responseObject) { + double duration = [[NSDate date] timeIntervalSinceDate:startTime]; + QNResponseInfo *info = [QNHttpManager buildResponseInfo:operation withError:nil withDuration:duration withResponse:operation.responseData withIp:ip]; + NSDictionary *resp = nil; + if (info.isOK) { + resp = responseObject; + } + completeBlock(info, resp); + } + failure:^(AFHTTPRequestOperation *operation, NSError *error) { + if (_converter != nil && (index + 1 < ips.count || times > 0) && needRetry(operation, error)) { + + NSLog(@"idx: %d, count: %lu", index, (unsigned long)ips.count); + int nindex = index; + if (ips.count != 0) + nindex = (index + 1) % ips.count; + + [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:nindex withDomain:domain withRetryTimes:times - 1 withStartTime:startTime]; + return; + } + double duration = [[NSDate date] timeIntervalSinceDate:startTime]; + QNResponseInfo *info = [QNHttpManager buildResponseInfo:operation withError:error withDuration:duration withResponse:operation.responseData withIp:ip]; + NSLog(@"failure %@", info); + completeBlock(info, nil); + }]; + + __block AFHTTPRequestOperation *op = nil; + if (cancelBlock) { + op = operation; + } + + [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { + + if (progressBlock) { + progressBlock(totalBytesWritten, totalBytesExpectedToWrite); + } + if (cancelBlock) { + if (cancelBlock()) { + [op cancel]; + } + op = nil; + } + }]; + + [_httpManager.operationQueue addOperation:operation]; } -- (void) sendRequest:(NSMutableURLRequest *)request - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - NSString *u = request.URL.absoluteString; - NSURL *url = request.URL; - NSString *domain =url.host; - NSArray * ips = nil; - NSDate *startTime = [NSDate date]; - - if (_converter != nil) { - url = [[NSURL alloc] initWithString:_converter(u)]; - request.URL = url; - domain = url.host; - }else if(_dns != nil && [url.scheme isEqual: @"http"]) { - ips = [_dns queryWithDomain:[[QNDomain alloc] init:domain hostsFirst:NO hasCname:YES maxTtl:1000]]; - double duration = [[NSDate date] timeIntervalSinceDate:startTime]; - if (ips == nil || ips.count == 0) { - NSError *error = [[NSError alloc] initWithDomain:domain code:-1003 userInfo:@{ @"error":@"unkonwn host" }]; - QNResponseInfo *info = [QNResponseInfo responseInfoWithNetError:error host:domain duration:duration]; - NSLog(@"failure %@", info); - completeBlock(info, nil); - return; - } - } - [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:0 withDomain:domain withRetryTimes:kQNRetryConnectTimes withStartTime:startTime]; +- (void)sendRequest:(NSMutableURLRequest *)request + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + NSString *u = request.URL.absoluteString; + NSURL *url = request.URL; + NSString *domain = url.host; + NSArray *ips = nil; + NSDate *startTime = [NSDate date]; + + if (_converter != nil) { + url = [[NSURL alloc] initWithString:_converter(u)]; + request.URL = url; + domain = url.host; + } else if (_dns != nil && [url.scheme isEqual:@"http"]) { + ips = [_dns queryWithDomain:[[QNDomain alloc] init:domain hostsFirst:NO hasCname:YES maxTtl:1000]]; + double duration = [[NSDate date] timeIntervalSinceDate:startTime]; + if (ips == nil || ips.count == 0) { + NSError *error = [[NSError alloc] initWithDomain:domain code:-1003 userInfo:@{ @"error" : @"unkonwn host" }]; + QNResponseInfo *info = [QNResponseInfo responseInfoWithNetError:error host:domain duration:duration]; + NSLog(@"failure %@", info); + completeBlock(info, nil); + return; + } + } + [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:0 withDomain:domain withRetryTimes:kQNRetryConnectTimes withStartTime:startTime]; } -- (void) multipartPost:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withFileName:(NSString *)key - withMimeType:(NSString *)mime - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - - NSMutableURLRequest *request = [_httpManager.requestSerializer - multipartFormRequestWithMethod:@"POST" - URLString:url - parameters:params - constructingBodyWithBlock: ^(id < AFMultipartFormData > formData) { - [formData appendPartWithFileData:data name:@"file" fileName:key mimeType:mime]; - } - - error:nil]; - [self sendRequest:request - withCompleteBlock:completeBlock - withProgressBlock:progressBlock - withCancelBlock:cancelBlock]; +- (void)multipartPost:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withFileName:(NSString *)key + withMimeType:(NSString *)mime + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + + NSMutableURLRequest *request = [_httpManager.requestSerializer + multipartFormRequestWithMethod:@"POST" + URLString:url + parameters:params + constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileData:data name:@"file" fileName:key mimeType:mime]; + } + + error:nil]; + [self sendRequest:request + withCompleteBlock:completeBlock + withProgressBlock:progressBlock + withCancelBlock:cancelBlock]; } -- (void) post:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withHeaders:(NSDictionary *)headers - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; - if (headers) { - [request setAllHTTPHeaderFields:headers]; - } - - [request setHTTPMethod:@"POST"]; - - if (params) { - [request setValuesForKeysWithDictionary:params]; - } - [request setHTTPBody:data]; - [self sendRequest:request - withCompleteBlock:completeBlock - withProgressBlock:progressBlock - withCancelBlock:cancelBlock]; +- (void)post:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withHeaders:(NSDictionary *)headers + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; + if (headers) { + [request setAllHTTPHeaderFields:headers]; + } + + [request setHTTPMethod:@"POST"]; + + if (params) { + [request setValuesForKeysWithDictionary:params]; + } + [request setHTTPBody:data]; + [self sendRequest:request + withCompleteBlock:completeBlock + withProgressBlock:progressBlock + withCancelBlock:cancelBlock]; } @end diff --git a/QiniuSDK/Http/QNResponseInfo.h b/QiniuSDK/Http/QNResponseInfo.h index e6fac4bf..7978ba2a 100644 --- a/QiniuSDK/Http/QNResponseInfo.h +++ b/QiniuSDK/Http/QNResponseInfo.h @@ -101,17 +101,17 @@ extern const int kQNFileError; /** * 是否取消 */ -@property (nonatomic, readonly, getter = isCancelled) BOOL canceled; +@property (nonatomic, readonly, getter=isCancelled) BOOL canceled; /** * 成功的请求 */ -@property (nonatomic, readonly, getter = isOK) BOOL ok; +@property (nonatomic, readonly, getter=isOK) BOOL ok; /** * 是否网络错误 */ -@property (nonatomic, readonly, getter = isConnectionBroken) BOOL broken; +@property (nonatomic, readonly, getter=isConnectionBroken) BOOL broken; /** * 是否需要重试,内部使用 @@ -126,7 +126,7 @@ extern const int kQNFileError; /** * 是否为 七牛响应 */ -@property (nonatomic, readonly, getter = isNotQiniu) BOOL notQiniu; +@property (nonatomic, readonly, getter=isNotQiniu) BOOL notQiniu; /** * 工厂函数,内部使用 diff --git a/QiniuSDK/Http/QNResponseInfo.m b/QiniuSDK/Http/QNResponseInfo.m index 4376f692..7dda06f1 100644 --- a/QiniuSDK/Http/QNResponseInfo.m +++ b/QiniuSDK/Http/QNResponseInfo.m @@ -6,7 +6,6 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // - #import "QNResponseInfo.h" #import "QNUserAgent.h" #import "QNVersion.h" @@ -74,67 +73,67 @@ @implementation QNResponseInfo + (instancetype)cancel { - return [[QNResponseInfo alloc] initWithCancelled]; + return [[QNResponseInfo alloc] initWithCancelled]; } + (instancetype)responseInfoWithInvalidArgument:(NSString *)text { - return [[QNResponseInfo alloc] initWithStatus:kQNInvalidArgument errorDescription:text]; + return [[QNResponseInfo alloc] initWithStatus:kQNInvalidArgument errorDescription:text]; } + (instancetype)responseInfoWithInvalidToken:(NSString *)text { - return [[QNResponseInfo alloc] initWithStatus:kQNInvalidToken errorDescription:text]; + return [[QNResponseInfo alloc] initWithStatus:kQNInvalidToken errorDescription:text]; } + (instancetype)responseInfoWithNetError:(NSError *)error host:(NSString *)host duration:(double)duration { - int code = kQNNetworkError; - if (error != nil) { - code = (int)error.code; - } - return [[QNResponseInfo alloc] initWithStatus:code error:error host:host duration:duration]; + int code = kQNNetworkError; + if (error != nil) { + code = (int)error.code; + } + return [[QNResponseInfo alloc] initWithStatus:code error:error host:host duration:duration]; } + (instancetype)responseInfoWithFileError:(NSError *)error { - return [[QNResponseInfo alloc] initWithStatus:kQNFileError error:error]; + return [[QNResponseInfo alloc] initWithStatus:kQNFileError error:error]; } + (instancetype)responseInfoOfZeroData:(NSString *)path { - NSString *desc; - if (path == nil) { - desc = @"data size is 0"; - }else { - desc = [[NSString alloc] initWithFormat:@"file %@ size is 0", path]; - } - return [[QNResponseInfo alloc] initWithStatus:kQNZeroDataSize errorDescription:desc]; + NSString *desc; + if (path == nil) { + desc = @"data size is 0"; + } else { + desc = [[NSString alloc] initWithFormat:@"file %@ size is 0", path]; + } + return [[QNResponseInfo alloc] initWithStatus:kQNZeroDataSize errorDescription:desc]; } - (instancetype)initWithCancelled { - return [self initWithStatus:kQNRequestCancelled errorDescription:@"cancelled by user"]; + return [self initWithStatus:kQNRequestCancelled errorDescription:@"cancelled by user"]; } - (instancetype)initWithStatus:(int)status error:(NSError *)error { - return [self initWithStatus:status error:error host:nil duration:0]; + return [self initWithStatus:status error:error host:nil duration:0]; } - (instancetype)initWithStatus:(int)status error:(NSError *)error host:(NSString *)host duration:(double)duration { - if (self = [super init]) { - _statusCode = status; - _error = error; - _host = host; - _duration = duration; - _id = [QNUserAgent sharedInstance].id; - _timeStamp = [[NSDate date] timeIntervalSince1970]; - } - return self; + if (self = [super init]) { + _statusCode = status; + _error = error; + _host = host; + _duration = duration; + _id = [QNUserAgent sharedInstance].id; + _timeStamp = [[NSDate date] timeIntervalSince1970]; + } + return self; } - (instancetype)initWithStatus:(int)status errorDescription:(NSString *)text { - NSError *error = [[NSError alloc] initWithDomain:domain code:status userInfo:@{ @"error":text }]; - return [self initWithStatus:status error:error]; + NSError *error = [[NSError alloc] initWithDomain:domain code:status userInfo:@{ @"error" : text }]; + return [self initWithStatus:status error:error]; } - (instancetype)init:(int)status @@ -145,69 +144,67 @@ - (instancetype)init:(int)status withIp:(NSString *)ip withDuration:(double)duration withBody:(NSData *)body { - if (self = [super init]) { - _statusCode = status; - _reqId = [reqId copy]; - _xlog = [xlog copy]; - _xvia = [xvia copy]; - _host = [host copy]; - _duration = duration; - _serverIp = ip; - _id = [QNUserAgent sharedInstance].id; - _timeStamp = [[NSDate date] timeIntervalSince1970]; - if (status != 200) { - if (body == nil) { - _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:nil]; - } - else { - NSError *tmp; - NSDictionary *uInfo = [NSJSONSerialization JSONObjectWithData:body options:NSJSONReadingMutableLeaves error:&tmp]; - if (tmp != nil) { - // 出现错误时,如果信息是非UTF8编码会失败,返回nil - NSString *str = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]; - if (str == nil) { - str = @""; - } - uInfo = @{ @"error": str }; - } - _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo]; - } - } - else if (body == nil || body.length == 0) { - NSDictionary *uInfo = @{ @"error":@"no response json" }; - _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo]; - } - } - return self; + if (self = [super init]) { + _statusCode = status; + _reqId = [reqId copy]; + _xlog = [xlog copy]; + _xvia = [xvia copy]; + _host = [host copy]; + _duration = duration; + _serverIp = ip; + _id = [QNUserAgent sharedInstance].id; + _timeStamp = [[NSDate date] timeIntervalSince1970]; + if (status != 200) { + if (body == nil) { + _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:nil]; + } else { + NSError *tmp; + NSDictionary *uInfo = [NSJSONSerialization JSONObjectWithData:body options:NSJSONReadingMutableLeaves error:&tmp]; + if (tmp != nil) { + // 出现错误时,如果信息是非UTF8编码会失败,返回nil + NSString *str = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]; + if (str == nil) { + str = @""; + } + uInfo = @{ @"error" : str }; + } + _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo]; + } + } else if (body == nil || body.length == 0) { + NSDictionary *uInfo = @{ @"error" : @"no response json" }; + _error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo]; + } + } + return self; } - (NSString *)description { - return [NSString stringWithFormat:@"<%@= id: %@, ver: %@, status: %d, requestId: %@, xlog: %@, xvia: %@, host: %@ ip: %@ duration: %f s time: %llu error: %@>", NSStringFromClass([self class]), _id, kQiniuVersion, _statusCode, _reqId, _xlog, _xvia, _host, _serverIp, _duration, _timeStamp, _error]; + return [NSString stringWithFormat:@"<%@= id: %@, ver: %@, status: %d, requestId: %@, xlog: %@, xvia: %@, host: %@ ip: %@ duration: %f s time: %llu error: %@>", NSStringFromClass([self class]), _id, kQiniuVersion, _statusCode, _reqId, _xlog, _xvia, _host, _serverIp, _duration, _timeStamp, _error]; } - (BOOL)isCancelled { - return _statusCode == kQNRequestCancelled || _statusCode == -999; + return _statusCode == kQNRequestCancelled || _statusCode == -999; } - (BOOL)isNotQiniu { - return (_statusCode >= 200 && _statusCode < 500) && _reqId == nil; + return (_statusCode >= 200 && _statusCode < 500) && _reqId == nil; } - (BOOL)isOK { - return _statusCode == 200 && _error == nil && _reqId != nil; + return _statusCode == 200 && _error == nil && _reqId != nil; } - (BOOL)isConnectionBroken { - // reqId is nill means the server is not qiniu - return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003); + // reqId is nill means the server is not qiniu + return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003); } - (BOOL)needSwitchServer { - return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003) || (_statusCode / 100 == 5 && _statusCode != 579); + return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003) || (_statusCode / 100 == 5 && _statusCode != 579); } - (BOOL)couldRetry { - return (_statusCode >= 500 && _statusCode < 600 && _statusCode != 579) || _statusCode == kQNNetworkError || _statusCode == 996 || _statusCode == 406 || (_statusCode == 200 && _error != nil) || _statusCode < -1000 || self.isNotQiniu; + return (_statusCode >= 500 && _statusCode < 600 && _statusCode != 579) || _statusCode == kQNNetworkError || _statusCode == 996 || _statusCode == 406 || (_statusCode == 200 && _error != nil) || _statusCode < -1000 || self.isNotQiniu; } @end diff --git a/QiniuSDK/Http/QNSessionManager.h b/QiniuSDK/Http/QNSessionManager.h index 9c7246b6..10d19a05 100644 --- a/QiniuSDK/Http/QNSessionManager.h +++ b/QiniuSDK/Http/QNSessionManager.h @@ -1,5 +1,5 @@ -#import #import "QNHttpDelegate.h" +#import #import "QNConfiguration.h" @@ -10,24 +10,24 @@ - (instancetype)initWithProxy:(NSDictionary *)proxyDict timeout:(UInt32)timeout urlConverter:(QNUrlConvert)converter - dns:(QNDnsManager*)dns; - -- (void) multipartPost:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withFileName:(NSString *)key - withMimeType:(NSString *)mime - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; - -- (void) post:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withHeaders:(NSDictionary *)headers - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock; + dns:(QNDnsManager *)dns; + +- (void)multipartPost:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withFileName:(NSString *)key + withMimeType:(NSString *)mime + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; + +- (void)post:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withHeaders:(NSDictionary *)headers + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock; @end diff --git a/QiniuSDK/Http/QNSessionManager.m b/QiniuSDK/Http/QNSessionManager.m index 34fbdaf0..2ac51a28 100644 --- a/QiniuSDK/Http/QNSessionManager.m +++ b/QiniuSDK/Http/QNSessionManager.m @@ -8,14 +8,14 @@ #import "AFNetworking.h" -#import "QNConfiguration.h" -#import "QNSessionManager.h" -#import "QNUserAgent.h" -#import "QNResponseInfo.h" +#import "HappyDNS.h" #import "QNAsyncRun.h" +#import "QNConfiguration.h" #import "QNDns.h" -#import "HappyDNS.h" +#import "QNResponseInfo.h" +#import "QNSessionManager.h" #import "QNSystem.h" +#import "QNUserAgent.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) @@ -28,50 +28,50 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N - (instancetype)initWithProgress:(QNInternalProgressBlock)progressBlock; @end -static NSURL *buildUrl(NSString *host, NSNumber *port, NSString *path){ - port = port == nil ?[NSNumber numberWithInt:80] : port; - NSString *p = [[NSString alloc] initWithFormat:@"http://%@:%@%@", host, port, path]; - return [[NSURL alloc] initWithString:p]; +static NSURL *buildUrl(NSString *host, NSNumber *port, NSString *path) { + port = port == nil ? [NSNumber numberWithInt:80] : port; + NSString *p = [[NSString alloc] initWithFormat:@"http://%@:%@%@", host, port, path]; + return [[NSURL alloc] initWithString:p]; } -static BOOL needRetry(NSHTTPURLResponse *httpResponse, NSError *error){ - if (error != nil) { - return error.code < -1000; - } - if (httpResponse == nil) { - return YES; - } - int status = (int)httpResponse.statusCode; - return status >= 500 && status < 600 && status != 579; +static BOOL needRetry(NSHTTPURLResponse *httpResponse, NSError *error) { + if (error != nil) { + return error.code < -1000; + } + if (httpResponse == nil) { + return YES; + } + int status = (int)httpResponse.statusCode; + return status >= 500 && status < 600 && status != 579; } @implementation QNProgessDelegate - (instancetype)initWithProgress:(QNInternalProgressBlock)progressBlock { - if (self = [super init]) { - _progressBlock = progressBlock; - _progress = nil; - } + if (self = [super init]) { + _progressBlock = progressBlock; + _progress = nil; + } - return self; + return self; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; { - if (context == nil || object == nil) { - return; - } - - NSProgress *progress = (NSProgress *)object; - - void *p = (__bridge void *)(self); - if (p == context) { - _progressBlock(progress.completedUnitCount, progress.totalUnitCount); - if (_cancelBlock && _cancelBlock()) { - [_task cancel]; - } - } - else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; +{ + if (context == nil || object == nil) { + return; + } + + NSProgress *progress = (NSProgress *)object; + + void *p = (__bridge void *)(self); + if (p == context) { + _progressBlock(progress.completedUnitCount, progress.totalUnitCount); + if (_cancelBlock && _cancelBlock()) { + [_task cancel]; + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } } @end @@ -89,27 +89,26 @@ @implementation QNSessionManager - (instancetype)initWithProxy:(NSDictionary *)proxyDict timeout:(UInt32)timeout urlConverter:(QNUrlConvert)converter - dns:(QNDnsManager*)dns{ - if (self = [super init]) { - if (proxyDict != nil) { - _noProxy = NO; - } - else { - _noProxy = YES; - } - + dns:(QNDnsManager *)dns { + if (self = [super init]) { + if (proxyDict != nil) { + _noProxy = NO; + } else { + _noProxy = YES; + } + _httpManager = [QNSessionManager httpManagerWithProxy:proxyDict]; - - _timeout = timeout; - _converter = converter; - _dns = dns; - } - return self; + _timeout = timeout; + _converter = converter; + _dns = dns; + } + + return self; } -+ (AFHTTPSessionManager*) httpManagerWithProxy:(NSDictionary *)proxyDict{ - NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; ++ (AFHTTPSessionManager *)httpManagerWithProxy:(NSDictionary *)proxyDict { + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; if (proxyDict != nil) { configuration.connectionProxyDictionary = proxyDict; } @@ -120,7 +119,7 @@ + (AFHTTPSessionManager*) httpManagerWithProxy:(NSDictionary *)proxyDict{ } - (instancetype)init { - return [self initWithProxy:nil timeout:60 urlConverter:nil dns:nil]; + return [self initWithProxy:nil timeout:60 urlConverter:nil dns:nil]; } + (QNResponseInfo *)buildResponseInfo:(NSHTTPURLResponse *)response @@ -129,184 +128,180 @@ + (QNResponseInfo *)buildResponseInfo:(NSHTTPURLResponse *)response withResponse:(NSData *)body withHost:(NSString *)host withIp:(NSString *)ip { - QNResponseInfo *info; - - if (response) { - int status = (int)[response statusCode]; - NSDictionary *headers = [response allHeaderFields]; - NSString *reqId = headers[@"X-Reqid"]; - NSString *xlog = headers[@"X-Log"]; - NSString *xvia = headers[@"X-Via"]; - if (xvia == nil) { - xvia = headers[@"X-Px"]; - } - if (xvia == nil) { - xvia = headers[@"Fw-Via"]; - } - info = [[QNResponseInfo alloc] init:status withReqId:reqId withXLog:xlog withXVia:xvia withHost:host withIp:ip withDuration:duration withBody:body]; - } - else { - info = [QNResponseInfo responseInfoWithNetError:error host:host duration:duration]; - } - return info; + QNResponseInfo *info; + + if (response) { + int status = (int)[response statusCode]; + NSDictionary *headers = [response allHeaderFields]; + NSString *reqId = headers[@"X-Reqid"]; + NSString *xlog = headers[@"X-Log"]; + NSString *xvia = headers[@"X-Via"]; + if (xvia == nil) { + xvia = headers[@"X-Px"]; + } + if (xvia == nil) { + xvia = headers[@"Fw-Via"]; + } + info = [[QNResponseInfo alloc] init:status withReqId:reqId withXLog:xlog withXVia:xvia withHost:host withIp:ip withDuration:duration withBody:body]; + } else { + info = [QNResponseInfo responseInfoWithNetError:error host:host duration:duration]; + } + return info; } -- (void) sendRequest:(NSMutableURLRequest *)request - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - __block NSDate *startTime = [NSDate date]; - - NSString *domain = request.URL.host; - - NSString *u = request.URL.absoluteString; - NSURL *url = request.URL; - NSArray *ips = nil; - if (_converter != nil) { - url = [[NSURL alloc] initWithString:_converter(u)]; - request.URL = url; - domain = url.host; - } else if (_noProxy && _dns != nil && [url.scheme isEqualToString:@"http"]) { - ips = [_dns queryWithDomain:[[QNDomain alloc] init:domain hostsFirst:NO hasCname:YES maxTtl:1000]]; - double duration = [[NSDate date] timeIntervalSinceDate:startTime]; - - if (ips == nil || ips.count == 0) { - NSError *error = [[NSError alloc] initWithDomain:domain code:-1003 userInfo:@{ @"error":@"unkonwn host" }]; - - QNResponseInfo *info = [QNResponseInfo responseInfoWithNetError:error host:domain duration:duration]; - NSLog(@"failure %@", info); - - completeBlock(info, nil); - return; - } - } - [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:0 withDomain:domain withRetryTimes:3 withStartTime:startTime]; +- (void)sendRequest:(NSMutableURLRequest *)request + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + __block NSDate *startTime = [NSDate date]; + + NSString *domain = request.URL.host; + + NSString *u = request.URL.absoluteString; + NSURL *url = request.URL; + NSArray *ips = nil; + if (_converter != nil) { + url = [[NSURL alloc] initWithString:_converter(u)]; + request.URL = url; + domain = url.host; + } else if (_noProxy && _dns != nil && [url.scheme isEqualToString:@"http"]) { + ips = [_dns queryWithDomain:[[QNDomain alloc] init:domain hostsFirst:NO hasCname:YES maxTtl:1000]]; + double duration = [[NSDate date] timeIntervalSinceDate:startTime]; + + if (ips == nil || ips.count == 0) { + NSError *error = [[NSError alloc] initWithDomain:domain code:-1003 userInfo:@{ @"error" : @"unkonwn host" }]; + + QNResponseInfo *info = [QNResponseInfo responseInfoWithNetError:error host:domain duration:duration]; + NSLog(@"failure %@", info); + + completeBlock(info, nil); + return; + } + } + [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:0 withDomain:domain withRetryTimes:3 withStartTime:startTime]; } -- (void) sendRequest2:(NSMutableURLRequest *)request - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock - withIpArray:(NSArray*)ips - withIndex:(int)index - withDomain:(NSString *)domain - withRetryTimes:(int)times - withStartTime:(NSDate *)startTime { - NSProgress *progress = nil; - NSURL *url = request.URL; - __block NSString *ip = nil; - if(ips != nil) { - ip = [ips objectAtIndex:(index%ips.count)]; - NSString *path = url.path; - if (path == nil || [@"" isEqualToString:path]) { - path = @"/"; - } - url = buildUrl(ip, url.port, path); - [request setValue:domain forHTTPHeaderField:@"Host"]; - } - - request.URL = url; - - [request setTimeoutInterval:_timeout]; - - [request setValue:[[QNUserAgent sharedInstance] description] forHTTPHeaderField:@"User-Agent"]; - [request setValue:nil forHTTPHeaderField:@"Accept-Language"]; - - if (progressBlock == nil) { - progressBlock = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { - }; - } - QNInternalProgressBlock progressBlock2 = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { - progressBlock(totalBytesWritten, totalBytesExpectedToWrite); - }; - __block QNProgessDelegate *delegate = [[QNProgessDelegate alloc] initWithProgress:progressBlock2]; - - NSURLSessionUploadTask *uploadTask = [_httpManager uploadTaskWithRequest:request fromData:nil progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { - NSData *data = responseObject; - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - double duration = [[NSDate date] timeIntervalSinceDate:startTime]; - QNResponseInfo *info; - NSDictionary *resp = nil; - if (delegate.progress != nil) { - [delegate.progress removeObserver:delegate forKeyPath:@"fractionCompleted" context:(__bridge void *)(delegate)]; - delegate.progress = nil; - } - if (_converter != nil && _noProxy && (index+1 < ips.count || times>0) && needRetry(httpResponse, error)) { - [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:index+1 withDomain:domain withRetryTimes:times -1 withStartTime:startTime]; - return; - } - if (error == nil) { - info = [QNSessionManager buildResponseInfo:httpResponse withError:nil withDuration:duration withResponse:data withHost:domain withIp:ip]; - if (info.isOK) { - NSError *tmp; - resp = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp]; - } - } - else { - info = [QNSessionManager buildResponseInfo:httpResponse withError:error withDuration:duration withResponse:data withHost:domain withIp:ip]; - } - - - - completeBlock(info, resp); - }]; - if (progress != nil) { - [progress addObserver:delegate forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:(__bridge void *)delegate]; - delegate.progress = progress; - delegate.task = uploadTask; - delegate.cancelBlock = cancelBlock; - } - - [uploadTask resume]; +- (void)sendRequest2:(NSMutableURLRequest *)request + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock + withIpArray:(NSArray *)ips + withIndex:(int)index + withDomain:(NSString *)domain + withRetryTimes:(int)times + withStartTime:(NSDate *)startTime { + NSProgress *progress = nil; + NSURL *url = request.URL; + __block NSString *ip = nil; + if (ips != nil) { + ip = [ips objectAtIndex:(index % ips.count)]; + NSString *path = url.path; + if (path == nil || [@"" isEqualToString:path]) { + path = @"/"; + } + url = buildUrl(ip, url.port, path); + [request setValue:domain forHTTPHeaderField:@"Host"]; + } + + request.URL = url; + + [request setTimeoutInterval:_timeout]; + + [request setValue:[[QNUserAgent sharedInstance] description] forHTTPHeaderField:@"User-Agent"]; + [request setValue:nil forHTTPHeaderField:@"Accept-Language"]; + + if (progressBlock == nil) { + progressBlock = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { + }; + } + QNInternalProgressBlock progressBlock2 = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { + progressBlock(totalBytesWritten, totalBytesExpectedToWrite); + }; + __block QNProgessDelegate *delegate = [[QNProgessDelegate alloc] initWithProgress:progressBlock2]; + + NSURLSessionUploadTask *uploadTask = [_httpManager uploadTaskWithRequest:request fromData:nil progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + NSData *data = responseObject; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + double duration = [[NSDate date] timeIntervalSinceDate:startTime]; + QNResponseInfo *info; + NSDictionary *resp = nil; + if (delegate.progress != nil) { + [delegate.progress removeObserver:delegate forKeyPath:@"fractionCompleted" context:(__bridge void *)(delegate)]; + delegate.progress = nil; + } + if (_converter != nil && _noProxy && (index + 1 < ips.count || times > 0) && needRetry(httpResponse, error)) { + [self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:index + 1 withDomain:domain withRetryTimes:times - 1 withStartTime:startTime]; + return; + } + if (error == nil) { + info = [QNSessionManager buildResponseInfo:httpResponse withError:nil withDuration:duration withResponse:data withHost:domain withIp:ip]; + if (info.isOK) { + NSError *tmp; + resp = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp]; + } + } else { + info = [QNSessionManager buildResponseInfo:httpResponse withError:error withDuration:duration withResponse:data withHost:domain withIp:ip]; + } + + completeBlock(info, resp); + }]; + if (progress != nil) { + [progress addObserver:delegate forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:(__bridge void *)delegate]; + delegate.progress = progress; + delegate.task = uploadTask; + delegate.cancelBlock = cancelBlock; + } + + [uploadTask resume]; } -- (void) multipartPost:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withFileName:(NSString *)key - withMimeType:(NSString *)mime - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - NSMutableURLRequest *request = [_httpManager.requestSerializer - multipartFormRequestWithMethod:@"POST" - URLString:url - parameters:params - constructingBodyWithBlock: ^(id < AFMultipartFormData > formData) { - [formData appendPartWithFileData:data name:@"file" fileName:key mimeType:mime]; - } - - error:nil]; - [self sendRequest:request - withCompleteBlock:completeBlock - withProgressBlock:progressBlock - withCancelBlock:cancelBlock]; +- (void)multipartPost:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withFileName:(NSString *)key + withMimeType:(NSString *)mime + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + NSMutableURLRequest *request = [_httpManager.requestSerializer + multipartFormRequestWithMethod:@"POST" + URLString:url + parameters:params + constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileData:data name:@"file" fileName:key mimeType:mime]; + } + + error:nil]; + [self sendRequest:request + withCompleteBlock:completeBlock + withProgressBlock:progressBlock + withCancelBlock:cancelBlock]; } -- (void) post:(NSString *)url - withData:(NSData *)data - withParams:(NSDictionary *)params - withHeaders:(NSDictionary *)headers - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock - withCancelBlock:(QNCancelBlock)cancelBlock { - NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; - if (headers) { - [request setAllHTTPHeaderFields:headers]; - } - - [request setHTTPMethod:@"POST"]; - - if (params) { - [request setValuesForKeysWithDictionary:params]; - } - [request setHTTPBody:data]; - QNAsyncRun( ^{ - [self sendRequest:request - withCompleteBlock:completeBlock - withProgressBlock:progressBlock - withCancelBlock:cancelBlock]; - }); +- (void)post:(NSString *)url + withData:(NSData *)data + withParams:(NSDictionary *)params + withHeaders:(NSDictionary *)headers + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock + withCancelBlock:(QNCancelBlock)cancelBlock { + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]]; + if (headers) { + [request setAllHTTPHeaderFields:headers]; + } + + [request setHTTPMethod:@"POST"]; + + if (params) { + [request setValuesForKeysWithDictionary:params]; + } + [request setHTTPBody:data]; + QNAsyncRun(^{ + [self sendRequest:request + withCompleteBlock:completeBlock + withProgressBlock:progressBlock + withCancelBlock:cancelBlock]; + }); } @end diff --git a/QiniuSDK/Http/QNUserAgent.m b/QiniuSDK/Http/QNUserAgent.m index f48f8289..4436324f 100644 --- a/QiniuSDK/Http/QNUserAgent.m +++ b/QiniuSDK/Http/QNUserAgent.m @@ -8,10 +8,10 @@ #import #if __IPHONE_OS_VERSION_MIN_REQUIRED - #import - #import +#import +#import #else - #import +#import #endif #import "QNUserAgent.h" @@ -19,23 +19,23 @@ static NSString *clientId(void) { #if __IPHONE_OS_VERSION_MIN_REQUIRED - NSString* s= [[[UIDevice currentDevice] identifierForVendor] UUIDString]; - if (s == nil ) { + NSString *s = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; + if (s == nil) { s = @"simulator"; } return s; #else - long long now_timestamp = [[NSDate date] timeIntervalSince1970] * 1000; - int r = arc4random() % 1000; - return [NSString stringWithFormat:@"%lld%u", now_timestamp, r]; + long long now_timestamp = [[NSDate date] timeIntervalSince1970] * 1000; + int r = arc4random() % 1000; + return [NSString stringWithFormat:@"%lld%u", now_timestamp, r]; #endif } static NSString *userAgent(NSString *id) { #if __IPHONE_OS_VERSION_MIN_REQUIRED - return [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], id]; + return [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], id]; #else - return [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], id]; + return [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], id]; #endif } @@ -46,29 +46,29 @@ @interface QNUserAgent () @implementation QNUserAgent - (NSString *)description { - return _ua; + return _ua; } - (instancetype)init { - if (self = [super init]) { - _id = clientId(); - _ua = userAgent(_id); - } - return self; + if (self = [super init]) { + _id = clientId(); + _ua = userAgent(_id); + } + return self; } /** * 单例 */ + (instancetype)sharedInstance { - static QNUserAgent *sharedInstance = nil; + static QNUserAgent *sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[self alloc] init]; - }); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); - return sharedInstance; + return sharedInstance; } @end diff --git a/QiniuSDK/QiniuSDK.h b/QiniuSDK/QiniuSDK.h index 40d80e2b..d9f2e6d9 100644 --- a/QiniuSDK/QiniuSDK.h +++ b/QiniuSDK/QiniuSDK.h @@ -8,9 +8,9 @@ #import -#import "QNUrlSafeBase64.h" +#import "QNConfiguration.h" +#import "QNFileRecorder.h" #import "QNResponseInfo.h" -#import "QNUploadOption.h" #import "QNUploadManager.h" -#import "QNFileRecorder.h" -#import "QNConfiguration.h" +#import "QNUploadOption.h" +#import "QNUrlSafeBase64.h" diff --git a/QiniuSDK/Recorder/QNFileRecorder.h b/QiniuSDK/Recorder/QNFileRecorder.h index e41a23cf..30bae0ef 100644 --- a/QiniuSDK/Recorder/QNFileRecorder.h +++ b/QiniuSDK/Recorder/QNFileRecorder.h @@ -6,8 +6,8 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import #import "QNRecorderDelegate.h" +#import /** * 将上传记录保存到文件系统中 @@ -49,5 +49,4 @@ directory:(NSString *)dir encodeKey:(BOOL)encode; - @end diff --git a/QiniuSDK/Recorder/QNFileRecorder.m b/QiniuSDK/Recorder/QNFileRecorder.m index e38562fb..09ffb67c 100644 --- a/QiniuSDK/Recorder/QNFileRecorder.m +++ b/QiniuSDK/Recorder/QNFileRecorder.m @@ -9,7 +9,7 @@ #import "QNFileRecorder.h" #import "QNUrlSafeBase64.h" -@interface QNFileRecorder () +@interface QNFileRecorder () @property (copy, readonly) NSString *directory; @property BOOL encode; @@ -19,81 +19,81 @@ @interface QNFileRecorder () @implementation QNFileRecorder - (NSString *)pathOfKey:(NSString *)key { - return [QNFileRecorder pathJoin:key path:_directory]; + return [QNFileRecorder pathJoin:key path:_directory]; } + (NSString *)pathJoin:(NSString *)key path:(NSString *)path { - return [[NSString alloc] initWithFormat:@"%@/%@", path, key]; + return [[NSString alloc] initWithFormat:@"%@/%@", path, key]; } + (instancetype)fileRecorderWithFolder:(NSString *)directory error:(NSError *__autoreleasing *)perror { - return [QNFileRecorder fileRecorderWithFolder:directory encodeKey:false error:perror]; + return [QNFileRecorder fileRecorderWithFolder:directory encodeKey:false error:perror]; } + (instancetype)fileRecorderWithFolder:(NSString *)directory encodeKey:(BOOL)encode error:(NSError *__autoreleasing *)perror { - NSError *error; - [[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]; - if (error != nil) { - if (perror) { - *perror = error; - } - return nil; - } - - return [[QNFileRecorder alloc] initWithFolder:directory encodeKey:encode]; + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]; + if (error != nil) { + if (perror) { + *perror = error; + } + return nil; + } + + return [[QNFileRecorder alloc] initWithFolder:directory encodeKey:encode]; } - (instancetype)initWithFolder:(NSString *)directory encodeKey:(BOOL)encode { - if (self = [super init]) { - _directory = directory; - _encode = encode; - } - return self; + if (self = [super init]) { + _directory = directory; + _encode = encode; + } + return self; } - (NSError *)set:(NSString *)key data:(NSData *)value { - NSError *error; - if (_encode) { - key = [QNUrlSafeBase64 encodeString:key]; - } - [value writeToFile:[self pathOfKey:key] options:NSDataWritingAtomic error:&error]; - return error; + NSError *error; + if (_encode) { + key = [QNUrlSafeBase64 encodeString:key]; + } + [value writeToFile:[self pathOfKey:key] options:NSDataWritingAtomic error:&error]; + return error; } - (NSData *)get:(NSString *)key { - if (_encode) { - key = [QNUrlSafeBase64 encodeString:key]; - } - return [NSData dataWithContentsOfFile:[self pathOfKey:key]]; + if (_encode) { + key = [QNUrlSafeBase64 encodeString:key]; + } + return [NSData dataWithContentsOfFile:[self pathOfKey:key]]; } - (NSError *)del:(NSString *)key { - NSError *error; - if (_encode) { - key = [QNUrlSafeBase64 encodeString:key]; - } - [[NSFileManager defaultManager] removeItemAtPath:[self pathOfKey:key] error:&error]; - return error; + NSError *error; + if (_encode) { + key = [QNUrlSafeBase64 encodeString:key]; + } + [[NSFileManager defaultManager] removeItemAtPath:[self pathOfKey:key] error:&error]; + return error; } + (void)removeKey:(NSString *)key directory:(NSString *)dir encodeKey:(BOOL)encode { - if (encode) { - key = [QNUrlSafeBase64 encodeString:key]; - } - NSError *error; - NSString *path = [QNFileRecorder pathJoin:key path:dir]; - [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; + if (encode) { + key = [QNUrlSafeBase64 encodeString:key]; + } + NSError *error; + NSString *path = [QNFileRecorder pathJoin:key path:dir]; + [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; } - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p, dir: %@>", NSStringFromClass([self class]), self, _directory]; + return [NSString stringWithFormat:@"<%@: %p, dir: %@>", NSStringFromClass([self class]), self, _directory]; } @end diff --git a/QiniuSDK/Recorder/QNRecorderDelegate.h b/QiniuSDK/Recorder/QNRecorderDelegate.h index 4c9c14f4..b308730a 100644 --- a/QiniuSDK/Recorder/QNRecorderDelegate.h +++ b/QiniuSDK/Recorder/QNRecorderDelegate.h @@ -16,8 +16,7 @@ * * @return 根据uploadKey, filepath 算出的记录key */ -typedef NSString *(^QNRecorderKeyGenerator)(NSString *uploadKey, NSString *filePath); - +typedef NSString * (^QNRecorderKeyGenerator)(NSString *uploadKey, NSString *filePath); /** * 持久化记录接口,可以实现将记录持久化到文件,数据库等 diff --git a/QiniuSDK/Storage/QNConfiguration.h b/QiniuSDK/Storage/QNConfiguration.h index 238c2307..1278b133 100644 --- a/QiniuSDK/Storage/QNConfiguration.h +++ b/QiniuSDK/Storage/QNConfiguration.h @@ -22,7 +22,7 @@ extern const UInt32 kQNBlockSize; * * @return 根据上传url算出代理url */ -typedef NSString *(^QNUrlConvert)(NSString *url); +typedef NSString * (^QNUrlConvert)(NSString *url); @class QNConfigurationBuilder; @class QNDnsManager; @@ -34,7 +34,6 @@ typedef NSString *(^QNUrlConvert)(NSString *url); */ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); - @interface QNConfiguration : NSObject /** @@ -67,11 +66,11 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); */ @property (readonly) UInt32 timeoutInterval; -@property (nonatomic, readonly) id recorder; +@property (nonatomic, readonly) id recorder; @property (nonatomic, readonly) QNRecorderKeyGenerator recorderKeyGen; -@property (nonatomic, readonly) NSDictionary *proxy; +@property (nonatomic, readonly) NSDictionary *proxy; @property (nonatomic, readonly) QNUrlConvert converter; @@ -88,10 +87,10 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); */ @interface QNServiceAddress : NSObject -- (instancetype) init:(NSString*)address ips:(NSArray*)ips; +- (instancetype)init:(NSString *)address ips:(NSArray *)ips; -@property (nonatomic, readonly) NSString* address; -@property (nonatomic, readonly) NSArray* ips; +@property (nonatomic, readonly) NSString *address; +@property (nonatomic, readonly) NSArray *ips; @end @@ -107,7 +106,6 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); */ @property (nonatomic, readonly) QNServiceAddress *upBackup; - /** * Zone初始化方法 * @@ -136,7 +134,6 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); @end - @interface QNConfigurationBuilder : NSObject /** @@ -164,11 +161,11 @@ typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder); */ @property (assign) UInt32 timeoutInterval; -@property (nonatomic, strong) id recorder; +@property (nonatomic, strong) id recorder; @property (nonatomic, strong) QNRecorderKeyGenerator recorderKeyGen; -@property (nonatomic, strong) NSDictionary *proxy; +@property (nonatomic, strong) NSDictionary *proxy; @property (nonatomic, strong) QNUrlConvert converter; diff --git a/QiniuSDK/Storage/QNConfiguration.m b/QiniuSDK/Storage/QNConfiguration.m index abd730ba..2b3449c7 100644 --- a/QiniuSDK/Storage/QNConfiguration.m +++ b/QiniuSDK/Storage/QNConfiguration.m @@ -7,79 +7,79 @@ // #import "QNConfiguration.h" -#import "QNNetworkInfo.h" #import "HappyDNS.h" +#import "QNNetworkInfo.h" #import "QNSystem.h" const UInt32 kQNBlockSize = 4 * 1024 * 1024; -static void addServiceToDns(QNServiceAddress* address, QNDnsManager *dns) { - NSArray *ips = address.ips; - if (ips == nil) { - return; - } - NSURL *u = [[NSURL alloc] initWithString:address.address]; - NSString *host = u.host; - for (int i = 0; i r1 = [QNResolver systemResolver]; - id r2 = [[QNResolver alloc] initWithAddres:@"119.29.29.29"]; - id r3 = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; - d = [[QNDnsManager alloc] init:[NSArray arrayWithObjects:r1,r2, r3, nil] networkInfo:[QNNetworkInfo normal ]]; - } - return d; +static QNDnsManager *initDns(QNConfigurationBuilder *builder) { + QNDnsManager *d = builder.dns; + if (d == nil) { + id r1 = [QNResolver systemResolver]; + id r2 = [[QNResolver alloc] initWithAddres:@"119.29.29.29"]; + id r3 = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; + d = [[QNDnsManager alloc] init:[NSArray arrayWithObjects:r1, r2, r3, nil] networkInfo:[QNNetworkInfo normal]]; + } + return d; } @implementation QNConfiguration + (instancetype)build:(QNConfigurationBuilderBlock)block { - QNConfigurationBuilder *builder = [[QNConfigurationBuilder alloc] init]; - block(builder); - return [[QNConfiguration alloc] initWithBuilder:builder]; + QNConfigurationBuilder *builder = [[QNConfigurationBuilder alloc] init]; + block(builder); + return [[QNConfiguration alloc] initWithBuilder:builder]; } - (instancetype)initWithBuilder:(QNConfigurationBuilder *)builder { - if (self = [super init]) { - _up = builder.zone.up; - _upBackup = builder.zone.upBackup == nil ? builder.zone.up : builder.zone.upBackup; + if (self = [super init]) { + _up = builder.zone.up; + _upBackup = builder.zone.upBackup == nil ? builder.zone.up : builder.zone.upBackup; - _chunkSize = builder.chunkSize; - _putThreshold = builder.putThreshold; - _retryMax = builder.retryMax; - _timeoutInterval = builder.timeoutInterval; + _chunkSize = builder.chunkSize; + _putThreshold = builder.putThreshold; + _retryMax = builder.retryMax; + _timeoutInterval = builder.timeoutInterval; - _recorder = builder.recorder; - _recorderKeyGen = builder.recorderKeyGen; + _recorder = builder.recorder; + _recorderKeyGen = builder.recorderKeyGen; - _proxy = builder.proxy; + _proxy = builder.proxy; + + _converter = builder.converter; - _converter = builder.converter; - _disableATS = builder.disableATS; - if (_disableATS) { - _dns = initDns(builder); - addZoneToDns(builder.zone, _dns); - }else{ - _dns = nil; - } - } - return self; + if (_disableATS) { + _dns = initDns(builder); + addZoneToDns(builder.zone, _dns); + } else { + _dns = nil; + } + } + return self; } @end @@ -87,39 +87,38 @@ - (instancetype)initWithBuilder:(QNConfigurationBuilder *)builder { @implementation QNConfigurationBuilder - (instancetype)init { - if (self = [super init]) { - _zone = [QNZone zone0]; - _chunkSize = 256 * 1024; - _putThreshold = 512 * 1024; - _retryMax = 2; - _timeoutInterval = 60; - - _recorder = nil; - _recorderKeyGen = nil; - - _proxy = nil; - _converter = nil; - + if (self = [super init]) { + _zone = [QNZone zone0]; + _chunkSize = 256 * 1024; + _putThreshold = 512 * 1024; + _retryMax = 2; + _timeoutInterval = 60; + + _recorder = nil; + _recorderKeyGen = nil; + + _proxy = nil; + _converter = nil; + if (hasAts() && !allowsArbitraryLoads()) { _disableATS = NO; - }else{ + } else { _disableATS = YES; } - } - return self; + } + return self; } @end @implementation QNServiceAddress : NSObject -- (instancetype) init:(NSString*)address ips:(NSArray*)ips { - if (self = [super init]) { - _address = address; - _ips = ips; - - } - return self; +- (instancetype)init:(NSString *)address ips:(NSArray *)ips { + if (self = [super init]) { + _address = address; + _ips = ips; + } + return self; } @end @@ -128,39 +127,39 @@ @implementation QNZone - (instancetype)initWithUp:(QNServiceAddress *)up upBackup:(QNServiceAddress *)upBackup { - if (self = [super init]) { - _up = up; - _upBackup = upBackup; - } + if (self = [super init]) { + _up = up; + _upBackup = upBackup; + } - return self; + return self; } -+ (instancetype)createWithHost:(NSString*)up backupHost:(NSString*)backup ip1:(NSString*)ip1 ip2:(NSString*)ip2 { - NSArray* ips = [NSArray arrayWithObjects:ip1,ip2, nil]; - NSString* a = [NSString stringWithFormat:@"http://%@", up]; - QNServiceAddress *s1 = [[QNServiceAddress alloc] init:a ips:ips]; - NSString* b = [NSString stringWithFormat:@"http://%@", backup]; - QNServiceAddress *s2 = [[QNServiceAddress alloc] init:b ips:ips]; - return [[QNZone alloc] initWithUp:s1 upBackup:s2]; ++ (instancetype)createWithHost:(NSString *)up backupHost:(NSString *)backup ip1:(NSString *)ip1 ip2:(NSString *)ip2 { + NSArray *ips = [NSArray arrayWithObjects:ip1, ip2, nil]; + NSString *a = [NSString stringWithFormat:@"http://%@", up]; + QNServiceAddress *s1 = [[QNServiceAddress alloc] init:a ips:ips]; + NSString *b = [NSString stringWithFormat:@"http://%@", backup]; + QNServiceAddress *s2 = [[QNServiceAddress alloc] init:b ips:ips]; + return [[QNZone alloc] initWithUp:s1 upBackup:s2]; } + (instancetype)zone0 { - static QNZone *z0 = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - z0 = [QNZone createWithHost:@"upload.qiniu.com" backupHost:@"up.qiniu.com" ip1:@"183.136.139.10" ip2:@"115.231.182.136"]; - }); - return z0; + static QNZone *z0 = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + z0 = [QNZone createWithHost:@"upload.qiniu.com" backupHost:@"up.qiniu.com" ip1:@"183.136.139.10" ip2:@"115.231.182.136"]; + }); + return z0; } + (instancetype)zone1 { - static QNZone *z1 = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - z1 = [QNZone createWithHost:@"upload-z1.qiniu.com" backupHost:@"up-z1.qiniu.com" ip1:@"106.38.227.28" ip2:@"106.38.227.27"]; - }); - return z1; + static QNZone *z1 = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + z1 = [QNZone createWithHost:@"upload-z1.qiniu.com" backupHost:@"up-z1.qiniu.com" ip1:@"106.38.227.28" ip2:@"106.38.227.27"]; + }); + return z1; } @end diff --git a/QiniuSDK/Storage/QNFormUpload.h b/QiniuSDK/Storage/QNFormUpload.h index 3959c1ef..be302371 100644 --- a/QiniuSDK/Storage/QNFormUpload.h +++ b/QiniuSDK/Storage/QNFormUpload.h @@ -6,23 +6,22 @@ // Copyright (c) 2015年 Qiniu. All rights reserved. // -#import -#import "QNUploadManager.h" #import "QNHttpDelegate.h" #import "QNUpToken.h" +#import "QNUploadManager.h" +#import @class QNHttpManager; @interface QNFormUpload : NSObject -- (instancetype) initWithData:(NSData *)data - withKey:(NSString *)key - withToken:(QNUpToken *)token - withCompletionHandler:(QNUpCompletionHandler)block - withOption:(QNUploadOption *)option - withHttpManager:(id )http - withConfiguration:(QNConfiguration *)config; +- (instancetype)initWithData:(NSData *)data + withKey:(NSString *)key + withToken:(QNUpToken *)token + withCompletionHandler:(QNUpCompletionHandler)block + withOption:(QNUploadOption *)option + withHttpManager:(id)http + withConfiguration:(QNConfiguration *)config; - (void)put; - @end diff --git a/QiniuSDK/Storage/QNFormUpload.m b/QiniuSDK/Storage/QNFormUpload.m index c761227f..173b9356 100644 --- a/QiniuSDK/Storage/QNFormUpload.m +++ b/QiniuSDK/Storage/QNFormUpload.m @@ -7,19 +7,19 @@ // #import "QNFormUpload.h" -#import "QNUploadManager.h" -#import "QNUrlSafeBase64.h" #import "QNConfiguration.h" -#import "QNResponseInfo.h" +#import "QNCrc32.h" #import "QNHttpManager.h" -#import "QNUploadOption+Private.h" #import "QNRecorderDelegate.h" -#import "QNCrc32.h" +#import "QNResponseInfo.h" +#import "QNUploadManager.h" +#import "QNUploadOption+Private.h" +#import "QNUrlSafeBase64.h" @interface QNFormUpload () @property (nonatomic, strong) NSData *data; -@property (nonatomic, strong) id httpManager; +@property (nonatomic, strong) id httpManager; @property (nonatomic) int retryTimes; @property (nonatomic, strong) NSString *key; @property (nonatomic, strong) QNUpToken *token; @@ -31,95 +31,92 @@ @interface QNFormUpload () @implementation QNFormUpload -- (instancetype) initWithData:(NSData *)data - withKey:(NSString *)key - withToken:(QNUpToken *)token - withCompletionHandler:(QNUpCompletionHandler)block - withOption:(QNUploadOption *)option - withHttpManager:(id )http - withConfiguration:(QNConfiguration *)config { - if (self = [super init]) { - _data = data; - _key = key; - _token = token; - _option = option != nil ? option :[QNUploadOption defaultOptions]; - _complete = block; - _httpManager = http; - _config = config; - } - return self; +- (instancetype)initWithData:(NSData *)data + withKey:(NSString *)key + withToken:(QNUpToken *)token + withCompletionHandler:(QNUpCompletionHandler)block + withOption:(QNUploadOption *)option + withHttpManager:(id)http + withConfiguration:(QNConfiguration *)config { + if (self = [super init]) { + _data = data; + _key = key; + _token = token; + _option = option != nil ? option : [QNUploadOption defaultOptions]; + _complete = block; + _httpManager = http; + _config = config; + } + return self; } - (void)put { - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - NSString *fileName = _key; - if (_key) { - parameters[@"key"] = _key; - } - else { - fileName = @"?"; - } - - parameters[@"token"] = _token.token; - - [parameters addEntriesFromDictionary:_option.params]; - - if (_option.checkCrc) { - parameters[@"crc32"] = [NSString stringWithFormat:@"%u", (unsigned int)[QNCrc32 data:_data]]; - } - - QNInternalProgressBlock p = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { - float percent = (float)totalBytesWritten / (float)totalBytesExpectedToWrite; - if (percent > 0.95) { - percent = 0.95; - } - _option.progressHandler(_key, percent); - }; - - - QNCompleteBlock complete = ^(QNResponseInfo *info, NSDictionary *resp) - { - if (info.isOK) { - _option.progressHandler(_key, 1.0); - } - if (info.isOK || !info.couldRetry) { - _complete(info, _key, resp); - return; - } - if (_option.cancellationSignal()) { - _complete([QNResponseInfo cancel], _key, nil); - return; - } - NSString *nextHost = _config.up.address; - if (info.isConnectionBroken || info.needSwitchServer) { - nextHost = _config.upBackup.address; - } - - QNCompleteBlock retriedComplete = ^(QNResponseInfo *info, NSDictionary *resp) { - if (info.isOK) { - _option.progressHandler(_key, 1.0); - } - _complete(info, _key, resp); - }; - - [_httpManager multipartPost:nextHost - withData:_data - withParams:parameters - withFileName:fileName - withMimeType:_option.mimeType - withCompleteBlock:retriedComplete - withProgressBlock:p - withCancelBlock:_option.cancellationSignal]; - }; - - [_httpManager multipartPost:_config.up.address - withData:_data - withParams:parameters - withFileName:fileName - withMimeType:_option.mimeType - withCompleteBlock:complete - withProgressBlock:p - withCancelBlock:_option.cancellationSignal]; + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + NSString *fileName = _key; + if (_key) { + parameters[@"key"] = _key; + } else { + fileName = @"?"; + } + + parameters[@"token"] = _token.token; + + [parameters addEntriesFromDictionary:_option.params]; + + if (_option.checkCrc) { + parameters[@"crc32"] = [NSString stringWithFormat:@"%u", (unsigned int)[QNCrc32 data:_data]]; + } + + QNInternalProgressBlock p = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { + float percent = (float)totalBytesWritten / (float)totalBytesExpectedToWrite; + if (percent > 0.95) { + percent = 0.95; + } + _option.progressHandler(_key, percent); + }; + + QNCompleteBlock complete = ^(QNResponseInfo *info, NSDictionary *resp) { + if (info.isOK) { + _option.progressHandler(_key, 1.0); + } + if (info.isOK || !info.couldRetry) { + _complete(info, _key, resp); + return; + } + if (_option.cancellationSignal()) { + _complete([QNResponseInfo cancel], _key, nil); + return; + } + NSString *nextHost = _config.up.address; + if (info.isConnectionBroken || info.needSwitchServer) { + nextHost = _config.upBackup.address; + } + + QNCompleteBlock retriedComplete = ^(QNResponseInfo *info, NSDictionary *resp) { + if (info.isOK) { + _option.progressHandler(_key, 1.0); + } + _complete(info, _key, resp); + }; + + [_httpManager multipartPost:nextHost + withData:_data + withParams:parameters + withFileName:fileName + withMimeType:_option.mimeType + withCompleteBlock:retriedComplete + withProgressBlock:p + withCancelBlock:_option.cancellationSignal]; + }; + + [_httpManager multipartPost:_config.up.address + withData:_data + withParams:parameters + withFileName:fileName + withMimeType:_option.mimeType + withCompleteBlock:complete + withProgressBlock:p + withCancelBlock:_option.cancellationSignal]; } @end diff --git a/QiniuSDK/Storage/QNResumeUpload.h b/QiniuSDK/Storage/QNResumeUpload.h index 18393eac..8ee83bcc 100644 --- a/QiniuSDK/Storage/QNResumeUpload.h +++ b/QiniuSDK/Storage/QNResumeUpload.h @@ -6,24 +6,24 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import -#import "QNUploadManager.h" +#import "QNFileDelegate.h" #import "QNHttpDelegate.h" #import "QNUpToken.h" -#import "QNFileDelegate.h" +#import "QNUploadManager.h" +#import @class QNHttpManager; @interface QNResumeUpload : NSObject -- (instancetype) initWithFile:(id )file - withKey:(NSString *)key - withToken:(QNUpToken *)token - withCompletionHandler:(QNUpCompletionHandler)block - withOption:(QNUploadOption *)option - withRecorder:(id )recorder - withRecorderKey:(NSString *)recorderKey - withHttpManager:(id )http - withConfiguration:(QNConfiguration *)config; +- (instancetype)initWithFile:(id)file + withKey:(NSString *)key + withToken:(QNUpToken *)token + withCompletionHandler:(QNUpCompletionHandler)block + withOption:(QNUploadOption *)option + withRecorder:(id)recorder + withRecorderKey:(NSString *)recorderKey + withHttpManager:(id)http + withConfiguration:(QNConfiguration *)config; - (void)run; diff --git a/QiniuSDK/Storage/QNResumeUpload.m b/QiniuSDK/Storage/QNResumeUpload.m index 303092f7..110b5871 100644 --- a/QiniuSDK/Storage/QNResumeUpload.m +++ b/QiniuSDK/Storage/QNResumeUpload.m @@ -7,20 +7,20 @@ // #import "QNResumeUpload.h" -#import "QNUploadManager.h" -#import "QNUrlSafeBase64.h" #import "QNConfiguration.h" -#import "QNResponseInfo.h" +#import "QNCrc32.h" #import "QNHttpManager.h" -#import "QNUploadOption+Private.h" #import "QNRecorderDelegate.h" -#import "QNCrc32.h" +#import "QNResponseInfo.h" +#import "QNUploadManager.h" +#import "QNUploadOption+Private.h" +#import "QNUrlSafeBase64.h" typedef void (^task)(void); @interface QNResumeUpload () -@property (nonatomic, strong) id httpManager; +@property (nonatomic, strong) id httpManager; @property UInt32 size; @property (nonatomic) int retryTimes; @property (nonatomic, strong) NSString *key; @@ -32,13 +32,13 @@ @interface QNResumeUpload () @property (nonatomic, strong) NSMutableArray *contexts; @property int64_t modifyTime; -@property (nonatomic, strong) id recorder; +@property (nonatomic, strong) id recorder; @property (nonatomic, strong) QNConfiguration *config; @property UInt32 chunkCrc; -@property (nonatomic, strong) id file; +@property (nonatomic, strong) id file; @property (nonatomic, strong) NSArray *fileAry; @@ -63,34 +63,34 @@ - (void)makeFile:(NSString *)uphost @implementation QNResumeUpload -- (instancetype) initWithFile:(id )file - withKey:(NSString *)key - withToken:(QNUpToken *)token - withCompletionHandler:(QNUpCompletionHandler)block - withOption:(QNUploadOption *)option - withRecorder:(id )recorder - withRecorderKey:(NSString *)recorderKey - withHttpManager:(id )http - withConfiguration:(QNConfiguration *)config; +- (instancetype)initWithFile:(id)file + withKey:(NSString *)key + withToken:(QNUpToken *)token + withCompletionHandler:(QNUpCompletionHandler)block + withOption:(QNUploadOption *)option + withRecorder:(id)recorder + withRecorderKey:(NSString *)recorderKey + withHttpManager:(id)http + withConfiguration:(QNConfiguration *)config; { - if (self = [super init]) { - _file = file; - _size = (UInt32)[file size]; - _key = key; - NSString *tokenUp = [NSString stringWithFormat:@"UpToken %@", token.token]; - _option = option != nil ? option :[QNUploadOption defaultOptions]; - _complete = block; - _headers = @{ @"Authorization":tokenUp, @"Content-Type":@"application/octet-stream" }; - _recorder = recorder; - _httpManager = http; - _modifyTime = [file modifyTime]; - _recorderKey = recorderKey; - _contexts = [[NSMutableArray alloc] initWithCapacity:(_size + kQNBlockSize - 1) / kQNBlockSize]; - _config = config; - - _token = token; - } - return self; + if (self = [super init]) { + _file = file; + _size = (UInt32)[file size]; + _key = key; + NSString *tokenUp = [NSString stringWithFormat:@"UpToken %@", token.token]; + _option = option != nil ? option : [QNUploadOption defaultOptions]; + _complete = block; + _headers = @{@"Authorization" : tokenUp, @"Content-Type" : @"application/octet-stream"}; + _recorder = recorder; + _httpManager = http; + _modifyTime = [file modifyTime]; + _recorderKey = recorderKey; + _contexts = [[NSMutableArray alloc] initWithCapacity:(_size + kQNBlockSize - 1) / kQNBlockSize]; + _config = config; + + _token = token; + } + return self; } // save json value @@ -102,157 +102,156 @@ - (instancetype) initWithFile:(id )file //} - (void)record:(UInt32)offset { - NSString *key = self.recorderKey; - if (offset == 0 || _recorder == nil || key == nil || [key isEqualToString:@""]) { - return; - } - NSNumber *n_size = @(self.size); - NSNumber *n_offset = @(offset); - NSNumber *n_time = [NSNumber numberWithLongLong:_modifyTime]; - NSMutableDictionary *rec = [NSMutableDictionary dictionaryWithObjectsAndKeys:n_size, @"size", n_offset, @"offset", n_time, @"modify_time", _contexts, @"contexts", nil]; - - NSError *error; - NSData *data = [NSJSONSerialization dataWithJSONObject:rec options:NSJSONWritingPrettyPrinted error:&error]; - if (error != nil) { - NSLog(@"up record json error %@ %@", key, error); - return; - } - error = [_recorder set:key data:data]; - if (error != nil) { - NSLog(@"up record set error %@ %@", key, error); - } + NSString *key = self.recorderKey; + if (offset == 0 || _recorder == nil || key == nil || [key isEqualToString:@""]) { + return; + } + NSNumber *n_size = @(self.size); + NSNumber *n_offset = @(offset); + NSNumber *n_time = [NSNumber numberWithLongLong:_modifyTime]; + NSMutableDictionary *rec = [NSMutableDictionary dictionaryWithObjectsAndKeys:n_size, @"size", n_offset, @"offset", n_time, @"modify_time", _contexts, @"contexts", nil]; + + NSError *error; + NSData *data = [NSJSONSerialization dataWithJSONObject:rec options:NSJSONWritingPrettyPrinted error:&error]; + if (error != nil) { + NSLog(@"up record json error %@ %@", key, error); + return; + } + error = [_recorder set:key data:data]; + if (error != nil) { + NSLog(@"up record set error %@ %@", key, error); + } } - (void)removeRecord { - if (_recorder == nil) { - return; - } - [_recorder del:self.recorderKey]; + if (_recorder == nil) { + return; + } + [_recorder del:self.recorderKey]; } - (UInt32)recoveryFromRecord { - NSString *key = self.recorderKey; - if (_recorder == nil || key == nil || [key isEqualToString:@""]) { - return 0; - } - - NSData *data = [_recorder get:key]; - if (data == nil) { - return 0; - } - - NSError *error; - NSDictionary *info = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; - if (error != nil) { - NSLog(@"recovery error %@ %@", key, error); - [_recorder del:self.key]; - return 0; - } - NSNumber *n_offset = info[@"offset"]; - NSNumber *n_size = info[@"size"]; - NSNumber *time = info[@"modify_time"]; - NSArray *contexts = info[@"contexts"]; - if (n_offset == nil || n_size == nil || time == nil || contexts == nil) { - return 0; - } - - UInt32 offset = [n_offset unsignedIntValue]; - UInt32 size = [n_size unsignedIntValue]; - if (offset > size || size != self.size) { - return 0; - } - UInt64 t = [time unsignedLongLongValue]; - if (t != _modifyTime) { - NSLog(@"modify time changed %llu, %llu", t, _modifyTime); - return 0; - } - _contexts = [[NSMutableArray alloc] initWithArray:contexts copyItems:true]; - return offset; + NSString *key = self.recorderKey; + if (_recorder == nil || key == nil || [key isEqualToString:@""]) { + return 0; + } + + NSData *data = [_recorder get:key]; + if (data == nil) { + return 0; + } + + NSError *error; + NSDictionary *info = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; + if (error != nil) { + NSLog(@"recovery error %@ %@", key, error); + [_recorder del:self.key]; + return 0; + } + NSNumber *n_offset = info[@"offset"]; + NSNumber *n_size = info[@"size"]; + NSNumber *time = info[@"modify_time"]; + NSArray *contexts = info[@"contexts"]; + if (n_offset == nil || n_size == nil || time == nil || contexts == nil) { + return 0; + } + + UInt32 offset = [n_offset unsignedIntValue]; + UInt32 size = [n_size unsignedIntValue]; + if (offset > size || size != self.size) { + return 0; + } + UInt64 t = [time unsignedLongLongValue]; + if (t != _modifyTime) { + NSLog(@"modify time changed %llu, %llu", t, _modifyTime); + return 0; + } + _contexts = [[NSMutableArray alloc] initWithArray:contexts copyItems:true]; + return offset; } - (void)nextTask:(UInt32)offset retriedTimes:(int)retried host:(NSString *)host { - if (self.option.cancellationSignal()) { - self.complete([QNResponseInfo cancel], self.key, nil); - return; - } - - if (offset == self.size) { - QNCompleteBlock completionHandler = ^(QNResponseInfo *info, NSDictionary *resp) { - if (info.isOK) { - [self removeRecord]; - self.option.progressHandler(self.key, 1.0); - } - else if (info.couldRetry && retried < _config.retryMax) { - [self nextTask:offset retriedTimes:retried + 1 host:host]; - return; - } - self.complete(info, self.key, resp); - }; - [self makeFile:host complete:completionHandler]; - return; - } - - UInt32 chunkSize = [self calcPutSize:offset]; - QNInternalProgressBlock progressBlock = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { - float percent = (float)(offset + totalBytesWritten) / (float)self.size; - if (percent > 0.95) { - percent = 0.95; - } - self.option.progressHandler(self.key, percent); - }; - - QNCompleteBlock completionHandler = ^(QNResponseInfo *info, NSDictionary *resp) { - if (info.error != nil) { - if (info.statusCode == 701) { - [self nextTask:(offset / kQNBlockSize) * kQNBlockSize retriedTimes:0 host:host]; - return; - } - if (retried >= _config.retryMax || !info.couldRetry) { - self.complete(info, self.key, resp); - return; - } - - NSString *nextHost = host; - if (info.isConnectionBroken || info.needSwitchServer) { - nextHost = _config.upBackup.address; - } - - [self nextTask:offset retriedTimes:retried + 1 host:nextHost]; - return; - } - - if (resp == nil) { - [self nextTask:offset retriedTimes:retried host:host]; - return; - } - - NSString *ctx = resp[@"ctx"]; - NSNumber *crc = resp[@"crc32"]; - if (ctx == nil || crc == nil || [crc unsignedLongValue] != _chunkCrc) { - [self nextTask:offset retriedTimes:retried host:host]; - return; - } - _contexts[offset / kQNBlockSize] = ctx; - [self record:offset + chunkSize]; - [self nextTask:offset + chunkSize retriedTimes:retried host:host]; - }; - if (offset % kQNBlockSize == 0) { - UInt32 blockSize = [self calcBlockSize:offset]; - [self makeBlock:host offset:offset blockSize:blockSize chunkSize:chunkSize progress:progressBlock complete:completionHandler]; - return; - } - NSString *context = _contexts[offset / kQNBlockSize]; - [self putChunk:host offset:offset size:chunkSize context:context progress:progressBlock complete:completionHandler]; + if (self.option.cancellationSignal()) { + self.complete([QNResponseInfo cancel], self.key, nil); + return; + } + + if (offset == self.size) { + QNCompleteBlock completionHandler = ^(QNResponseInfo *info, NSDictionary *resp) { + if (info.isOK) { + [self removeRecord]; + self.option.progressHandler(self.key, 1.0); + } else if (info.couldRetry && retried < _config.retryMax) { + [self nextTask:offset retriedTimes:retried + 1 host:host]; + return; + } + self.complete(info, self.key, resp); + }; + [self makeFile:host complete:completionHandler]; + return; + } + + UInt32 chunkSize = [self calcPutSize:offset]; + QNInternalProgressBlock progressBlock = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) { + float percent = (float)(offset + totalBytesWritten) / (float)self.size; + if (percent > 0.95) { + percent = 0.95; + } + self.option.progressHandler(self.key, percent); + }; + + QNCompleteBlock completionHandler = ^(QNResponseInfo *info, NSDictionary *resp) { + if (info.error != nil) { + if (info.statusCode == 701) { + [self nextTask:(offset / kQNBlockSize) * kQNBlockSize retriedTimes:0 host:host]; + return; + } + if (retried >= _config.retryMax || !info.couldRetry) { + self.complete(info, self.key, resp); + return; + } + + NSString *nextHost = host; + if (info.isConnectionBroken || info.needSwitchServer) { + nextHost = _config.upBackup.address; + } + + [self nextTask:offset retriedTimes:retried + 1 host:nextHost]; + return; + } + + if (resp == nil) { + [self nextTask:offset retriedTimes:retried host:host]; + return; + } + + NSString *ctx = resp[@"ctx"]; + NSNumber *crc = resp[@"crc32"]; + if (ctx == nil || crc == nil || [crc unsignedLongValue] != _chunkCrc) { + [self nextTask:offset retriedTimes:retried host:host]; + return; + } + _contexts[offset / kQNBlockSize] = ctx; + [self record:offset + chunkSize]; + [self nextTask:offset + chunkSize retriedTimes:retried host:host]; + }; + if (offset % kQNBlockSize == 0) { + UInt32 blockSize = [self calcBlockSize:offset]; + [self makeBlock:host offset:offset blockSize:blockSize chunkSize:chunkSize progress:progressBlock complete:completionHandler]; + return; + } + NSString *context = _contexts[offset / kQNBlockSize]; + [self putChunk:host offset:offset size:chunkSize context:context progress:progressBlock complete:completionHandler]; } - (UInt32)calcPutSize:(UInt32)offset { - UInt32 left = self.size - offset; - return left < _config.chunkSize ? left : _config.chunkSize; + UInt32 left = self.size - offset; + return left < _config.chunkSize ? left : _config.chunkSize; } - (UInt32)calcBlockSize:(UInt32)offset { - UInt32 left = self.size - offset; - return left < kQNBlockSize ? left : kQNBlockSize; + UInt32 left = self.size - offset; + return left < kQNBlockSize ? left : kQNBlockSize; } - (void)makeBlock:(NSString *)uphost @@ -261,10 +260,10 @@ - (void)makeBlock:(NSString *)uphost chunkSize:(UInt32)chunkSize progress:(QNInternalProgressBlock)progressBlock complete:(QNCompleteBlock)complete { - NSData *data = [self.file read:offset size:chunkSize]; - NSString *url = [[NSString alloc] initWithFormat:@"%@/mkblk/%u", uphost, (unsigned int)blockSize]; - _chunkCrc = [QNCrc32 data:data]; - [self post:url withData:data withCompleteBlock:complete withProgressBlock:progressBlock]; + NSData *data = [self.file read:offset size:chunkSize]; + NSString *url = [[NSString alloc] initWithFormat:@"%@/mkblk/%u", uphost, (unsigned int)blockSize]; + _chunkCrc = [QNCrc32 data:data]; + [self post:url withData:data withCompleteBlock:complete withProgressBlock:progressBlock]; } - (void)putChunk:(NSString *)uphost @@ -273,61 +272,60 @@ - (void)putChunk:(NSString *)uphost context:(NSString *)context progress:(QNInternalProgressBlock)progressBlock complete:(QNCompleteBlock)complete { - NSData *data = [self.file read:offset size:size]; - UInt32 chunkOffset = offset % kQNBlockSize; - NSString *url = [[NSString alloc] initWithFormat:@"%@/bput/%@/%u", uphost, context, (unsigned int)chunkOffset]; - _chunkCrc = [QNCrc32 data:data]; - [self post:url withData:data withCompleteBlock:complete withProgressBlock:progressBlock]; + NSData *data = [self.file read:offset size:size]; + UInt32 chunkOffset = offset % kQNBlockSize; + NSString *url = [[NSString alloc] initWithFormat:@"%@/bput/%@/%u", uphost, context, (unsigned int)chunkOffset]; + _chunkCrc = [QNCrc32 data:data]; + [self post:url withData:data withCompleteBlock:complete withProgressBlock:progressBlock]; } - (void)makeFile:(NSString *)uphost complete:(QNCompleteBlock)complete { - NSString *mime = [[NSString alloc] initWithFormat:@"/mimeType/%@", [QNUrlSafeBase64 encodeString:self.option.mimeType]]; + NSString *mime = [[NSString alloc] initWithFormat:@"/mimeType/%@", [QNUrlSafeBase64 encodeString:self.option.mimeType]]; + + __block NSString *url = [[NSString alloc] initWithFormat:@"%@/mkfile/%u%@", uphost, (unsigned int)self.size, mime]; - __block NSString *url = [[NSString alloc] initWithFormat:@"%@/mkfile/%u%@", uphost,(unsigned int)self.size, mime]; + if (self.key != nil) { + NSString *keyStr = [[NSString alloc] initWithFormat:@"/key/%@", [QNUrlSafeBase64 encodeString:self.key]]; + url = [NSString stringWithFormat:@"%@%@", url, keyStr]; + } - if (self.key != nil) { - NSString *keyStr = [[NSString alloc] initWithFormat:@"/key/%@", [QNUrlSafeBase64 encodeString:self.key]]; - url = [NSString stringWithFormat:@"%@%@", url, keyStr]; - } + [self.option.params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { + url = [NSString stringWithFormat:@"%@/%@/%@", url, key, [QNUrlSafeBase64 encodeString:obj]]; + }]; - [self.option.params enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *obj, BOOL *stop) { - url = [NSString stringWithFormat:@"%@/%@/%@", url, key, [QNUrlSafeBase64 encodeString:obj]]; - }]; - //添加路径 - NSString *fname = [[NSString alloc]initWithFormat:@"/fname/%@",[QNUrlSafeBase64 encodeString:[self dealFilePath]]]; + NSString *fname = [[NSString alloc] initWithFormat:@"/fname/%@", [QNUrlSafeBase64 encodeString:[self dealFilePath]]]; url = [NSString stringWithFormat:@"%@%@", url, fname]; - NSMutableData *postData = [NSMutableData data]; - NSString *bodyStr = [self.contexts componentsJoinedByString:@","]; - [postData appendData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]]; - [self post:url withData:postData withCompleteBlock:complete withProgressBlock:nil]; + NSMutableData *postData = [NSMutableData data]; + NSString *bodyStr = [self.contexts componentsJoinedByString:@","]; + [postData appendData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]]; + [self post:url withData:postData withCompleteBlock:complete withProgressBlock:nil]; } #pragma mark - 处理文件路径 --(NSString *)dealFilePath{ - +- (NSString *)dealFilePath { + _fileAry = [NSArray array]; NSString *filePath = [_file path]; _fileAry = [filePath componentsSeparatedByString:@"/"]; - NSString *fname = [_fileAry objectAtIndex:(_fileAry.count-1)]; + NSString *fname = [_fileAry objectAtIndex:(_fileAry.count - 1)]; return fname; - } -- (void) post:(NSString *)url - withData:(NSData *)data - withCompleteBlock:(QNCompleteBlock)completeBlock - withProgressBlock:(QNInternalProgressBlock)progressBlock { - [_httpManager post:url withData:data withParams:nil withHeaders:_headers withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:_option.cancellationSignal]; +- (void)post:(NSString *)url + withData:(NSData *)data + withCompleteBlock:(QNCompleteBlock)completeBlock + withProgressBlock:(QNInternalProgressBlock)progressBlock { + [_httpManager post:url withData:data withParams:nil withHeaders:_headers withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:_option.cancellationSignal]; } - (void)run { - @autoreleasepool { - UInt32 offset = [self recoveryFromRecord]; - [self nextTask:offset retriedTimes:0 host:_config.up.address]; - } + @autoreleasepool { + UInt32 offset = [self recoveryFromRecord]; + [self nextTask:offset retriedTimes:0 host:_config.up.address]; + } } @end diff --git a/QiniuSDK/Storage/QNUpToken.m b/QiniuSDK/Storage/QNUpToken.m index dd2d7f0d..4113840a 100644 --- a/QiniuSDK/Storage/QNUpToken.m +++ b/QiniuSDK/Storage/QNUpToken.m @@ -18,53 +18,52 @@ - (instancetype)init:(NSDictionary *)policy token:(NSString *)token; @implementation QNUpToken - (instancetype)init:(NSDictionary *)policy token:(NSString *)token { - if (self = [super init]) { - _token = token; + if (self = [super init]) { + _token = token; _access = [self getAccess]; _bucket = [self getBucket:policy]; - _hasReturnUrl = (policy[@"returnUrl"] != nil); - } + _hasReturnUrl = (policy[@"returnUrl"] != nil); + } - return self; + return self; } -- (NSString *) getAccess { +- (NSString *)getAccess { - NSRange range = [_token rangeOfString:@":" options:NSCaseInsensitiveSearch]; - return [_token substringToIndex:range.location]; + NSRange range = [_token rangeOfString:@":" options:NSCaseInsensitiveSearch]; + return [_token substringToIndex:range.location]; } -- (NSString *) getBucket:(NSDictionary *)info { - - NSString *scope = [info objectForKey:@"scope"]; - if (!scope) { - return @""; - } +- (NSString *)getBucket:(NSDictionary *)info { - NSRange range = [scope rangeOfString:@":"]; - if (range.location == NSNotFound) { - return scope; - } - return [scope substringToIndex:range.location]; -} + NSString *scope = [info objectForKey:@"scope"]; + if (!scope) { + return @""; + } + NSRange range = [scope rangeOfString:@":"]; + if (range.location == NSNotFound) { + return scope; + } + return [scope substringToIndex:range.location]; +} + (instancetype)parse:(NSString *)token { - if (token == nil) { - return nil; - } - NSArray *array = [token componentsSeparatedByString:@":"]; - if (array == nil || array.count != 3) { - return nil; - } + if (token == nil) { + return nil; + } + NSArray *array = [token componentsSeparatedByString:@":"]; + if (array == nil || array.count != 3) { + return nil; + } - NSData *data = [QNUrlSafeBase64 decodeString:array[2]]; - NSError *tmp = nil; - NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp]; - if (tmp != nil || dict[@"scope"] == nil || dict[@"deadline"] == nil) { - return nil; - } - return [[QNUpToken alloc] init:dict token:token]; + NSData *data = [QNUrlSafeBase64 decodeString:array[2]]; + NSError *tmp = nil; + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp]; + if (tmp != nil || dict[@"scope"] == nil || dict[@"deadline"] == nil) { + return nil; + } + return [[QNUpToken alloc] init:dict token:token]; } @end diff --git a/QiniuSDK/Storage/QNUploadManager.h b/QiniuSDK/Storage/QNUploadManager.h index 173070d6..43cda538 100644 --- a/QiniuSDK/Storage/QNUploadManager.h +++ b/QiniuSDK/Storage/QNUploadManager.h @@ -10,7 +10,6 @@ #import "QNRecorderDelegate.h" - @class QNResponseInfo; @class QNUploadOption; @class QNConfiguration; @@ -18,7 +17,6 @@ @class PHAsset; @class PHAssetResource; - /** * 上传完成后的回调函数 * @@ -47,7 +45,7 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * * @return 上传管理类实例 */ -- (instancetype)initWithRecorder:(id )recorder; +- (instancetype)initWithRecorder:(id)recorder; /** * 使用持久化记录接口以及持久化key生成函数的构造方法,默认情况下使用上传存储的key, 如果key为nil或者有特殊字符比如/,建议使用自己的生成函数 @@ -57,7 +55,7 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * * @return 上传管理类实例 */ -- (instancetype)initWithRecorder:(id )recorder +- (instancetype)initWithRecorder:(id)recorder recorderKeyGenerator:(QNRecorderKeyGenerator)recorderKeyGenerator; /** @@ -69,7 +67,6 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic */ - (instancetype)initWithConfiguration:(QNConfiguration *)config; - /** * 方便使用的单例方法 * @@ -88,11 +85,11 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * @param completionHandler 上传完成后的回调函数 * @param option 上传时传入的可选参数 */ -- (void) putData:(NSData *)data - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option; +- (void)putData:(NSData *)data + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option; /** * 上传文件 @@ -103,11 +100,11 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * @param completionHandler 上传完成后的回调函数 * @param option 上传时传入的可选参数 */ -- (void) putFile:(NSString *)filePath - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option; +- (void)putFile:(NSString *)filePath + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option; /** * 上传ALAsset文件 @@ -118,11 +115,11 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * @param completionHandler 上传完成后的回调函数 * @param option 上传时传入的可选参数 */ -- (void) putALAsset:(ALAsset *)asset - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option; +- (void)putALAsset:(ALAsset *)asset + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option; /** * 上传PHAsset文件(IOS8 andLater) @@ -133,11 +130,11 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * @param completionHandler 上传完成后的回调函数 * @param option 上传时传入的可选参数 */ -- (void) putPHAsset:(PHAsset *)asset - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option; +- (void)putPHAsset:(PHAsset *)asset + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option; /** * 上传PHAssetResource文件(IOS9.1 andLater) @@ -149,12 +146,10 @@ typedef void (^QNUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDic * @param option 上传时传入的可选参数 */ -- (void) putPHAssetResource:(PHAssetResource *)assetResource - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option; - - +- (void)putPHAssetResource:(PHAssetResource *)assetResource + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option; @end diff --git a/QiniuSDK/Storage/QNUploadManager.m b/QiniuSDK/Storage/QNUploadManager.m index 56510b80..2c963179 100644 --- a/QiniuSDK/Storage/QNUploadManager.m +++ b/QiniuSDK/Storage/QNUploadManager.m @@ -9,17 +9,16 @@ #import #if __IPHONE_OS_VERSION_MIN_REQUIRED -#import -#import #import "QNALAssetFile.h" #import +#import +#import #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 #import "QNPHAssetFile.h" #import #endif - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100 #import "QNPHAssetResource.h" #endif @@ -28,276 +27,269 @@ #import #endif - +#import "QNAsyncRun.h" #import "QNConfiguration.h" +#import "QNCrc32.h" +#import "QNFile.h" +#import "QNFormUpload.h" #import "QNHttpManager.h" -#import "QNSessionManager.h" #import "QNResponseInfo.h" -#import "QNCrc32.h" -#import "QNUploadManager.h" #import "QNResumeUpload.h" -#import "QNFormUpload.h" -#import "QNUploadOption+Private.h" -#import "QNAsyncRun.h" -#import "QNUpToken.h" -#import "QNFile.h" +#import "QNSessionManager.h" #import "QNSystem.h" +#import "QNUpToken.h" +#import "QNUploadManager.h" +#import "QNUploadOption+Private.h" @interface QNUploadManager () -@property (nonatomic) id httpManager; +@property (nonatomic) id httpManager; @property (nonatomic) QNConfiguration *config; @end @implementation QNUploadManager - (instancetype)init { - return [self initWithConfiguration:nil]; + return [self initWithConfiguration:nil]; } -- (instancetype)initWithRecorder:(id )recorder { - return [self initWithRecorder:recorder recorderKeyGenerator:nil]; +- (instancetype)initWithRecorder:(id)recorder { + return [self initWithRecorder:recorder recorderKeyGenerator:nil]; } -- (instancetype)initWithRecorder:(id )recorder +- (instancetype)initWithRecorder:(id)recorder recorderKeyGenerator:(QNRecorderKeyGenerator)recorderKeyGenerator { - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - builder.recorder = recorder; - builder.recorderKeyGen = recorderKeyGenerator; - }]; - return [self initWithConfiguration:config]; + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + builder.recorder = recorder; + builder.recorderKeyGen = recorderKeyGenerator; + }]; + return [self initWithConfiguration:config]; } - (instancetype)initWithConfiguration:(QNConfiguration *)config { - if (self = [super init]) { - if (config == nil) { - config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - }]; - } - _config = config; + if (self = [super init]) { + if (config == nil) { + 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) - if (hasNSURLSession()) { - _httpManager = [[QNSessionManager alloc] initWithProxy:config.proxy timeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; - } - else { - _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; - } + if (hasNSURLSession()) { + _httpManager = [[QNSessionManager alloc] initWithProxy:config.proxy timeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; + } else { + _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; + } #else - _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; + _httpManager = [[QNHttpManager alloc] initWithTimeout:config.timeoutInterval urlConverter:config.converter dns:config.dns]; #endif - } - return self; + } + return self; } + (instancetype)sharedInstanceWithConfiguration:(QNConfiguration *)config { - static QNUploadManager *sharedInstance = nil; + static QNUploadManager *sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[self alloc] initWithConfiguration:config]; - }); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] initWithConfiguration:config]; + }); - return sharedInstance; + return sharedInstance; } + (BOOL)checkAndNotifyError:(NSString *)key token:(NSString *)token input:(NSObject *)input complete:(QNUpCompletionHandler)completionHandler { - NSString *desc = nil; - if (completionHandler == nil) { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:@"no completionHandler" userInfo:nil]; - return YES; - } - if (input == nil) { - desc = @"no input data"; - } - else if (token == nil || [token isEqualToString:@""]) { - desc = @"no token"; - } - if (desc != nil) { - QNAsyncRunInMain( ^{ - completionHandler([QNResponseInfo responseInfoWithInvalidArgument:desc], key, nil); - }); - return YES; - } - return NO; + NSString *desc = nil; + if (completionHandler == nil) { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:@"no completionHandler" + userInfo:nil]; + return YES; + } + if (input == nil) { + desc = @"no input data"; + } else if (token == nil || [token isEqualToString:@""]) { + desc = @"no token"; + } + if (desc != nil) { + QNAsyncRunInMain(^{ + completionHandler([QNResponseInfo responseInfoWithInvalidArgument:desc], key, nil); + }); + return YES; + } + return NO; } -- (void) putData:(NSData *)data - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option { - if ([QNUploadManager checkAndNotifyError:key token:token input:data complete:completionHandler]) { - return; - } - - QNUpToken *t = [QNUpToken parse:token]; - if (t == nil) { - QNAsyncRunInMain( ^{ - completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil); - }); - return; - } - - if ([data length] == 0) { - QNAsyncRunInMain( ^{ - completionHandler([QNResponseInfo responseInfoOfZeroData:nil], key, nil); - }); - return; - } - QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) - { - QNAsyncRunInMain( ^{ - completionHandler(info, key, resp); - }); - }; - QNFormUpload *up = [[QNFormUpload alloc] - initWithData:data - withKey:key - withToken:t - withCompletionHandler:complete - withOption:option - withHttpManager:_httpManager - withConfiguration:_config]; - QNAsyncRun( ^{ - [up put]; - }); -} +- (void)putData:(NSData *)data + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { + if ([QNUploadManager checkAndNotifyError:key token:token input:data complete:completionHandler]) { + return; + } -- (void) putFileInternal:(id )file - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option { - @autoreleasepool { - QNUpToken *t = [QNUpToken parse:token]; - if (t == nil) { - QNAsyncRunInMain( ^{ - completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil); - }); - return; - } - - QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) - { - [file close]; - QNAsyncRunInMain( ^{ - completionHandler(info, key, resp); - }); - }; - - if ([file size] <= _config.putThreshold) { - NSData *data = [file readAll]; - [self putData:data key:key token:token complete:complete option:option]; - return; - } - - NSString *recorderKey = key; - if (_config.recorder != nil && _config.recorderKeyGen != nil) { - recorderKey = _config.recorderKeyGen(key, [file path]); - } - - NSLog(@"recorder %@", _config.recorder); - - QNResumeUpload *up = [[QNResumeUpload alloc] - initWithFile:file - withKey:key - withToken:t - withCompletionHandler:complete - withOption:option - withRecorder:_config.recorder - withRecorderKey:recorderKey - withHttpManager:_httpManager - withConfiguration:_config]; - QNAsyncRun( ^{ - [up run]; - }); - } + QNUpToken *t = [QNUpToken parse:token]; + if (t == nil) { + QNAsyncRunInMain(^{ + completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil); + }); + return; + } + if ([data length] == 0) { + QNAsyncRunInMain(^{ + completionHandler([QNResponseInfo responseInfoOfZeroData:nil], key, nil); + }); + return; + } + QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + QNAsyncRunInMain(^{ + completionHandler(info, key, resp); + }); + }; + QNFormUpload *up = [[QNFormUpload alloc] + initWithData:data + withKey:key + withToken:t + withCompletionHandler:complete + withOption:option + withHttpManager:_httpManager + withConfiguration:_config]; + QNAsyncRun(^{ + [up put]; + }); } -- (void) putFile:(NSString *)filePath - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option { - if ([QNUploadManager checkAndNotifyError:key token:token input:filePath complete:completionHandler]) { - return; - } - - @autoreleasepool { - NSError *error = nil; - __block QNFile *file = [[QNFile alloc] init:filePath error:&error]; - if (error) { - QNAsyncRunInMain( ^{ - QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; - completionHandler(info, key, nil); - }); - return; - } - [self putFileInternal:file key:key token:token complete:completionHandler option:option]; - } +- (void)putFileInternal:(id)file + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { + @autoreleasepool { + QNUpToken *t = [QNUpToken parse:token]; + if (t == nil) { + QNAsyncRunInMain(^{ + completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil); + }); + return; + } + + QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + [file close]; + QNAsyncRunInMain(^{ + completionHandler(info, key, resp); + }); + }; + + if ([file size] <= _config.putThreshold) { + NSData *data = [file readAll]; + [self putData:data key:key token:token complete:complete option:option]; + return; + } + + NSString *recorderKey = key; + if (_config.recorder != nil && _config.recorderKeyGen != nil) { + recorderKey = _config.recorderKeyGen(key, [file path]); + } + + NSLog(@"recorder %@", _config.recorder); + + QNResumeUpload *up = [[QNResumeUpload alloc] + initWithFile:file + withKey:key + withToken:t + withCompletionHandler:complete + withOption:option + withRecorder:_config.recorder + withRecorderKey:recorderKey + withHttpManager:_httpManager + withConfiguration:_config]; + QNAsyncRun(^{ + [up run]; + }); + } } +- (void)putFile:(NSString *)filePath + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { + if ([QNUploadManager checkAndNotifyError:key token:token input:filePath complete:completionHandler]) { + return; + } -- (void) putALAsset:(ALAsset *)asset - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option { + @autoreleasepool { + NSError *error = nil; + __block QNFile *file = [[QNFile alloc] init:filePath error:&error]; + if (error) { + QNAsyncRunInMain(^{ + QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; + completionHandler(info, key, nil); + }); + return; + } + [self putFileInternal:file key:key token:token complete:completionHandler option:option]; + } +} + +- (void)putALAsset:(ALAsset *)asset + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { #if __IPHONE_OS_VERSION_MIN_REQUIRED - if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) { - return; - } - - @autoreleasepool { - NSError *error = nil; - __block QNALAssetFile *file = [[QNALAssetFile alloc] init:asset error:&error]; - if (error) { - QNAsyncRunInMain( ^{ - QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; - completionHandler(info, key, nil); - }); - return; - } - [self putFileInternal:file key:key token:token complete:completionHandler option:option]; - } + if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) { + return; + } + + @autoreleasepool { + NSError *error = nil; + __block QNALAssetFile *file = [[QNALAssetFile alloc] init:asset error:&error]; + if (error) { + QNAsyncRunInMain(^{ + QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; + completionHandler(info, key, nil); + }); + return; + } + [self putFileInternal:file key:key token:token complete:completionHandler option:option]; + } #endif } -- (void) putPHAsset:(PHAsset *)asset - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option { +- (void)putPHAsset:(PHAsset *)asset + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) - if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) { - return; - } - - @autoreleasepool { - NSError *error = nil; - __block QNPHAssetFile *file = [[QNPHAssetFile alloc] init:asset error:&error]; - if (error) { - QNAsyncRunInMain( ^{ - QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; - completionHandler(info, key, nil); - }); - return; - } - [self putFileInternal:file key:key token:token complete:completionHandler option:option]; - } + if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) { + return; + } + + @autoreleasepool { + NSError *error = nil; + __block QNPHAssetFile *file = [[QNPHAssetFile alloc] init:asset error:&error]; + if (error) { + QNAsyncRunInMain(^{ + QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; + completionHandler(info, key, nil); + }); + return; + } + [self putFileInternal:file key:key token:token complete:completionHandler option:option]; + } #endif } -- (void) putPHAssetResource:(PHAssetResource *)assetResource - key:(NSString *)key - token:(NSString *)token - complete:(QNUpCompletionHandler)completionHandler - option:(QNUploadOption *)option -{ +- (void)putPHAssetResource:(PHAssetResource *)assetResource + key:(NSString *)key + token:(NSString *)token + complete:(QNUpCompletionHandler)completionHandler + option:(QNUploadOption *)option { #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100) if ([QNUploadManager checkAndNotifyError:key token:token input:assetResource complete:completionHandler]) { return; @@ -306,7 +298,7 @@ - (void) putPHAssetResource:(PHAssetResource *)assetResource NSError *error = nil; __block QNPHAssetResource *file = [[QNPHAssetResource alloc] init:assetResource error:&error]; if (error) { - QNAsyncRunInMain( ^{ + QNAsyncRunInMain(^{ QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error]; completionHandler(info, key, nil); }); @@ -317,6 +309,4 @@ - (void) putPHAssetResource:(PHAssetResource *)assetResource #endif } - - @end diff --git a/QiniuSDK/Storage/QNUploadOption+Private.h b/QiniuSDK/Storage/QNUploadOption+Private.h index 8ae8ad6e..370d05f1 100644 --- a/QiniuSDK/Storage/QNUploadOption+Private.h +++ b/QiniuSDK/Storage/QNUploadOption+Private.h @@ -10,5 +10,5 @@ @interface QNUploadOption (Private) -@property (nonatomic, getter = priv_isCancelled, readonly) BOOL cancelled; +@property (nonatomic, getter=priv_isCancelled, readonly) BOOL cancelled; @end diff --git a/QiniuSDK/Storage/QNUploadOption.m b/QiniuSDK/Storage/QNUploadOption.m index 83182b38..95857c50 100644 --- a/QiniuSDK/Storage/QNUploadOption.m +++ b/QiniuSDK/Storage/QNUploadOption.m @@ -10,35 +10,35 @@ #import "QNUploadManager.h" static NSString *mime(NSString *mimeType) { - if (mimeType == nil || [mimeType isEqualToString:@""]) { - return @"application/octet-stream"; - } - return mimeType; + if (mimeType == nil || [mimeType isEqualToString:@""]) { + return @"application/octet-stream"; + } + return mimeType; } @implementation QNUploadOption + (NSDictionary *)filteParam:(NSDictionary *)params { - NSMutableDictionary *ret = [NSMutableDictionary dictionary]; - if (params == nil) { - return ret; - } + NSMutableDictionary *ret = [NSMutableDictionary dictionary]; + if (params == nil) { + return ret; + } - [params enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *obj, BOOL *stop) { - if ([key hasPrefix:@"x:"] && ![obj isEqualToString:@""]) { - ret[key] = obj; - } - }]; + [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { + if ([key hasPrefix:@"x:"] && ![obj isEqualToString:@""]) { + ret[key] = obj; + } + }]; - return ret; + return ret; } - (instancetype)initWithProgessHandler:(QNUpProgressHandler)progress { - return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil]; + return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil]; } - (instancetype)initWithProgressHandler:(QNUpProgressHandler)progress { - return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil]; + return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil]; } - (instancetype)initWithMime:(NSString *)mimeType @@ -46,22 +46,22 @@ - (instancetype)initWithMime:(NSString *)mimeType params:(NSDictionary *)params checkCrc:(BOOL)check cancellationSignal:(QNUpCancellationSignal)cancel { - if (self = [super init]) { - _mimeType = mime(mimeType); - _progressHandler = progress != nil ? progress : ^(NSString *key, float percent) { - }; - _params = [QNUploadOption filteParam:params]; - _checkCrc = check; - _cancellationSignal = cancel != nil ? cancel : ^BOOL () { - return NO; - }; - } + if (self = [super init]) { + _mimeType = mime(mimeType); + _progressHandler = progress != nil ? progress : ^(NSString *key, float percent) { + }; + _params = [QNUploadOption filteParam:params]; + _checkCrc = check; + _cancellationSignal = cancel != nil ? cancel : ^BOOL() { + return NO; + }; + } - return self; + return self; } + (instancetype)defaultOptions { - return [[QNUploadOption alloc] initWithMime:nil progressHandler:nil params:nil checkCrc:NO cancellationSignal:nil]; + return [[QNUploadOption alloc] initWithMime:nil progressHandler:nil params:nil checkCrc:NO cancellationSignal:nil]; } @end diff --git a/QiniuSDKTests/QNBase64Test.m b/QiniuSDKTests/QNBase64Test.m index 6b09a416..df4e349e 100644 --- a/QiniuSDKTests/QNBase64Test.m +++ b/QiniuSDKTests/QNBase64Test.m @@ -6,8 +6,8 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import #import "QiniuSDK.h" +#import @interface QNBase64Test : XCTestCase @@ -16,10 +16,10 @@ @interface QNBase64Test : XCTestCase @implementation QNBase64Test - (void)testEncode { - // This is an example of a functional test case. - NSString *source = @"你好/+="; + // This is an example of a functional test case. + NSString *source = @"你好/+="; - XCTAssert([[QNUrlSafeBase64 encodeString:source] isEqual:@"5L2g5aW9Lys9"], @"Pass"); + XCTAssert([[QNUrlSafeBase64 encodeString:source] isEqual:@"5L2g5aW9Lys9"], @"Pass"); } @end diff --git a/QiniuSDKTests/QNCrc32Test.m b/QiniuSDKTests/QNCrc32Test.m index c2cc06a8..cefee1bb 100644 --- a/QiniuSDKTests/QNCrc32Test.m +++ b/QiniuSDKTests/QNCrc32Test.m @@ -6,9 +6,9 @@ // Copyright (c) 2014年 Qiniu. All rights reserved. // -#import #import "QNCrc32.h" #import "QNTempFile.h" +#import @interface QNCrc32Test : XCTestCase @@ -17,19 +17,19 @@ @interface QNCrc32Test : XCTestCase @implementation QNCrc32Test - (void)testData { - NSData *buffer = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - UInt32 crc = [QNCrc32 data:buffer]; + NSData *buffer = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + UInt32 crc = [QNCrc32 data:buffer]; - XCTAssert(crc == 3964322768, @"Pass"); + XCTAssert(crc == 3964322768, @"Pass"); } - (void)testFile { - NSError *error; - NSURL *file = [QNTempFile createTempfileWithSize:5 * 1024 * 1024]; - UInt32 u = [QNCrc32 file:[file relativePath] error:&error]; + NSError *error; + NSURL *file = [QNTempFile createTempfileWithSize:5 * 1024 * 1024]; + UInt32 u = [QNCrc32 file:[file relativePath] error:&error]; - XCTAssert(u == 3376132981, @"Pass"); - [QNTempFile removeTempfile:file]; + XCTAssert(u == 3376132981, @"Pass"); + [QNTempFile removeTempfile:file]; } @end diff --git a/QiniuSDKTests/QNDnsTest.m b/QiniuSDKTests/QNDnsTest.m index 5ee70ef7..e7b22fb8 100644 --- a/QiniuSDKTests/QNDnsTest.m +++ b/QiniuSDKTests/QNDnsTest.m @@ -17,17 +17,17 @@ @interface QNDnsTest : XCTestCase @implementation QNDnsTest - (void)testQiniu { - NSString *host = @"qiniu.com"; - NSString *ip = [[QNDns getAddresses:host] objectAtIndex:0]; - XCTAssert(ip != nil, @"Pass"); - NSLog(@"dns result %@", ip); + NSString *host = @"qiniu.com"; + NSString *ip = [[QNDns getAddresses:host] objectAtIndex:0]; + XCTAssert(ip != nil, @"Pass"); + NSLog(@"dns result %@", ip); } - (void)testNoHost { - NSString *nohost = @"nodns.qiniu.com"; - NSArray *noip = [QNDns getAddresses:nohost]; - XCTAssert(noip.count == 0, @"Pass"); - NSLog(@"dns result %@", noip); + NSString *nohost = @"nodns.qiniu.com"; + NSArray *noip = [QNDns getAddresses:nohost]; + XCTAssert(noip.count == 0, @"Pass"); + NSLog(@"dns result %@", noip); } @end diff --git a/QiniuSDKTests/QNEtagTest.m b/QiniuSDKTests/QNEtagTest.m index b6f029fe..776bb8d6 100644 --- a/QiniuSDKTests/QNEtagTest.m +++ b/QiniuSDKTests/QNEtagTest.m @@ -18,15 +18,15 @@ @interface QNEtagTest : XCTestCase @implementation QNEtagTest - (void)testEtagZero { - XCTAssert([@"Fto5o-5ea0sNMlW_75VgGJCv2AcJ" isEqualToString:[QNEtag data:nil]], @"Pass"); + XCTAssert([@"Fto5o-5ea0sNMlW_75VgGJCv2AcJ" isEqualToString:[QNEtag data:nil]], @"Pass"); } - (void)testFile5M { - NSError *error; - NSURL *file = [QNTempFile createTempfileWithSize:5 * 1024 * 1024]; - NSString *x = [QNEtag file:[file relativePath] error:&error]; - XCTAssert([@"lrMhp7oU8rzWSRlmUeGJ73Q2pVa-" isEqualToString:x], @"Pass"); - [QNTempFile removeTempfile:file]; + NSError *error; + NSURL *file = [QNTempFile createTempfileWithSize:5 * 1024 * 1024]; + NSString *x = [QNEtag file:[file relativePath] error:&error]; + XCTAssert([@"lrMhp7oU8rzWSRlmUeGJ73Q2pVa-" isEqualToString:x], @"Pass"); + [QNTempFile removeTempfile:file]; } - (void)testFile3M { @@ -38,9 +38,9 @@ - (void)testFile3M { } - (void)testData { - NSData *data = [@"etag" dataUsingEncoding:NSUTF8StringEncoding]; - NSLog(@"%@", [QNEtag data:data]); - XCTAssert([@"FpLiADEaVoALPkdb8tJEJyRTXoe_" isEqualToString:[QNEtag data:data]], @"Pass"); + NSData *data = [@"etag" dataUsingEncoding:NSUTF8StringEncoding]; + NSLog(@"%@", [QNEtag data:data]); + XCTAssert([@"FpLiADEaVoALPkdb8tJEJyRTXoe_" isEqualToString:[QNEtag data:data]], @"Pass"); } @end diff --git a/QiniuSDKTests/QNFileRecorderTest.m b/QiniuSDKTests/QNFileRecorderTest.m index 996d0976..598e851b 100644 --- a/QiniuSDKTests/QNFileRecorderTest.m +++ b/QiniuSDKTests/QNFileRecorderTest.m @@ -10,11 +10,11 @@ #import -#import "QiniuSDK.h" +#import "QNConfiguration.h" #import "QNFileRecorder.h" #import "QNTempFile.h" #import "QNTestConfig.h" -#import "QNConfiguration.h" +#import "QiniuSDK.h" @interface QNFileRecorderTest : XCTestCase @property QNUploadManager *upManager; @@ -24,108 +24,115 @@ @interface QNFileRecorderTest : XCTestCase @implementation QNFileRecorderTest - (void)setUp { - [super setUp]; - NSError *error = nil; - QNFileRecorder *file = [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"qiniutest"] error:&error]; - NSLog(@"recorder error %@", error); - _upManager = [[QNUploadManager alloc] initWithRecorder:file - ]; + [super setUp]; + NSError *error = nil; + QNFileRecorder *file = [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"qiniutest"] error:&error]; + NSLog(@"recorder error %@", error); + _upManager = [[QNUploadManager alloc] initWithRecorder:file]; #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED - NSString *travis = [[NSProcessInfo processInfo]environment][@"QINIU_TEST_ENV"]; - if ([travis isEqualToString:@"travis"]) { - _inTravis = YES; - } + NSString *travis = [[NSProcessInfo processInfo] environment][@"QINIU_TEST_ENV"]; + if ([travis isEqualToString:@"travis"]) { + _inTravis = YES; + } #endif } - (void)testInit { - NSError *error = nil; - [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"qiniutest"] error:&error]; - XCTAssert(error == nil, @"Pass"); - [QNFileRecorder fileRecorderWithFolder:@"/qiniutest" error:&error]; - NSLog(@"file recorder %@", error); - XCTAssert(error != nil, @"Pass"); - [QNFileRecorder fileRecorderWithFolder:@"/qiniutest" error:nil]; + NSError *error = nil; + [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"qiniutest"] error:&error]; + XCTAssert(error == nil, @"Pass"); + [QNFileRecorder fileRecorderWithFolder:@"/qiniutest" error:&error]; + NSLog(@"file recorder %@", error); + XCTAssert(error != nil, @"Pass"); + [QNFileRecorder fileRecorderWithFolder:@"/qiniutest" error:nil]; } -- (void)template:(int)size pos:(float)pos { - NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; - NSString *keyUp = [NSString stringWithFormat:@"r-%dk", size]; - __block NSString *key = nil; - __block QNResponseInfo *info = nil; - __block BOOL flag = NO; - QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil progressHandler: ^(NSString *key, float percent) { - if (percent >= pos) { - flag = YES; - } - NSLog(@"progress %f", percent); - } params:nil checkCrc:NO cancellationSignal: ^BOOL () { - return flag; - }]; - [_upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - } option:opt]; - AGWW_WAIT_WHILE(key == nil, 60 * 30); - NSLog(@"info %@", info); - XCTAssert(info.isCancelled, @"Pass"); - XCTAssert([keyUp isEqualToString:key], @"Pass"); - - // continue - key = nil; - info = nil; - __block BOOL failed = NO; - opt = [[QNUploadOption alloc] initWithMime:nil progressHandler: ^(NSString *key, float percent) { - if (percent < pos - (256 * 1024.0) / (size * 1024.0)) { - failed = YES; - } - NSLog(@"continue progress %f", percent); - } params:nil checkCrc:NO cancellationSignal:nil]; - [_upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - } option:opt]; - AGWW_WAIT_WHILE(key == nil, 60 * 30); - NSLog(@"info %@", info); - XCTAssert(info.isOK, @"Pass"); - XCTAssert(!failed, @"Pass"); - XCTAssert([keyUp isEqualToString:key], @"Pass"); - [QNTempFile removeTempfile:tempFile]; +- (void) template:(int)size pos:(float)pos { + NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; + NSString *keyUp = [NSString stringWithFormat:@"r-%dk", size]; + __block NSString *key = nil; + __block QNResponseInfo *info = nil; + __block BOOL flag = NO; + QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { + if (percent >= pos) { + flag = YES; + } + NSLog(@"progress %f", percent); + } + params:nil + checkCrc:NO + cancellationSignal:^BOOL() { + return flag; + }]; + [_upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } + option:opt]; + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.isCancelled, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + + // continue + key = nil; + info = nil; + __block BOOL failed = NO; + opt = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { + if (percent < pos - (256 * 1024.0) / (size * 1024.0)) { + failed = YES; + } + NSLog(@"continue progress %f", percent); + } + params:nil + checkCrc:NO + cancellationSignal:nil]; + [_upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } + option:opt]; + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.isOK, @"Pass"); + XCTAssert(!failed, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + [QNTempFile removeTempfile:tempFile]; } - (void)tearDown { - [super tearDown]; + [super tearDown]; } - (void)test600k { - [self template:600 pos:0.7]; + [self template:600 pos:0.7]; } - (void)test700k { - [self template:700 pos:0.1]; + [self template:700 pos:0.1]; } #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED - (void)test1M { - if (_inTravis) { - return; - } - [self template:1024 pos:0.51]; + if (_inTravis) { + return; + } + [self template:1024 pos:0.51]; } - (void)test4M { - if (_inTravis) { - return; - } - [self template:4 * 1024 pos:0.9]; + if (_inTravis) { + return; + } + [self template:4 * 1024 pos:0.9]; } - (void)test8M { - if (_inTravis) { - return; - } - [self template:8 * 1024 + 1 pos:0.8]; + if (_inTravis) { + return; + } + [self template:8 * 1024 + 1 pos:0.8]; } #endif diff --git a/QiniuSDKTests/QNFormUploadTest.m b/QiniuSDKTests/QNFormUploadTest.m index 31618153..9b0f9134 100644 --- a/QiniuSDKTests/QNFormUploadTest.m +++ b/QiniuSDKTests/QNFormUploadTest.m @@ -12,8 +12,8 @@ #import "QiniuSDK.h" -#import "QNTestConfig.h" #import "HappyDns.h" +#import "QNTestConfig.h" @interface QNFormUploadTest : XCTestCase @@ -24,37 +24,38 @@ @interface QNFormUploadTest : XCTestCase @implementation QNFormUploadTest - (void)setUp { - [super setUp]; - _upManager = [QNUploadManager sharedInstanceWithConfiguration:nil]; + [super setUp]; + _upManager = [QNUploadManager sharedInstanceWithConfiguration:nil]; } - (void)tearDown { - [super tearDown]; + [super tearDown]; } - (void)testUp { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - - QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo":@"bar" } checkCrc:YES cancellationSignal:nil]; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - [self.upManager putData:data key:@"你好" token:g_token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:opt]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - NSLog(@"%@", testResp); - XCTAssert(testInfo.isOK, @"Pass"); - XCTAssert(testInfo.reqId, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + + QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo" : @"bar" } checkCrc:YES cancellationSignal:nil]; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [self.upManager putData:data key:@"你好" token:g_token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:opt]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + NSLog(@"%@", testResp); + XCTAssert(testInfo.isOK, @"Pass"); + XCTAssert(testInfo.reqId, @"Pass"); } // travis ci iOS simulator 8.1 failed,其他环境(mac, iOS 9.0)正常,待详细排查 //- (void)testHttpsUp { // __block QNResponseInfo *testInfo = nil; // __block NSDictionary *testResp = nil; -// +// // QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo":@"bar" } checkCrc:YES cancellationSignal:nil]; // NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; // QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { @@ -66,7 +67,7 @@ - (void)testUp { // testInfo = info; // testResp = resp; // } option:opt]; -// +// // AGWW_WAIT_WHILE(testInfo == nil, 100.0); // NSLog(@"%@", testInfo); // NSLog(@"%@", testResp); @@ -75,235 +76,245 @@ - (void)testUp { //} - (void)testUpUnAuth { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - NSString *token = @"noauth"; - [self.upManager putData:data key:@"hello" token:token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidToken, @"Pass"); - XCTAssert(testInfo.reqId == nil, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + NSString *token = @"noauth"; + [self.upManager putData:data key:@"hello" token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidToken, @"Pass"); + XCTAssert(testInfo.reqId == nil, @"Pass"); } - (void)testNoData { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - NSString *token = @"noauth"; - [self.upManager putData:nil key:@"hello" token:token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + NSString *token = @"noauth"; + [self.upManager putData:nil key:@"hello" token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); } - (void)testNoFile { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - NSString *token = @"noauth"; - [self.upManager putFile:nil key:@"hello" token:token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + NSString *token = @"noauth"; + [self.upManager putFile:nil key:@"hello" token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); } - (void)testNoToken { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - [self.upManager putData:data key:@"hello" token:nil complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); - - testInfo = nil; - testResp = nil; - [self.upManager putData:data key:@"hello" token:@"" complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); - - testInfo = nil; - testResp = nil; - [self.upManager putData:nil key:@"hello" token:nil complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [self.upManager putData:data key:@"hello" token:nil complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); + + testInfo = nil; + testResp = nil; + [self.upManager putData:data key:@"hello" token:@"" complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); + + testInfo = nil; + testResp = nil; + [self.upManager putData:nil key:@"hello" token:nil complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + XCTAssert(testInfo.statusCode == kQNInvalidArgument, @"Pass"); } - (void)testNoComplete { - NSException *e; - @try { - [self.upManager putFile:nil key:nil token:nil complete:nil option:nil]; - } - @catch (NSException *exception) - { - e = exception; - } - - XCTAssert(e != nil, @"Pass"); - XCTAssert([e.name isEqualToString:NSInvalidArgumentException], @"Pass"); + NSException *e; + @try { + [self.upManager putFile:nil key:nil token:nil complete:nil option:nil]; + } + @catch (NSException *exception) { + e = exception; + } + + XCTAssert(e != nil, @"Pass"); + XCTAssert([e.name isEqualToString:NSInvalidArgumentException], @"Pass"); } - (void)testNoKey { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - __block NSString *key = nil; - - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - [self.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([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + __block NSString *key = nil; + + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [self.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([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); } - (void)testProxy { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - __block NSString *key = nil; - - NSDictionary *proxyDict = @{ - @"HTTPEnable" : [NSNumber numberWithInt:1], - (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", - (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, - }; - - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - builder.proxy = proxyDict; - QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; - builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; - }]; - - 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([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + __block NSString *key = nil; + + NSDictionary *proxyDict = @{ + @"HTTPEnable" : [NSNumber numberWithInt:1], + (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", + (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, + }; + + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + builder.proxy = proxyDict; + QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; + builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; + }]; + + 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([@"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"]; - }; - QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; - builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; - }]; - - 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"); + __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"]; + }; + QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; + builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; + }]; + + 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"); } - (void)testDnsHosts { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - __block NSString *key = nil; - QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; - QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - NSArray *ips = [QNZone zone0].up.ips; - QNServiceAddress *s1 = [[QNServiceAddress alloc] init:@"http://uphosttest.qiniu.com" ips:ips]; - QNServiceAddress *s2 = [[QNServiceAddress alloc] init:@"http://uphosttestbak.qiniu.com" ips:ips]; - builder.zone = [[QNZone alloc] initWithUp:s1 upBackup:s2]; - builder.dns = dns; - }]; - - 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:@"uphosttest.qiniu.com"], @"Pass"); - XCTAssert([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + __block NSString *key = nil; + QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; + QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + NSArray *ips = [QNZone zone0].up.ips; + QNServiceAddress *s1 = [[QNServiceAddress alloc] init:@"http://uphosttest.qiniu.com" ips:ips]; + QNServiceAddress *s2 = [[QNServiceAddress alloc] init:@"http://uphosttestbak.qiniu.com" ips:ips]; + builder.zone = [[QNZone alloc] initWithUp:s1 upBackup:s2]; + builder.dns = dns; + }]; + + 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:@"uphosttest.qiniu.com"], @"Pass"); + XCTAssert([@"FgoKnypncpQlV6tTVddq9EL49l4B" isEqualToString:testResp[@"key"]], @"Pass"); } - (void)test0sizeData { - __block QNResponseInfo *testInfo = nil; - __block NSDictionary *testResp = nil; - - QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo":@"bar" } checkCrc:YES cancellationSignal:nil]; - NSData *data = [@"" dataUsingEncoding:NSUTF8StringEncoding]; - [self.upManager putData:data key:@"你好" token:g_token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { - testInfo = info; - testResp = resp; - } option:opt]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - NSLog(@"%@", testResp); - XCTAssert(testInfo.statusCode == kQNZeroDataSize, @"Pass"); + __block QNResponseInfo *testInfo = nil; + __block NSDictionary *testResp = nil; + + QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo" : @"bar" } checkCrc:YES cancellationSignal:nil]; + NSData *data = [@"" dataUsingEncoding:NSUTF8StringEncoding]; + [self.upManager putData:data key:@"你好" token:g_token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + testInfo = info; + testResp = resp; + } + option:opt]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + NSLog(@"%@", testResp); + XCTAssert(testInfo.statusCode == kQNZeroDataSize, @"Pass"); } @end diff --git a/QiniuSDKTests/QNHttpTest.m b/QiniuSDKTests/QNHttpTest.m index c45b9c09..b75dfd7d 100644 --- a/QiniuSDKTests/QNHttpTest.m +++ b/QiniuSDKTests/QNHttpTest.m @@ -13,8 +13,8 @@ #import "QNHttpManager.h" #import "QNResponseInfo.h" -#import "QNConfiguration.h" #import "HappyDNS.h" +#import "QNConfiguration.h" @interface QNHttpTest : XCTestCase @property QNHttpManager *httpManager; @@ -23,110 +23,126 @@ @interface QNHttpTest : XCTestCase @implementation QNHttpTest - (void)setUp { - [super setUp]; - _httpManager = [[QNHttpManager alloc] init]; + [super setUp]; + _httpManager = [[QNHttpManager alloc] init]; } - (void)tearDown { - [super tearDown]; + [super tearDown]; } - (void)testPost { - __block QNResponseInfo *testInfo = nil; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - [_httpManager post:@"http://www.baidu.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 == nil, @"Pass"); - - testInfo = nil; - - [_httpManager post:@"http://up.qiniu.com" withData:nil 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"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/500" withData:nil 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.statusCode == 500, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/418" withData:nil 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.statusCode == 418, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/200" withData:nil 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.statusCode == 200, @"Pass"); - XCTAssert(!testInfo.isOK, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); + __block QNResponseInfo *testInfo = nil; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [_httpManager post:@"http://www.baidu.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 == nil, @"Pass"); + + testInfo = nil; + + [_httpManager post:@"http://up.qiniu.com" withData:nil 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"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/500" withData:nil 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.statusCode == 500, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/418" withData:nil 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.statusCode == 418, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/200" withData:nil 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.statusCode == 200, @"Pass"); + XCTAssert(!testInfo.isOK, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); } - (void)testUrlConvert { - QNUrlConvert c = ^NSString *(NSString *url) { - return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; - }; - - QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:c dns:nil]; - 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"); + QNUrlConvert c = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + + QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:c dns:nil]; + 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"); } - (void)testPostIp { - __block QNResponseInfo *testInfo = nil; - QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; - QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; - [dns putHosts: @"upnonono.qiniu.com" ip: [QNZone zone0].up.ips[0]]; - QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:nil dns:dns]; - [httpManager post:@"http://upnonono.qiniu.com" withData:nil 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"); + __block QNResponseInfo *testInfo = nil; + QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; + QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; + [dns putHosts:@"upnonono.qiniu.com" ip:[QNZone zone0].up.ips[0]]; + QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:nil dns:dns]; + [httpManager post:@"http://upnonono.qiniu.com" withData:nil 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"); } - (void)testPostNoPort { - __block QNResponseInfo *testInfo = nil; - QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:nil dns:nil]; - [httpManager post:@"http://up.qiniu.com:12345/" withData:nil withParams:nil withHeaders:nil withCompleteBlock: ^(QNResponseInfo *info, NSDictionary *resp) { - testInfo = info; - } withProgressBlock:nil withCancelBlock:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"testInfo: %@ %d", testInfo, testInfo.statusCode); - XCTAssert(testInfo.statusCode < 0, @"Pass"); + __block QNResponseInfo *testInfo = nil; + QNHttpManager *httpManager = [[QNHttpManager alloc] initWithTimeout:60 urlConverter:nil dns:nil]; + [httpManager post:@"http://up.qiniu.com:12345/" withData:nil withParams:nil withHeaders:nil withCompleteBlock:^(QNResponseInfo *info, NSDictionary *resp) { + testInfo = info; + } + withProgressBlock:nil + withCancelBlock:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"testInfo: %@ %d", testInfo, testInfo.statusCode); + XCTAssert(testInfo.statusCode < 0, @"Pass"); } // travis ci iOS simulator 8.1 failed,其他环境(mac, iOS 9.0)正常,待详细排查 diff --git a/QiniuSDKTests/QNResumeUploadTest.m b/QiniuSDKTests/QNResumeUploadTest.m index 3e6f70e0..ae439984 100644 --- a/QiniuSDKTests/QNResumeUploadTest.m +++ b/QiniuSDKTests/QNResumeUploadTest.m @@ -10,11 +10,11 @@ #import -#import "QiniuSDK.h" #import "HappyDNS.h" +#import "QiniuSDK.h" -#import "QNTestConfig.h" #import "QNTempFile.h" +#import "QNTestConfig.h" @interface QNResumeUploadTest : XCTestCase @property QNUploadManager *upManager; @@ -24,64 +24,71 @@ @interface QNResumeUploadTest : XCTestCase @implementation QNResumeUploadTest - (void)setUp { - [super setUp]; - _upManager = [[QNUploadManager alloc] init]; + [super setUp]; + _upManager = [[QNUploadManager alloc] init]; #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED - NSString *travis = [[NSProcessInfo processInfo]environment][@"QINIU_TEST_ENV"]; - if ([travis isEqualToString:@"travis"]) { - _inTravis = YES; - } + NSString *travis = [[NSProcessInfo processInfo] environment][@"QINIU_TEST_ENV"]; + if ([travis isEqualToString:@"travis"]) { + _inTravis = YES; + } #endif } - (void)tearDown { - [super tearDown]; + [super tearDown]; } - (void)testCancel { - int size = 6 * 1024; - NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; - NSString *keyUp = [NSString stringWithFormat:@"%dk", size]; - __block NSString *key = nil; - __block QNResponseInfo *info = nil; - __block BOOL flag = NO; - QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil progressHandler: ^(NSString *key, float percent) { - flag = YES; - } params:@{ @"x:七牛":@"objc", @"x:no":@"", @"invalid":@"invalid" } checkCrc:NO cancellationSignal: ^BOOL () { - return flag; - }]; - [_upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - } option:opt]; - - AGWW_WAIT_WHILE(key == nil, 60 * 30); - NSLog(@"info %@", info); - XCTAssert(info.isCancelled, @"Pass"); - XCTAssert([keyUp isEqualToString:key], @"Pass"); - - [QNTempFile removeTempfile:tempFile]; + int size = 6 * 1024; + NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; + NSString *keyUp = [NSString stringWithFormat:@"%dk", size]; + __block NSString *key = nil; + __block QNResponseInfo *info = nil; + __block BOOL flag = NO; + QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { + flag = YES; + } + params:@{ @"x:七牛" : @"objc", + @"x:no" : @"", + @"invalid" : @"invalid" } + checkCrc:NO + cancellationSignal:^BOOL() { + return flag; + }]; + [_upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } + option:opt]; + + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.isCancelled, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + + [QNTempFile removeTempfile:tempFile]; } -- (void)template:(int)size { - NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; - NSString *keyUp = [NSString stringWithFormat:@"%dk", size]; - __block NSString *key = nil; - __block QNResponseInfo *info = nil; - QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler: ^(NSString *key, float percent) { - NSLog(@"progress %f", percent); - }]; - [_upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - } option:opt]; - AGWW_WAIT_WHILE(key == nil, 60 * 30); - NSLog(@"info %@", info); - XCTAssert(info.isOK, @"Pass"); - XCTAssert(info.reqId, @"Pass"); - XCTAssert([keyUp isEqualToString:key], @"Pass"); - - [QNTempFile removeTempfile:tempFile]; +- (void) template:(int)size { + NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; + NSString *keyUp = [NSString stringWithFormat:@"%dk", size]; + __block NSString *key = nil; + __block QNResponseInfo *info = nil; + QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler:^(NSString *key, float percent) { + NSLog(@"progress %f", percent); + }]; + [_upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } + option:opt]; + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.isOK, @"Pass"); + XCTAssert(info.reqId, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + + [QNTempFile removeTempfile:tempFile]; } - (void)templateHttps:(int)size { @@ -89,77 +96,79 @@ - (void)templateHttps:(int)size { NSString *keyUp = [NSString stringWithFormat:@"%dk", size]; __block NSString *key = nil; __block QNResponseInfo *info = nil; - QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler: ^(NSString *key, float percent) { + QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler:^(NSString *key, float percent) { NSLog(@"progress %f", percent); }]; - + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { QNServiceAddress *s = [[QNServiceAddress alloc] init:@"https://uptemp.qbox.me" ips:nil]; builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; }]; - QNUploadManager *upManager = [[QNUploadManager alloc]initWithConfiguration:config]; - - [upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; + + [upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { key = k; info = i; - } option:opt]; + } + option:opt]; AGWW_WAIT_WHILE(key == nil, 60 * 30); NSLog(@"info %@", info); XCTAssert(info.isOK, @"Pass"); XCTAssert(info.reqId, @"Pass"); XCTAssert([keyUp isEqualToString:key], @"Pass"); - + [QNTempFile removeTempfile:tempFile]; } - (void)testNoKey { - NSURL *tempFile = [QNTempFile createTempfileWithSize:600 * 1024]; - __block QNResponseInfo *info = nil; - __block NSDictionary *testResp = nil; - __block NSString *key = nil; - [_upManager putFile:tempFile.path key:nil token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - testResp = resp; - } option:nil]; - AGWW_WAIT_WHILE(info == nil, 60 * 30); - NSLog(@"resp %@", testResp); - XCTAssert(info.isOK, @"Pass"); - XCTAssert(info.reqId, @"Pass"); - XCTAssert(key == nil, @"Pass"); - XCTAssert([@"FnwKMB9tve71u37IlABna6j4Gdyr" isEqualToString:testResp[@"key"]], @"Pass"); - [QNTempFile removeTempfile:tempFile]; + NSURL *tempFile = [QNTempFile createTempfileWithSize:600 * 1024]; + __block QNResponseInfo *info = nil; + __block NSDictionary *testResp = nil; + __block NSString *key = nil; + [_upManager putFile:tempFile.path key:nil token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + testResp = resp; + } + option:nil]; + AGWW_WAIT_WHILE(info == nil, 60 * 30); + NSLog(@"resp %@", testResp); + XCTAssert(info.isOK, @"Pass"); + XCTAssert(info.reqId, @"Pass"); + XCTAssert(key == nil, @"Pass"); + XCTAssert([@"FnwKMB9tve71u37IlABna6j4Gdyr" isEqualToString:testResp[@"key"]], @"Pass"); + [QNTempFile removeTempfile:tempFile]; } - (void)test0k { - NSURL *tempFile = [QNTempFile createTempfileWithSize:0]; - NSString *keyUp = [NSString stringWithFormat:@"%dk", 0]; - __block NSString *key = nil; - __block QNResponseInfo *info = nil; - QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler: ^(NSString *key, float percent) { - NSLog(@"progress %f", percent); - }]; - [_upManager putFile:tempFile.path key:keyUp token:g_token complete: ^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { - key = k; - info = i; - } option:opt]; - AGWW_WAIT_WHILE(key == nil, 60 * 30); - NSLog(@"info %@", info); - XCTAssert(info.statusCode == kQNZeroDataSize, @"Pass"); - XCTAssert([keyUp isEqualToString:key], @"Pass"); - - [QNTempFile removeTempfile:tempFile]; + NSURL *tempFile = [QNTempFile createTempfileWithSize:0]; + NSString *keyUp = [NSString stringWithFormat:@"%dk", 0]; + __block NSString *key = nil; + __block QNResponseInfo *info = nil; + QNUploadOption *opt = [[QNUploadOption alloc] initWithProgressHandler:^(NSString *key, float percent) { + NSLog(@"progress %f", percent); + }]; + [_upManager putFile:tempFile.path key:keyUp token:g_token complete:^(QNResponseInfo *i, NSString *k, NSDictionary *resp) { + key = k; + info = i; + } + option:opt]; + AGWW_WAIT_WHILE(key == nil, 60 * 30); + NSLog(@"info %@", info); + XCTAssert(info.statusCode == kQNZeroDataSize, @"Pass"); + XCTAssert([keyUp isEqualToString:key], @"Pass"); + + [QNTempFile removeTempfile:tempFile]; } - (void)test500k { - [self template:500]; + [self template:500]; } - (void)test600k { - [self template:600]; + [self template:600]; } - //- (void)test500ks { // [self templateHttps:500]; //} @@ -168,121 +177,123 @@ - (void)test600k { // [self templateHttps:600]; //} - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED - (void)test1M { - if (_inTravis) { - return; - } - [self template:1024]; + if (_inTravis) { + return; + } + [self template:1024]; } - (void)test4M { - if (_inTravis) { - return; - } - [self template:4 * 1024]; + if (_inTravis) { + return; + } + [self template:4 * 1024]; } - (void)test8M { - if (_inTravis) { - return; - } - [self template:8 * 1024 + 1]; + if (_inTravis) { + return; + } + [self template:8 * 1024 + 1]; } - (void)testProxy { - NSDictionary *proxyDict = @{ - @"HTTPEnable" : [NSNumber numberWithInt:1], - (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", - (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, - }; - - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - builder.proxy = proxyDict; - QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; - builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; - }]; - - QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; - - int size = 600; - NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; - NSString *keyUp = [NSString stringWithFormat:@"%dkproxy", 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"); - - [QNTempFile removeTempfile:tempFile]; + NSDictionary *proxyDict = @{ + @"HTTPEnable" : [NSNumber numberWithInt:1], + (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", + (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, + }; + + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + builder.proxy = proxyDict; + QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; + builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; + }]; + + QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; + + int size = 600; + NSURL *tempFile = [QNTempFile createTempfileWithSize:size * 1024]; + NSString *keyUp = [NSString stringWithFormat:@"%dkproxy", 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"); + + [QNTempFile removeTempfile:tempFile]; } - (void)testUrlConvert { - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - builder.converter = ^NSString *(NSString *url) { - return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; - }; - QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; - builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; - }]; - - 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]; + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + builder.converter = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + QNServiceAddress *s = [[QNServiceAddress alloc] init:@"http://upnono.qiniu.com" ips:nil]; + builder.zone = [[QNZone alloc] initWithUp:s upBackup:nil]; + }]; + + 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]; } - (void)testHosts { - QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; - QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; - QNConfiguration *config = [QNConfiguration build: ^(QNConfigurationBuilder *builder) { - NSArray *ips = [QNZone zone0].up.ips; - QNServiceAddress *s1 = [[QNServiceAddress alloc] init:@"http://uphosttest.qiniu.com" ips:ips]; - QNServiceAddress *s2 = [[QNServiceAddress alloc] init:@"http://uphosttestbak.qiniu.com" ips:ips]; - builder.zone = [[QNZone alloc] initWithUp:s1 upBackup:s2]; - builder.dns = dns; - }]; - - 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:@"uphosttest.qiniu.com"] || [info.host isEqual:@"uphosttestbak.qiniu.com"], @"Pass"); - [QNTempFile removeTempfile:tempFile]; + QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; + QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + NSArray *ips = [QNZone zone0].up.ips; + QNServiceAddress *s1 = [[QNServiceAddress alloc] init:@"http://uphosttest.qiniu.com" ips:ips]; + QNServiceAddress *s2 = [[QNServiceAddress alloc] init:@"http://uphosttestbak.qiniu.com" ips:ips]; + builder.zone = [[QNZone alloc] initWithUp:s1 upBackup:s2]; + builder.dns = dns; + }]; + + 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:@"uphosttest.qiniu.com"] || [info.host isEqual:@"uphosttestbak.qiniu.com"], @"Pass"); + [QNTempFile removeTempfile:tempFile]; } #endif diff --git a/QiniuSDKTests/QNSessionTest.m b/QiniuSDKTests/QNSessionTest.m index a90ced26..d2adaca3 100644 --- a/QiniuSDKTests/QNSessionTest.m +++ b/QiniuSDKTests/QNSessionTest.m @@ -12,11 +12,11 @@ #import -#import "QNSessionManager.h" #import "QNResponseInfo.h" +#import "QNSessionManager.h" -#import "QNConfiguration.h" #import "HappyDNS.h" +#import "QNConfiguration.h" @interface QNSessionTest : XCTestCase @property QNSessionManager *httpManager; @@ -25,117 +25,133 @@ @interface QNSessionTest : XCTestCase @implementation QNSessionTest - (void)setUp { - [super setUp]; - _httpManager = [[QNSessionManager alloc] init]; + [super setUp]; + _httpManager = [[QNSessionManager alloc] init]; } - (void)tearDown { - [super tearDown]; + [super tearDown]; } - (void)testPost { - __block QNResponseInfo *testInfo = nil; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - [_httpManager post:@"http://www.baidu.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 == nil, @"Pass"); - - testInfo = nil; - [_httpManager post:@"http://up.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"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/500" 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.statusCode == 500, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/418" 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.statusCode == 418, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); - - testInfo = nil; - [_httpManager post:@"http://httpbin.org/status/200" 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.statusCode == 200, @"Pass"); - XCTAssert(!testInfo.isOK, @"Pass"); - XCTAssert(testInfo.error != nil, @"Pass"); + __block QNResponseInfo *testInfo = nil; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + [_httpManager post:@"http://www.baidu.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 == nil, @"Pass"); + + testInfo = nil; + [_httpManager post:@"http://up.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"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/500" 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.statusCode == 500, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/418" 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.statusCode == 418, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); + + testInfo = nil; + [_httpManager post:@"http://httpbin.org/status/200" 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.statusCode == 200, @"Pass"); + XCTAssert(!testInfo.isOK, @"Pass"); + XCTAssert(testInfo.error != nil, @"Pass"); } - (void)testProxy { - NSDictionary *proxyDict = @{ - @"HTTPEnable" : [NSNumber numberWithInt:1], - (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", - (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, - }; - - QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:proxyDict timeout:60 urlConverter:nil dns: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) { - testInfo = info; - } withProgressBlock:nil withCancelBlock:nil]; - - AGWW_WAIT_WHILE(testInfo == nil, 100.0); - NSLog(@"%@", testInfo); - XCTAssert(testInfo.reqId, @"Pass"); + NSDictionary *proxyDict = @{ + @"HTTPEnable" : [NSNumber numberWithInt:1], + (NSString *)kCFStreamPropertyHTTPProxyHost : @"183.136.139.16", + (NSString *)kCFStreamPropertyHTTPProxyPort : @8888, + }; + + QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:proxyDict timeout:60 urlConverter:nil dns: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) { + testInfo = info; + } + withProgressBlock:nil + withCancelBlock:nil]; + + AGWW_WAIT_WHILE(testInfo == nil, 100.0); + NSLog(@"%@", testInfo); + 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 dns:nil]; - 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"); + QNUrlConvert c = ^NSString *(NSString *url) { + return [url stringByReplacingOccurrencesOfString:@"upnono" withString:@"up"]; + }; + + QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:nil timeout:60 urlConverter:c dns:nil]; + 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"); } - (void)testPostIp { - __block QNResponseInfo *testInfo = nil; - NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; - QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; - QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; - [dns putHosts: @"upnonono.qiniu.com" ip: [QNZone zone0].up.ips[0]]; - QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:nil timeout:60 urlConverter:nil dns:dns]; - [httpManager post:@"http://upnonono.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"); + __block QNResponseInfo *testInfo = nil; + NSData *data = [@"Hello, World!" dataUsingEncoding:NSUTF8StringEncoding]; + QNResolver *resolver = [[QNResolver alloc] initWithAddres:@"114.114.115.115"]; + QNDnsManager *dns = [[QNDnsManager alloc] init:[NSArray arrayWithObject:resolver] networkInfo:[QNNetworkInfo normal]]; + [dns putHosts:@"upnonono.qiniu.com" ip:[QNZone zone0].up.ips[0]]; + QNSessionManager *httpManager = [[QNSessionManager alloc] initWithProxy:nil timeout:60 urlConverter:nil dns:dns]; + [httpManager post:@"http://upnonono.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"); } //- (void)testPostNoPort { diff --git a/QiniuSDKTests/QNTempFile.m b/QiniuSDKTests/QNTempFile.m index fb0ab921..004ba1eb 100644 --- a/QiniuSDKTests/QNTempFile.m +++ b/QiniuSDKTests/QNTempFile.m @@ -11,17 +11,17 @@ @implementation QNTempFile + (NSURL *)createTempfileWithSize:(int)size { - NSString *fileName = [NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"file.txt"]; - NSURL *fileUrl = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]]; - NSData *data = [NSMutableData dataWithLength:size]; - NSError *error = nil; - [data writeToURL:fileUrl options:NSDataWritingAtomic error:&error]; - return fileUrl; + NSString *fileName = [NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], @"file.txt"]; + NSURL *fileUrl = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]]; + NSData *data = [NSMutableData dataWithLength:size]; + NSError *error = nil; + [data writeToURL:fileUrl options:NSDataWritingAtomic error:&error]; + return fileUrl; } + (void)removeTempfile:(NSURL *)fileUrl { - NSError *error = nil; - [[NSFileManager defaultManager] removeItemAtURL:fileUrl error:&error]; + NSError *error = nil; + [[NSFileManager defaultManager] removeItemAtURL:fileUrl error:&error]; } @end diff --git a/QiniuSDKTests/QNUpTokenTest.m b/QiniuSDKTests/QNUpTokenTest.m index 7372657a..6cdaea08 100644 --- a/QiniuSDKTests/QNUpTokenTest.m +++ b/QiniuSDKTests/QNUpTokenTest.m @@ -6,12 +6,11 @@ // Copyright (c) 2015年 Qiniu. All rights reserved. // - #import #import -#import "QNUpToken.h" #import "QNTestConfig.h" +#import "QNUpToken.h" @interface QNUpTokenTest : XCTestCase @@ -20,13 +19,13 @@ @interface QNUpTokenTest : XCTestCase @implementation QNUpTokenTest - (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; } //public void testReturnUrl() { @@ -35,26 +34,26 @@ - (void)tearDown { //} - (void)testRight { - QNUpToken *t = [QNUpToken parse:g_token]; - // This is an example of a functional test case. - XCTAssert(t != nil, @"Pass"); - XCTAssert(!t.hasReturnUrl, @"Pass"); + QNUpToken *t = [QNUpToken parse:g_token]; + // This is an example of a functional test case. + XCTAssert(t != nil, @"Pass"); + XCTAssert(!t.hasReturnUrl, @"Pass"); } - (void)testEmpty { - QNUpToken *t = [QNUpToken parse:nil]; - // This is an example of a functional test case. - XCTAssert(t == nil, @"Pass"); + QNUpToken *t = [QNUpToken parse:nil]; + // This is an example of a functional test case. + XCTAssert(t == nil, @"Pass"); - t = [QNUpToken parse:@""]; - // This is an example of a functional test case. - XCTAssert(t == nil, @"Pass"); + t = [QNUpToken parse:@""]; + // This is an example of a functional test case. + XCTAssert(t == nil, @"Pass"); } - (void)testReturnUrl { - QNUpToken *t = [QNUpToken parse:@"QWYn5TFQsLLU1pL5MFEmX3s5DmHdUThav9WyOWOm:1jLiztn4plVyeB8Hie1ryO5z9uo=:eyJzY29wZSI6InB5c2RrIiwiZGVhZGxpbmUiOjE0MzM0ODM5MzYsInJldHVyblVybCI6Imh0dHA6Ly8xMjcuMC4wLjEvIn0="]; - // This is an example of a functional test case. - XCTAssert(t.hasReturnUrl, @"Pass"); + QNUpToken *t = [QNUpToken parse:@"QWYn5TFQsLLU1pL5MFEmX3s5DmHdUThav9WyOWOm:1jLiztn4plVyeB8Hie1ryO5z9uo=:eyJzY29wZSI6InB5c2RrIiwiZGVhZGxpbmUiOjE0MzM0ODM5MzYsInJldHVyblVybCI6Imh0dHA6Ly8xMjcuMC4wLjEvIn0="]; + // This is an example of a functional test case. + XCTAssert(t.hasReturnUrl, @"Pass"); } @end diff --git a/format.sh b/format.sh new file mode 100644 index 00000000..cc0c99fe --- /dev/null +++ b/format.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Change this if your clang-format executable is somewhere else +CLANG_FORMAT="$HOME/Library/Application Support/Alcatraz/Plug-ins/ClangFormat/bin/clang-format" + +find . \( -name '*.h' -or -name '*.m' -or -name '*.mm' \) -print0 | xargs -0 "$CLANG_FORMAT" -i