mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-02-22 00:00:05 +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) {
|
||||
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) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
|
||||
} else {
|
||||
|
||||
@@ -126,6 +126,7 @@ 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.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;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
@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) 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) BOOL acceptsGzipContentEncoding;
|
||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query;
|
||||
|
||||
@@ -145,7 +145,8 @@
|
||||
NSString* _type;
|
||||
BOOL _chunked;
|
||||
NSUInteger _length;
|
||||
NSDate* _modifiedSinceDate;
|
||||
NSDate* _modifiedSince;
|
||||
NSString* _noneMatch;
|
||||
NSRange _range;
|
||||
BOOL _gzipAccepted;
|
||||
|
||||
@@ -157,7 +158,7 @@
|
||||
|
||||
@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;
|
||||
|
||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
||||
@@ -191,10 +192,11 @@
|
||||
_length = NSNotFound;
|
||||
}
|
||||
|
||||
NSString* ifModifiedSinceHeader = [_headers objectForKey:@"If-Modified-Since"];
|
||||
if (ifModifiedSinceHeader) {
|
||||
_modifiedSinceDate = [GCDWebServerParseHTTPDate(ifModifiedSinceHeader) copy];
|
||||
NSString* modifiedHeader = [_headers objectForKey:@"If-Modified-Since"];
|
||||
if (modifiedHeader) {
|
||||
_modifiedSince = [GCDWebServerParseHTTPDate(modifiedHeader) copy];
|
||||
}
|
||||
_noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]);
|
||||
|
||||
_range = NSMakeRange(NSNotFound, 0);
|
||||
NSString* rangeHeader = [[_headers objectForKey:@"Range"] lowercaseString];
|
||||
@@ -243,6 +245,7 @@
|
||||
ARC_RELEASE(_query);
|
||||
ARC_RELEASE(_type);
|
||||
ARC_RELEASE(_modifiedSinceDate);
|
||||
ARC_RELEASE(_noneMatch);
|
||||
ARC_RELEASE(_decoders);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
@property(nonatomic) NSInteger statusCode; // Default is 200
|
||||
@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, copy) NSString* eTag; // Default is nil i.e. no "ETag" header
|
||||
@property(nonatomic, getter=isGZipContentEncodingEnabled) BOOL gzipContentEncodingEnabled; // Default is disabled
|
||||
+ (instancetype)response;
|
||||
- (instancetype)init;
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
NSInteger _status;
|
||||
NSUInteger _maxAge;
|
||||
NSDate* _lastModified;
|
||||
NSString* _eTag;
|
||||
NSMutableDictionary* _headers;
|
||||
BOOL _chunked;
|
||||
BOOL _gzipped;
|
||||
@@ -169,7 +170,7 @@
|
||||
|
||||
@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;
|
||||
|
||||
+ (instancetype)response {
|
||||
@@ -191,6 +192,7 @@
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_type);
|
||||
ARC_RELEASE(_lastModified);
|
||||
ARC_RELEASE(_eTag);
|
||||
ARC_RELEASE(_headers);
|
||||
ARC_RELEASE(_encoders);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user