|  |  |  | @ -25,12 +25,20 @@ BOOL IsNSErrorNetworkFailure(NSError *_Nullable error) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @interface TSNetworkManager () | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // This property should only be accessed on udSerialQueue. | 
		
	
		
			
				|  |  |  |  | @property (atomic, readonly) AFHTTPSessionManager *udSessionManager; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @property (atomic, readonly) dispatch_queue_t udSerialQueue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @implementation TSNetworkManager | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @synthesize udSessionManager = _udSessionManager; | 
		
	
		
			
				|  |  |  |  | @synthesize udSerialQueue = _udSerialQueue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #pragma mark Singleton implementation | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | + (instancetype)sharedManager | 
		
	
	
		
			
				
					|  |  |  | @ -47,6 +55,8 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); | 
		
	
		
			
				|  |  |  |  |         return self; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     _udSerialQueue = dispatch_queue_create("org.whispersystems.networkManager.udQueue", DISPATCH_QUEUE_SERIAL); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     OWSSingletonAssert(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return self; | 
		
	
	
		
			
				
					|  |  |  | @ -70,10 +80,16 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(successBlock); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(failureBlock); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (request.isUDRequest) { | 
		
	
		
			
				|  |  |  |  |         dispatch_async(self.udSerialQueue, ^{ | 
		
	
		
			
				|  |  |  |  |             [self makeUDRequestSync:request success:successBlock failure:failureBlock]; | 
		
	
		
			
				|  |  |  |  |         }); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ | 
		
	
		
			
				|  |  |  |  |             [self makeRequestSync:request completionQueue:completionQueue success:successBlock failure:failureBlock]; | 
		
	
		
			
				|  |  |  |  |         }); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (void)makeRequestSync:(TSRequest *)request | 
		
	
		
			
				|  |  |  |  |         completionQueue:(dispatch_queue_t)completionQueue | 
		
	
	
		
			
				
					|  |  |  | @ -84,11 +100,11 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(successBlock); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(failureBlock); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     OWSLogInfo(@"Making request: %@", request); | 
		
	
		
			
				|  |  |  |  |     OWSLogInfo(@"Making Non-UD request: %@", request); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // TODO: Remove this logging when the call connection issues have been resolved. | 
		
	
		
			
				|  |  |  |  |     TSNetworkManagerSuccess success = ^(NSURLSessionDataTask *task, _Nullable id responseObject) { | 
		
	
		
			
				|  |  |  |  |         OWSLogInfo(@"request succeeded : %@", request); | 
		
	
		
			
				|  |  |  |  |         OWSLogInfo(@"Non-UD request succeeded : %@", request); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (request.shouldHaveAuthorizationHeaders) { | 
		
	
		
			
				|  |  |  |  |             [TSAccountManager.sharedInstance setIsDeregistered:NO]; | 
		
	
	
		
			
				
					|  |  |  | @ -110,17 +126,72 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); | 
		
	
		
			
				|  |  |  |  |                                                                          password:request.authPassword]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Honor the request's preferences about default cookie handling. | 
		
	
		
			
				|  |  |  |  |     // | 
		
	
		
			
				|  |  |  |  |     // Default is YES. | 
		
	
		
			
				|  |  |  |  |     sessionManager.requestSerializer.HTTPShouldHandleCookies = request.HTTPShouldHandleCookies; | 
		
	
		
			
				|  |  |  |  |     // Honor the request's headers. | 
		
	
		
			
				|  |  |  |  |     for (NSString *headerField in request.allHTTPHeaderFields) { | 
		
	
		
			
				|  |  |  |  |         NSString *headerValue = request.allHTTPHeaderFields[headerField]; | 
		
	
		
			
				|  |  |  |  |         [sessionManager.requestSerializer setValue:headerValue forHTTPHeaderField:headerField]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     [self performRequest:request sessionManager:sessionManager success:success failure:failure]; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // This method should only be invoked on udSerialQueue. | 
		
	
		
			
				|  |  |  |  | - (AFHTTPSessionManager *)udSessionManager | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     if (!_udSessionManager) { | 
		
	
		
			
				|  |  |  |  |         _udSessionManager = [OWSSignalService sharedInstance].signalServiceSessionManager; | 
		
	
		
			
				|  |  |  |  |         _udSessionManager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | 
		
	
		
			
				|  |  |  |  |         // NOTE: We could enable HTTPShouldUsePipelining here. | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return _udSessionManager; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (void)makeUDRequestSync:(TSRequest *)request | 
		
	
		
			
				|  |  |  |  |                   success:(TSNetworkManagerSuccess)successBlock | 
		
	
		
			
				|  |  |  |  |                   failure:(TSNetworkManagerFailure)failureBlock | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(request); | 
		
	
		
			
				|  |  |  |  |     OWSAssert(!request.shouldHaveAuthorizationHeaders); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(successBlock); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(failureBlock); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     OWSLogInfo(@"Making UD request: %@", request); | 
		
	
		
			
				|  |  |  |  |     uint64_t before = [NSDate ows_millisecondTimeStamp]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     TSNetworkManagerSuccess success = ^(NSURLSessionDataTask *task, _Nullable id responseObject) { | 
		
	
		
			
				|  |  |  |  |         OWSLogInfo(@"UD request succeeded : %@", request); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         successBlock(task, responseObject); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         [OutageDetection.sharedManager reportConnectionSuccess]; | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |     TSNetworkManagerFailure failure = [TSNetworkManager errorPrettifyingForFailureBlock:failureBlock request:request]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     AFHTTPSessionManager *sessionManager = self.udSessionManager; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Honor the request's headers. | 
		
	
		
			
				|  |  |  |  |     for (NSString *headerField in sessionManager.requestSerializer.HTTPRequestHeaders.allKeys.copy) { | 
		
	
		
			
				|  |  |  |  |         [sessionManager.requestSerializer setValue:nil forHTTPHeaderField:headerField]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     for (NSString *headerField in request.allHTTPHeaderFields) { | 
		
	
		
			
				|  |  |  |  |         NSString *headerValue = request.allHTTPHeaderFields[headerField]; | 
		
	
		
			
				|  |  |  |  |         [sessionManager.requestSerializer setValue:headerValue forHTTPHeaderField:headerField]; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     [self performRequest:request sessionManager:sessionManager success:success failure:failure]; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | - (void)performRequest:(TSRequest *)request | 
		
	
		
			
				|  |  |  |  |         sessionManager:(AFHTTPSessionManager *)sessionManager | 
		
	
		
			
				|  |  |  |  |                success:(TSNetworkManagerSuccess)success | 
		
	
		
			
				|  |  |  |  |                failure:(TSNetworkManagerFailure)failure | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(request); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(sessionManager); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(success); | 
		
	
		
			
				|  |  |  |  |     OWSAssertDebug(failure); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if ([request.HTTPMethod isEqualToString:@"GET"]) { | 
		
	
		
			
				|  |  |  |  |         [sessionManager GET:request.URL.absoluteString | 
		
	
		
			
				|  |  |  |  |                  parameters:request.parameters | 
		
	
	
		
			
				
					|  |  |  | 
 |