mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-02 18:59:51 +00:00
250 lines
6.9 KiB
Objective-C
250 lines
6.9 KiB
Objective-C
/*
|
|
* This is the source code of Telegram for iOS v. 1.1
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Peter Iakovlev, 2013.
|
|
*/
|
|
|
|
#import "MTHttpWorker.h"
|
|
|
|
#import "MTTimer.h"
|
|
#import "MTQueue.h"
|
|
|
|
#import "MTDatacenterAddress.h"
|
|
|
|
#import "MTInternalId.h"
|
|
|
|
MTInternalIdClass(MTHttpWorker)
|
|
|
|
@implementation MTHttpWorkerBlockDelegate
|
|
|
|
- (void)httpWorker:(MTHttpWorker *)__unused httpWorker completedWithData:(NSData *)data
|
|
{
|
|
if (_completedWithData)
|
|
_completedWithData(data);
|
|
}
|
|
|
|
- (void)httpWorkerConnected:(MTHttpWorker *)__unused httpWorker
|
|
{
|
|
if (_connected)
|
|
_connected();
|
|
}
|
|
|
|
- (void)httpWorkerFailed:(MTHttpWorker *)__unused httpWorker
|
|
{
|
|
if (_failed)
|
|
_failed();
|
|
}
|
|
|
|
@end
|
|
|
|
@interface MTHttpWorker ()
|
|
{
|
|
MTTimer *_timeoutTimer;
|
|
AFHTTPRequestOperation *_operation;
|
|
bool _notifiedDelegateAboutConnection;
|
|
bool _isConnected;
|
|
bool _stopped;
|
|
NSTimeInterval _timeout;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation MTHttpWorker
|
|
|
|
+ (MTQueue *)httpWorkerProcessingQueue
|
|
{
|
|
static MTQueue *queue = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
queue = [[MTQueue alloc] initWithName:"org.mtproto.httpWorkerProcessingQueue"];
|
|
});
|
|
return queue;
|
|
}
|
|
|
|
- (instancetype)initWithDelegate:(id<MTHttpWorkerDelegate>)delegate address:(MTDatacenterAddress *)address payloadData:(NSData *)payloadData performsLongPolling:(bool)performsLongPolling
|
|
{
|
|
int32_t randomId = 0;
|
|
arc4random_buf(&randomId, 4);
|
|
|
|
/*#ifdef DEBUG
|
|
if (![address isIpv6]) {
|
|
address = [[MTDatacenterAddress alloc] initWithIp:@"127.0.0.1" port:443 preferForMedia:address.preferForMedia restrictToTcp:address.restrictToTcp];
|
|
}
|
|
#endif*/
|
|
|
|
NSString *urlString = [[NSString alloc] initWithFormat:@"http://%@:%d/api%" PRIx32 "", address.ip, (int)address.port, randomId];
|
|
|
|
self = [super initWithBaseURL:[[NSURL alloc] initWithString:urlString]];
|
|
if (self != nil)
|
|
{
|
|
_internalId = [[MTInternalId(MTHttpWorker) alloc] init];
|
|
_delegate = delegate;
|
|
_performsLongPolling = performsLongPolling;
|
|
|
|
[[MTHttpWorker httpWorkerProcessingQueue] dispatchOnQueue:^
|
|
{
|
|
__weak MTHttpWorker *weakSelf = self;
|
|
|
|
_timeout = performsLongPolling ? 40 : 12;
|
|
_timeoutTimer = [[MTTimer alloc] initWithTimeout:_timeout repeat:false completion:^
|
|
{
|
|
MTHttpWorker *strongSelf = weakSelf;
|
|
[strongSelf requestTimeout];
|
|
} queue:[MTHttpWorker httpWorkerProcessingQueue].nativeQueue];
|
|
[_timeoutTimer start];
|
|
|
|
NSMutableURLRequest *urlRequest = [self requestWithMethod:@"POST" path:urlString parameters:nil];
|
|
[urlRequest setHTTPBody:payloadData];
|
|
|
|
_operation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
|
|
|
|
[_operation setSuccessCallbackQueue:[MTHttpWorker httpWorkerProcessingQueue].nativeQueue];
|
|
[_operation setFailureCallbackQueue:[MTHttpWorker httpWorkerProcessingQueue].nativeQueue];
|
|
|
|
[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, __unused id responseObject)
|
|
{
|
|
MTHttpWorker *strongSelf = weakSelf;
|
|
[strongSelf requestCompleted:[operation responseData] error:nil];
|
|
} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error)
|
|
{
|
|
MTHttpWorker *strongSelf = weakSelf;
|
|
[strongSelf requestCompleted:nil error:error];
|
|
}];
|
|
|
|
[_operation setUploadProgressBlock:^(__unused NSInteger bytesWritten, __unused NSInteger totalBytesWritten, __unused NSInteger totalBytesExpectedToWrite)
|
|
{
|
|
MTHttpWorker *strongSelf = weakSelf;
|
|
[strongSelf requestUploadProgress];
|
|
}];
|
|
|
|
/*if (request.progressBlock != nil)
|
|
{
|
|
[httpOperation setDownloadProgressBlock:^(__unused NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead)
|
|
{
|
|
if (totalBytesExpectedToRead > 0 && totalBytesRead > 0)
|
|
{
|
|
request.progressBlock(((float)totalBytesRead) / ((float)totalBytesExpectedToRead));
|
|
}
|
|
}];
|
|
}*/
|
|
|
|
[self enqueueHTTPRequestOperation:_operation];
|
|
}];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[self stop];
|
|
}
|
|
|
|
- (bool)isConnected
|
|
{
|
|
return _isConnected;
|
|
}
|
|
|
|
- (void)stop
|
|
{
|
|
_stopped = true;
|
|
|
|
AFHTTPRequestOperation *operation = _operation;
|
|
_operation = nil;
|
|
|
|
[[MTHttpWorker httpWorkerProcessingQueue] dispatchOnQueue:^
|
|
{
|
|
[operation cancel];
|
|
}];
|
|
|
|
[self cancelTimer];
|
|
}
|
|
|
|
- (void)terminateWithFailure
|
|
{
|
|
[[MTHttpWorker httpWorkerProcessingQueue] dispatchOnQueue:^
|
|
{
|
|
[self stop];
|
|
|
|
id<MTHttpWorkerDelegate> delegate = _delegate;
|
|
if ([delegate respondsToSelector:@selector(httpWorkerFailed:)])
|
|
[delegate httpWorkerFailed:self];
|
|
}];
|
|
}
|
|
|
|
- (void)cancelTimer
|
|
{
|
|
if (_timeoutTimer != nil)
|
|
{
|
|
MTTimer *timeoutTimer = _timeoutTimer;
|
|
_timeoutTimer = nil;
|
|
|
|
[[MTHttpWorker httpWorkerProcessingQueue] dispatchOnQueue:^
|
|
{
|
|
[timeoutTimer invalidate];
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)requestUploadProgress
|
|
{
|
|
[[MTHttpWorker httpWorkerProcessingQueue] dispatchOnQueue:^
|
|
{
|
|
_isConnected = true;
|
|
|
|
if (!_notifiedDelegateAboutConnection)
|
|
{
|
|
_notifiedDelegateAboutConnection = true;
|
|
|
|
id<MTHttpWorkerDelegate> delegate = _delegate;
|
|
if ([delegate respondsToSelector:@selector(httpWorkerConnected:)])
|
|
[delegate httpWorkerConnected:self];
|
|
}
|
|
|
|
[_timeoutTimer resetTimeout:_timeout];
|
|
}];
|
|
}
|
|
|
|
- (void)requestCompleted:(NSData *)response error:(NSError *)error
|
|
{
|
|
if (!_stopped)
|
|
{
|
|
id<MTHttpWorkerDelegate> delegate = _delegate;
|
|
|
|
if (error == nil && response != nil)
|
|
{
|
|
if ([delegate respondsToSelector:@selector(httpWorker:completedWithData:)])
|
|
[delegate httpWorker:self completedWithData:response];
|
|
}
|
|
else
|
|
{
|
|
if ([delegate respondsToSelector:@selector(httpWorkerFailed:)])
|
|
[delegate httpWorkerFailed:self];
|
|
}
|
|
}
|
|
|
|
[self cancelTimer];
|
|
_stopped = true;
|
|
_operation = nil;
|
|
}
|
|
|
|
- (void)requestTimeout
|
|
{
|
|
if (!_stopped)
|
|
{
|
|
[self stop];
|
|
|
|
id<MTHttpWorkerDelegate> delegate = _delegate;
|
|
if ([delegate respondsToSelector:@selector(httpWorkerFailed:)])
|
|
[delegate httpWorkerFailed:self];
|
|
}
|
|
|
|
[self cancelTimer];
|
|
_stopped = true;
|
|
_operation = nil;
|
|
}
|
|
|
|
@end
|