1251 lines
43 KiB
Objective-C
1251 lines
43 KiB
Objective-C
/*
|
||
* Licensed to the Apache Software Foundation (ASF) under one
|
||
* or more contributor license agreements. See the NOTICE file
|
||
* distributed with this work for additional information
|
||
* regarding copyright ownership. The ASF licenses this file
|
||
* to you under the Apache License, Version 2.0 (the
|
||
* "License"); you may not use this file except in compliance
|
||
* with the License. You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing,
|
||
* software distributed under the License is distributed on an
|
||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
* KIND, either express or implied. See the License for the
|
||
* specific language governing permissions and limitations
|
||
* under the License.
|
||
*/
|
||
#import "HttpdnsService_Internal.h"
|
||
#import "HttpdnsRemoteResolver.h"
|
||
#import "HttpdnsInternalConstant.h"
|
||
#import "HttpdnsHostObject.h"
|
||
#import "HttpdnsRequest_Internal.h"
|
||
#import "HttpdnsUtil.h"
|
||
#import "HttpdnsRequest.h"
|
||
#import "HttpdnsLog_Internal.h"
|
||
#import "HttpdnsScheduleCenter.h"
|
||
#import "HttpdnsPublicConstant.h"
|
||
#import "HttpdnsRegionConfigLoader.h"
|
||
#import "HttpdnsIpStackDetector.h"
|
||
|
||
|
||
|
||
static dispatch_queue_t asyncTaskConcurrentQueue;
|
||
static NSMutableDictionary<NSNumber *, HttpDnsService *> *httpdnsServiceInstances;
|
||
static dispatch_queue_t httpdnsServiceInstancesQueue;
|
||
static HttpDnsService *httpdnsFirstInitializedInstance;
|
||
static HttpDnsService *httpdnsSharedStubInstance;
|
||
|
||
@interface HttpDnsService ()
|
||
|
||
@property (nonatomic, assign) NSInteger accountID;
|
||
@property (nonatomic, copy) NSString *secretKey;
|
||
@property (nonatomic, copy) NSString *aesSecretKey;
|
||
@property (nonatomic, assign) BOOL hasConfiguredAccount;
|
||
|
||
// æ¯<C3A6>次访问的ç¾å<C2BE><C3A5>有效期,SDK内部定æ»ï¼Œå½“å‰<C3A5>ä¸<C3A4>暴露设置接å<C2A5>£ï¼Œæœ‰æ•ˆæœŸå®šä¸º10分钟ã€?
|
||
@property (nonatomic, assign) NSUInteger authTimeoutInterval;
|
||
|
||
@property (nonatomic, copy) NSDictionary<NSString *, NSString *> *presetSdnsParamsDict;
|
||
|
||
// scheduleCenter 已在 HttpdnsService_Internal.h 暴露,é<C592>¿å…<C3A5>é‡<C3A9>å¤<C3A5>声æ˜?
|
||
|
||
@end
|
||
|
||
@implementation HttpDnsService
|
||
|
||
+ (void)initialize {
|
||
static dispatch_once_t onceToken;
|
||
dispatch_once(&onceToken, ^{
|
||
asyncTaskConcurrentQueue = dispatch_queue_create("com.New.sdk.httpdns.asyncTask", DISPATCH_QUEUE_CONCURRENT);
|
||
httpdnsServiceInstances = [NSMutableDictionary dictionary];
|
||
httpdnsServiceInstancesQueue = dispatch_queue_create("com.New.sdk.httpdns.serviceRegistry", DISPATCH_QUEUE_SERIAL);
|
||
});
|
||
}
|
||
|
||
#pragma mark -
|
||
#pragma mark ---------- singleton
|
||
|
||
|
||
+ (nonnull instancetype)sharedInstance {
|
||
__block HttpDnsService *firstInstance = nil;
|
||
dispatch_sync(httpdnsServiceInstancesQueue, ^{
|
||
firstInstance = httpdnsFirstInitializedInstance;
|
||
});
|
||
if (firstInstance) {
|
||
return firstInstance;
|
||
}
|
||
|
||
static dispatch_once_t stubOnceToken;
|
||
dispatch_once(&stubOnceToken, ^{
|
||
httpdnsSharedStubInstance = [[self alloc] init];
|
||
});
|
||
return httpdnsSharedStubInstance;
|
||
}
|
||
|
||
+ (nullable instancetype)getInstanceByAccountId:(NSInteger)accountID {
|
||
__block HttpDnsService *instance = nil;
|
||
dispatch_sync(httpdnsServiceInstancesQueue, ^{
|
||
instance = httpdnsServiceInstances[@(accountID)];
|
||
});
|
||
return instance;
|
||
}
|
||
|
||
+ (NSArray<HttpDnsService *> *)allRegisteredInstances {
|
||
__block NSArray<HttpDnsService *> *instances = nil;
|
||
dispatch_sync(httpdnsServiceInstancesQueue, ^{
|
||
instances = [httpdnsServiceInstances allValues];
|
||
});
|
||
return instances ?: @[];
|
||
}
|
||
|
||
+ (HttpDnsService *)instanceForAccountIDCreatingIfNeeded:(NSInteger)accountID {
|
||
__block HttpDnsService *instance = nil;
|
||
dispatch_sync(httpdnsServiceInstancesQueue, ^{
|
||
instance = httpdnsServiceInstances[@(accountID)];
|
||
if (instance) {
|
||
return;
|
||
}
|
||
|
||
if (!httpdnsFirstInitializedInstance) {
|
||
if (httpdnsSharedStubInstance) {
|
||
instance = httpdnsSharedStubInstance;
|
||
} else {
|
||
instance = [[self alloc] init];
|
||
httpdnsSharedStubInstance = instance;
|
||
}
|
||
httpdnsFirstInitializedInstance = instance;
|
||
} else {
|
||
instance = [[self alloc] init];
|
||
}
|
||
|
||
httpdnsServiceInstances[@(accountID)] = instance;
|
||
});
|
||
return instance;
|
||
}
|
||
|
||
- (nonnull instancetype)initWithAccountID:(NSInteger)accountID {
|
||
#pragma clang diagnostic push
|
||
#pragma clang diagnostic ignored "-Wnonnull"
|
||
return [self initWithAccountID:accountID secretKey:nil];
|
||
#pragma clang diagnostic pop
|
||
}
|
||
|
||
- (nonnull instancetype)initWithAccountID:(NSInteger)accountID secretKey:(NSString *)secretKey {
|
||
return [self initWithAccountID:accountID secretKey:secretKey aesSecretKey:nil];
|
||
}
|
||
|
||
- (nonnull instancetype)initWithAccountID:(NSInteger)accountID secretKey:(NSString *)secretKey aesSecretKey:(NSString *)aesSecretKey {
|
||
HttpDnsService *existing = [HttpDnsService getInstanceByAccountId:accountID];
|
||
if (existing) {
|
||
return existing;
|
||
}
|
||
|
||
HttpDnsService *service = [HttpDnsService instanceForAccountIDCreatingIfNeeded:accountID];
|
||
[service configureWithAccountID:accountID secretKey:secretKey aesSecretKey:aesSecretKey];
|
||
return service;
|
||
}
|
||
|
||
- (void)configureWithAccountID:(NSInteger)accountID
|
||
secretKey:(NSString *)secretKey
|
||
aesSecretKey:(NSString *)aesSecretKey {
|
||
@synchronized (self) {
|
||
if (self.hasConfiguredAccount) {
|
||
return;
|
||
}
|
||
|
||
self.accountID = accountID;
|
||
self.secretKey = [secretKey copy];
|
||
self.aesSecretKey = [aesSecretKey copy];
|
||
|
||
self.timeoutInterval = HTTPDNS_DEFAULT_REQUEST_TIMEOUT_INTERVAL;
|
||
self.authTimeoutInterval = HTTPDNS_DEFAULT_AUTH_TIMEOUT_INTERVAL;
|
||
self.enableHttpsRequest = NO;
|
||
self.hasAllowedArbitraryLoadsInATS = NO;
|
||
self.enableDegradeToLocalDNS = NO;
|
||
|
||
self.requestManager = [[HttpdnsRequestManager alloc] initWithAccountId:accountID ownerService:self];
|
||
|
||
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
|
||
NSString *regionKey = [NSString stringWithFormat:@"%@.%ld", kNewHttpdnsRegionKey, (long)accountID];
|
||
NSString *cachedRegion = [userDefault objectForKey:regionKey];
|
||
|
||
HttpdnsScheduleCenter *scheduleCenter = [[HttpdnsScheduleCenter alloc] initWithAccountId:accountID];
|
||
[scheduleCenter initRegion:cachedRegion];
|
||
self.scheduleCenter = scheduleCenter;
|
||
|
||
self.hasConfiguredAccount = YES;
|
||
}
|
||
}
|
||
|
||
- (void)attachAccountInfoToRequest:(HttpdnsRequest *)request {
|
||
request.accountId = self.accountID;
|
||
}
|
||
|
||
#pragma mark -
|
||
#pragma mark -------------- public
|
||
|
||
- (void)setAuthCurrentTime:(NSUInteger)authCurrentTime {
|
||
[self setInternalAuthTimeBaseBySpecifyingCurrentTime:authCurrentTime];
|
||
}
|
||
|
||
- (void)setInternalAuthTimeBaseBySpecifyingCurrentTime:(NSTimeInterval)currentTime {
|
||
NSTimeInterval localTime = [[NSDate date] timeIntervalSince1970];
|
||
self.authTimeOffset = currentTime - localTime;
|
||
}
|
||
|
||
- (void)setCachedIPEnabled:(BOOL)enable {
|
||
[self setPersistentCacheIPEnabled:enable];
|
||
}
|
||
|
||
- (void)setPersistentCacheIPEnabled:(BOOL)enable {
|
||
[_requestManager setCachedIPEnabled:enable discardRecordsHasExpiredFor:0];
|
||
}
|
||
|
||
- (void)setPersistentCacheIPEnabled:(BOOL)enable discardRecordsHasExpiredFor:(NSTimeInterval)duration {
|
||
if (duration < 0) {
|
||
duration = 0;
|
||
}
|
||
if (duration > SECONDS_OF_ONE_YEAR) {
|
||
duration = SECONDS_OF_ONE_YEAR;
|
||
}
|
||
[_requestManager setCachedIPEnabled:enable discardRecordsHasExpiredFor:duration];
|
||
}
|
||
|
||
- (void)setExpiredIPEnabled:(BOOL)enable {
|
||
[self setReuseExpiredIPEnabled:enable];
|
||
}
|
||
|
||
- (void)setReuseExpiredIPEnabled:(BOOL)enable {
|
||
[_requestManager setExpiredIPEnabled:enable];
|
||
}
|
||
|
||
- (void)setHTTPSRequestEnabled:(BOOL)enable {
|
||
self.enableHttpsRequest = enable;
|
||
}
|
||
|
||
- (void)setHasAllowedArbitraryLoadsInATS:(BOOL)hasAllowedArbitraryLoadsInATS {
|
||
self.allowedArbitraryLoadsInATS = hasAllowedArbitraryLoadsInATS;
|
||
}
|
||
|
||
- (void)setNetworkingTimeoutInterval:(NSTimeInterval)timeoutInterval {
|
||
self.timeoutInterval = timeoutInterval;
|
||
}
|
||
|
||
- (void)setRegion:(NSString *)region {
|
||
if ([HttpdnsUtil isEmptyString:region]) {
|
||
region = NEW_HTTPDNS_DEFAULT_REGION_KEY;
|
||
}
|
||
|
||
if (![[HttpdnsRegionConfigLoader getAvailableRegionList] containsObject:region]) {
|
||
HttpdnsLogDebug("Invalid region: %@, we currently only support these regions: %@", region, [HttpdnsRegionConfigLoader getAvailableRegionList]);
|
||
return;
|
||
}
|
||
|
||
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
|
||
NSString *regionKey = [NSString stringWithFormat:@"%@.%ld", kNewHttpdnsRegionKey, (long)self.accountID];
|
||
NSString *oldRegion = [userDefault objectForKey:regionKey];
|
||
if (![region isEqualToString:oldRegion]) {
|
||
[userDefault setObject:region forKey:regionKey];
|
||
|
||
// 仅清空本实例缓å˜ï¼Œè°ƒåº¦æŒ‰è´¦å<C2A6>·éš”离
|
||
[self cleanHostCache:nil];
|
||
|
||
// regionå<6E>˜åŒ–å<E28093>Žä»…更新本实例的æœ<C3A6>务IP
|
||
[self.scheduleCenter resetRegion:region];
|
||
}
|
||
}
|
||
|
||
- (void)setPreResolveHosts:(NSArray *)hosts {
|
||
[self setPreResolveHosts:hosts byIPType:HttpdnsQueryIPTypeBoth];
|
||
}
|
||
|
||
|
||
- (void)setPreResolveHosts:(NSArray *)hosts queryIPType:(NewHttpDNS_IPType)ipType {
|
||
HttpdnsQueryIPType ipQueryType;
|
||
switch (ipType) {
|
||
case NewHttpDNS_IPTypeV4:
|
||
ipQueryType = HttpdnsQueryIPTypeIpv4;
|
||
break;
|
||
case NewHttpDNS_IPTypeV6:
|
||
ipQueryType = HttpdnsQueryIPTypeIpv6;
|
||
break;
|
||
case NewHttpDNS_IPTypeV64:
|
||
ipQueryType = HttpdnsQueryIPTypeIpv4 | HttpdnsQueryIPTypeIpv6;
|
||
break;
|
||
default:
|
||
ipQueryType = HttpdnsQueryIPTypeIpv4;
|
||
break;
|
||
}
|
||
|
||
[self setPreResolveHosts:hosts byIPType:ipQueryType];
|
||
}
|
||
|
||
- (void)setPreResolveHosts:(NSArray *)hosts byIPType:(HttpdnsQueryIPType)ipType {
|
||
// åˆ<C3A5>始化过程包å<E280A6>«äº†regioné…<C3A9>置更新æµ<C3A6>程,region切æ<E280A1>¢ä¼šå¯¼è‡´ç¼“å˜æ¸…空,立å<E280B9>³å<C2B3>šé¢„è§£æž<C3A6>å<EFBFBD>¯èƒ½æ˜¯æ²¡æœ‰æ„<C3A6>义的
|
||
// 这是sdk接å<C2A5>£è®¾è®¡çš„历å<E280A0>²é—®é¢˜ï¼Œç›®å‰<C3A5>没有太好办法,这é‡?.5秒之å<EFBFBD>Žå†<EFBFBD>å<EFBFBD>‘预解æž<EFBFBD>请求
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), asyncTaskConcurrentQueue, ^{
|
||
[self->_requestManager preResolveHosts:hosts queryType:ipType];
|
||
});
|
||
}
|
||
|
||
- (void)setLogEnabled:(BOOL)enable {
|
||
if (enable) {
|
||
[HttpdnsLog enableLog];
|
||
} else {
|
||
[HttpdnsLog disableLog];
|
||
}
|
||
}
|
||
|
||
- (void)setPreResolveAfterNetworkChanged:(BOOL)enable {
|
||
[_requestManager setPreResolveAfterNetworkChanged:enable];
|
||
}
|
||
|
||
- (void)setIPRankingDatasource:(NSDictionary<NSString *, NSNumber *> *)IPRankingDatasource {
|
||
_IPRankingDataSource = IPRankingDatasource;
|
||
}
|
||
|
||
- (NSDictionary<NSString *, NSNumber *> *)getIPRankingDatasource {
|
||
return [_IPRankingDataSource copy];
|
||
}
|
||
|
||
- (void)setDegradeToLocalDNSEnabled:(BOOL)enable {
|
||
self.enableDegradeToLocalDNS = enable;
|
||
[_requestManager setDegradeToLocalDNSEnabled:enable];
|
||
}
|
||
|
||
- (void)enableIPv6:(BOOL)enable {
|
||
[self setIPv6Enabled:enable];
|
||
}
|
||
|
||
- (void)setIPv6Enabled:(BOOL)enable {
|
||
// 默认都支�
|
||
}
|
||
|
||
- (void)enableNetworkInfo:(BOOL)enable {
|
||
// å¼ƒç”¨æ¤æŽ¥å<C2A5>?
|
||
}
|
||
|
||
- (void)setReadNetworkInfoEnabled:(BOOL)enable {
|
||
// å¼ƒç”¨æ¤æŽ¥å<C2A5>?
|
||
}
|
||
|
||
- (void)enableCustomIPRank:(BOOL)enable {
|
||
// ä¸<C3A4>å†<C3A5>生效,ä¿<C3A4>留接å<C2A5>?
|
||
// 是å<C2AF>¦å¼€å<E282AC>¯è‡ªå®šä¹‰IP排åº<C3A5>,由是å<C2AF>¦è®¾ç½®IPRankingDatasourceå’ŒIPRankingDatasource䏿˜¯å<C2AF>¦èƒ½æ ¹æ<C2B9>®host找到对应的IPæ<50>¥å†³å®?
|
||
}
|
||
|
||
- (NSString *)getSessionId {
|
||
return [HttpdnsUtil generateSessionID];
|
||
}
|
||
|
||
#pragma mark -
|
||
#pragma mark -------------- resolving method start
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSync:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType {
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:queryIpType];
|
||
[self attachAccountInfoToRequest:request];
|
||
return [self resolveHostSync:request];
|
||
}
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSync:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType withSdnsParams:(NSDictionary<NSString *,NSString *> *)sdnsParams sdnsCacheKey:(NSString *)cacheKey {
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:queryIpType sdnsParams:sdnsParams cacheKey:cacheKey];
|
||
[self attachAccountInfoToRequest:request];
|
||
return [self resolveHostSync:request];
|
||
}
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSync:(HttpdnsRequest *)request {
|
||
if ([NSThread isMainThread]) {
|
||
// 主线程å<E280B9>šä¸€ä¸ªé˜²å¾?
|
||
return [self resolveHostSyncNonBlocking:request];
|
||
}
|
||
|
||
if (![self validateResolveRequest:request]) {
|
||
return nil;
|
||
}
|
||
|
||
if ([self _shouldDegradeHTTPDNS:request.host]) {
|
||
return nil;
|
||
}
|
||
|
||
[self refineResolveRequest:request];
|
||
[request becomeBlockingRequest];
|
||
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (!hostObject) {
|
||
return nil;
|
||
}
|
||
return [self constructResultFromHostObject:hostObject underQueryType:request.queryIpType];
|
||
}
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSyncNonBlocking:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType {
|
||
return [self resolveHostSyncNonBlocking:host byIpType:queryIpType withSdnsParams:nil sdnsCacheKey:nil];
|
||
}
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSyncNonBlocking:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType withSdnsParams:(NSDictionary<NSString *,NSString *> *)sdnsParams sdnsCacheKey:(NSString *)cacheKey {
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:queryIpType sdnsParams:sdnsParams cacheKey:cacheKey];
|
||
[self attachAccountInfoToRequest:request];
|
||
return [self resolveHostSyncNonBlocking:request];
|
||
}
|
||
|
||
- (nullable HttpdnsResult *)resolveHostSyncNonBlocking:(HttpdnsRequest *)request {
|
||
if (![self validateResolveRequest:request]) {
|
||
return nil;
|
||
}
|
||
|
||
if ([self _shouldDegradeHTTPDNS:request.host]) {
|
||
return nil;
|
||
}
|
||
|
||
[self refineResolveRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (!hostObject) {
|
||
return nil;
|
||
}
|
||
return [self constructResultFromHostObject:hostObject underQueryType:request.queryIpType];
|
||
}
|
||
|
||
- (void)resolveHostAsync:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType completionHandler:(void (^)(HttpdnsResult * nullable))handler {
|
||
[self resolveHostAsync:host byIpType:queryIpType withSdnsParams:nil sdnsCacheKey:nil completionHandler:handler];
|
||
}
|
||
|
||
- (void)resolveHostAsync:(NSString *)host byIpType:(HttpdnsQueryIPType)queryIpType withSdnsParams:(NSDictionary<NSString *,NSString *> *)sdnsParams sdnsCacheKey:(NSString *)cacheKey completionHandler:(void (^)(HttpdnsResult * nullable))handler {
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:queryIpType sdnsParams:sdnsParams cacheKey:cacheKey];
|
||
[self attachAccountInfoToRequest:request];
|
||
[self resolveHostAsync:request completionHandler:handler];
|
||
}
|
||
|
||
- (void)resolveHostAsync:(HttpdnsRequest *)request completionHandler:(void (^)(HttpdnsResult * nullable))handler {
|
||
if (![self validateResolveRequest:request]) {
|
||
dispatch_async(asyncTaskConcurrentQueue, ^{
|
||
handler(nil);
|
||
});
|
||
return;
|
||
}
|
||
|
||
if ([self _shouldDegradeHTTPDNS:request.host]) {
|
||
dispatch_async(asyncTaskConcurrentQueue, ^{
|
||
handler(nil);
|
||
});
|
||
return;
|
||
}
|
||
|
||
[self refineResolveRequest:request];
|
||
|
||
double enqueueStart = [[NSDate date] timeIntervalSince1970] * 1000;
|
||
dispatch_async(asyncTaskConcurrentQueue, ^{
|
||
double executeStart = [[NSDate date] timeIntervalSince1970] * 1000;
|
||
[request becomeBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [self->_requestManager resolveHost:request];
|
||
double innerEnd = [[NSDate date] timeIntervalSince1970] * 1000;
|
||
HttpdnsLogDebug("resolveHostAsync done, inner cost time from enqueue: %fms, from execute: %fms", (innerEnd - enqueueStart), (innerEnd - executeStart));
|
||
|
||
if (!hostObject) {
|
||
handler(nil);
|
||
} else {
|
||
handler([self constructResultFromHostObject:hostObject underQueryType:request.queryIpType]);
|
||
}
|
||
});
|
||
}
|
||
|
||
- (HttpdnsQueryIPType)determineLegitQueryIpType:(HttpdnsQueryIPType)specifiedQueryIpType {
|
||
// 自动选择,需è¦<C3A8>判æ–当å‰<C3A5>网络环境æ<C692>¥å†³å®š
|
||
if (specifiedQueryIpType == HttpdnsQueryIPTypeAuto) {
|
||
HttpdnsIPStackType stackType = [[HttpdnsIpStackDetector sharedInstance] currentIpStack];
|
||
switch (stackType) {
|
||
// å<>Œæ ˆå’Œipv6only,两个类型都è¦<C3A8>请æ±?
|
||
// è™½ç„¶åˆ¤æ–æ˜¯ipv6only,但现实ä¸å<C2AD>ªæœ‰å®žéªŒå®¤æ‰<C3A6>会有这ç§<C3A7>情况,考虑判æ–网络å<C593><C3A5>è®®æ ˆæ˜¯æœ‰è¯¯åˆ¤å<C2A4>¯èƒ½çš„,æ<C592>ƒè¡¡ä¹‹ä¸‹ï¼Œè¿˜æ˜¯åº”该请求ipv4
|
||
// 如果用户是在明确的实验室环境ä¸å<C2AD>šæµ‹è¯•ï¼Œä»–åº”è¯¥ç›´æŽ¥æŒ‡å®šè¯·æ±‚type为ipv6
|
||
case kHttpdnsIpDual:
|
||
case kHttpdnsIpv6Only:
|
||
return HttpdnsQueryIPTypeIpv4 | HttpdnsQueryIPTypeIpv6;
|
||
|
||
// å<>ªæœ‰ipv4only的情况,å<C592>ªè¯·æ±‚ipv4
|
||
case kHttpdnsIpv4Only:
|
||
default:
|
||
return HttpdnsQueryIPTypeIpv4;
|
||
}
|
||
}
|
||
|
||
// å<>¦åˆ™å°±æŒ‰æŒ‡å®šç±»åž‹æ<E280B9>¥è§£æž?
|
||
return specifiedQueryIpType;
|
||
}
|
||
|
||
- (BOOL)validateResolveRequest:(HttpdnsRequest *)request {
|
||
if (!request.host) {
|
||
HttpdnsLogDebug("validateResolveRequest failed, the host should not be nil.")
|
||
return NO;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:request.host]) {
|
||
HttpdnsLogDebug("validateResolveRequest failed, the host is just an IP.");
|
||
return NO;
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:request.host]) {
|
||
HttpdnsLogDebug("validateResolveRequest failed, the host is illegal.");
|
||
return NO;
|
||
}
|
||
|
||
return YES;
|
||
}
|
||
|
||
- (void)refineResolveRequest:(HttpdnsRequest *)request {
|
||
if (request.accountId == 0) {
|
||
request.accountId = self.accountID;
|
||
}
|
||
HttpdnsQueryIPType clarifiedQueryIpType = [self determineLegitQueryIpType:request.queryIpType];
|
||
request.queryIpType = clarifiedQueryIpType;
|
||
|
||
NSDictionary *mergedSdnsParam = [self mergeWithPresetSdnsParams:request.sdnsParams];
|
||
request.sdnsParams = mergedSdnsParam;
|
||
|
||
if (!request.cacheKey) {
|
||
// 缓å˜é€»è¾‘是ä¾<C3A4>èµ–cacheKey工作的,如果没有主动设置cacheKey,它实际上就是host
|
||
request.cacheKey = request.host;
|
||
}
|
||
|
||
[request ensureResolveTimeoutInReasonableRange];
|
||
}
|
||
|
||
- (HttpdnsResult *)constructResultFromHostObject:(HttpdnsHostObject *)hostObject underQueryType:(HttpdnsQueryIPType)queryType {
|
||
if (!hostObject) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isEmptyArray:[hostObject getV4Ips]] && [HttpdnsUtil isEmptyArray:[hostObject getV6Ips]]) {
|
||
// 这里是为了兼容过去用法的行为,如果完全没有ipä¿¡æ<C2A1>¯ï¼Œå<C592>¯ä»¥å¯¹é½<C3A9>åˆ°è¿‡åŽ»ç¼“å˜æ²¡æœ‰ip或解æž<C3A6>ä¸<C3A4>到ip的情况,直接返回nil
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsResult *result = [HttpdnsResult new];
|
||
result.host = [hostObject getHostName];
|
||
|
||
// 由于结果å<C593>¯èƒ½æ˜¯ä»Žç¼“å˜ä¸èŽ·å¾—ï¼Œæ‰€ä»¥è¿˜è¦<C3A8>æ ¹æ<C2B9>®å®žé™…å<E280A6><C3A5>è®®æ ˆæƒ…å†µå†<C3A5>ç›é€‰ä¸‹ç»“æžœ
|
||
if (queryType & HttpdnsQueryIPTypeIpv4) {
|
||
NSArray *ipv4s = [hostObject getV4Ips];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipv4s]) {
|
||
NSMutableArray *ipv4Array = [NSMutableArray array];
|
||
for (HttpdnsIpObject *ipObject in ipv4s) {
|
||
[ipv4Array addObject:[ipObject getIpString]];
|
||
}
|
||
result.ips = [ipv4Array copy];
|
||
result.ttl = hostObject.getV4TTL;
|
||
result.lastUpdatedTimeInterval = hostObject.lastIPv4LookupTime;
|
||
}
|
||
}
|
||
|
||
if (queryType & HttpdnsQueryIPTypeIpv6) {
|
||
NSArray *ipv6s = [hostObject getV6Ips];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipv6s]) {
|
||
NSMutableArray *ipv6Array = [NSMutableArray array];
|
||
for (HttpdnsIpObject *ipObject in ipv6s) {
|
||
[ipv6Array addObject:[ipObject getIpString]];
|
||
}
|
||
result.ipv6s = [ipv6Array copy];
|
||
result.v6ttl = hostObject.getV6TTL;
|
||
result.v6LastUpdatedTimeInterval = hostObject.lastIPv6LookupTime;
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
- (HttpdnsResult *)constructResultFromIp:(NSString *)ip underQueryType:(HttpdnsQueryIPType)queryType {
|
||
HttpdnsResult *result = [HttpdnsResult new];
|
||
result.host = ip;
|
||
|
||
if (queryType & HttpdnsQueryIPTypeIpv4) {
|
||
if ([HttpdnsUtil isIPv4Address:ip]) {
|
||
result.ips = @[ip];
|
||
}
|
||
}
|
||
|
||
if (queryType & HttpdnsQueryIPTypeIpv6) {
|
||
if ([HttpdnsUtil isIPv6Address:ip]) {
|
||
result.ipv6s = @[ip];
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
- (NSString *)getIpByHostAsync:(NSString *)host {
|
||
NSArray *ips = [self getIpsByHostAsync:host];
|
||
if ([HttpdnsUtil isNotEmptyArray:ips]) {
|
||
return ips[0];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSString *)getIPv4ForHostAsync:(NSString *)host {
|
||
NSArray *ips = [self getIPv4ListForHostAsync:host];
|
||
if ([HttpdnsUtil isNotEmptyArray:ips]) {
|
||
return ips[0];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIpsByHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
NSMutableArray *ipsArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
return ipsArray;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIPv4ListForHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal.");
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
NSMutableArray *ipsArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
return ipsArray;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIPv4ListForHostSync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
//需è¦<C3A8>检查是ä¸<C3A4>是在主线程,如果是主线程,ä¿<C3A4>æŒ<C3A6>异æ¥é€»è¾‘
|
||
if ([NSThread isMainThread]) {
|
||
//如果是主线程,ä»<C3A4>然使用异æ¥çš„æ–¹å¼<C3A5>,å<C592>³å…ˆæŸ¥è¯¢ç¼“å˜ï¼Œå¦‚果没有,则å<E284A2>‘é€<C3A9>异æ¥è¯·æ±?
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
NSMutableArray *ipsArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
return ipsArray;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
} else {
|
||
NSMutableArray *ipsArray = nil;
|
||
double start = [[NSDate date] timeIntervalSince1970] * 1000;
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeBlockingRequest];
|
||
__block HttpdnsHostObject *hostObject = [self->_requestManager resolveHost:request];
|
||
double end = [[NSDate date] timeIntervalSince1970] * 1000;
|
||
HttpdnsLogDebug("###### getIPv4ListForHostSync result: %@, resolve time delta is %f ms", hostObject, (end - start));
|
||
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
ipsArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
}
|
||
}
|
||
return ipsArray;
|
||
}
|
||
}
|
||
|
||
- (NSString *)getIpByHostAsyncInURLFormat:(NSString *)host {
|
||
NSString *IP = [self getIpByHostAsync:host];
|
||
if ([HttpdnsUtil isIPv6Address:IP]) {
|
||
return [NSString stringWithFormat:@"[%@]", IP];
|
||
}
|
||
return IP;
|
||
}
|
||
|
||
- (NSString *)getIPv6ByHostAsync:(NSString *)host {
|
||
NSArray *ips = [self getIPv6sByHostAsync:host];
|
||
if ([HttpdnsUtil isNotEmptyArray:ips]) {
|
||
return ips[0];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSString *)getIPv6ForHostAsync:(NSString *)host {
|
||
NSArray *ips = [self getIPv6ListForHostAsync:host];
|
||
if ([HttpdnsUtil isNotEmptyArray:ips]) {
|
||
return ips[0];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIPv6sByHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip6sObject = [hostObject getV6Ips];
|
||
NSMutableArray *ip6sArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6sObject]) {
|
||
for (HttpdnsIpObject *ip6Object in ip6sObject) {
|
||
[ip6sArray addObject:[ip6Object getIpString]];
|
||
}
|
||
return ip6sArray;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIPv6ListForHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip6sObject = [hostObject getV6Ips];
|
||
NSMutableArray *ip6sArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6sObject]) {
|
||
for (HttpdnsIpObject *ip6Object in ip6sObject) {
|
||
[ip6sArray addObject:[ip6Object getIpString]];
|
||
}
|
||
return ip6sArray;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIPv6ListForHostSync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
if ([NSThread isMainThread]) {
|
||
// 如果是主线程,ä»<C3A4>然使用异æ¥çš„æ–¹å¼<C3A5>,å<C592>³å…ˆæŸ¥è¯¢ç¼“å˜ï¼Œå¦‚果没有,则å<E284A2>‘é€<C3A9>异æ¥è¯·æ±?
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ipv6List = [hostObject getV6Ips];
|
||
NSMutableArray *ipv6Array = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipv6List]) {
|
||
for (HttpdnsIpObject *ipv6Obj in ipv6List) {
|
||
[ipv6Array addObject:[ipv6Obj getIpString]];
|
||
}
|
||
return ipv6Array;
|
||
}
|
||
}
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
} else {
|
||
NSMutableArray *ipv6Array = nil;
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
|
||
if (hostObject) {
|
||
NSArray * ipv6List = [hostObject getV6Ips];
|
||
ipv6Array = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipv6List]) {
|
||
for (HttpdnsIpObject *ipv6Obj in ipv6List) {
|
||
[ipv6Array addObject:[ipv6Obj getIpString]];
|
||
}
|
||
}
|
||
}
|
||
return ipv6Array;
|
||
}
|
||
}
|
||
|
||
- (NSDictionary<NSString *,NSArray *> *)getIPv4_v6ByHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
if ([HttpdnsUtil isIPv4Address:host]) {
|
||
return @{NewHDNS_IPV4: @[host?:@""]};
|
||
} else if ([HttpdnsUtil isIPv6Address:host]) {
|
||
return @{NewHDNS_IPV6: @[host?:@""]};
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4|HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip4s = [hostObject getV4IpStrings];
|
||
NSArray *ip6s = [hostObject getV6IpStrings];
|
||
NSMutableDictionary *resultMDic = [NSMutableDictionary dictionary];
|
||
if ([HttpdnsUtil isNotEmptyArray:ip4s]) {
|
||
[resultMDic setObject:ip4s forKey:NewHDNS_IPV4];
|
||
}
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6s]) {
|
||
[resultMDic setObject:ip6s forKey:NewHDNS_IPV6];
|
||
}
|
||
NSLog(@"getIPv4_v6ByHostAsync result is %@", resultMDic);
|
||
return resultMDic;
|
||
}
|
||
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
|
||
}
|
||
|
||
- (NSDictionary <NSString *, NSArray *>*)getHttpDnsResultHostAsync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
if ([HttpdnsUtil isIPv4Address:host]) {
|
||
return @{NewHDNS_IPV4: @[host?:@""]};
|
||
} else if ([HttpdnsUtil isIPv6Address:host]) {
|
||
return @{NewHDNS_IPV6: @[host?:@""]};
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4|HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip4s = [hostObject getV4IpStrings];
|
||
NSArray *ip6s = [hostObject getV6IpStrings];
|
||
NSMutableDictionary *httpdnsResult = [NSMutableDictionary dictionary];
|
||
NSLog(@"getHttpDnsResultHostAsync result is %@", httpdnsResult);
|
||
if ([HttpdnsUtil isNotEmptyArray:ip4s]) {
|
||
[httpdnsResult setObject:ip4s forKey:NewHDNS_IPV4];
|
||
}
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6s]) {
|
||
[httpdnsResult setObject:ip6s forKey:NewHDNS_IPV6];
|
||
}
|
||
return httpdnsResult;
|
||
}
|
||
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
}
|
||
|
||
- (NSDictionary <NSString *, NSArray *>*)getHttpDnsResultHostSync:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
if ([HttpdnsUtil isIPv4Address:host]) {
|
||
return @{NewHDNS_IPV4: @[host?:@""]};
|
||
} else if ([HttpdnsUtil isIPv6Address:host]) {
|
||
return @{NewHDNS_IPV6: @[host?:@""]};
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
if ([NSThread isMainThread]) {
|
||
// 主线程的è¯<C3A8>ä»<C3A4>然是走异æ¥çš„逻辑
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4|HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip4s = [hostObject getV4IpStrings];
|
||
NSArray *ip6s = [hostObject getV6IpStrings];
|
||
NSMutableDictionary *resultMDic = [NSMutableDictionary dictionary];
|
||
NSLog(@"getIPv4_v6ByHostAsync result is %@", resultMDic);
|
||
if ([HttpdnsUtil isNotEmptyArray:ip4s]) {
|
||
[resultMDic setObject:ip4s forKey:NewHDNS_IPV4];
|
||
}
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6s]) {
|
||
[resultMDic setObject:ip6s forKey:NewHDNS_IPV6];
|
||
}
|
||
return resultMDic;
|
||
}
|
||
|
||
HttpdnsLogDebug("No available IP cached for %@", host);
|
||
return nil;
|
||
} else {
|
||
NSMutableDictionary *resultMDic = nil;
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4|HttpdnsQueryIPTypeIpv6];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray *ip4s = [hostObject getV4IpStrings];
|
||
NSArray *ip6s = [hostObject getV6IpStrings];
|
||
resultMDic = [NSMutableDictionary dictionary];
|
||
if ([HttpdnsUtil isNotEmptyArray:ip4s]) {
|
||
[resultMDic setObject:ip4s forKey:NewHDNS_IPV4];
|
||
}
|
||
if ([HttpdnsUtil isNotEmptyArray:ip6s]) {
|
||
[resultMDic setObject:ip6s forKey:NewHDNS_IPV6];
|
||
}
|
||
NSLog(@"###### getHttpDnsResultHostSync result is %@", resultMDic);
|
||
}
|
||
return resultMDic;
|
||
}
|
||
}
|
||
|
||
-(NSDictionary <NSString *, NSArray *>*)autoGetIpsByHostAsync:(NSString *)host {
|
||
HttpdnsIPStackType stackType = [[HttpdnsIpStackDetector sharedInstance] currentIpStack];
|
||
NSMutableDictionary *ipv4_ipv6 = [NSMutableDictionary dictionary];
|
||
if (stackType == kHttpdnsIpDual) {
|
||
ipv4_ipv6 = [[self getIPv4_v6ByHostAsync:host] mutableCopy];
|
||
} else if (stackType == kHttpdnsIpv4Only) {
|
||
NSArray* ipv4Ips = [self getIpsByHostAsync:host];
|
||
if (ipv4Ips != nil) {
|
||
[ipv4_ipv6 setObject:ipv4Ips forKey:NewHDNS_IPV4];
|
||
}
|
||
} else if (stackType == kHttpdnsIpv6Only) {
|
||
NSArray* ipv6Ips = [self getIPv6sByHostAsync:host];
|
||
if (ipv6Ips != nil) {
|
||
[ipv4_ipv6 setObject:ipv6Ips forKey:NewHDNS_IPV6];
|
||
}
|
||
}
|
||
|
||
return ipv4_ipv6;
|
||
}
|
||
|
||
-(NSDictionary <NSString *, NSArray *>*)autoGetHttpDnsResultForHostAsync:(NSString *)host {
|
||
HttpdnsIPStackType stackType = [[HttpdnsIpStackDetector sharedInstance] currentIpStack];
|
||
NSMutableDictionary *httpdnsResult = [NSMutableDictionary dictionary];
|
||
if (stackType == kHttpdnsIpDual) {
|
||
httpdnsResult = [[self getHttpDnsResultHostAsync:host] mutableCopy];
|
||
} else if (stackType == kHttpdnsIpv4Only) {
|
||
NSArray* ipv4IpList = [self getIPv4ListForHostAsync:host];
|
||
if (ipv4IpList) {
|
||
[httpdnsResult setObject:ipv4IpList forKey:NewHDNS_IPV4];
|
||
}
|
||
} else if (stackType == kHttpdnsIpv6Only) {
|
||
NSArray* ipv6List = [self getIPv6ListForHostAsync:host];
|
||
if (ipv6List) {
|
||
[httpdnsResult setObject:ipv6List forKey:NewHDNS_IPV6];
|
||
}
|
||
}
|
||
|
||
return httpdnsResult;
|
||
}
|
||
|
||
- (NSDictionary <NSString *, NSArray *>*)autoGetHttpDnsResultForHostSync:(NSString *)host {
|
||
HttpdnsIPStackType stackType = [[HttpdnsIpStackDetector sharedInstance] currentIpStack];
|
||
NSMutableDictionary *httpdnsResult = [NSMutableDictionary dictionary];
|
||
if (stackType == kHttpdnsIpv4Only) {
|
||
NSArray* ipv4IpList = [self getIPv4ListForHostSync:host];
|
||
if (ipv4IpList) {
|
||
[httpdnsResult setObject:ipv4IpList forKey:NewHDNS_IPV4];
|
||
}
|
||
} else if (stackType == kHttpdnsIpDual) {
|
||
httpdnsResult = [[self getHttpDnsResultHostSync:host] mutableCopy];
|
||
} else if (stackType == kHttpdnsIpv6Only) {
|
||
NSArray* ipv6List = [self getIPv6ListForHostSync:host];
|
||
if (ipv6List) {
|
||
[httpdnsResult setObject:ipv6List forKey:NewHDNS_IPV6];
|
||
}
|
||
}
|
||
return httpdnsResult;
|
||
}
|
||
|
||
- (void)setLogHandler:(id<HttpdnsLoggerProtocol>)logHandler {
|
||
if (logHandler != nil) {
|
||
[HttpdnsLog setLogHandler:logHandler];
|
||
} else {
|
||
[HttpdnsLog unsetLogHandler];
|
||
}
|
||
}
|
||
|
||
- (void)cleanHostCache:(NSArray<NSString *> *)hostArray {
|
||
if ([HttpdnsUtil isEmptyArray:hostArray]) {
|
||
[self cleanAllHostCache];
|
||
return;
|
||
}
|
||
|
||
[_requestManager cleanMemoryAndPersistentCacheOfHostArray:hostArray];
|
||
}
|
||
|
||
- (void)cleanAllHostCache {
|
||
[_requestManager cleanMemoryAndPersistentCacheOfAllHosts];
|
||
}
|
||
|
||
- (void)setSdnsGlobalParams:(NSDictionary<NSString *, NSString *> *)params {
|
||
if ([HttpdnsUtil isNotEmptyDictionary:params]) {
|
||
self.presetSdnsParamsDict = params;
|
||
}
|
||
}
|
||
|
||
- (void)clearSdnsGlobalParams {
|
||
self.presetSdnsParamsDict = nil;
|
||
}
|
||
|
||
- (NSDictionary *)getIpsByHostAsync:(NSString *)host withParams:(NSDictionary<NSString *, NSString *> *)params withCacheKey:(NSString *)cacheKey {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
if (!host) {
|
||
return nil;
|
||
}
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSDictionary dictionaryWithObject:host forKey:@"host"];
|
||
}
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
if (![HttpdnsUtil isNotEmptyString: cacheKey]) {
|
||
cacheKey = @"";
|
||
}
|
||
|
||
params = [self mergeWithPresetSdnsParams:params];
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4 sdnsParams:params cacheKey:cacheKey];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeNonBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
NSMutableArray *ipsArray = [[NSMutableArray alloc] init];
|
||
NSMutableDictionary * ipsDictionary = [[NSMutableDictionary alloc] init];
|
||
[ipsDictionary setObject:host forKey:@"host"];
|
||
if ([HttpdnsUtil isNotEmptyString:hostObject.extra]) {
|
||
[ipsDictionary setObject:hostObject.extra forKey:@"extra"];
|
||
}
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
[ipsDictionary setObject:ipsArray forKey:@"ips"];
|
||
return ipsDictionary;
|
||
}
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
|
||
#pragma mark -
|
||
#pragma mark -------------- private
|
||
|
||
- (NSDictionary<NSString *, NSString *> *)mergeWithPresetSdnsParams:(NSDictionary<NSString *, NSString *> *)params {
|
||
if (!self.presetSdnsParamsDict) {
|
||
return params;
|
||
}
|
||
|
||
|
||
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:self.presetSdnsParamsDict];
|
||
if (params) {
|
||
// æ˜Žç¡®ä¼ å<C2A0>‚çš„params优先级更高,å<C592>¯ä»¥è¦†ç›–预é…<C3A9>置的å<E2809E>‚æ•°
|
||
[result addEntriesFromDictionary:params];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
- (BOOL)_shouldDegradeHTTPDNS:(NSString *)host {
|
||
#pragma clang diagnostic push
|
||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||
if (self.delegate && [self.delegate respondsToSelector:@selector(shouldDegradeHTTPDNS:)]) {
|
||
return [self.delegate shouldDegradeHTTPDNS:host];
|
||
}
|
||
#pragma clang diagnostic pop
|
||
return NO;
|
||
}
|
||
|
||
- (NSString *)getIpByHost:(NSString *)host {
|
||
NSArray *ips = [self getIpsByHost:host];
|
||
if ([HttpdnsUtil isNotEmptyArray:ips]) {
|
||
return ips[0];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSArray *)getIpsByHost:(NSString *)host {
|
||
if ([self _shouldDegradeHTTPDNS:host]) {
|
||
return nil;
|
||
}
|
||
|
||
if ([HttpdnsUtil isAnIP:host]) {
|
||
HttpdnsLogDebug("The host is just an IP: %@", host);
|
||
return [NSArray arrayWithObjects:host, nil];
|
||
}
|
||
|
||
if (![HttpdnsUtil isAHost:host]) {
|
||
HttpdnsLogDebug("The host is illegal: %@", host);
|
||
return nil;
|
||
}
|
||
|
||
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:host queryIpType:HttpdnsQueryIPTypeIpv4];
|
||
[self attachAccountInfoToRequest:request];
|
||
[request becomeBlockingRequest];
|
||
HttpdnsHostObject *hostObject = [_requestManager resolveHost:request];
|
||
if (hostObject) {
|
||
NSArray * ipsObject = [hostObject getV4Ips];
|
||
NSMutableArray *ipsArray = [[NSMutableArray alloc] init];
|
||
if ([HttpdnsUtil isNotEmptyArray:ipsObject]) {
|
||
for (HttpdnsIpObject *ipObject in ipsObject) {
|
||
[ipsArray addObject:[ipObject getIpString]];
|
||
}
|
||
return ipsArray;
|
||
}
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSString *)getIpByHostInURLFormat:(NSString *)host {
|
||
NSString *IP = [self getIpByHost:host];
|
||
if ([HttpdnsUtil isIPv6Address:IP]) {
|
||
return [NSString stringWithFormat:@"[%@]", IP];
|
||
}
|
||
return IP;
|
||
}
|
||
|
||
@end
|