mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-05-31 00:00:10 +08:00
Added support for "ETag" and "If-None-Match" headers
This commit is contained in:
@@ -411,6 +411,9 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
|||||||
if (_response.lastModifiedDate) {
|
if (_response.lastModifiedDate) {
|
||||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate(_response.lastModifiedDate));
|
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate(_response.lastModifiedDate));
|
||||||
}
|
}
|
||||||
|
if (_response.eTag) {
|
||||||
|
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (ARC_BRIDGE CFStringRef)_response.eTag);
|
||||||
|
}
|
||||||
if (_response.cacheControlMaxAge > 0) {
|
if (_response.cacheControlMaxAge > 0) {
|
||||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
|
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
|||||||
self.contentType = GCDWebServerGetMimeTypeForExtension([path pathExtension]);
|
self.contentType = GCDWebServerGetMimeTypeForExtension([path pathExtension]);
|
||||||
self.contentLength = (range.location != NSNotFound ? range.length : (NSUInteger)info.st_size);
|
self.contentLength = (range.location != NSNotFound ? range.length : (NSUInteger)info.st_size);
|
||||||
self.lastModifiedDate = _NSDateFromTimeSpec(&info.st_mtimespec);
|
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];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
@property(nonatomic, readonly) NSDictionary* query; // May be nil
|
@property(nonatomic, readonly) NSDictionary* query; // May be nil
|
||||||
@property(nonatomic, readonly) NSString* contentType; // Automatically parsed from headers (nil if request has no body or set to "application/octet-stream" if a body is present without a "Content-Type" header)
|
@property(nonatomic, readonly) NSString* contentType; // Automatically parsed from headers (nil if request has no body or set to "application/octet-stream" if a body is present without a "Content-Type" header)
|
||||||
@property(nonatomic, readonly) NSUInteger contentLength; // Automatically parsed from headers (NSNotFound if request has no "Content-Length" header)
|
@property(nonatomic, readonly) NSUInteger contentLength; // Automatically parsed from headers (NSNotFound if request has no "Content-Length" header)
|
||||||
@property(nonatomic, readonly) NSDate* ifModifiedSinceDate; // Automatically parsed from headers (nil if request has no "If-Modified-Since" header or it is malformatted)
|
@property(nonatomic, readonly) NSDate* ifModifiedSince; // Automatically parsed from headers (nil if request has no "If-Modified-Since" header or it is malformatted)
|
||||||
|
@property(nonatomic, readonly) NSString* ifNoneMatch; // Automatically parsed from headers (nil if request has no "If-None-Match" header)
|
||||||
@property(nonatomic, readonly) NSRange byteRange; // Automatically parsed from headers ([NSNotFound, 0] if request has no "Range" header, [offset, length] for byte range from beginning or [NSNotFound, -bytes] from end)
|
@property(nonatomic, readonly) NSRange byteRange; // Automatically parsed from headers ([NSNotFound, 0] if request has no "Range" header, [offset, length] for byte range from beginning or [NSNotFound, -bytes] from end)
|
||||||
@property(nonatomic, readonly) BOOL acceptsGzipContentEncoding;
|
@property(nonatomic, readonly) BOOL acceptsGzipContentEncoding;
|
||||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query;
|
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query;
|
||||||
|
|||||||
@@ -145,7 +145,8 @@
|
|||||||
NSString* _type;
|
NSString* _type;
|
||||||
BOOL _chunked;
|
BOOL _chunked;
|
||||||
NSUInteger _length;
|
NSUInteger _length;
|
||||||
NSDate* _modifiedSinceDate;
|
NSDate* _modifiedSince;
|
||||||
|
NSString* _noneMatch;
|
||||||
NSRange _range;
|
NSRange _range;
|
||||||
BOOL _gzipAccepted;
|
BOOL _gzipAccepted;
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@
|
|||||||
|
|
||||||
@implementation GCDWebServerRequest : NSObject
|
@implementation GCDWebServerRequest : NSObject
|
||||||
|
|
||||||
@synthesize method=_method, URL=_url, headers=_headers, path=_path, query=_query, contentType=_type, contentLength=_length, ifModifiedSinceDate=_modifiedSinceDate,
|
@synthesize method=_method, URL=_url, headers=_headers, path=_path, query=_query, contentType=_type, contentLength=_length, ifModifiedSince=_modifiedSince, ifNoneMatch=_noneMatch,
|
||||||
byteRange=_range, acceptsGzipContentEncoding=_gzipAccepted, usesChunkedTransferEncoding=_chunked;
|
byteRange=_range, acceptsGzipContentEncoding=_gzipAccepted, usesChunkedTransferEncoding=_chunked;
|
||||||
|
|
||||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
||||||
@@ -191,10 +192,11 @@
|
|||||||
_length = NSNotFound;
|
_length = NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* ifModifiedSinceHeader = [_headers objectForKey:@"If-Modified-Since"];
|
NSString* modifiedHeader = [_headers objectForKey:@"If-Modified-Since"];
|
||||||
if (ifModifiedSinceHeader) {
|
if (modifiedHeader) {
|
||||||
_modifiedSinceDate = [GCDWebServerParseHTTPDate(ifModifiedSinceHeader) copy];
|
_modifiedSince = [GCDWebServerParseHTTPDate(modifiedHeader) copy];
|
||||||
}
|
}
|
||||||
|
_noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]);
|
||||||
|
|
||||||
_range = NSMakeRange(NSNotFound, 0);
|
_range = NSMakeRange(NSNotFound, 0);
|
||||||
NSString* rangeHeader = [[_headers objectForKey:@"Range"] lowercaseString];
|
NSString* rangeHeader = [[_headers objectForKey:@"Range"] lowercaseString];
|
||||||
@@ -243,6 +245,7 @@
|
|||||||
ARC_RELEASE(_query);
|
ARC_RELEASE(_query);
|
||||||
ARC_RELEASE(_type);
|
ARC_RELEASE(_type);
|
||||||
ARC_RELEASE(_modifiedSinceDate);
|
ARC_RELEASE(_modifiedSinceDate);
|
||||||
|
ARC_RELEASE(_noneMatch);
|
||||||
ARC_RELEASE(_decoders);
|
ARC_RELEASE(_decoders);
|
||||||
|
|
||||||
ARC_DEALLOC(super);
|
ARC_DEALLOC(super);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
@property(nonatomic) NSInteger statusCode; // Default is 200
|
@property(nonatomic) NSInteger statusCode; // Default is 200
|
||||||
@property(nonatomic) NSUInteger cacheControlMaxAge; // Default is 0 seconds i.e. "Cache-Control: no-cache"
|
@property(nonatomic) NSUInteger cacheControlMaxAge; // Default is 0 seconds i.e. "Cache-Control: no-cache"
|
||||||
@property(nonatomic, retain) NSDate* lastModifiedDate; // Default is nil i.e. no "Last-Modified" header
|
@property(nonatomic, retain) NSDate* lastModifiedDate; // Default is nil i.e. no "Last-Modified" header
|
||||||
|
@property(nonatomic, copy) NSString* eTag; // Default is nil i.e. no "ETag" header
|
||||||
@property(nonatomic, getter=isGZipContentEncodingEnabled) BOOL gzipContentEncodingEnabled; // Default is disabled
|
@property(nonatomic, getter=isGZipContentEncodingEnabled) BOOL gzipContentEncodingEnabled; // Default is disabled
|
||||||
+ (instancetype)response;
|
+ (instancetype)response;
|
||||||
- (instancetype)init;
|
- (instancetype)init;
|
||||||
|
|||||||
@@ -157,6 +157,7 @@
|
|||||||
NSInteger _status;
|
NSInteger _status;
|
||||||
NSUInteger _maxAge;
|
NSUInteger _maxAge;
|
||||||
NSDate* _lastModified;
|
NSDate* _lastModified;
|
||||||
|
NSString* _eTag;
|
||||||
NSMutableDictionary* _headers;
|
NSMutableDictionary* _headers;
|
||||||
BOOL _chunked;
|
BOOL _chunked;
|
||||||
BOOL _gzipped;
|
BOOL _gzipped;
|
||||||
@@ -169,7 +170,7 @@
|
|||||||
|
|
||||||
@implementation GCDWebServerResponse
|
@implementation GCDWebServerResponse
|
||||||
|
|
||||||
@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, lastModifiedDate=_lastModified,
|
@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, lastModifiedDate=_lastModified, eTag=_eTag,
|
||||||
gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers;
|
gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers;
|
||||||
|
|
||||||
+ (instancetype)response {
|
+ (instancetype)response {
|
||||||
@@ -191,6 +192,7 @@
|
|||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
ARC_RELEASE(_type);
|
ARC_RELEASE(_type);
|
||||||
ARC_RELEASE(_lastModified);
|
ARC_RELEASE(_lastModified);
|
||||||
|
ARC_RELEASE(_eTag);
|
||||||
ARC_RELEASE(_headers);
|
ARC_RELEASE(_headers);
|
||||||
ARC_RELEASE(_encoders);
|
ARC_RELEASE(_encoders);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user