| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -509,11 +509,9 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assetRequestQueue.append(assetRequest)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Process the queue (which may start this request)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // asynchronously so that the caller has time to store
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // a reference to the asset request returned by this 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // a reference to the asset request returned by this
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // method before its success/failure handler is called.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DispatchQueue.main.async {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        processRequestQueueAsync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return assetRequest
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -545,7 +543,7 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.assetRequestDidSucceed(assetRequest: assetRequest, asset: asset)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            } else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.processRequestQueueSync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -562,7 +560,6 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // TODO: If we wanted to implement segment retry, we'll need to add
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    //       a segmentRequestDidFail() method.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private func segmentRequestDidFail(assetRequest: GiphyAssetRequest, assetSegment: GiphyAssetSegment) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DispatchQueue.main.async {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetSegment.state = .failed
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequest.state = .failed
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -587,13 +584,21 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assetRequestQueue = assetRequestQueue.filter { $0 != assetRequest }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Process the queue async to ensure that state in the downloader
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // classes is consistent before we try to start a new request.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        processRequestQueueAsync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private func processRequestQueueAsync() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DispatchQueue.main.async {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.processRequestQueueSync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // * Start a segment request or content length request if possible.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // * Complete/cancel asset requests if possible.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    //
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private func processRequestQueue() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private func processRequestQueueSync() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        AssertIsOnMainThread()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        guard let assetRequest = popNextAssetRequest() else {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -608,7 +613,7 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            // If app is not active, fail the asset request.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequest.state = .failed
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequestDidFail(assetRequest:assetRequest)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            processRequestQueueSync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -630,11 +635,11 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            request.httpMethod = "HEAD"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            request.httpShouldUsePipelining = true
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let task = giphyDownloadSession.dataTask(with:request, completionHandler: { [weak self] data, response, error -> Void in
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let task = giphyDownloadSession.dataTask(with:request, completionHandler: { data, response, error -> Void in
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if let data = data, data.count > 0 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    owsFail("\(self?.TAG) HEAD request has unexpected body: \(data.count).")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    owsFail("\(self.TAG) HEAD request has unexpected body: \(data.count).")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self?.handleAssetSizeResponse(assetRequest:assetRequest, response:response, error:error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.handleAssetSizeResponse(assetRequest:assetRequest, response:response, error:error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequest.contentLengthTask = task
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            task.resume()
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -659,7 +664,7 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Recurse; we may be able to start multiple downloads.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        processRequestQueueSync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private func handleAssetSizeResponse(assetRequest: GiphyAssetRequest, response: URLResponse?, error: Error?) {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -696,7 +701,7 @@ extension URLSessionTask {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DispatchQueue.main.async {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequest.contentLength = contentLength
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            assetRequest.state = .active
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.processRequestQueue()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.processRequestQueueSync()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |