diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index 8f7742e..1371697 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -937,7 +937,7 @@ static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData, while (1) { ssize_t result = read(httpSocket, (char*)outData.mutableBytes + length, outData.length - length); if (result < 0) { - length = NSNotFound; + length = NSUIntegerMax; break; } else if (result == 0) { break; @@ -947,7 +947,7 @@ static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData, outData.length = 2 * outData.length; } } - if (length != NSNotFound) { + if (length != NSUIntegerMax) { outData.length = length; response = _CreateHTTPMessageFromData(outData, NO); } else { diff --git a/GCDWebServer/Core/GCDWebServerConnection.m b/GCDWebServer/Core/GCDWebServerConnection.m index e80ca75..a8e447b 100644 --- a/GCDWebServer/Core/GCDWebServerConnection.m +++ b/GCDWebServer/Core/GCDWebServerConnection.m @@ -416,7 +416,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { if (_response.contentType != nil) { CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (ARC_BRIDGE CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType)); } - if (_response.contentLength != NSNotFound) { + if (_response.contentLength != NSUIntegerMax) { CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]); } if (_response.usesChunkedTransferEncoding) { diff --git a/GCDWebServer/Core/GCDWebServerPrivate.h b/GCDWebServer/Core/GCDWebServerPrivate.h index b8adbaa..73b0697 100644 --- a/GCDWebServer/Core/GCDWebServerPrivate.h +++ b/GCDWebServer/Core/GCDWebServerPrivate.h @@ -111,7 +111,7 @@ extern void GCDLogMessage(GCDWebServerLogLevel level, NSString* format, ...) NS_ #define kGCDWebServerErrorDomain @"GCDWebServerErrorDomain" static inline BOOL GCDWebServerIsValidByteRange(NSRange range) { - return ((range.location != NSNotFound) || (range.length > 0)); + return ((range.location != NSUIntegerMax) || (range.length > 0)); } static inline NSError* GCDWebServerMakePosixError(int code) { diff --git a/GCDWebServer/Core/GCDWebServerRequest.h b/GCDWebServer/Core/GCDWebServerRequest.h index b2af74f..c599b7e 100644 --- a/GCDWebServer/Core/GCDWebServerRequest.h +++ b/GCDWebServer/Core/GCDWebServerRequest.h @@ -119,7 +119,7 @@ * Returns the content length for the body of the request parsed from the * "Content-Length" header. * - * This property will be set to "NSNotFound" if the request has no body or + * This property will be set to "NSUIntegerMax" if the request has no body or * if there is a body but no "Content-Length" header, typically because * chunked transfer encoding is used. */ @@ -136,9 +136,9 @@ @property(nonatomic, readonly) NSString* ifNoneMatch; /** - * Returns the parsed "Range" header or (NSNotFound, 0) if absent or malformed. + * Returns the parsed "Range" header or (NSUIntegerMax, 0) if absent or malformed. * The range will be set to (offset, length) if expressed from the beginning - * of the entity body, or (NSNotFound, -length) if expressed from its end. + * of the entity body, or (NSUIntegerMax, length) if expressed from its end. */ @property(nonatomic, readonly) NSRange byteRange; diff --git a/GCDWebServer/Core/GCDWebServerRequest.m b/GCDWebServer/Core/GCDWebServerRequest.m index ac2d988..e495fde 100644 --- a/GCDWebServer/Core/GCDWebServerRequest.m +++ b/GCDWebServer/Core/GCDWebServerRequest.m @@ -187,14 +187,14 @@ if (_type == nil) { _type = kGCDWebServerDefaultMimeType; } - _length = NSNotFound; + _length = NSUIntegerMax; } else { if (_type) { DNOT_REACHED(); ARC_RELEASE(self); return nil; } - _length = NSNotFound; + _length = NSUIntegerMax; } NSString* modifiedHeader = [_headers objectForKey:@"If-Modified-Since"]; @@ -203,7 +203,7 @@ } _noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]); - _range = NSMakeRange(NSNotFound, 0); + _range = NSMakeRange(NSUIntegerMax, 0); NSString* rangeHeader = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Range"]); if (rangeHeader) { if ([rangeHeader hasPrefix:@"bytes="]) { @@ -222,13 +222,13 @@ _range.location = startValue; _range.length = NSUIntegerMax; } else if (endString.length && (endValue > 0)) { // The final 500 bytes: "-500" - _range.location = NSNotFound; + _range.location = NSUIntegerMax; _range.length = endValue; } } } } - if ((_range.location == NSNotFound) && (_range.length == 0)) { // Ignore "Range" header if syntactically invalid + if ((_range.location == NSUIntegerMax) && (_range.length == 0)) { // Ignore "Range" header if syntactically invalid LOG_WARNING(@"Failed to parse 'Range' header \"%@\" for url: %@", rangeHeader, url); } } diff --git a/GCDWebServer/Core/GCDWebServerResponse.h b/GCDWebServer/Core/GCDWebServerResponse.h index d65f2f0..ee626a6 100644 --- a/GCDWebServer/Core/GCDWebServerResponse.h +++ b/GCDWebServer/Core/GCDWebServerResponse.h @@ -87,12 +87,12 @@ /** * Sets the content length for the body of the response. If a body is present - * but this property is set to "NSNotFound", this means the length of the body + * but this property is set to "NSUIntegerMax", this means the length of the body * cannot be known ahead of time. Chunked transfer encoding will be * automatically enabled by the GCDWebServerConnection to comply with HTTP/1.1 * specifications. * - * The default value is "NSNotFound" i.e. the response has no body or its length + * The default value is "NSUIntegerMax" i.e. the response has no body or its length * is undefined. */ @property(nonatomic) NSUInteger contentLength; diff --git a/GCDWebServer/Core/GCDWebServerResponse.m b/GCDWebServer/Core/GCDWebServerResponse.m index 0182ee2..e431dda 100644 --- a/GCDWebServer/Core/GCDWebServerResponse.m +++ b/GCDWebServer/Core/GCDWebServerResponse.m @@ -81,7 +81,7 @@ - (id)initWithResponse:(GCDWebServerResponse*)response reader:(id)reader { if ((self = [super initWithResponse:response reader:reader])) { - response.contentLength = NSNotFound; // Make sure "Content-Length" header is not set since we don't know it + response.contentLength = NSUIntegerMax; // Make sure "Content-Length" header is not set since we don't know it [response setValue:@"gzip" forAdditionalHeader:@"Content-Encoding"]; } return self; @@ -180,7 +180,7 @@ - (instancetype)init { if ((self = [super init])) { _type = nil; - _length = NSNotFound; + _length = NSUIntegerMax; _status = kGCDWebServerHTTPStatusCode_OK; _maxAge = 0; _headers = [[NSMutableDictionary alloc] init]; @@ -208,7 +208,7 @@ } - (BOOL)usesChunkedTransferEncoding { - return (_type != nil) && (_length == NSNotFound); + return (_type != nil) && (_length == NSUIntegerMax); } - (BOOL)open:(NSError**)error { @@ -259,7 +259,7 @@ if (_type) { [description appendFormat:@"\nContent Type = %@", _type]; } - if (_length != NSNotFound) { + if (_length != NSUIntegerMax) { [description appendFormat:@"\nContent Length = %lu", (unsigned long)_length]; } [description appendFormat:@"\nCache Control Max Age = %lu", (unsigned long)_maxAge]; diff --git a/GCDWebServer/Requests/GCDWebServerDataRequest.m b/GCDWebServer/Requests/GCDWebServerDataRequest.m index c3836de..cdf0719 100644 --- a/GCDWebServer/Requests/GCDWebServerDataRequest.m +++ b/GCDWebServer/Requests/GCDWebServerDataRequest.m @@ -49,7 +49,7 @@ } - (BOOL)open:(NSError**)error { - if (self.contentLength != NSNotFound) { + if (self.contentLength != NSUIntegerMax) { _data = [[NSMutableData alloc] initWithCapacity:self.contentLength]; } else { _data = [[NSMutableData alloc] init]; diff --git a/GCDWebServer/Responses/GCDWebServerFileResponse.h b/GCDWebServer/Responses/GCDWebServerFileResponse.h index 648f4b9..19d284d 100644 --- a/GCDWebServer/Responses/GCDWebServerFileResponse.h +++ b/GCDWebServer/Responses/GCDWebServerFileResponse.h @@ -77,9 +77,9 @@ /** * Initializes a response like -initWithFile: but restricts the file contents - * to a specific byte range. This range should be set to (NSNotFound, 0) for + * to a specific byte range. This range should be set to (NSUIntegerMax, 0) for * the full file, (offset, length) if expressed from the beginning of the file, - * or (NSNotFound, -length) if expressed from the end of the file. The "offset" + * or (NSUIntegerMax, length) if expressed from the end of the file. The "offset" * and "length" values will be automatically adjusted to be compatible with the * actual size of the file. * diff --git a/GCDWebServer/Responses/GCDWebServerFileResponse.m b/GCDWebServer/Responses/GCDWebServerFileResponse.m index 423d8b2..acf7bd0 100644 --- a/GCDWebServer/Responses/GCDWebServerFileResponse.m +++ b/GCDWebServer/Responses/GCDWebServerFileResponse.m @@ -59,11 +59,11 @@ } - (instancetype)initWithFile:(NSString*)path { - return [self initWithFile:path byteRange:NSMakeRange(NSNotFound, 0) isAttachment:NO]; + return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:NO]; } - (instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment { - return [self initWithFile:path byteRange:NSMakeRange(NSNotFound, 0) isAttachment:attachment]; + return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:attachment]; } - (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range { @@ -81,31 +81,34 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) { ARC_RELEASE(self); return nil; } - if (GCDWebServerIsValidByteRange(range)) { - if (range.location != NSNotFound) { - range.location = MIN(range.location, (NSUInteger)info.st_size); - range.length = MIN(range.length, (NSUInteger)info.st_size - range.location); + NSUInteger fileSize = (NSUInteger)info.st_size; + + BOOL hasByteRange = GCDWebServerIsValidByteRange(range); + if (hasByteRange) { + if (range.location != NSUIntegerMax) { + range.location = MIN(range.location, fileSize); + range.length = MIN(range.length, fileSize - range.location); } else { - range.length = MIN(range.length, (NSUInteger)info.st_size); - range.location = (NSUInteger)info.st_size - range.length; + range.length = MIN(range.length, fileSize); + range.location = fileSize - range.length; } if (range.length == 0) { ARC_RELEASE(self); return nil; // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header } + } else { + range.location = 0; + range.length = fileSize; } if ((self = [super init])) { _path = [path copy]; - if (range.location != NSNotFound) { - _offset = range.location; - _size = range.length; + _offset = range.location; + _size = range.length; + if (hasByteRange) { [self setStatusCode:kGCDWebServerHTTPStatusCode_PartialContent]; - [self setValue:[NSString stringWithFormat:@"bytes %i-%i/%i", (int)range.location, (int)(range.location + range.length - 1), (int)info.st_size] forAdditionalHeader:@"Content-Range"]; - LOG_DEBUG(@"Using content bytes range [%i-%i] for file \"%@\"", (int)range.location, (int)(range.location + range.length - 1), path); - } else { - _offset = 0; - _size = (NSUInteger)info.st_size; + [self setValue:[NSString stringWithFormat:@"bytes %lu-%lu/%lu", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), (unsigned long)fileSize] forAdditionalHeader:@"Content-Range"]; + LOG_DEBUG(@"Using content bytes range [%lu-%lu] for file \"%@\"", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), path); } if (attachment) { @@ -121,8 +124,8 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) { } } - self.contentType = GCDWebServerGetMimeTypeForExtension([path pathExtension]); - self.contentLength = (range.location != NSNotFound ? range.length : (NSUInteger)info.st_size); + self.contentType = GCDWebServerGetMimeTypeForExtension([_path pathExtension]); + self.contentLength = _size; self.lastModifiedDate = _NSDateFromTimeSpec(&info.st_mtimespec); self.eTag = [NSString stringWithFormat:@"%llu/%li/%li", info.st_ino, info.st_mtimespec.tv_sec, info.st_mtimespec.tv_nsec]; }