mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-05-31 00:00:10 +08:00
Added -replaceResponse:forRequest: hook
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
- (void)didUpdateBytesRead; // Called from arbitrary thread after @totalBytesRead is updated - Default implementation does nothing
|
- (void)didUpdateBytesRead; // Called from arbitrary thread after @totalBytesRead is updated - Default implementation does nothing
|
||||||
- (void)didUpdateBytesWritten; // Called from arbitrary thread after @totalBytesWritten is updated - Default implementation does nothing
|
- (void)didUpdateBytesWritten; // Called from arbitrary thread after @totalBytesWritten is updated - Default implementation does nothing
|
||||||
- (GCDWebServerResponse*)processRequest:(GCDWebServerRequest*)request withBlock:(GCDWebServerProcessBlock)block; // Only called if the request can be processed
|
- (GCDWebServerResponse*)processRequest:(GCDWebServerRequest*)request withBlock:(GCDWebServerProcessBlock)block; // Only called if the request can be processed
|
||||||
|
- (GCDWebServerResponse*)replaceResponse:(GCDWebServerResponse*)response forRequest:(GCDWebServerRequest*)request; // Default implementation replaces any response matching the "ETag" or "Last-Modified-Date" header of the request by a barebone "Not-Modified" (304) one
|
||||||
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode; // If request headers was malformed, "request" will be nil
|
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode; // If request headers was malformed, "request" will be nil
|
||||||
- (void)close;
|
- (void)close;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -392,35 +392,14 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
|||||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate([NSDate date]));
|
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate([NSDate date]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
|
|
||||||
static inline BOOL _CompareResources(NSString* responseETag, NSString* requestETag, NSDate* responseLastModified, NSDate* requestLastModified) {
|
|
||||||
if ([requestETag isEqualToString:@"*"] && (!responseLastModified || !requestLastModified || ([responseLastModified compare:requestLastModified] != NSOrderedDescending))) {
|
|
||||||
return YES;
|
|
||||||
} else {
|
|
||||||
if ([responseETag isEqualToString:requestETag]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
if (responseLastModified && requestLastModified && ([responseLastModified compare:requestLastModified] != NSOrderedDescending)) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||||
- (void)_processRequest {
|
- (void)_processRequest {
|
||||||
DCHECK(_responseMessage == NULL);
|
DCHECK(_responseMessage == NULL);
|
||||||
|
|
||||||
GCDWebServerResponse* response = [self processRequest:_request withBlock:_handler.processBlock];
|
GCDWebServerResponse* response = [self processRequest:_request withBlock:_handler.processBlock];
|
||||||
if (response) {
|
if (response) {
|
||||||
if ((response.statusCode >= 200) && (response.statusCode < 300) && _CompareResources(response.eTag, _request.ifNoneMatch, response.lastModifiedDate, _request.ifModifiedSince)) {
|
response = [self replaceResponse:response forRequest:_request];
|
||||||
NSInteger code = [_request.method isEqualToString:@"HEAD"] || [_request.method isEqualToString:@"GET"] ? kGCDWebServerHTTPStatusCode_NotModified : kGCDWebServerHTTPStatusCode_PreconditionFailed;
|
if (response) {
|
||||||
_response = [[GCDWebServerResponse alloc] initWithStatusCode:code];
|
|
||||||
_response.cacheControlMaxAge = response.cacheControlMaxAge;
|
|
||||||
_response.lastModifiedDate = response.lastModifiedDate;
|
|
||||||
_response.eTag = response.eTag;
|
|
||||||
DCHECK(_response);
|
|
||||||
} else {
|
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
if ([response hasBody] && ![response performOpen:&error]) {
|
if ([response hasBody] && ![response performOpen:&error]) {
|
||||||
LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error);
|
LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error);
|
||||||
@@ -695,6 +674,34 @@ static NSString* _StringFromAddressData(NSData* data) {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
|
||||||
|
static inline BOOL _CompareResources(NSString* responseETag, NSString* requestETag, NSDate* responseLastModified, NSDate* requestLastModified) {
|
||||||
|
if ([requestETag isEqualToString:@"*"] && (!responseLastModified || !requestLastModified || ([responseLastModified compare:requestLastModified] != NSOrderedDescending))) {
|
||||||
|
return YES;
|
||||||
|
} else {
|
||||||
|
if ([responseETag isEqualToString:requestETag]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
if (responseLastModified && requestLastModified && ([responseLastModified compare:requestLastModified] != NSOrderedDescending)) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GCDWebServerResponse*)replaceResponse:(GCDWebServerResponse*)response forRequest:(GCDWebServerRequest*)request {
|
||||||
|
if ((response.statusCode >= 200) && (response.statusCode < 300) && _CompareResources(response.eTag, request.ifNoneMatch, response.lastModifiedDate, request.ifModifiedSince)) {
|
||||||
|
NSInteger code = [request.method isEqualToString:@"HEAD"] || [request.method isEqualToString:@"GET"] ? kGCDWebServerHTTPStatusCode_NotModified : kGCDWebServerHTTPStatusCode_PreconditionFailed;
|
||||||
|
GCDWebServerResponse* newResponse = [GCDWebServerResponse responseWithStatusCode:code];
|
||||||
|
newResponse.cacheControlMaxAge = response.cacheControlMaxAge;
|
||||||
|
newResponse.lastModifiedDate = response.lastModifiedDate;
|
||||||
|
newResponse.eTag = response.eTag;
|
||||||
|
DCHECK(newResponse);
|
||||||
|
return newResponse;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode {
|
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode {
|
||||||
DCHECK(_responseMessage == NULL);
|
DCHECK(_responseMessage == NULL);
|
||||||
DCHECK((statusCode >= 400) && (statusCode < 600));
|
DCHECK((statusCode >= 400) && (statusCode < 600));
|
||||||
|
|||||||
Reference in New Issue
Block a user