Better range/length handling in STKHTTPDataSource. Handles out-of-range requests gracefully

This commit is contained in:
Thong Nguyen 2014-02-01 00:23:23 +00:00
parent a9b1e143a0
commit 56b2dd4ace
3 changed files with 53 additions and 32 deletions

View File

@ -1205,9 +1205,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn
}
[currentEntry updateAudioDataSource];
[currentEntry reset];
[currentEntry.dataSource seekToOffset:seekByteOffset];
self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek;

View File

@ -230,7 +230,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
{
NSLog(@"dataSourceEof");
if ([self position] != [self length])
if ([self position] < [self length])
{
[self processRetryOnError];

View File

@ -138,40 +138,61 @@
-(void) dataAvailable
{
if (fileLength < 0)
{
CFTypeRef response = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
if (self.httpStatusCode == 0)
{
CFTypeRef response = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
httpHeaders = (__bridge_transfer NSDictionary*)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)response);
self.httpStatusCode = CFHTTPMessageGetResponseStatusCode((CFHTTPMessageRef)response);
CFRelease(response);
if (self.httpStatusCode == 200)
{
if (seekStart == 0)
{
fileLength = (long long)[[httpHeaders objectForKey:@"Content-Length"] integerValue];
}
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"];
AudioFileTypeID typeIdFromMimeType = [STKHTTPDataSource audioFileTypeHintFromMimeType:contentType];
if (typeIdFromMimeType != 0)
{
audioFileTypeHint = typeIdFromMimeType;
}
}
else
{
[self errorOccured];
return;
}
}
[super dataAvailable];
if (self.httpStatusCode == 200)
{
if (seekStart == 0)
{
fileLength = (long long)[[httpHeaders objectForKey:@"Content-Length"] integerValue];
}
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"];
AudioFileTypeID typeIdFromMimeType = [STKHTTPDataSource audioFileTypeHintFromMimeType:contentType];
if (typeIdFromMimeType != 0)
{
audioFileTypeHint = typeIdFromMimeType;
}
}
else if (self.httpStatusCode == 206)
{
NSString* contentRange = [httpHeaders objectForKey:@"Content-Range"];
NSArray* components = [contentRange componentsSeparatedByString:@"/"];
if (components.count == 2)
{
fileLength = [[components objectAtIndex:1] integerValue];
}
}
else if (self.httpStatusCode == 416)
{
if (self.length >= 0)
{
seekStart = self.length;
}
[self eof];
return;
}
else if (self.httpStatusCode >= 300)
{
[self errorOccured];
return;
}
}
[super dataAvailable];
}
-(long long) position
@ -196,7 +217,7 @@
CFReadStreamClose(stream);
CFRelease(stream);
}
NSAssert([NSRunLoop currentRunLoop] == eventsRunLoop, @"Seek called on wrong thread");
stream = 0;
@ -296,6 +317,8 @@
[self reregisterForEvents];
self.httpStatusCode = 0;
// Open
if (!CFReadStreamOpen(stream))