Merge branch 'charlesmchen/prekeyFetchViaWebSocket'

pull/1/head
Matthew Chen 7 years ago
commit b5ed4e8ead

@ -1501,41 +1501,86 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
TSRequest *request = [OWSRequestFactory recipientPrekeyRequestWithRecipient:recipientId TSRequest *request = [OWSRequestFactory recipientPrekeyRequestWithRecipient:recipientId
deviceId:[deviceId stringValue] deviceId:[deviceId stringValue]
unidentifiedAccess:messageSend.unidentifiedAccess]; unidentifiedAccess:messageSend.unidentifiedAccess];
OWSWebSocketType webSocketType = (isUDSend ? OWSWebSocketTypeUD : OWSWebSocketTypeDefault);
[self.networkManager makeRequest:request BOOL canMakeWebsocketRequests
completionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) = ([TSSocketManager.shared canMakeRequestsOfType:webSocketType] && !messageSend.hasWebsocketSendFailed);
success:^(NSURLSessionDataTask *task, id responseObject) { if (canMakeWebsocketRequests) {
PreKeyBundle *_Nullable bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject [TSSocketManager.shared makeRequest:request
forDeviceNumber:deviceId]; webSocketType:webSocketType
success(bundle); success:^(id _Nullable responseObject) {
} dispatch_async([OWSDispatch sendingQueue], ^{
failure:^(NSURLSessionDataTask *task, NSError *error) { PreKeyBundle *_Nullable bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject
if (!IsNSErrorNetworkFailure(error)) { forDeviceNumber:deviceId];
OWSProdError([OWSAnalyticsEvents messageSenderErrorRecipientPrekeyRequestFailed]); success(bundle);
});
} }
OWSLogError(@"request: %@", request); failure:^(NSInteger statusCode, NSData *_Nullable responseData, NSError *error) {
OWSLogError(@"Server replied to PreKeyBundle request with error: %@", error); dispatch_async([OWSDispatch sendingQueue], ^{
OWSLogFlush(); OWSLogDebug(@"Web socket prekey request failed; failing over to REST: %@.", error);
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSUInteger statusCode = response.statusCode; if (isUDSend && (statusCode == 401 || statusCode == 403)) {
if (isUDSend && (statusCode == 401 || statusCode == 403)) { // If a UD send fails due to service response (as opposed to network
// If a UD send fails due to service response (as opposed to network // failure), mark recipient as _not_ in UD mode, then retry.
// failure), mark recipient as _not_ in UD mode, then retry. OWSLogDebug(@"UD prekey request failed; failing over to non-UD prekey request.");
OWSLogDebug(@"UD prekey request failed; failing over to non-UD prekey request."); [self.udManager setUnidentifiedAccessMode:UnidentifiedAccessModeDisabled
// We need to update the UD access mode for this user async to recipientId:recipient.uniqueId];
// avoid deadlock, since this method is called inside a transaction. [messageSend setHasUDAuthFailed];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Try again without UD auth.
[self.udManager setUnidentifiedAccessMode:UnidentifiedAccessModeDisabled [self makePrekeyRequestForMessageSend:messageSend
recipientId:recipient.uniqueId]; deviceId:deviceId
success:success
failure:failure];
return;
}
// Websockets can fail in different ways, so we don't decrement remainingAttempts for websocket
// failure. Instead we fall back to REST, which will decrement retries. e.g. after linking a new
// device, sync messages will fail until the websocket re-opens.
messageSend.hasWebsocketSendFailed = YES;
// Try again without websocket.
[self makePrekeyRequestForMessageSend:messageSend
deviceId:deviceId
success:success
failure:failure];
});
}];
} else {
[self.networkManager makeRequest:request
completionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
success:^(NSURLSessionDataTask *task, id responseObject) {
dispatch_async([OWSDispatch sendingQueue], ^{
PreKeyBundle *_Nullable bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject
forDeviceNumber:deviceId];
success(bundle);
}); });
[messageSend setHasUDAuthFailed];
// Try again without UD auth.
[self makePrekeyRequestForMessageSend:messageSend deviceId:deviceId success:success failure:failure];
return;
} }
failure:^(NSURLSessionDataTask *task, NSError *error) {
dispatch_async([OWSDispatch sendingQueue], ^{
if (!IsNSErrorNetworkFailure(error)) {
OWSProdError([OWSAnalyticsEvents messageSenderErrorRecipientPrekeyRequestFailed]);
}
OWSLogDebug(@"REST prekey request failed: %@.", error);
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSUInteger statusCode = response.statusCode;
if (isUDSend && (statusCode == 401 || statusCode == 403)) {
// If a UD send fails due to service response (as opposed to network
// failure), mark recipient as _not_ in UD mode, then retry.
OWSLogDebug(@"UD prekey request failed; failing over to non-UD prekey request.");
[self.udManager setUnidentifiedAccessMode:UnidentifiedAccessModeDisabled
recipientId:recipient.uniqueId];
[messageSend setHasUDAuthFailed];
// Try again without UD auth.
[self makePrekeyRequestForMessageSend:messageSend
deviceId:deviceId
success:success
failure:failure];
return;
}
failure(statusCode); failure(statusCode);
}]; });
}];
}
} }
// NOTE: This method uses exceptions for control flow. // NOTE: This method uses exceptions for control flow.

Loading…
Cancel
Save