Use websocket for sends.
This commit is contained in:
parent
fb3efe3647
commit
5f1682deab
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 086242800e27b3ee431ad23e9f29f3358e813059
|
||||
Subproject commit 9ed0ac557a1056bc8628d110199afcad87209d5d
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Copyright (C) 2014-2016 Open Whisper Systems
|
||||
*
|
||||
* Licensed according to the LICENSE file in this repository.
|
||||
*/
|
||||
|
||||
package signalservice;
|
||||
|
||||
option java_package = "org.whispersystems.signalservice.internal.websocket";
|
||||
option java_outer_classname = "WebSocketProtos";
|
||||
|
||||
// Signal-iOS
|
||||
import "objectivec-descriptor.proto";
|
||||
option (google.protobuf.objectivec_file_options).class_prefix = "WebSocketResources";
|
||||
|
||||
message WebSocketRequestMessage
|
||||
{
|
||||
optional string verb = 1;
|
||||
optional string path = 2;
|
||||
optional bytes body = 3;
|
||||
repeated string headers = 5;
|
||||
optional uint64 id = 4;
|
||||
}
|
||||
|
||||
message WebSocketResponseMessage
|
||||
{
|
||||
optional uint64 id = 1;
|
||||
optional uint32 status = 2;
|
||||
optional string message = 3;
|
||||
repeated string headers = 5;
|
||||
optional bytes body = 4;
|
||||
}
|
||||
|
||||
message WebSocketMessage
|
||||
{
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
REQUEST = 1;
|
||||
RESPONSE = 2;
|
||||
}
|
||||
|
||||
optional Type type = 1;
|
||||
optional WebSocketRequestMessage request = 2;
|
||||
optional WebSocketResponseMessage response = 3;
|
||||
}
|
|
@ -39,6 +39,7 @@
|
|||
#import "TSOutgoingMessage.h"
|
||||
#import "TSPreKeyManager.h"
|
||||
#import "TSQuotedMessage.h"
|
||||
#import "TSSocketManager.h"
|
||||
#import "TSThread.h"
|
||||
#import "Threading.h"
|
||||
#import <AxolotlKit/AxolotlExceptions.h>
|
||||
|
@ -975,117 +976,240 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
messages:deviceMessages
|
||||
relay:recipient.relay
|
||||
timeStamp:message.timestamp];
|
||||
[self.networkManager makeRequest:request
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
if (isLocalNumber && deviceMessages.count == 0) {
|
||||
DDLogInfo(@"%@ Sent a message with no device messages; clearing 'mayHaveLinkedDevices'.", self.logTag);
|
||||
// In order to avoid skipping necessary sync messages, the default value
|
||||
// for mayHaveLinkedDevices is YES. Once we've successfully sent a
|
||||
// sync message with no device messages (e.g. the service has confirmed
|
||||
// that we have no linked devices), we can set mayHaveLinkedDevices to NO
|
||||
// to avoid unnecessary message sends for sync messages until we learn
|
||||
// of a linked device (e.g. through the device linking UI or by receiving
|
||||
// a sync message, etc.).
|
||||
[OWSDeviceManager.sharedManager clearMayHaveLinkedDevicesIfNotSet];
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sendingQueue], ^{
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[recipient saveWithTransaction:transaction];
|
||||
[message updateWithSentRecipient:recipient.uniqueId transaction:transaction];
|
||||
}];
|
||||
|
||||
[self handleMessageSentLocally:message];
|
||||
successHandler();
|
||||
});
|
||||
}
|
||||
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
DDLogInfo(@"%@ sending to recipient: %@, failed with error.", self.logTag, recipient.uniqueId);
|
||||
[DDLog flushLog];
|
||||
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
NSData *responseData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
||||
|
||||
void (^retrySend)(void) = ^void() {
|
||||
if (remainingAttempts <= 0) {
|
||||
// Since we've already repeatedly failed to send to the messaging API,
|
||||
// it's unlikely that repeating the whole process will succeed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
if (YES) {
|
||||
[TSSocketManager.sharedManager makeRequest:request
|
||||
success:^{
|
||||
DDLogInfo(@"%@ Message send succeeded.", self.logTag);
|
||||
if (isLocalNumber && deviceMessages.count == 0) {
|
||||
DDLogInfo(
|
||||
@"%@ Sent a message with no device messages; clearing 'mayHaveLinkedDevices'.", self.logTag);
|
||||
// In order to avoid skipping necessary sync messages, the default value
|
||||
// for mayHaveLinkedDevices is YES. Once we've successfully sent a
|
||||
// sync message with no device messages (e.g. the service has confirmed
|
||||
// that we have no linked devices), we can set mayHaveLinkedDevices to NO
|
||||
// to avoid unnecessary message sends for sync messages until we learn
|
||||
// of a linked device (e.g. through the device linking UI or by receiving
|
||||
// a sync message, etc.).
|
||||
[OWSDeviceManager.sharedManager clearMayHaveLinkedDevicesIfNotSet];
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sendingQueue], ^{
|
||||
DDLogDebug(@"%@ Retrying: %@", self.logTag, message.debugDescription);
|
||||
[self sendMessageToService:message
|
||||
recipient:recipient
|
||||
thread:thread
|
||||
attempts:remainingAttempts
|
||||
success:successHandler
|
||||
failure:failureHandler];
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[recipient saveWithTransaction:transaction];
|
||||
[message updateWithSentRecipient:recipient.uniqueId transaction:transaction];
|
||||
}];
|
||||
|
||||
[self handleMessageSentLocally:message];
|
||||
successHandler();
|
||||
});
|
||||
};
|
||||
|
||||
switch (statuscode) {
|
||||
case 401: {
|
||||
DDLogWarn(@"%@ Unable to send due to invalid credentials. Did the user's client get de-authed by "
|
||||
@"registering elsewhere?",
|
||||
self.logTag);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeSignalServiceFailure, NSLocalizedString(@"ERROR_DESCRIPTION_SENDING_UNAUTHORIZED", @"Error message when attempting to send message"));
|
||||
// No need to retry if we've been de-authed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 404: {
|
||||
DDLogWarn(@"%@ Unregistered recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
[self unregisteredRecipient:recipient message:message thread:thread];
|
||||
NSError *error = OWSErrorMakeNoSuchSignalRecipientError();
|
||||
// No need to retry if the recipient is not registered.
|
||||
[error setIsRetryable:NO];
|
||||
// If one member of a group deletes their account,
|
||||
// the group should ignore errors when trying to send
|
||||
// messages to this ex-member.
|
||||
[error setShouldBeIgnoredForGroups:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 409: {
|
||||
// Mismatched devices
|
||||
DDLogWarn(@"%@ Mismatch Devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *serializedResponse =
|
||||
[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
|
||||
if (error) {
|
||||
OWSProdError([OWSAnalyticsEvents messageSenderErrorCouldNotParseMismatchedDevicesJson]);
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleMismatchedDevices:serializedResponse recipient:recipient completion:retrySend];
|
||||
break;
|
||||
}
|
||||
case 410: {
|
||||
// Stale devices
|
||||
DDLogWarn(@"%@ Stale devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
if (!responseData) {
|
||||
DDLogWarn(@"Stale devices but server didn't specify devices in response.");
|
||||
NSError *error = OWSErrorMakeUnableToProcessServerResponseError();
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleStaleDevicesWithResponse:responseData
|
||||
recipientId:recipient.uniqueId
|
||||
completion:retrySend];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
retrySend();
|
||||
break;
|
||||
}
|
||||
}];
|
||||
failure:^(NSInteger statusCode, NSError *error) {
|
||||
DDLogError(@"%@ Message send failed.", self.logTag);
|
||||
DDLogInfo(@"%@ sending to recipient: %@, failed with error.", self.logTag, recipient.uniqueId);
|
||||
[DDLog flushLog];
|
||||
|
||||
// NSHTTPURLResponse *response = (NSHTTPURLResponse
|
||||
// *)task.response; long statuscode = response.statusCode;
|
||||
NSData *responseData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
||||
|
||||
void (^retrySend)(void) = ^void() {
|
||||
if (remainingAttempts <= 0) {
|
||||
// Since we've already repeatedly failed to send to the messaging API,
|
||||
// it's unlikely that repeating the whole process will succeed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sendingQueue], ^{
|
||||
DDLogDebug(@"%@ Retrying: %@", self.logTag, message.debugDescription);
|
||||
[self sendMessageToService:message
|
||||
recipient:recipient
|
||||
thread:thread
|
||||
attempts:remainingAttempts
|
||||
success:successHandler
|
||||
failure:failureHandler];
|
||||
});
|
||||
};
|
||||
|
||||
switch (statusCode) {
|
||||
case 401: {
|
||||
DDLogWarn(
|
||||
@"%@ Unable to send due to invalid credentials. Did the user's client get de-authed by "
|
||||
@"registering elsewhere?",
|
||||
self.logTag);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeSignalServiceFailure,
|
||||
NSLocalizedString(@"ERROR_DESCRIPTION_SENDING_UNAUTHORIZED",
|
||||
@"Error message when attempting to send message"));
|
||||
// No need to retry if we've been de-authed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 404: {
|
||||
DDLogWarn(@"%@ Unregistered recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
[self unregisteredRecipient:recipient message:message thread:thread];
|
||||
NSError *error = OWSErrorMakeNoSuchSignalRecipientError();
|
||||
// No need to retry if the recipient is not registered.
|
||||
[error setIsRetryable:NO];
|
||||
// If one member of a group deletes their account,
|
||||
// the group should ignore errors when trying to send
|
||||
// messages to this ex-member.
|
||||
[error setShouldBeIgnoredForGroups:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 409: {
|
||||
// Mismatched devices
|
||||
DDLogWarn(@"%@ Mismatch Devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *serializedResponse =
|
||||
[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
|
||||
if (error) {
|
||||
OWSProdError([OWSAnalyticsEvents messageSenderErrorCouldNotParseMismatchedDevicesJson]);
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleMismatchedDevices:serializedResponse recipient:recipient completion:retrySend];
|
||||
break;
|
||||
}
|
||||
case 410: {
|
||||
// Stale devices
|
||||
DDLogWarn(@"%@ Stale devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
if (!responseData) {
|
||||
DDLogWarn(@"Stale devices but server didn't specify devices in response.");
|
||||
NSError *error = OWSErrorMakeUnableToProcessServerResponseError();
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleStaleDevicesWithResponse:responseData
|
||||
recipientId:recipient.uniqueId
|
||||
completion:retrySend];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
retrySend();
|
||||
break;
|
||||
}
|
||||
}];
|
||||
} else
|
||||
[self.networkManager makeRequest:request
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
if (isLocalNumber && deviceMessages.count == 0) {
|
||||
DDLogInfo(
|
||||
@"%@ Sent a message with no device messages; clearing 'mayHaveLinkedDevices'.", self.logTag);
|
||||
// In order to avoid skipping necessary sync messages, the default value
|
||||
// for mayHaveLinkedDevices is YES. Once we've successfully sent a
|
||||
// sync message with no device messages (e.g. the service has confirmed
|
||||
// that we have no linked devices), we can set mayHaveLinkedDevices to NO
|
||||
// to avoid unnecessary message sends for sync messages until we learn
|
||||
// of a linked device (e.g. through the device linking UI or by receiving
|
||||
// a sync message, etc.).
|
||||
[OWSDeviceManager.sharedManager clearMayHaveLinkedDevicesIfNotSet];
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sendingQueue], ^{
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[recipient saveWithTransaction:transaction];
|
||||
[message updateWithSentRecipient:recipient.uniqueId transaction:transaction];
|
||||
}];
|
||||
|
||||
[self handleMessageSentLocally:message];
|
||||
successHandler();
|
||||
});
|
||||
}
|
||||
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
DDLogInfo(@"%@ sending to recipient: %@, failed with error.", self.logTag, recipient.uniqueId);
|
||||
[DDLog flushLog];
|
||||
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
NSData *responseData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
||||
|
||||
void (^retrySend)(void) = ^void() {
|
||||
if (remainingAttempts <= 0) {
|
||||
// Since we've already repeatedly failed to send to the messaging API,
|
||||
// it's unlikely that repeating the whole process will succeed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
dispatch_async([OWSDispatch sendingQueue], ^{
|
||||
DDLogDebug(@"%@ Retrying: %@", self.logTag, message.debugDescription);
|
||||
[self sendMessageToService:message
|
||||
recipient:recipient
|
||||
thread:thread
|
||||
attempts:remainingAttempts
|
||||
success:successHandler
|
||||
failure:failureHandler];
|
||||
});
|
||||
};
|
||||
|
||||
switch (statuscode) {
|
||||
case 401: {
|
||||
DDLogWarn(
|
||||
@"%@ Unable to send due to invalid credentials. Did the user's client get de-authed by "
|
||||
@"registering elsewhere?",
|
||||
self.logTag);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeSignalServiceFailure,
|
||||
NSLocalizedString(@"ERROR_DESCRIPTION_SENDING_UNAUTHORIZED",
|
||||
@"Error message when attempting to send message"));
|
||||
// No need to retry if we've been de-authed.
|
||||
[error setIsRetryable:NO];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 404: {
|
||||
DDLogWarn(@"%@ Unregistered recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
[self unregisteredRecipient:recipient message:message thread:thread];
|
||||
NSError *error = OWSErrorMakeNoSuchSignalRecipientError();
|
||||
// No need to retry if the recipient is not registered.
|
||||
[error setIsRetryable:NO];
|
||||
// If one member of a group deletes their account,
|
||||
// the group should ignore errors when trying to send
|
||||
// messages to this ex-member.
|
||||
[error setShouldBeIgnoredForGroups:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
case 409: {
|
||||
// Mismatched devices
|
||||
DDLogWarn(@"%@ Mismatch Devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *serializedResponse =
|
||||
[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
|
||||
if (error) {
|
||||
OWSProdError([OWSAnalyticsEvents messageSenderErrorCouldNotParseMismatchedDevicesJson]);
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleMismatchedDevices:serializedResponse recipient:recipient completion:retrySend];
|
||||
break;
|
||||
}
|
||||
case 410: {
|
||||
// Stale devices
|
||||
DDLogWarn(@"%@ Stale devices for recipient: %@", self.logTag, recipient.uniqueId);
|
||||
|
||||
if (!responseData) {
|
||||
DDLogWarn(@"Stale devices but server didn't specify devices in response.");
|
||||
NSError *error = OWSErrorMakeUnableToProcessServerResponseError();
|
||||
[error setIsRetryable:YES];
|
||||
return failureHandler(error);
|
||||
}
|
||||
|
||||
[self handleStaleDevicesWithResponse:responseData
|
||||
recipientId:recipient.uniqueId
|
||||
completion:retrySend];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
retrySend();
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)handleMismatchedDevices:(NSDictionary *)dictionary
|
||||
|
|
|
@ -1,273 +0,0 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
#import <ProtocolBuffers/ProtocolBuffers.h>
|
||||
|
||||
// @@protoc_insertion_point(imports)
|
||||
|
||||
@class WebSocketMessage;
|
||||
@class WebSocketMessageBuilder;
|
||||
@class WebSocketRequestMessage;
|
||||
@class WebSocketRequestMessageBuilder;
|
||||
@class WebSocketResponseMessage;
|
||||
@class WebSocketResponseMessageBuilder;
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif // __has_feature
|
||||
|
||||
#ifndef NS_RETURNS_NOT_RETAINED
|
||||
#if __has_feature(attribute_ns_returns_not_retained)
|
||||
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
|
||||
#else
|
||||
#define NS_RETURNS_NOT_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WebSocketMessageTypeUnknown = 0,
|
||||
WebSocketMessageTypeRequest = 1,
|
||||
WebSocketMessageTypeResponse = 2,
|
||||
} WebSocketMessageType;
|
||||
|
||||
BOOL WebSocketMessageTypeIsValidValue(WebSocketMessageType value);
|
||||
|
||||
|
||||
@interface SubProtocolRoot : NSObject {
|
||||
}
|
||||
+ (PBExtensionRegistry *)extensionRegistry;
|
||||
+ (void)registerAllExtensions:(PBMutableExtensionRegistry *)registry;
|
||||
@end
|
||||
|
||||
@interface WebSocketRequestMessage : PBGeneratedMessage {
|
||||
@private
|
||||
BOOL hasId_ : 1;
|
||||
BOOL hasVerb_ : 1;
|
||||
BOOL hasPath_ : 1;
|
||||
BOOL hasBody_ : 1;
|
||||
UInt64 id;
|
||||
NSString *verb;
|
||||
NSString *path;
|
||||
NSData *body;
|
||||
}
|
||||
- (BOOL)hasVerb;
|
||||
- (BOOL)hasPath;
|
||||
- (BOOL)hasBody;
|
||||
- (BOOL)hasId;
|
||||
@property (readonly, strong) NSString *verb;
|
||||
@property (readonly, strong) NSString *path;
|
||||
@property (readonly, strong) NSData *body;
|
||||
@property (readonly) UInt64 id;
|
||||
|
||||
+ (WebSocketRequestMessage *)defaultInstance;
|
||||
- (WebSocketRequestMessage *)defaultInstance;
|
||||
|
||||
- (BOOL)isInitialized;
|
||||
- (void)writeToCodedOutputStream:(PBCodedOutputStream *)output;
|
||||
- (WebSocketRequestMessageBuilder *)builder;
|
||||
+ (WebSocketRequestMessageBuilder *)builder;
|
||||
+ (WebSocketRequestMessageBuilder *)builderWithPrototype:(WebSocketRequestMessage *)prototype;
|
||||
- (WebSocketRequestMessageBuilder *)toBuilder;
|
||||
|
||||
+ (WebSocketRequestMessage *)parseFromData:(NSData *)data;
|
||||
+ (WebSocketRequestMessage *)parseFromData:(NSData *)data extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketRequestMessage *)parseFromInputStream:(NSInputStream *)input;
|
||||
+ (WebSocketRequestMessage *)parseFromInputStream:(NSInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketRequestMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
+ (WebSocketRequestMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketRequestMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketRequestMessage *result;
|
||||
}
|
||||
|
||||
- (WebSocketRequestMessage *)defaultInstance;
|
||||
|
||||
- (WebSocketRequestMessageBuilder *)clear;
|
||||
- (WebSocketRequestMessageBuilder *)clone;
|
||||
|
||||
- (WebSocketRequestMessage *)build;
|
||||
- (WebSocketRequestMessage *)buildPartial;
|
||||
|
||||
- (WebSocketRequestMessageBuilder *)mergeFrom:(WebSocketRequestMessage *)other;
|
||||
- (WebSocketRequestMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
- (WebSocketRequestMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
|
||||
- (BOOL)hasVerb;
|
||||
- (NSString *)verb;
|
||||
- (WebSocketRequestMessageBuilder *)setVerb:(NSString *)value;
|
||||
- (WebSocketRequestMessageBuilder *)clearVerb;
|
||||
|
||||
- (BOOL)hasPath;
|
||||
- (NSString *)path;
|
||||
- (WebSocketRequestMessageBuilder *)setPath:(NSString *)value;
|
||||
- (WebSocketRequestMessageBuilder *)clearPath;
|
||||
|
||||
- (BOOL)hasBody;
|
||||
- (NSData *)body;
|
||||
- (WebSocketRequestMessageBuilder *)setBody:(NSData *)value;
|
||||
- (WebSocketRequestMessageBuilder *)clearBody;
|
||||
|
||||
- (BOOL)hasId;
|
||||
- (UInt64)id;
|
||||
- (WebSocketRequestMessageBuilder *)setId:(UInt64)value;
|
||||
- (WebSocketRequestMessageBuilder *)clearId;
|
||||
@end
|
||||
|
||||
@interface WebSocketResponseMessage : PBGeneratedMessage {
|
||||
@private
|
||||
BOOL hasId_ : 1;
|
||||
BOOL hasMessage_ : 1;
|
||||
BOOL hasBody_ : 1;
|
||||
BOOL hasStatus_ : 1;
|
||||
UInt64 id;
|
||||
NSString *message;
|
||||
NSData *body;
|
||||
UInt32 status;
|
||||
}
|
||||
- (BOOL)hasId;
|
||||
- (BOOL)hasStatus;
|
||||
- (BOOL)hasMessage;
|
||||
- (BOOL)hasBody;
|
||||
@property (readonly) UInt64 id;
|
||||
@property (readonly) UInt32 status;
|
||||
@property (readonly, strong) NSString *message;
|
||||
@property (readonly, strong) NSData *body;
|
||||
|
||||
+ (WebSocketResponseMessage *)defaultInstance;
|
||||
- (WebSocketResponseMessage *)defaultInstance;
|
||||
|
||||
- (BOOL)isInitialized;
|
||||
- (void)writeToCodedOutputStream:(PBCodedOutputStream *)output;
|
||||
- (WebSocketResponseMessageBuilder *)builder;
|
||||
+ (WebSocketResponseMessageBuilder *)builder;
|
||||
+ (WebSocketResponseMessageBuilder *)builderWithPrototype:(WebSocketResponseMessage *)prototype;
|
||||
- (WebSocketResponseMessageBuilder *)toBuilder;
|
||||
|
||||
+ (WebSocketResponseMessage *)parseFromData:(NSData *)data;
|
||||
+ (WebSocketResponseMessage *)parseFromData:(NSData *)data extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketResponseMessage *)parseFromInputStream:(NSInputStream *)input;
|
||||
+ (WebSocketResponseMessage *)parseFromInputStream:(NSInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketResponseMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
+ (WebSocketResponseMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketResponseMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketResponseMessage *result;
|
||||
}
|
||||
|
||||
- (WebSocketResponseMessage *)defaultInstance;
|
||||
|
||||
- (WebSocketResponseMessageBuilder *)clear;
|
||||
- (WebSocketResponseMessageBuilder *)clone;
|
||||
|
||||
- (WebSocketResponseMessage *)build;
|
||||
- (WebSocketResponseMessage *)buildPartial;
|
||||
|
||||
- (WebSocketResponseMessageBuilder *)mergeFrom:(WebSocketResponseMessage *)other;
|
||||
- (WebSocketResponseMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
- (WebSocketResponseMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
|
||||
- (BOOL)hasId;
|
||||
- (UInt64)id;
|
||||
- (WebSocketResponseMessageBuilder *)setId:(UInt64)value;
|
||||
- (WebSocketResponseMessageBuilder *)clearId;
|
||||
|
||||
- (BOOL)hasStatus;
|
||||
- (UInt32)status;
|
||||
- (WebSocketResponseMessageBuilder *)setStatus:(UInt32)value;
|
||||
- (WebSocketResponseMessageBuilder *)clearStatus;
|
||||
|
||||
- (BOOL)hasMessage;
|
||||
- (NSString *)message;
|
||||
- (WebSocketResponseMessageBuilder *)setMessage:(NSString *)value;
|
||||
- (WebSocketResponseMessageBuilder *)clearMessage;
|
||||
|
||||
- (BOOL)hasBody;
|
||||
- (NSData *)body;
|
||||
- (WebSocketResponseMessageBuilder *)setBody:(NSData *)value;
|
||||
- (WebSocketResponseMessageBuilder *)clearBody;
|
||||
@end
|
||||
|
||||
@interface WebSocketMessage : PBGeneratedMessage {
|
||||
@private
|
||||
BOOL hasRequest_ : 1;
|
||||
BOOL hasResponse_ : 1;
|
||||
BOOL hasType_ : 1;
|
||||
WebSocketRequestMessage *request;
|
||||
WebSocketResponseMessage *response;
|
||||
WebSocketMessageType type;
|
||||
}
|
||||
- (BOOL)hasType;
|
||||
- (BOOL)hasRequest;
|
||||
- (BOOL)hasResponse;
|
||||
@property (readonly) WebSocketMessageType type;
|
||||
@property (readonly, strong) WebSocketRequestMessage *request;
|
||||
@property (readonly, strong) WebSocketResponseMessage *response;
|
||||
|
||||
+ (WebSocketMessage *)defaultInstance;
|
||||
- (WebSocketMessage *)defaultInstance;
|
||||
|
||||
- (BOOL)isInitialized;
|
||||
- (void)writeToCodedOutputStream:(PBCodedOutputStream *)output;
|
||||
- (WebSocketMessageBuilder *)builder;
|
||||
+ (WebSocketMessageBuilder *)builder;
|
||||
+ (WebSocketMessageBuilder *)builderWithPrototype:(WebSocketMessage *)prototype;
|
||||
- (WebSocketMessageBuilder *)toBuilder;
|
||||
|
||||
+ (WebSocketMessage *)parseFromData:(NSData *)data;
|
||||
+ (WebSocketMessage *)parseFromData:(NSData *)data extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketMessage *)parseFromInputStream:(NSInputStream *)input;
|
||||
+ (WebSocketMessage *)parseFromInputStream:(NSInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
+ (WebSocketMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
+ (WebSocketMessage *)parseFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketMessage *result;
|
||||
}
|
||||
|
||||
- (WebSocketMessage *)defaultInstance;
|
||||
|
||||
- (WebSocketMessageBuilder *)clear;
|
||||
- (WebSocketMessageBuilder *)clone;
|
||||
|
||||
- (WebSocketMessage *)build;
|
||||
- (WebSocketMessage *)buildPartial;
|
||||
|
||||
- (WebSocketMessageBuilder *)mergeFrom:(WebSocketMessage *)other;
|
||||
- (WebSocketMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input;
|
||||
- (WebSocketMessageBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
|
||||
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
|
||||
|
||||
- (BOOL)hasType;
|
||||
- (WebSocketMessageType)type;
|
||||
- (WebSocketMessageBuilder *)setType:(WebSocketMessageType)value;
|
||||
- (WebSocketMessageBuilder *)clearType;
|
||||
|
||||
- (BOOL)hasRequest;
|
||||
- (WebSocketRequestMessage *)request;
|
||||
- (WebSocketMessageBuilder *)setRequest:(WebSocketRequestMessage *)value;
|
||||
- (WebSocketMessageBuilder *)setRequestBuilder:(WebSocketRequestMessageBuilder *)builderForValue;
|
||||
- (WebSocketMessageBuilder *)mergeRequest:(WebSocketRequestMessage *)value;
|
||||
- (WebSocketMessageBuilder *)clearRequest;
|
||||
|
||||
- (BOOL)hasResponse;
|
||||
- (WebSocketResponseMessage *)response;
|
||||
- (WebSocketMessageBuilder *)setResponse:(WebSocketResponseMessage *)value;
|
||||
- (WebSocketMessageBuilder *)setResponseBuilder:(WebSocketResponseMessageBuilder *)builderForValue;
|
||||
- (WebSocketMessageBuilder *)mergeResponse:(WebSocketResponseMessage *)value;
|
||||
- (WebSocketMessageBuilder *)clearResponse;
|
||||
@end
|
||||
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SocketRocket/SRWebSocket.h>
|
||||
|
@ -14,6 +14,11 @@ typedef NS_ENUM(NSUInteger, SocketManagerState) {
|
|||
SocketManagerStateOpen,
|
||||
};
|
||||
|
||||
typedef void (^TSSocketMessageSuccess)(void);
|
||||
typedef void (^TSSocketMessageFailure)(NSInteger statusCode, NSError *error);
|
||||
|
||||
@class TSRequest;
|
||||
|
||||
@interface TSSocketManager : NSObject <SRWebSocketDelegate>
|
||||
|
||||
@property (nonatomic, readonly) SocketManagerState state;
|
||||
|
@ -33,4 +38,10 @@ typedef NS_ENUM(NSUInteger, SocketManagerState) {
|
|||
// This method can be called from any thread.
|
||||
+ (void)requestSocketOpen;
|
||||
|
||||
#pragma mark - Message Sending
|
||||
|
||||
- (void)makeRequest:(TSRequest *)request
|
||||
success:(TSSocketMessageSuccess)success
|
||||
failure:(TSSocketMessageFailure)failure;
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,18 +10,20 @@
|
|||
#import "NSTimer+OWS.h"
|
||||
#import "NotificationsProtocol.h"
|
||||
#import "OWSBackgroundTask.h"
|
||||
#import "OWSError.h"
|
||||
#import "OWSMessageManager.h"
|
||||
#import "OWSMessageReceiver.h"
|
||||
#import "OWSPrimaryStorage.h"
|
||||
#import "OWSSignalService.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
#import "OWSWebsocketSecurityPolicy.h"
|
||||
#import "SubProtocol.pb.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSConstants.h"
|
||||
#import "TSErrorMessage.h"
|
||||
#import "TSRequest.h"
|
||||
#import "TextSecureKitEnv.h"
|
||||
#import "Threading.h"
|
||||
#import "WebSocketResources.pb.h"
|
||||
|
||||
static const CGFloat kSocketHeartbeatPeriodSeconds = 30.f;
|
||||
static const CGFloat kSocketReconnectDelaySeconds = 5.f;
|
||||
|
@ -36,6 +38,71 @@ static const CGFloat kBackgroundKeepSocketAliveDurationSeconds = 15.f;
|
|||
|
||||
NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_SocketManagerStateDidChange";
|
||||
|
||||
@interface TSSocketMessage : NSObject
|
||||
|
||||
@property (nonatomic) UInt64 requestId;
|
||||
@property (nonatomic) TSSocketMessageSuccess success;
|
||||
@property (nonatomic) TSSocketMessageFailure failure;
|
||||
@property (nonatomic) BOOL hasCompleted;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation TSSocketMessage
|
||||
|
||||
- (void)didSucceed
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
if (self.hasCompleted) {
|
||||
return;
|
||||
}
|
||||
self.hasCompleted = YES;
|
||||
}
|
||||
|
||||
OWSAssert(self.success);
|
||||
OWSAssert(self.failure);
|
||||
|
||||
self.success();
|
||||
|
||||
self.success = nil;
|
||||
self.failure = nil;
|
||||
}
|
||||
|
||||
- (void)didFailBeforeSending
|
||||
{
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeMessageRequestFailed,
|
||||
NSLocalizedString(@"ERROR_DESCRIPTION_REQUEST_FAILED", @"Error indicating that a socket request failed."));
|
||||
|
||||
[self didFailWithStatusCode:0 error:error];
|
||||
}
|
||||
|
||||
- (void)didFailWithStatusCode:(NSInteger)statusCode error:(NSError *)error
|
||||
{
|
||||
OWSAssert(error);
|
||||
|
||||
@synchronized(self)
|
||||
{
|
||||
if (self.hasCompleted) {
|
||||
return;
|
||||
}
|
||||
self.hasCompleted = YES;
|
||||
}
|
||||
|
||||
OWSAssert(self.success);
|
||||
OWSAssert(self.failure);
|
||||
|
||||
self.failure(statusCode, error);
|
||||
|
||||
self.success = nil;
|
||||
self.failure = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// TSSocketManager's properties should only be accessed from the main thread.
|
||||
@interface TSSocketManager ()
|
||||
|
||||
|
@ -60,6 +127,8 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
// Due to concurrency, this property can fall out of sync with the
|
||||
// websocket's actual state, so we're defensive and distrustful of
|
||||
// this property.
|
||||
//
|
||||
// We only ever access this state on the main thread.
|
||||
@property (nonatomic) SocketManagerState state;
|
||||
|
||||
#pragma mark -
|
||||
|
@ -87,6 +156,10 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
|
||||
@property (nonatomic) BOOL hasObservedNotifications;
|
||||
|
||||
// These two properties should only be accessed while synchronized on the socket manager.
|
||||
@property (nonatomic) UInt64 requestIdCounter;
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSNumber *, TSSocketMessage *> *socketMessageMap;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
@ -106,6 +179,9 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
_signalService = [OWSSignalService sharedInstance];
|
||||
_messageReceiver = [OWSMessageReceiver sharedInstance];
|
||||
_state = SocketManagerStateClosed;
|
||||
// Ensure that all request ids are non-zero.
|
||||
_requestIdCounter = 1;
|
||||
_socketMessageMap = [NSMutableDictionary new];
|
||||
|
||||
OWSSingletonAssert();
|
||||
|
||||
|
@ -330,6 +406,104 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
self.state = SocketManagerStateClosed;
|
||||
}
|
||||
|
||||
#pragma mark - Message Sending
|
||||
|
||||
- (void)makeRequest:(TSRequest *)request success:(TSSocketMessageSuccess)success failure:(TSSocketMessageFailure)failure
|
||||
{
|
||||
DispatchMainThreadSafe(^{
|
||||
[self makeRequestOnMain:request success:success failure:failure];
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Currently we schedule requests on main since we want to consult the state property.
|
||||
// There are alternatives.
|
||||
- (void)makeRequestOnMain:(TSRequest *)request
|
||||
success:(TSSocketMessageSuccess)success
|
||||
failure:(TSSocketMessageFailure)failure
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(request);
|
||||
OWSAssert(request.HTTPMethod.length > 0);
|
||||
OWSAssert(success);
|
||||
OWSAssert(failure);
|
||||
|
||||
TSSocketMessage *socketMessage = [TSSocketMessage new];
|
||||
socketMessage.success = success;
|
||||
socketMessage.failure = failure;
|
||||
@synchronized(self)
|
||||
{
|
||||
socketMessage.requestId = self.requestIdCounter++;
|
||||
self.socketMessageMap[@(socketMessage.requestId)] = socketMessage;
|
||||
}
|
||||
|
||||
NSURL *requestUrl = request.URL;
|
||||
NSString *requestPath = [@"/" stringByAppendingString:requestUrl.path];
|
||||
|
||||
NSData *_Nullable jsonData = nil;
|
||||
if (request.parameters) {
|
||||
NSError *error;
|
||||
jsonData = [NSJSONSerialization
|
||||
dataWithJSONObject:request.parameters
|
||||
// TODO:
|
||||
options:(NSJSONWritingOptions)0
|
||||
// options:NSJSONWritingPrettyPrinted
|
||||
error:&error];
|
||||
if (!jsonData || error) {
|
||||
OWSProdLogAndFail(@"%@ could not serialize request JSON: %@", self.logTag, error);
|
||||
// TODO:
|
||||
[socketMessage didFailBeforeSending];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.state != SocketManagerStateOpen) {
|
||||
DDLogError(@"%@ makeRequest: socket not open.", self.logTag);
|
||||
// TODO:
|
||||
[socketMessage didFailBeforeSending];
|
||||
return;
|
||||
}
|
||||
|
||||
WebSocketResourcesWebSocketRequestMessageBuilder *requestBuilder =
|
||||
[WebSocketResourcesWebSocketRequestMessageBuilder new];
|
||||
requestBuilder.id = socketMessage.requestId;
|
||||
[requestBuilder setVerb:request.HTTPMethod];
|
||||
[requestBuilder setPath:requestPath];
|
||||
[requestBuilder setBody:jsonData];
|
||||
[requestBuilder setHeadersArray:@[
|
||||
@"content-type:application/json",
|
||||
]];
|
||||
|
||||
WebSocketResourcesWebSocketMessageBuilder *messageBuilder = [WebSocketResourcesWebSocketMessageBuilder new];
|
||||
[messageBuilder setType:WebSocketResourcesWebSocketMessageTypeRequest];
|
||||
[messageBuilder setRequestBuilder:requestBuilder];
|
||||
|
||||
NSData *messageData = [messageBuilder build].data;
|
||||
if (!messageData) {
|
||||
OWSProdLogAndFail(@"%@ could not serialize message.", self.logTag);
|
||||
// TODO:
|
||||
[socketMessage didFailBeforeSending];
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
BOOL wasScheduled =
|
||||
// TODO: Consider using sendDataNoCopy.
|
||||
[self.websocket sendData:messageData error:&error];
|
||||
if (!wasScheduled || error) {
|
||||
OWSProdLogAndFail(@"%@ could not serialize request JSON: %@", self.logTag, error);
|
||||
// TODO:
|
||||
[socketMessage didFailBeforeSending];
|
||||
return;
|
||||
}
|
||||
DDLogVerbose(@"%@ message scheduled: %lld, %@, %@, %zd.",
|
||||
self.logTag,
|
||||
socketMessage.requestId,
|
||||
request.HTTPMethod,
|
||||
requestPath,
|
||||
jsonData.length);
|
||||
// [socketMessage didSucceed];
|
||||
}
|
||||
|
||||
#pragma mark - Delegate methods
|
||||
|
||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
|
||||
|
@ -364,18 +538,21 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
return;
|
||||
}
|
||||
|
||||
WebSocketMessage *wsMessage = [WebSocketMessage parseFromData:data];
|
||||
WebSocketResourcesWebSocketMessage *wsMessage = [WebSocketResourcesWebSocketMessage parseFromData:data];
|
||||
|
||||
if (wsMessage.type == WebSocketMessageTypeRequest) {
|
||||
if (wsMessage.type == WebSocketResourcesWebSocketMessageTypeRequest) {
|
||||
DDLogVerbose(@"%@ webSocket:didReceiveMessage: request.", self.logTag);
|
||||
[self processWebSocketRequestMessage:wsMessage.request];
|
||||
} else if (wsMessage.type == WebSocketMessageTypeResponse) {
|
||||
} else if (wsMessage.type == WebSocketResourcesWebSocketMessageTypeResponse) {
|
||||
DDLogVerbose(@"%@ webSocket:didReceiveMessage: response.", self.logTag);
|
||||
[self processWebSocketResponseMessage:wsMessage.response];
|
||||
} else {
|
||||
DDLogWarn(@"Got a WebSocketMessage of unknown type");
|
||||
DDLogWarn(@"%@ webSocket:didReceiveMessage: unknown.", self.logTag);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processWebSocketRequestMessage:(WebSocketRequestMessage *)message {
|
||||
- (void)processWebSocketRequestMessage:(WebSocketResourcesWebSocketRequestMessage *)message
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
DDLogInfo(@"%@ Got message with verb: %@ and path: %@", self.logTag, message.verb, message.path);
|
||||
|
@ -395,7 +572,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
|
||||
if (!decryptedPayload) {
|
||||
DDLogWarn(@"%@ Failed to decrypt incoming payload or bad HMAC", self.logTag);
|
||||
[self sendWebSocketMessageAcknowledgement:message];
|
||||
[self sendWebSocketResourcesWebSocketMessageAcknowledgement:message];
|
||||
backgroundTask = nil;
|
||||
return;
|
||||
}
|
||||
|
@ -417,38 +594,91 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
|
|||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self sendWebSocketMessageAcknowledgement:message];
|
||||
[self sendWebSocketResourcesWebSocketMessageAcknowledgement:message];
|
||||
backgroundTask = nil;
|
||||
});
|
||||
});
|
||||
} else if ([message.path isEqualToString:@"/api/v1/queue/empty"]) {
|
||||
// Queue is drained.
|
||||
|
||||
[self sendWebSocketMessageAcknowledgement:message];
|
||||
[self sendWebSocketResourcesWebSocketMessageAcknowledgement:message];
|
||||
} else {
|
||||
DDLogWarn(@"%@ Unsupported WebSocket Request", self.logTag);
|
||||
|
||||
[self sendWebSocketMessageAcknowledgement:message];
|
||||
[self sendWebSocketResourcesWebSocketMessageAcknowledgement:message];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processWebSocketResponseMessage:(WebSocketResponseMessage *)message {
|
||||
- (void)processWebSocketResponseMessage:(WebSocketResourcesWebSocketResponseMessage *)message
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(message);
|
||||
|
||||
DDLogWarn(@"Client should not receive WebSocket Respond messages");
|
||||
DDLogInfo(@"%@ received WebSocket response.", self.logTag);
|
||||
|
||||
if (![message hasId]) {
|
||||
DDLogError(@"%@ received incomplete WebSocket response.", self.logTag);
|
||||
return;
|
||||
}
|
||||
|
||||
UInt64 requestId = message.id;
|
||||
UInt32 responseStatus = 0;
|
||||
if (message.hasStatus) {
|
||||
responseStatus = message.status;
|
||||
}
|
||||
NSString *_Nullable responseMessage;
|
||||
if (message.hasMessage) {
|
||||
responseMessage = message.message;
|
||||
}
|
||||
NSData *_Nullable responseBody;
|
||||
if (message.hasBody) {
|
||||
responseBody = message.body;
|
||||
}
|
||||
NSArray<NSString *> *_Nullable responseHeaders = message.headers;
|
||||
|
||||
TSSocketMessage *_Nullable socketMessage;
|
||||
@synchronized(self)
|
||||
{
|
||||
socketMessage = self.socketMessageMap[@(requestId)];
|
||||
[self.socketMessageMap removeObjectForKey:@(requestId)];
|
||||
|
||||
if (!socketMessage) {
|
||||
DDLogError(@"%@ received response to unknown request.", self.logTag);
|
||||
} else {
|
||||
BOOL didSucceed = 200 <= responseStatus && responseStatus <= 299;
|
||||
if (didSucceed) {
|
||||
[socketMessage didSucceed];
|
||||
} else {
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeMessageResponseFailed,
|
||||
NSLocalizedString(
|
||||
@"ERROR_DESCRIPTION_RESPONSE_FAILED", @"Error indicating that a socket response failed."));
|
||||
[socketMessage didFailWithStatusCode:(NSInteger)responseStatus error:error];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DDLogVerbose(@"%@ received WebSocket response: %llu, %zd, %@, %zd, %@, %d.",
|
||||
self.logTag,
|
||||
(unsigned long long)requestId,
|
||||
(NSInteger)responseStatus,
|
||||
responseMessage,
|
||||
responseBody.length,
|
||||
responseHeaders,
|
||||
socketMessage != nil);
|
||||
}
|
||||
|
||||
- (void)sendWebSocketMessageAcknowledgement:(WebSocketRequestMessage *)request {
|
||||
- (void)sendWebSocketResourcesWebSocketMessageAcknowledgement:(WebSocketResourcesWebSocketRequestMessage *)request
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
WebSocketResponseMessageBuilder *response = [WebSocketResponseMessage builder];
|
||||
WebSocketResourcesWebSocketResponseMessageBuilder *response = [WebSocketResourcesWebSocketResponseMessage builder];
|
||||
[response setStatus:200];
|
||||
[response setMessage:@"OK"];
|
||||
[response setId:request.id];
|
||||
|
||||
WebSocketMessageBuilder *message = [WebSocketMessage builder];
|
||||
WebSocketResourcesWebSocketMessageBuilder *message = [WebSocketResourcesWebSocketMessage builder];
|
||||
[message setResponse:response.build];
|
||||
[message setType:WebSocketMessageTypeResponse];
|
||||
[message setType:WebSocketResourcesWebSocketMessageTypeResponse];
|
||||
|
||||
NSError *error;
|
||||
[self.websocket sendDataNoCopy:message.build.data error:&error];
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
#import <ProtocolBuffers/ProtocolBuffers.h>
|
||||
|
||||
// @@protoc_insertion_point(imports)
|
||||
|
||||
@class ObjectiveCFileOptions;
|
||||
@class ObjectiveCFileOptionsBuilder;
|
||||
@class PBDescriptorProto;
|
||||
@class PBDescriptorProtoBuilder;
|
||||
@class PBDescriptorProtoExtensionRange;
|
||||
@class PBDescriptorProtoExtensionRangeBuilder;
|
||||
@class PBEnumDescriptorProto;
|
||||
@class PBEnumDescriptorProtoBuilder;
|
||||
@class PBEnumOptions;
|
||||
@class PBEnumOptionsBuilder;
|
||||
@class PBEnumValueDescriptorProto;
|
||||
@class PBEnumValueDescriptorProtoBuilder;
|
||||
@class PBEnumValueOptions;
|
||||
@class PBEnumValueOptionsBuilder;
|
||||
@class PBFieldDescriptorProto;
|
||||
@class PBFieldDescriptorProtoBuilder;
|
||||
@class PBFieldOptions;
|
||||
@class PBFieldOptionsBuilder;
|
||||
@class PBFileDescriptorProto;
|
||||
@class PBFileDescriptorProtoBuilder;
|
||||
@class PBFileDescriptorSet;
|
||||
@class PBFileDescriptorSetBuilder;
|
||||
@class PBFileOptions;
|
||||
@class PBFileOptionsBuilder;
|
||||
@class PBMessageOptions;
|
||||
@class PBMessageOptionsBuilder;
|
||||
@class PBMethodDescriptorProto;
|
||||
@class PBMethodDescriptorProtoBuilder;
|
||||
@class PBMethodOptions;
|
||||
@class PBMethodOptionsBuilder;
|
||||
@class PBOneofDescriptorProto;
|
||||
@class PBOneofDescriptorProtoBuilder;
|
||||
@class PBServiceDescriptorProto;
|
||||
@class PBServiceDescriptorProtoBuilder;
|
||||
@class PBServiceOptions;
|
||||
@class PBServiceOptionsBuilder;
|
||||
@class PBSourceCodeInfo;
|
||||
@class PBSourceCodeInfoBuilder;
|
||||
@class PBSourceCodeInfoLocation;
|
||||
@class PBSourceCodeInfoLocationBuilder;
|
||||
@class PBUninterpretedOption;
|
||||
@class PBUninterpretedOptionBuilder;
|
||||
@class PBUninterpretedOptionNamePart;
|
||||
@class PBUninterpretedOptionNamePartBuilder;
|
||||
@class WebSocketResourcesWebSocketMessage;
|
||||
@class WebSocketResourcesWebSocketMessageBuilder;
|
||||
@class WebSocketResourcesWebSocketRequestMessage;
|
||||
@class WebSocketResourcesWebSocketRequestMessageBuilder;
|
||||
@class WebSocketResourcesWebSocketResponseMessage;
|
||||
@class WebSocketResourcesWebSocketResponseMessageBuilder;
|
||||
|
||||
|
||||
typedef NS_ENUM(SInt32, WebSocketResourcesWebSocketMessageType) {
|
||||
WebSocketResourcesWebSocketMessageTypeUnknown = 0,
|
||||
WebSocketResourcesWebSocketMessageTypeRequest = 1,
|
||||
WebSocketResourcesWebSocketMessageTypeResponse = 2,
|
||||
};
|
||||
|
||||
BOOL WebSocketResourcesWebSocketMessageTypeIsValidValue(WebSocketResourcesWebSocketMessageType value);
|
||||
NSString *NSStringFromWebSocketResourcesWebSocketMessageType(WebSocketResourcesWebSocketMessageType value);
|
||||
|
||||
|
||||
@interface WebSocketResourcesWebSocketResourcesRoot : NSObject {
|
||||
}
|
||||
+ (PBExtensionRegistry*) extensionRegistry;
|
||||
+ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry;
|
||||
@end
|
||||
|
||||
#define WebSocketRequestMessage_verb @"verb"
|
||||
#define WebSocketRequestMessage_path @"path"
|
||||
#define WebSocketRequestMessage_body @"body"
|
||||
#define WebSocketRequestMessage_headers @"headers"
|
||||
#define WebSocketRequestMessage_id @"id"
|
||||
@interface WebSocketResourcesWebSocketRequestMessage : PBGeneratedMessage<GeneratedMessageProtocol> {
|
||||
@private
|
||||
BOOL hasId_:1;
|
||||
BOOL hasVerb_:1;
|
||||
BOOL hasPath_:1;
|
||||
BOOL hasBody_:1;
|
||||
UInt64 id;
|
||||
NSString* verb;
|
||||
NSString* path;
|
||||
NSData* body;
|
||||
NSMutableArray * headersArray;
|
||||
}
|
||||
- (BOOL) hasVerb;
|
||||
- (BOOL) hasPath;
|
||||
- (BOOL) hasBody;
|
||||
- (BOOL) hasId;
|
||||
@property (readonly, strong) NSString* verb;
|
||||
@property (readonly, strong) NSString* path;
|
||||
@property (readonly, strong) NSData* body;
|
||||
@property (readonly, strong) NSArray * headers;
|
||||
@property (readonly) UInt64 id;
|
||||
- (NSString*)headersAtIndex:(NSUInteger)index;
|
||||
|
||||
+ (instancetype) defaultInstance;
|
||||
- (instancetype) defaultInstance;
|
||||
|
||||
- (BOOL) isInitialized;
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketRequestMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketRequestMessageBuilder*) builderWithPrototype:(WebSocketResourcesWebSocketRequestMessage*) prototype;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) toBuilder;
|
||||
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromData:(NSData*) data;
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromInputStream:(NSInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketRequestMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketResourcesWebSocketRequestMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketResourcesWebSocketRequestMessage* resultWebSocketRequestMessage;
|
||||
}
|
||||
|
||||
- (WebSocketResourcesWebSocketRequestMessage*) defaultInstance;
|
||||
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clear;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clone;
|
||||
|
||||
- (WebSocketResourcesWebSocketRequestMessage*) build;
|
||||
- (WebSocketResourcesWebSocketRequestMessage*) buildPartial;
|
||||
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) mergeFrom:(WebSocketResourcesWebSocketRequestMessage*) other;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
- (BOOL) hasVerb;
|
||||
- (NSString*) verb;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) setVerb:(NSString*) value;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clearVerb;
|
||||
|
||||
- (BOOL) hasPath;
|
||||
- (NSString*) path;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) setPath:(NSString*) value;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clearPath;
|
||||
|
||||
- (BOOL) hasBody;
|
||||
- (NSData*) body;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) setBody:(NSData*) value;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clearBody;
|
||||
|
||||
- (NSMutableArray *)headers;
|
||||
- (NSString*)headersAtIndex:(NSUInteger)index;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder *)addHeaders:(NSString*)value;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder *)setHeadersArray:(NSArray *)array;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder *)clearHeaders;
|
||||
|
||||
- (BOOL) hasId;
|
||||
- (UInt64) id;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) setId:(UInt64) value;
|
||||
- (WebSocketResourcesWebSocketRequestMessageBuilder*) clearId;
|
||||
@end
|
||||
|
||||
#define WebSocketResponseMessage_id @"id"
|
||||
#define WebSocketResponseMessage_status @"status"
|
||||
#define WebSocketResponseMessage_message @"message"
|
||||
#define WebSocketResponseMessage_headers @"headers"
|
||||
#define WebSocketResponseMessage_body @"body"
|
||||
@interface WebSocketResourcesWebSocketResponseMessage : PBGeneratedMessage<GeneratedMessageProtocol> {
|
||||
@private
|
||||
BOOL hasId_:1;
|
||||
BOOL hasMessage_:1;
|
||||
BOOL hasBody_:1;
|
||||
BOOL hasStatus_:1;
|
||||
UInt64 id;
|
||||
NSString* message;
|
||||
NSData* body;
|
||||
UInt32 status;
|
||||
NSMutableArray * headersArray;
|
||||
}
|
||||
- (BOOL) hasId;
|
||||
- (BOOL) hasStatus;
|
||||
- (BOOL) hasMessage;
|
||||
- (BOOL) hasBody;
|
||||
@property (readonly) UInt64 id;
|
||||
@property (readonly) UInt32 status;
|
||||
@property (readonly, strong) NSString* message;
|
||||
@property (readonly, strong) NSArray * headers;
|
||||
@property (readonly, strong) NSData* body;
|
||||
- (NSString*)headersAtIndex:(NSUInteger)index;
|
||||
|
||||
+ (instancetype) defaultInstance;
|
||||
- (instancetype) defaultInstance;
|
||||
|
||||
- (BOOL) isInitialized;
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketResponseMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketResponseMessageBuilder*) builderWithPrototype:(WebSocketResourcesWebSocketResponseMessage*) prototype;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) toBuilder;
|
||||
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromData:(NSData*) data;
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromInputStream:(NSInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketResponseMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketResourcesWebSocketResponseMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketResourcesWebSocketResponseMessage* resultWebSocketResponseMessage;
|
||||
}
|
||||
|
||||
- (WebSocketResourcesWebSocketResponseMessage*) defaultInstance;
|
||||
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clear;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clone;
|
||||
|
||||
- (WebSocketResourcesWebSocketResponseMessage*) build;
|
||||
- (WebSocketResourcesWebSocketResponseMessage*) buildPartial;
|
||||
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) mergeFrom:(WebSocketResourcesWebSocketResponseMessage*) other;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
- (BOOL) hasId;
|
||||
- (UInt64) id;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) setId:(UInt64) value;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clearId;
|
||||
|
||||
- (BOOL) hasStatus;
|
||||
- (UInt32) status;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) setStatus:(UInt32) value;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clearStatus;
|
||||
|
||||
- (BOOL) hasMessage;
|
||||
- (NSString*) message;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) setMessage:(NSString*) value;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clearMessage;
|
||||
|
||||
- (NSMutableArray *)headers;
|
||||
- (NSString*)headersAtIndex:(NSUInteger)index;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder *)addHeaders:(NSString*)value;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder *)setHeadersArray:(NSArray *)array;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder *)clearHeaders;
|
||||
|
||||
- (BOOL) hasBody;
|
||||
- (NSData*) body;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) setBody:(NSData*) value;
|
||||
- (WebSocketResourcesWebSocketResponseMessageBuilder*) clearBody;
|
||||
@end
|
||||
|
||||
#define WebSocketMessage_type @"type"
|
||||
#define WebSocketMessage_request @"request"
|
||||
#define WebSocketMessage_response @"response"
|
||||
@interface WebSocketResourcesWebSocketMessage : PBGeneratedMessage<GeneratedMessageProtocol> {
|
||||
@private
|
||||
BOOL hasRequest_:1;
|
||||
BOOL hasResponse_:1;
|
||||
BOOL hasType_:1;
|
||||
WebSocketResourcesWebSocketRequestMessage* request;
|
||||
WebSocketResourcesWebSocketResponseMessage* response;
|
||||
WebSocketResourcesWebSocketMessageType type;
|
||||
}
|
||||
- (BOOL) hasType;
|
||||
- (BOOL) hasRequest;
|
||||
- (BOOL) hasResponse;
|
||||
@property (readonly) WebSocketResourcesWebSocketMessageType type;
|
||||
@property (readonly, strong) WebSocketResourcesWebSocketRequestMessage* request;
|
||||
@property (readonly, strong) WebSocketResourcesWebSocketResponseMessage* response;
|
||||
|
||||
+ (instancetype) defaultInstance;
|
||||
- (instancetype) defaultInstance;
|
||||
|
||||
- (BOOL) isInitialized;
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketMessageBuilder*) builder;
|
||||
+ (WebSocketResourcesWebSocketMessageBuilder*) builderWithPrototype:(WebSocketResourcesWebSocketMessage*) prototype;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) toBuilder;
|
||||
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromData:(NSData*) data;
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromInputStream:(NSInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
+ (WebSocketResourcesWebSocketMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface WebSocketResourcesWebSocketMessageBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
WebSocketResourcesWebSocketMessage* resultWebSocketMessage;
|
||||
}
|
||||
|
||||
- (WebSocketResourcesWebSocketMessage*) defaultInstance;
|
||||
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) clear;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) clone;
|
||||
|
||||
- (WebSocketResourcesWebSocketMessage*) build;
|
||||
- (WebSocketResourcesWebSocketMessage*) buildPartial;
|
||||
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) mergeFrom:(WebSocketResourcesWebSocketMessage*) other;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
- (BOOL) hasType;
|
||||
- (WebSocketResourcesWebSocketMessageType) type;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) setType:(WebSocketResourcesWebSocketMessageType) value;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) clearType;
|
||||
|
||||
- (BOOL) hasRequest;
|
||||
- (WebSocketResourcesWebSocketRequestMessage*) request;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) setRequest:(WebSocketResourcesWebSocketRequestMessage*) value;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) setRequestBuilder:(WebSocketResourcesWebSocketRequestMessageBuilder*) builderForValue;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) mergeRequest:(WebSocketResourcesWebSocketRequestMessage*) value;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) clearRequest;
|
||||
|
||||
- (BOOL) hasResponse;
|
||||
- (WebSocketResourcesWebSocketResponseMessage*) response;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) setResponse:(WebSocketResourcesWebSocketResponseMessage*) value;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) setResponseBuilder:(WebSocketResourcesWebSocketResponseMessageBuilder*) builderForValue;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) mergeResponse:(WebSocketResourcesWebSocketResponseMessage*) value;
|
||||
- (WebSocketResourcesWebSocketMessageBuilder*) clearResponse;
|
||||
@end
|
||||
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
File diff suppressed because it is too large
Load Diff
|
@ -43,6 +43,8 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
|
|||
// A non-recoverable while importing or exporting a backup.
|
||||
OWSErrorCodeBackupFailure = 777419,
|
||||
OWSErrorCodeLocalAuthenticationError = 777420,
|
||||
OWSErrorCodeMessageRequestFailed = 777421,
|
||||
OWSErrorCodeMessageResponseFailed = 777422,
|
||||
};
|
||||
|
||||
extern NSString *const OWSErrorRecipientIdentifierKey;
|
||||
|
|
|
@ -59,7 +59,7 @@ NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError()
|
|||
|
||||
NSError *OWSErrorMakeMessageSendFailedToBlockListError()
|
||||
{
|
||||
return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendFailedToBlockList,
|
||||
return OWSErrorWithCodeDescription(OWSErrorCodeMessageRequestFailedToBlockList,
|
||||
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCK_LIST",
|
||||
@"Error message indicating that message send failed due to block list"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue