session-ios/Signal/src/network/http/HttpSocket.m

97 lines
3.6 KiB
Objective-C

#import "HttpRequest.h"
#import "HttpResponse.h"
#import "HttpSocket.h"
#import "Util.h"
@implementation HttpSocket
+(HttpSocket*) httpSocketOver:(NetworkStream*)rawDataChannel {
require(rawDataChannel != nil);
HttpSocket* h = [HttpSocket new];
h->rawDataChannelTcp = rawDataChannel;
h->partialDataBuffer = [NSMutableData data];
h->sentPacketsLogger = [Environment.logging getOccurrenceLoggerForSender:self withKey:@"sent"];
h->receivedPacketsLogger = [Environment.logging getOccurrenceLoggerForSender:self withKey:@"received"];
return h;
}
+(HttpSocket*) httpSocketOverUdp:(UdpSocket*)rawDataChannel {
require(rawDataChannel != nil);
HttpSocket* h = [HttpSocket new];
h->rawDataChannelUdp = rawDataChannel;
h->partialDataBuffer = [NSMutableData data];
h->sentPacketsLogger = [Environment.logging getOccurrenceLoggerForSender:self withKey:@"sent"];
h->receivedPacketsLogger = [Environment.logging getOccurrenceLoggerForSender:self withKey:@"received"];
return h;
}
-(void) sendHttpRequestOrResponse:(HttpRequestOrResponse*)requestOrResponse {
require(requestOrResponse != nil);
requireState(httpSignalResponseHandler != nil);
[sentPacketsLogger markOccurrence:requestOrResponse];
NSData* data = [requestOrResponse serialize];
if (rawDataChannelUdp != nil) {
[rawDataChannelUdp send:data];
} else {
[rawDataChannelTcp send:data];
}
}
-(void) sendHttpRequest:(HttpRequest*)request {
require(request != nil);
[self sendHttpRequestOrResponse:[HttpRequestOrResponse httpRequestOrResponse:request]];
}
-(void) sendHttpResponse:(HttpResponse*)response {
require(response != nil);
[self sendHttpRequestOrResponse:[HttpRequestOrResponse httpRequestOrResponse:response]];
}
-(void) send:(HttpRequestOrResponse*)packet {
require(packet != nil);
[self sendHttpRequestOrResponse:packet];
}
-(void) startWithHandler:(PacketHandler*)handler
untilCancelled:(TOCCancelToken*)untilCancelledToken {
require(handler != nil);
requireState(httpSignalResponseHandler == nil);
httpSignalResponseHandler = handler;
TOCCancelTokenSource* lifetime = [TOCCancelTokenSource cancelTokenSourceUntil:untilCancelledToken];
PacketHandler* packetHandler = [PacketHandler packetHandler:^(id packet) {
require(packet != nil);
require([packet isKindOfClass:NSData.class]);
NSData* data = packet;
[partialDataBuffer replaceBytesInRange:NSMakeRange(partialDataBuffer.length, data.length) withBytes:[data bytes]];
while (true) {
NSUInteger usedDataLength;
HttpRequestOrResponse* s = nil;
@try {
s = [HttpRequestOrResponse tryExtractFromPartialData:partialDataBuffer usedLengthOut:&usedDataLength];
} @catch (OperationFailed* error) {
[handler handleError:error
relatedInfo:packet
causedTermination:true];
[lifetime cancel];
return;
}
if (s == nil) break;
[partialDataBuffer replaceBytesInRange:NSMakeRange(0, usedDataLength) withBytes:NULL length:0];
[receivedPacketsLogger markOccurrence:s];
[handler handlePacket:s];
}
} withErrorHandler:handler.errorHandler];
if (rawDataChannelTcp != nil) {
[rawDataChannelTcp startWithHandler:packetHandler];
[lifetime.token whenCancelledTerminate:rawDataChannelTcp];
} else {
[rawDataChannelUdp startWithHandler:packetHandler
untilCancelled:lifetime.token];
}
}
@end