#import <Foundation/Foundation.h>
#import <TPHTTPClient/TPHTTPRequest.h>
@class TPSSError;
@class TPNetResqustManager;
typedef void (^TPNetSucceedBlk)(NSDictionary *);
typedef void (^TPNetFailureBlk)(NSError *);
typedef void (^TPNetRequestHeaderBlk)(NSMutableDictionary *);
@interface TPNetResqustManager : NSObject
@property(nonatomic, copy) TPNetRequestHeaderBlk reqHeaderBlk;
@property(nonatomic, copy) NSString *appType;
@property(nonatomic, strong, readonly) dispatch_queue_t seriaQueue;
(instancetype)shareInstance;
(void)postWithUrl:(NSString *)url params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk;
(void)getWithUrl:(NSString *)url params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk;
(void)postWithUrl:(NSString *)url header:(NSDictionary *)header params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk;
(void)getWithUrl:(NSString *)url header:(NSDictionary *)header params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk;
@end
#import “TPNetResqustManager.h”
#import <TPHTTPClient/TPHTTPClient.h>
#import <TPHandle-ObjC/TPHandle.h>
#import <TPHandle-ObjC/TPGCDReprocessHandle.h>
#import <TPHandle-ObjC/TPAbstractHandle.h>
#import <TPHTTPClient/TPHTTPResponse.h>
#import <TPHTTPClient/TPHTTPResponseConfig.h>
#import “TPSecurityPolicy.h”
#import “TPNetworkUtil.h”
@interface TPNetResqustManager()
@property(nonatomic, strong) dispatch_queue_t seriaQueue;
@property(nonatomic, strong) NSMutableDictionary *serverDomain;
@end
static const NSInteger kTPRequestTimeOut = 30;
@implementation TPNetResqustManager
(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
NSURLCredential *card = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}
(instancetype)shareInstance {
static dispatch_once_t onceToken;
static TPNetResqustManager *instance = nil;
dispatch_once(&onceToken, ^{
if (instance == nil) {
instance = [super allocWithZone:nil];
instance.seriaQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
instance.serverDomain = [NSMutableDictionary new];
}
});
return instance;
}
(instancetype)allocWithZone:(struct _NSZone *)zone {
return [TPNetResqustManager shareInstance];
}
#pragma mark -
(void)postWithUrl:(NSString *)url params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk {
[self postWithUrl:url header:nil params:params succeedBlk:sucBlk failureBlk:failureBlk];
}
(void)getWithUrl:(NSString *)url params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk {
[self getWithUrl:url header:nil params:params succeedBlk:sucBlk failureBlk:failureBlk];
}
(void)postWithUrl:(NSString *)url header:(NSDictionary *)header params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk {
[self requstWithUrl:url header:header method:TPHTTPRequestConfigRequestMethodPOST params:params succeedBlk:sucBlk failureBlk:failureBlk];
}
(void)getWithUrl:(NSString *)url header:(NSDictionary *)header params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk {
[self requstWithUrl:url header:header method:TPHTTPRequestConfigRequestMethodGET params:params succeedBlk:sucBlk failureBlk:failureBlk];
}
(void)requstWithUrl:(NSString *)url header:(NSDictionary *)header method:(NSString *)method params:(NSDictionary *)params succeedBlk:(TPNetSucceedBlk)sucBlk failureBlk:(TPNetFailureBlk)failureBlk {
TPHTTPRequest *request = [TPHTTPRequest new];
request.timeout = kTPRequestTimeOut;
request.httpConfig.url = url;
request.httpConfig.method = method;
[request.httpConfig.header addEntriesFromDictionary:[TPNetworkUtil defaultHeaders]];
header ? [request.httpConfig.header addEntriesFromDictionary:header] : nil;
[TPNetResqustManager shareInstance].reqHeaderBlk ? [TPNetResqustManager shareInstance].reqHeaderBlk(request.httpConfig.header) : nil;
#if DEBUG
NSLog(@“tprequest:%@ \nheader:%@ \nbody:%@\n”, url, header, params);
#endif
request.httpConfig.body = params;
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@“tp-link-CA.der”];
// TPHTTPClient *client = [self certClient:path];
TPHTTPClient *client = [self defaultClient];
[TPGCDReprocessHandle reprocessFromHandle:[client sendRequest:request] queue:dispatch_get_main_queue() reprocessAction:^TPHandleResult * _Nullable(TPHandleResult<TPHTTPResponse *> * _Nonnull result) {
[client.sessionManager.session finishTasksAndInvalidate];
if (!result.success) {
NSDictionary *codeDict = @{
@“httpStatusCode”: @(result.obj.httpConfig.statusCode),
@“httpErrorCode”: @(result.obj.httpConfig.urlErrorDomainCode),
};
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[@“statusCode”] = codeDict;
if (result.obj.httpConfig.body) {
dict[@“content”] = result.obj.httpConfig.body;
}
NSError *err = [NSError errorWithDomain:@"tplink.com" code:1 userInfo:dict]; failureBlk ? failureBlk(err) : nil; return nil; } sucBlk ? sucBlk(result.obj.httpConfig.body) : nil; return nil;
}];
}
#pragma mark - Private
(TPHTTPClient *)defaultClient {
return [self certClient:@“”];
}
(TPHTTPClient *)certClient:(NSString *)certPath {
TPHTTPClient *client = [TPHTTPClient new];
NSMutableSet *types = client.sessionManager.responseSerializer.acceptableContentTypes.mutableCopy;
[types addObjectsFromArray:@[@“application/json”, @“text/json”, @“text/javascript”, @“text/html”, @“text/plain”]];
client.sessionManager.responseSerializer.acceptableContentTypes = types;
NSData *data = [NSData dataWithContentsOfFile:certPath.length > 0 ? certPath : @“”];
if (data) {
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[NSSet setWithObject:data]];
policy.allowInvalidCertificates = YES;
policy.validatesDomainName = YES;
client.sessionManager.securityPolicy = policy;
} else {
client.sessionManager.securityPolicy = [TPSecurityPolicy defaultPolicy];
}
return client;
}
@end
#import <Foundation/Foundation.h>
@interface TPNetworkUtil : NSObject
(NSDictionary *)defaultHeaders;
(NSData *)HMACForData:(NSData *)data withKey:(NSData *)key;
(NSString *)strNetSettingForKey:(NSString *)key;
@end
@interface NSDictionary (Json)
(id)jsonValueForKey:(NSString *)key;
@end
#import “TPNetworkUtil.h”
#import <TPHTTPClient/TPHTTPRequest.h>
//#import <TPFoundation/TPFoundation.h>
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonHMAC.h>
#import “TPNetResqustManager.h”
static const NSString * const kTPNetRequestHeaderContentTypeKey = @“Content-Type”;
@implementation TPNetworkUtil
(NSDictionary *)defaultHeaders {
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[kTPNetRequestHeaderContentTypeKey] = @“application/json”;
return dict;
}
(NSData *)HMACForData:(NSData *)data withKey:(NSData *)key {
if (key.length <= 0 || data.length <= 0) {
return nil;
}
NSMutableData* hmac = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, key.bytes, key.length, data.bytes, data.length, hmac.mutableBytes);
return hmac.copy;
}
(NSString *)strNetSettingForKey:(NSString *)key {
return [self netSettingForKey:key];
}
(id)netSettingForKey:(NSString *)key {
static NSDictionary *setting = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
setting = [self envirenment];
});
if (setting == nil) {
setting = [self envirenment];
}
if (key.length == 0) {
return nil;
}
#if BETA_EXPORT_SALE_CLOUD
key = [NSString stringWithFormat:@“%@.beta”,key];
#else
key = [NSString stringWithFormat:@“%@.release”, key];
#endif
return [setting jsonValueForKey:key];
}
#pragma mark - Private
(NSDictionary *)envirenment {
NSString *filePath = [[NSBundle mainBundle] pathForResource:@“VIGIAPPConfig” ofType:@“json”];
NSData *data = [NSData dataWithContentsOfFile:filePath];
if (data) {
NSError *error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
return jsonObject != nil ? jsonObject : @{};
}
return @{};
}
@end
@implementation NSDictionary (Json)
(id)jsonValueForKey:(NSString *)key {
NSArray *keys = [key componentsSeparatedByString:@“.”];
NSDictionary *value = self;
for (NSString *key in keys) {
if (![value isKindOfClass:[NSDictionary class]]) {
return nil;
}
value = [value valueForKey:key];
}
return value;
}
@end
#import <AFNetworking/AFNetworking.h>
@interface TPSecurityPolicy : AFSecurityPolicy
@end
#import “TPSecurityPolicy.h”
@implementation TPSecurityPolicy
(BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain {
NSString *tmp = [domain.lowercaseString stringByReplacingOccurrencesOfString:@“_” withString:@“”];
tmp = [tmp stringByReplacingOccurrencesOfString:@“-” withString:@“”];
if ([tmp containsString:@“tplink”]) {
return YES;
}
return [super evaluateServerTrust:serverTrust forDomain:domain];
}
@end
这六个文件实现了一个完整的模块,实现了什么功能?用swift写一个类,通过上面的架构实现下面这个接口请求:curl --location 'https://n-aps1-device-api.i.tplinkcloud.com/v1/firmware/batchGetSecureFwList?model=default&hwId=47C26D2BF192B61BBC0303A9BF0F75CD&hwVer=1.0&oemId=9BF735F1FB702AE2AF540201276E5063&fwVer=1.2.9&deviceType=CDD.PC.CLIENTSOFTWARE&user=default&deviceId=default&deviceToken=default'
--header 'Content-Type: application/json'
--header 'Cookie: SameSite=Lax'
--data '{
"queryList": [
{
"hwId": "47C26D2BF192B61BBC0303A9BF0F75CD",
"oemId": "9BF735F1FB702AE2AF540201276E5063",
"currentFwVer": "1.2.0",
"fwId": "",
"locale": "en_US"
}
],
"bizId": "xxx"
}'
最新发布