QNAutoZone.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. // QNAutoZone.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2020/4/16.
  6. // Copyright © 2020 Qiniu. All rights reserved.
  7. //
  8. #import "QNAutoZone.h"
  9. #import "QNSessionManager.h"
  10. #import "QNZoneInfo.h"
  11. #import "QNUpToken.h"
  12. #import "QNResponseInfo.h"
  13. @interface QNAutoZoneCache : NSObject
  14. @property(nonatomic, strong)NSMutableDictionary *cache;
  15. @end
  16. @implementation QNAutoZoneCache
  17. + (instancetype)share{
  18. static QNAutoZoneCache *cache = nil;
  19. static dispatch_once_t onceToken;
  20. dispatch_once(&onceToken, ^{
  21. cache = [[QNAutoZoneCache alloc] init];
  22. [cache setupData];
  23. });
  24. return cache;
  25. }
  26. - (void)setupData{
  27. self.cache = [NSMutableDictionary dictionary];
  28. }
  29. - (void)cache:(NSDictionary *)zonesInfo
  30. forToken:(QNUpToken *)token{
  31. NSString *cacheKey = token.index;
  32. if (!cacheKey || [cacheKey isEqualToString:@""]) {
  33. return;
  34. }
  35. @synchronized (self) {
  36. if (zonesInfo) {
  37. self.cache[cacheKey] = zonesInfo;
  38. } else {
  39. [self.cache removeObjectForKey:cacheKey];
  40. }
  41. }
  42. }
  43. - (QNZonesInfo *)zonesInfoForToken:(QNUpToken *)token{
  44. NSString *cacheKey = token.index;
  45. if (!cacheKey || [cacheKey isEqualToString:@""]) {
  46. return nil;
  47. }
  48. NSDictionary *zonesInfoDic = nil;
  49. @synchronized (self) {
  50. zonesInfoDic = self.cache[cacheKey];
  51. }
  52. if (zonesInfoDic == nil) {
  53. return nil;
  54. }
  55. QNZonesInfo *zonesInfo = [QNZonesInfo buildZonesInfoWithResp:zonesInfoDic];
  56. NSMutableArray *zonesInfoArray = [NSMutableArray array];
  57. for (QNZoneInfo *zoneInfo in zonesInfo.zonesInfo) {
  58. if ([zoneInfo isValid]) {
  59. [zonesInfoArray addObject:zoneInfo];
  60. }
  61. }
  62. zonesInfo.zonesInfo = [zonesInfoArray copy];
  63. return zonesInfo;
  64. }
  65. @end
  66. @implementation QNAutoZone {
  67. NSString *server;
  68. NSMutableDictionary *cache;
  69. NSLock *lock;
  70. QNSessionManager *sesionManager;
  71. }
  72. - (instancetype)init{
  73. if (self = [super init]) {
  74. server = @"https://uc.qbox.me";
  75. cache = [NSMutableDictionary new];
  76. lock = [NSLock new];
  77. sesionManager = [[QNSessionManager alloc] initWithProxy:nil timeout:10 urlConverter:nil];
  78. }
  79. return self;
  80. }
  81. - (NSString *)up:(QNUpToken *)token
  82. zoneInfoType:(QNZoneInfoType)zoneInfoType
  83. isHttps:(BOOL)isHttps
  84. frozenDomain:(NSString *)frozenDomain {
  85. NSString *index = [token index];
  86. [lock lock];
  87. QNZonesInfo *zonesInfo = [cache objectForKey:index];
  88. [lock unlock];
  89. if (zonesInfo == nil) {
  90. return nil;
  91. }
  92. return [self upHost:[zonesInfo getZoneInfoWithType:zoneInfoType] isHttps:isHttps lastUpHost:frozenDomain];
  93. }
  94. - (QNZonesInfo *)getZonesInfoWithToken:(QNUpToken *)token {
  95. if (token == nil) return nil;
  96. [lock lock];
  97. QNZonesInfo *zonesInfo = [cache objectForKey:[token index]];
  98. [lock unlock];
  99. return zonesInfo;
  100. }
  101. - (void)preQuery:(QNUpToken *)token
  102. on:(QNPrequeryReturn)ret {
  103. if (token == nil) {
  104. ret(-1, nil);
  105. return;
  106. }
  107. [lock lock];
  108. QNZonesInfo *zonesInfo = [cache objectForKey:[token index]];
  109. [lock unlock];
  110. if (zonesInfo == nil) {
  111. zonesInfo = [[QNAutoZoneCache share] zonesInfoForToken:token];
  112. [self->lock lock];
  113. [self->cache setValue:zonesInfo forKey:[token index]];
  114. [self->lock unlock];
  115. }
  116. if (zonesInfo != nil) {
  117. ret(0, nil);
  118. return;
  119. }
  120. //https://uc.qbox.me/v3/query?ak=T3sAzrwItclPGkbuV4pwmszxK7Ki46qRXXGBBQz3&bucket=if-pbl
  121. NSString *url = [NSString stringWithFormat:@"%@/v3/query?ak=%@&bucket=%@", server, token.access, token.bucket];
  122. [sesionManager get:url withHeaders:nil withCompleteBlock:^(QNHttpResponseInfo *httpResponseInfo, NSDictionary *respBody) {
  123. if (!httpResponseInfo.error) {
  124. QNZonesInfo *zonesInfo = [QNZonesInfo buildZonesInfoWithResp:respBody];
  125. if (httpResponseInfo == nil) {
  126. ret(kQNInvalidToken, httpResponseInfo);
  127. } else {
  128. [self->lock lock];
  129. [self->cache setValue:zonesInfo forKey:[token index]];
  130. [self->lock unlock];
  131. [[QNAutoZoneCache share] cache:respBody forToken:token];
  132. ret(0, httpResponseInfo);
  133. }
  134. } else {
  135. ret(kQNNetworkError, httpResponseInfo);
  136. }
  137. }];
  138. }
  139. @end