Added -abortRequest:withStatusCode: API

This commit is contained in:
Pierre-Olivier Latour 2014-04-07 14:18:32 -07:00
parent e85a0c9a61
commit f61ff832ea
2 changed files with 28 additions and 23 deletions

View File

@ -43,6 +43,7 @@
- (void)open;
- (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
- (GCDWebServerResponse*)processRequest:(GCDWebServerRequest*)request withBlock:(GCDWebServerProcessBlock)block;
- (GCDWebServerResponse*)processRequest:(GCDWebServerRequest*)request withBlock:(GCDWebServerProcessBlock)block; // Only called if the request can be processed
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode; // If request headers was malformed, "request" will be nil
- (void)close;
@end

View File

@ -62,6 +62,7 @@ static dispatch_queue_t _formatterQueue = NULL;
GCDWebServerHandler* _handler;
CFHTTPMessageRef _responseMessage;
GCDWebServerResponse* _response;
NSInteger _statusCode;
}
@end
@ -398,6 +399,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
}
- (void)_initializeResponseHeadersWithStatusCode:(NSInteger)statusCode {
_statusCode = statusCode;
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)[[_server class] serverName]);
@ -407,16 +409,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
});
}
- (void)_abortWithStatusCode:(NSUInteger)statusCode {
DCHECK(_responseMessage == NULL);
DCHECK((statusCode >= 400) && (statusCode < 600));
[self _initializeResponseHeadersWithStatusCode:statusCode];
[self _writeHeadersWithCompletionBlock:^(BOOL success) {
; // Nothing more to do
}];
LOG_DEBUG(@"Connection aborted with status code %i on socket %i", (int)statusCode, _socket);
}
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- (void)_processRequest {
DCHECK(_responseMessage == NULL);
@ -457,7 +449,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
[self _writeBodyWithCompletionBlock:^(BOOL successInner) {
[_response performClose];
LOG_VERBOSE(@"%@ | %@ \"%@ %@\" %i %lu", self.localAddressString, self.remoteAddressString, _request.method, _request.path, (int)_response.statusCode, (unsigned long)_bytesWritten);
}];
}
@ -467,7 +458,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
}];
} else {
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
}
}
@ -476,7 +467,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
NSError* error = nil;
if (![_request performOpen:&error]) {
LOG_ERROR(@"Failed opening request body for socket %i: %@", _socket, error);
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
return;
}
@ -486,7 +477,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
if (![_request performClose:&error]) {
LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
}
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
return;
}
length -= initialData.length;
@ -500,7 +491,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
[self _processRequest];
} else {
LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
}
}];
@ -509,7 +500,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
[self _processRequest];
} else {
LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
}
}
}
@ -518,7 +509,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
NSError* error = nil;
if (![_request performOpen:&error]) {
LOG_ERROR(@"Failed opening request body for socket %i: %@", _socket, error);
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
return;
}
@ -530,7 +521,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
[self _processRequest];
} else {
LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
[self _abortWithStatusCode:500];
[self abortRequest:_request withStatusCode:500];
}
}];
@ -581,7 +572,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
}];
} else {
LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", _socket);
[self _abortWithStatusCode:417];
[self abortRequest:_request withStatusCode:417];
}
} else {
if (_request.usesChunkedTransferEncoding) {
@ -592,16 +583,18 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
}
} else {
LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", _socket);
[self _abortWithStatusCode:400];
[self abortRequest:_request withStatusCode:400];
}
} else {
[self _processRequest];
}
} else {
[self _abortWithStatusCode:405];
_request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery];
DCHECK(_request);
[self abortRequest:_request withStatusCode:405];
}
} else {
[self _abortWithStatusCode:500];
[self abortRequest:nil withStatusCode:500];
}
}];
@ -689,12 +682,23 @@ static NSString* _StringFromAddressData(NSData* data) {
return response;
}
- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode {
DCHECK(_responseMessage == NULL);
DCHECK((statusCode >= 400) && (statusCode < 600));
[self _initializeResponseHeadersWithStatusCode:statusCode];
[self _writeHeadersWithCompletionBlock:^(BOOL success) {
; // Nothing more to do
}];
LOG_DEBUG(@"Connection aborted with status code %i on socket %i", (int)statusCode, _socket);
}
- (void)close {
int result = close(_socket);
if (result != 0) {
LOG_ERROR(@"Failed closing socket %i for connection (%i): %s", _socket, errno, strerror(errno));
}
LOG_DEBUG(@"Did close connection on socket %i", _socket);
LOG_VERBOSE(@"[%@] %@ %i \"%@ %@\" (%lu | %lu)", self.localAddressString, self.remoteAddressString, (int)_statusCode, _request.method, _request.path, (unsigned long)_bytesRead, (unsigned long)_bytesWritten);
}
@end