2009-03-05 05:01:36 -03:00
|
|
|
//
|
|
|
|
// HTTPSource.m
|
|
|
|
// HTTPSource
|
|
|
|
//
|
|
|
|
// Created by Vincent Spader on 3/1/07.
|
2020-03-07 21:08:47 -03:00
|
|
|
// Replaced by Christopher Snowhill on 3/7/20.
|
|
|
|
// Copyright 2020 __LoSnoCo__. All rights reserved.
|
2009-03-05 05:01:36 -03:00
|
|
|
//
|
|
|
|
|
|
|
|
#import "HTTPSource.h"
|
|
|
|
|
2013-10-11 09:03:55 -03:00
|
|
|
#import "Logging.h"
|
|
|
|
|
2020-03-07 21:08:47 -03:00
|
|
|
#define BUFFER_SIZE 131072
|
|
|
|
|
2009-03-05 05:01:36 -03:00
|
|
|
@implementation HTTPSource
|
|
|
|
|
2020-03-07 21:08:47 -03:00
|
|
|
- (NSURLSession *)createSession
|
2009-03-05 05:01:36 -03:00
|
|
|
{
|
2020-03-07 21:08:47 -03:00
|
|
|
queue = [[NSOperationQueue alloc] init];
|
|
|
|
[queue setMaxConcurrentOperationCount:1];
|
|
|
|
|
|
|
|
NSURLSession *session = nil;
|
|
|
|
session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
|
|
|
|
delegate:self
|
|
|
|
delegateQueue:queue];
|
|
|
|
return session;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)URLSession:(NSURLSession *)session
|
|
|
|
dataTask:(NSURLSessionDataTask *)dataTask
|
|
|
|
didReceiveData:(NSData *)data{
|
|
|
|
long bytesBuffered = 0;
|
|
|
|
if (cancelled) return;
|
|
|
|
@synchronized(bufferedData) {
|
|
|
|
[bufferedData addObject:data];
|
|
|
|
_bytesBuffered += [data length];
|
|
|
|
bytesBuffered = _bytesBuffered;
|
|
|
|
}
|
|
|
|
if (bytesBuffered > BUFFER_SIZE) {
|
|
|
|
[task suspend];
|
|
|
|
}
|
|
|
|
}
|
2009-03-05 05:01:36 -03:00
|
|
|
|
2020-03-07 21:08:47 -03:00
|
|
|
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
|
|
|
|
willCacheResponse:(NSCachedURLResponse *)proposedResponse
|
|
|
|
completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler{
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)URLSession:(NSURLSession *)session
|
|
|
|
task:(NSURLSessionTask *)task
|
|
|
|
didCompleteWithError:(NSError *)error{
|
|
|
|
cancelled = YES;
|
|
|
|
errorOccurred = YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)open:(NSURL *)url
|
|
|
|
{
|
|
|
|
cancelled = NO;
|
|
|
|
errorOccurred = NO;
|
|
|
|
|
|
|
|
bufferedData = [[NSMutableArray alloc] init];
|
|
|
|
|
|
|
|
URL = url;
|
|
|
|
NSURLRequest * request = [NSURLRequest requestWithURL:url];
|
|
|
|
session = [self createSession];
|
|
|
|
task = [session dataTaskWithRequest:request];
|
|
|
|
[task resume];
|
|
|
|
|
|
|
|
NSURLResponse * response = nil;
|
|
|
|
while (!response) {
|
|
|
|
response = [task response];
|
|
|
|
if (response) break;
|
|
|
|
if (errorOccurred) return NO;
|
|
|
|
usleep(100);
|
|
|
|
}
|
|
|
|
if (response) {
|
|
|
|
_mimeType = [response MIMEType];
|
|
|
|
}
|
|
|
|
|
2009-03-05 05:01:36 -03:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)mimeType
|
|
|
|
{
|
2013-10-11 09:03:55 -03:00
|
|
|
DLog(@"Returning mimetype! %@", _mimeType);
|
2009-03-05 05:01:36 -03:00
|
|
|
return _mimeType;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)seekable
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)seek:(long)position whence:(int)whence
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (long)tell
|
|
|
|
{
|
|
|
|
return _byteCount;
|
|
|
|
}
|
|
|
|
|
2013-10-03 05:00:58 -03:00
|
|
|
- (long)read:(void *)buffer amount:(long)amount
|
2009-03-05 05:01:36 -03:00
|
|
|
{
|
2013-10-03 05:00:58 -03:00
|
|
|
long totalRead = 0;
|
2020-03-07 21:08:47 -03:00
|
|
|
long bytesBuffered = 0;
|
2009-03-05 05:01:36 -03:00
|
|
|
|
|
|
|
while (totalRead < amount) {
|
2020-03-07 21:08:47 -03:00
|
|
|
NSData * dataBlock = nil;
|
|
|
|
@synchronized(bufferedData) {
|
|
|
|
if ([bufferedData count])
|
|
|
|
dataBlock = [bufferedData objectAtIndex:0];
|
|
|
|
}
|
|
|
|
if (!dataBlock) {
|
|
|
|
if (errorOccurred) return totalRead;
|
|
|
|
if (cancelled) return 0;
|
|
|
|
usleep(1000);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
NSInteger amountReceived = [dataBlock length];
|
2009-03-07 06:25:13 -03:00
|
|
|
if (amountReceived <= 0) {
|
|
|
|
break;
|
2009-03-07 02:58:50 -03:00
|
|
|
}
|
2020-03-07 21:08:47 -03:00
|
|
|
|
|
|
|
NSInteger amountUsed = amountReceived;
|
|
|
|
|
|
|
|
if (amountUsed > (amount - totalRead) )
|
|
|
|
amountUsed = amount - totalRead;
|
|
|
|
|
|
|
|
const void * dataBytes = [dataBlock bytes];
|
|
|
|
memcpy(((uint8_t *)buffer) + totalRead, dataBytes, amountUsed);
|
|
|
|
|
|
|
|
if (amountUsed < amountReceived) {
|
|
|
|
NSData * dataOut = [NSData dataWithBytes:(((uint8_t *)dataBytes) + amountUsed) length:(amountReceived - amountUsed)];
|
|
|
|
@synchronized(bufferedData) {
|
|
|
|
[bufferedData removeObjectAtIndex:0];
|
|
|
|
[bufferedData insertObject:dataOut atIndex:0];
|
|
|
|
_bytesBuffered -= amountUsed;
|
|
|
|
bytesBuffered = _bytesBuffered;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
@synchronized(bufferedData) {
|
|
|
|
[bufferedData removeObjectAtIndex:0];
|
|
|
|
_bytesBuffered -= amountUsed;
|
|
|
|
bytesBuffered = _bytesBuffered;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bytesBuffered <= (BUFFER_SIZE * 3 / 4)) {
|
|
|
|
[task resume];
|
|
|
|
}
|
|
|
|
|
|
|
|
totalRead += amountUsed;
|
2009-03-05 05:01:36 -03:00
|
|
|
}
|
2009-03-07 02:58:50 -03:00
|
|
|
|
2009-03-05 05:01:36 -03:00
|
|
|
_byteCount += totalRead;
|
|
|
|
|
|
|
|
return totalRead;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)close
|
|
|
|
{
|
2020-03-07 21:08:47 -03:00
|
|
|
cancelled = YES;
|
|
|
|
|
|
|
|
[task cancel];
|
|
|
|
task = nil;
|
2009-03-05 05:01:36 -03:00
|
|
|
|
|
|
|
_mimeType = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
[self close];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSURL *)url
|
|
|
|
{
|
2020-03-07 21:08:47 -03:00
|
|
|
return URL;
|
2009-03-05 05:01:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *)schemes
|
|
|
|
{
|
2018-09-23 20:45:03 -03:00
|
|
|
return [NSArray arrayWithObjects:@"http", @"https", nil];
|
2009-03-05 05:01:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|