|
| 1 | +// |
| 2 | +// COSXMLCSPGetSignatureHelper.m |
| 3 | +// QCloudCSPDemo |
| 4 | +// |
| 5 | +// Created by karisli(李雪) on 2018/9/20. |
| 6 | +// Copyright © 2018年 karisli(李雪). All rights reserved. |
| 7 | +// |
| 8 | + |
| 9 | +#import "COSXMLGetSignatureTool.h" |
| 10 | + |
| 11 | +#import "QCloudRequestSerializer.h" |
| 12 | +#import "QCloudLogger.h" |
| 13 | +#import "QCloudURLHelper.h" |
| 14 | +#import <QCloudCore/QCloudError.h> |
| 15 | +@implementation NSDictionary(HeaderFilter) |
| 16 | +- (NSDictionary*)filteHeaders; { |
| 17 | + NSMutableDictionary* signedHeaders = [[NSMutableDictionary alloc] init]; |
| 18 | + __block const NSMutableArray* shouldSignedHeaderList = @[ @"Content-Length", @"Content-MD5"]; |
| 19 | + [self enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { |
| 20 | + //签名的Headers列表:x开头的(x-cos-之类的),content-length,content-MD5 |
| 21 | + BOOL shouldSigned = NO; |
| 22 | + for (NSString* header in shouldSignedHeaderList) { |
| 23 | + if ([header isEqualToString:((NSString*)key)]) { |
| 24 | + shouldSigned = YES; |
| 25 | + } |
| 26 | + } |
| 27 | + NSArray* headerSeperatedArray = [key componentsSeparatedByString:@"-"]; |
| 28 | + if ([headerSeperatedArray firstObject] && [headerSeperatedArray.firstObject isEqualToString:@"x"]) { |
| 29 | + shouldSigned = YES; |
| 30 | + } |
| 31 | + if (shouldSigned) { |
| 32 | + signedHeaders[key]=obj; |
| 33 | + } |
| 34 | + }]; |
| 35 | + return [signedHeaders copy]; |
| 36 | +} |
| 37 | +@end |
| 38 | +@implementation NSURL(QCloudCSPExtension) |
| 39 | + |
| 40 | +/** |
| 41 | + 返回 COS 签名中用到的 path , 。如果没有path时,为 / |
| 42 | + |
| 43 | + 例如 |
| 44 | + 1. URL 为: http://test-123456.cos.ap-shanghai.myqcloud.com?delimiter=%2F&max-keys=1000&prefix=test%2F |
| 45 | + |
| 46 | + path为 / |
| 47 | + |
| 48 | + 2. URL为: http://test-123456.cos.ap-shanghai.myqcloud.com/test |
| 49 | + path 为 test |
| 50 | + |
| 51 | + 3. URL为: http://test-123456.cos.ap-shanghai.myqcloud.com/test/ |
| 52 | + path 为 test/ |
| 53 | + |
| 54 | + |
| 55 | + @return COS签名中定义的 path |
| 56 | + */ |
| 57 | + |
| 58 | +- (NSString*)qcloud_csp_path { |
| 59 | + NSString* path = QCloudPercentEscapedStringFromString(self.path); |
| 60 | + //absoluteString in NSURL is URLEncoded |
| 61 | + NSRange pathRange = [self.absoluteString rangeOfString:path]; |
| 62 | + NSUInteger URLLength = self.absoluteString.length; |
| 63 | + if ( pathRange.location == NSNotFound ) { |
| 64 | + return self.path; |
| 65 | + } |
| 66 | + NSUInteger pathLocation = pathRange.location + pathRange.length; |
| 67 | + if (pathLocation >= URLLength) { |
| 68 | + return self.path; |
| 69 | + } |
| 70 | + if ( [self.absoluteString characterAtIndex:(pathLocation)] == '/' ) { |
| 71 | + path = [self.path stringByAppendingString:@"/"]; |
| 72 | + return path; |
| 73 | + } |
| 74 | + |
| 75 | + return self.path; |
| 76 | +} |
| 77 | + |
| 78 | +@end |
| 79 | +@implementation COSXMLGetSignatureTool |
| 80 | ++(instancetype)sharedNewtWorkTool |
| 81 | +{ |
| 82 | + static id _instance; |
| 83 | + static dispatch_once_t onceToken; |
| 84 | + dispatch_once(&onceToken, ^{ |
| 85 | + _instance = [[self alloc] init]; |
| 86 | + }); |
| 87 | + return _instance; |
| 88 | +} |
| 89 | + |
| 90 | +-(void)PutRequestWithUrl:(NSString *)urlString request:(NSMutableURLRequest* )urlRequest successBlock:(SuccessBlock)success; |
| 91 | +{ |
| 92 | + //取出参数 |
| 93 | + NSDictionary* headers = [[urlRequest allHTTPHeaderFields] filteHeaders]; |
| 94 | + NSDictionary* paramas = QCloudURLReadQuery(urlRequest.URL); |
| 95 | + NSMutableDictionary *paramaters = [NSMutableDictionary dictionary]; |
| 96 | + paramaters[@"path"] = urlRequest.URL.qcloud_csp_path; |
| 97 | + paramaters[@"method"] = urlRequest.HTTPMethod; |
| 98 | + paramaters[@"host"] = urlRequest.URL.host; |
| 99 | + paramaters[@"headers"] = headers; |
| 100 | + paramaters[@"params"] = paramas; |
| 101 | + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; |
| 102 | + request.HTTPMethod = @"PUT"; |
| 103 | + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; |
| 104 | + [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:paramaters options:NSJSONWritingPrettyPrinted error:nil]]; |
| 105 | + |
| 106 | + NSLog(@"request Body: %@",[[NSString alloc]initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]); |
| 107 | + [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { |
| 108 | + QCloudLogInfo(@"response data:%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); |
| 109 | + if (data && !error) { |
| 110 | + id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; |
| 111 | + if (!obj) { |
| 112 | + @throw [NSException exceptionWithName:QCloudErrorDomain reason:@"返回的不是json数据" userInfo:nil]; |
| 113 | + } |
| 114 | + NSDictionary *dic = (NSDictionary *)obj; |
| 115 | + QCloudLogInfo(@"%@ 的签名%@",urlRequest.URL,dic[@"sign"]); |
| 116 | + dispatch_async(dispatch_get_main_queue(), ^{ |
| 117 | + if (success) { |
| 118 | + success(obj[@"sign"]); |
| 119 | + } |
| 120 | + }); |
| 121 | + }else |
| 122 | + { |
| 123 | + @throw [NSException exceptionWithName:QCloudErrorDomain reason:@"获取签名错误" userInfo:nil]; |
| 124 | + } |
| 125 | + |
| 126 | + }] resume]; |
| 127 | + |
| 128 | +} |
| 129 | +@end |
0 commit comments