diff --git a/CGDWebServer/GCDWebServerConnection.h b/CGDWebServer/GCDWebServerConnection.h index 2f5f1aa..4eee105 100644 --- a/CGDWebServer/GCDWebServerConnection.h +++ b/CGDWebServer/GCDWebServerConnection.h @@ -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 diff --git a/CGDWebServer/GCDWebServerConnection.m b/CGDWebServer/GCDWebServerConnection.m index 4c01393..e1d39d5 100644 --- a/CGDWebServer/GCDWebServerConnection.m +++ b/CGDWebServer/GCDWebServerConnection.m @@ -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