From 56b2dd4ace08afcfea7acb7925a01a876ce9a964 Mon Sep 17 00:00:00 2001 From: Thong Nguyen Date: Sat, 1 Feb 2014 00:23:23 +0000 Subject: [PATCH] Better range/length handling in STKHTTPDataSource. Handles out-of-range requests gracefully --- StreamingKit/StreamingKit/STKAudioPlayer.m | 2 - .../STKAutoRecoveringHTTPDataSource.m | 2 +- StreamingKit/StreamingKit/STKHTTPDataSource.m | 81 ++++++++++++------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index defa6cc..e6d0205 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -1205,9 +1205,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn } [currentEntry updateAudioDataSource]; - [currentEntry reset]; - [currentEntry.dataSource seekToOffset:seekByteOffset]; self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek; diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m index 286ac7d..87db858 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m @@ -230,7 +230,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach { NSLog(@"dataSourceEof"); - if ([self position] != [self length]) + if ([self position] < [self length]) { [self processRetryOnError]; diff --git a/StreamingKit/StreamingKit/STKHTTPDataSource.m b/StreamingKit/StreamingKit/STKHTTPDataSource.m index 287e8b5..7874015 100644 --- a/StreamingKit/StreamingKit/STKHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKHTTPDataSource.m @@ -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))