@@ -26,19 +26,21 @@ #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFNumber.h" #import "OFTCPSocket.h" +#import "OFTLSSocket.h" #import "OFTimer.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" +#import "OFUnsupportedProtocolException.h" #import "OFWriteFailedException.h" #import "socket_helpers.h" #define BUFFER_SIZE 1024 @@ -47,33 +49,33 @@ * FIXME: Key normalization replaces headers like "DNT" with "Dnt". * FIXME: Errors are not reported to the user. */ @interface OFHTTPServer () -- (bool)of_socket: (OFTCPSocket *)sock - didAcceptSocket: (OFTCPSocket *)clientSocket +- (bool)of_socket: (OF_KINDOF(OFTCPSocket *))sock + didAcceptSocket: (OF_KINDOF(OFTCPSocket *))clientSocket context: (id)context exception: (id)exception; @end @interface OFHTTPServerResponse: OFHTTPResponse { - OFTCPSocket *_socket; + OF_KINDOF(OFTCPSocket *) _socket; OFHTTPServer *_server; OFHTTPRequest *_request; bool _chunked, _headersSent; } -- (instancetype)initWithSocket: (OFTCPSocket *)sock +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end @interface OFHTTPServer_Connection: OFObject { @public - OFTCPSocket *_socket; + OF_KINDOF(OFTCPSocket *) _socket; OFHTTPServer *_server; OFTimer *_timer; enum { AWAITING_PROLOG, PARSING_HEADERS, @@ -86,13 +88,13 @@ OFMutableDictionary *_headers; size_t _contentLength; OFStream *_requestBody; } -- (instancetype)initWithSocket: (OFTCPSocket *)sock +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock server: (OFHTTPServer *)server; -- (bool)socket: (OFTCPSocket *)sock +- (bool)socket: (OF_KINDOF(OFTCPSocket *))sock didReadLine: (OFString *)line context: (id)context exception: (id)exception; - (bool)parseProlog: (OFString *)line; - (bool)parseHeaders: (OFString *)line; @@ -100,16 +102,16 @@ - (void)createResponse; @end @interface OFHTTPServerRequestBodyStream: OFStream { - OFTCPSocket *_socket; + OF_KINDOF(OFTCPSocket *) _socket; uintmax_t _toRead; bool _atEndOfStream; } -- (instancetype)initWithSocket: (OFTCPSocket *)sock +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock contentLength: (uintmax_t)contentLength; @end static const char * statusCodeToString(short code) @@ -229,11 +231,11 @@ return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @implementation OFHTTPServerResponse -- (instancetype)initWithSocket: (OFTCPSocket *)sock +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request { self = [super init]; @@ -366,11 +368,11 @@ return [_socket fileDescriptorForWriting]; } @end @implementation OFHTTPServer_Connection -- (instancetype)initWithSocket: (OFTCPSocket *)sock +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock server: (OFHTTPServer *)server { self = [super init]; @try { @@ -405,11 +407,11 @@ [_requestBody release]; [super dealloc]; } -- (bool)socket: (OFTCPSocket *)sock +- (bool)socket: (OF_KINDOF(OFTCPSocket *))sock didReadLine: (OFString *)line context: (id)context exception: (id)exception { if (line == nil || exception != nil) @@ -657,12 +659,12 @@ objc_autoreleasePoolPop(pool); } @end @implementation OFHTTPServerRequestBodyStream -- (instancetype)initWithSocket: (OFTCPSocket *)sock - contentLength: (uintmax_t)contentLength +- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock + contentLength: (uintmax_t)contentLength { self = [super init]; @try { _socket = [sock retain]; @@ -724,11 +726,15 @@ _socket = nil; } @end @implementation OFHTTPServer -@synthesize host = _host, port = _port, delegate = _delegate, name = _name; +@synthesize host = _host, port = _port, usesTLS = _usesTLS; +@synthesize certificateFile = _certificateFile; +@synthesize privateKeyFile = _privateKeyFile; +@synthesize privateKeyPassphrase = _privateKeyPassphrase, delegate = _delegate; +@synthesize name = _name; + (instancetype)server { return [[[self alloc] init] autorelease]; } @@ -758,11 +764,26 @@ @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyConnectedException exception]; - _listeningSocket = [[OFTCPSocket alloc] init]; + if (_usesTLS) { + id listeningSocket; + + if (of_tls_socket_class == Nil) + @throw [OFUnsupportedProtocolException exception]; + + _listeningSocket = [[of_tls_socket_class alloc] init]; + + listeningSocket = _listeningSocket; + [listeningSocket setCertificateFile: _certificateFile]; + [listeningSocket setPrivateKeyFile: _privateKeyFile]; + [listeningSocket + setPrivateKeyPassphrase: _privateKeyPassphrase]; + } else + _listeningSocket = [[OFTCPSocket alloc] init]; + _port = [_listeningSocket bindToHost: _host port: _port]; [_listeningSocket listen]; [_listeningSocket asyncAcceptWithTarget: self @@ -777,12 +798,12 @@ [_listeningSocket cancelAsyncRequests]; [_listeningSocket release]; _listeningSocket = nil; } -- (bool)of_socket: (OFTCPSocket *)sock - didAcceptSocket: (OFTCPSocket *)clientSocket +- (bool)of_socket: (OF_KINDOF(OFTCPSocket *))sock + didAcceptSocket: (OF_KINDOF(OFTCPSocket *))clientSocket context: (id)context exception: (id)exception { OFHTTPServer_Connection *connection;