Index: src/OFHTTPServer.h ================================================================== --- src/OFHTTPServer.h +++ src/OFHTTPServer.h @@ -60,10 +60,29 @@ * connections will still be handled and you can start accepting new * connections again by calling @ref OFHTTPServer::start again. */ - (bool)server: (OFHTTPServer*)server didReceiveExceptionOnListeningSocket: (OFException*)exception; + +/*! + * @brief This method is called when a client socket encountered an exception. + * + * This can happen when the OFHTTPServer tries to properly close the + * connection. If no headers have been sent yet, it will send headers, and if + * chunked transfer encoding was used, it will send a chunk of size 0. However, + * if the other end already closed the connection before that, this will raise + * an exception. + * + * @param server The HTTP server which encountered an exception + * @param response The response for which the exception occurred + * @param request The request for the response for which the exception occurred + * @param exception The exception which occurred + */ +- (void)server: (OFHTTPServer*)server + didReceiveExceptionForResponse: (OFHTTPResponse*)response + request: (OFHTTPRequest*)request + exception: (OFException*)exception; @end /*! * @class OFHTTPServer OFHTTPServer.h ObjFW/OFHTTPServer.h * Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -172,26 +172,30 @@ @interface OFHTTPServerResponse: OFHTTPResponse { OFTCPSocket *_socket; OFHTTPServer *_server; + OFHTTPRequest *_request; bool _chunked, _headersSent; } - initWithSocket: (OFTCPSocket*)socket - server: (OFHTTPServer*)server; + server: (OFHTTPServer*)server + request: (OFHTTPRequest*)request; @end @implementation OFHTTPServerResponse - initWithSocket: (OFTCPSocket*)socket server: (OFHTTPServer*)server + request: (OFHTTPRequest*)request { self = [super init]; _statusCode = 500; _socket = [socket retain]; _server = [server retain]; + _request = [request retain]; return self; } - (void)dealloc @@ -198,10 +202,11 @@ { if (_socket != nil) [self close]; /* includes [_socket release] */ [_server release]; + [_request release]; [super dealloc]; } - (void)OF_sendHeaders @@ -265,16 +270,27 @@ - (void)close { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; - if (!_headersSent) - [self OF_sendHeaders]; + @try { + if (!_headersSent) + [self OF_sendHeaders]; - if (_chunked) - [_socket writeBuffer: "0\r\n\r\n" - length: 5]; + if (_chunked) + [_socket writeBuffer: "0\r\n\r\n" + length: 5]; + } @catch (OFWriteFailedException *e) { + id delegate = [_server delegate]; + + if ([delegate respondsToSelector: @selector(server: + didReceiveExceptionForResponse:request:exception:)]) + [delegate server: _server + didReceiveExceptionForResponse: self + request: _request + exception: e]; + } [_socket release]; _socket = nil; } @@ -635,11 +651,12 @@ [request setBody: _body]; [request setRemoteAddress: [_socket remoteAddress]]; response = [[[OFHTTPServerResponse alloc] initWithSocket: _socket - server: _server] autorelease]; + server: _server + request: request] autorelease]; [[_server delegate] server: _server didReceiveRequest: request response: response]; }