Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -1,5 +1,7 @@ *.o *~ ObjWebServer htdocs +localhost.crt +localhost.key modules Index: ConfigParser.h ================================================================== --- ConfigParser.h +++ ConfigParser.h @@ -15,20 +15,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #import + +@interface ListenConfig: OFObject +{ + OFString *_host; + uint16_t _port; + OFString *_TLSCertificateFile, *_TLSKeyFile; +} + +@property (copy, nonatomic) OFString *host; +@property (nonatomic) uint16_t port; +@property (copy, nonatomic) OFString *TLSCertificateFile, *TLSKeyFile; +@end @interface ConfigParser: OFObject { - OFArray OF_GENERIC(OFPair OF_GENERIC(OFString *, OFNumber *) *) - *_listenHosts; + OFArray OF_GENERIC(ListenConfig *) *_listenConfigs; OFArray OF_GENERIC(OFXMLElement *) *_modules; } -@property (readonly, nonatomic) OFArray OF_GENERIC( - OFPair OF_GENERIC(OFString *, OFNumber *) *) *listenHosts; +@property (readonly, nonatomic) OFArray OF_GENERIC(ListenConfig *) + *listenConfigs; @property (readonly, nonatomic) OFArray OF_GENERIC(OFXMLElement *) *modules; - (instancetype)init OF_UNAVAILABLE; - (instancetype)initWithConfigPath: (OFString *)configPath; @end Index: ConfigParser.m ================================================================== --- ConfigParser.m +++ ConfigParser.m @@ -22,13 +22,28 @@ - (void)_parseConfig: (OFXMLElement *)config; - (void)_parseListens: (OFArray OF_GENERIC(OFXMLElement *) *)elements; - (void)_parseModules: (OFArray OF_GENERIC(OFXMLElement *) *)elements; - (void)_invalidConfig: (OFString *)message; @end + +@implementation ListenConfig +@synthesize host = _host, port = _port; +@synthesize TLSCertificateFile = _TLSCertificateFile; +@synthesize TLSKeyFile = _TLSKeyFile; + +- (void)dealloc +{ + [_host release]; + [_TLSCertificateFile release]; + [_TLSKeyFile release]; + + [super dealloc]; +} +@end @implementation ConfigParser -@synthesize listenHosts = _listenHosts, modules = _modules; +@synthesize listenConfigs = _listenConfigs, modules = _modules; - (instancetype)init { OF_INVALID_INIT_METHOD } @@ -53,11 +68,11 @@ return self; } - (void)dealloc { - [_listenHosts release]; + [_listenConfigs release]; [super dealloc]; } - (void)_parseConfig: (OFXMLElement *)config @@ -74,43 +89,63 @@ objc_autoreleasePoolPop(pool); } - (void)_parseListens: (OFArray OF_GENERIC(OFXMLElement *) *)elements { - OFMutableArray OF_GENERIC(OFPair OF_GENERIC(OFString *, OFNumber *) *) - *listenHosts = [OFMutableArray array]; + OFMutableArray OF_GENERIC(ListenConfig *) *listenConfigs = + [OFMutableArray array]; for (OFXMLElement *element in elements) { + ListenConfig *listenConfig = + [[[ListenConfig alloc] init] autorelease]; OFString *host = [[element attributeForName: @"host"] stringValue]; OFString *portString = [[element attributeForName: @"port"] stringValue]; - OFNumber *port; + OFXMLElement *TLS = [element elementForName: @"tls"]; if (host == nil) [self _invalidConfig: @" is missing host attribute"]; if (portString == nil) [self _invalidConfig: @" is missing port attribute"]; + [listenConfig setHost: host]; + @try { - intmax_t tmp = [portString decimalValue]; - if (tmp < 0 || tmp > 65535) + intmax_t port = [portString decimalValue]; + if (port < 0 || port > 65535) @throw [OFInvalidFormatException exception]; - port = [OFNumber numberWithUInt16: (uint16_t)tmp]; + [listenConfig setPort: port]; } @catch (OFInvalidFormatException *e) { [self _invalidConfig: @" has invalid port"]; } - [listenHosts addObject: [OFPair pairWithFirstObject: host - secondObject: port]]; + if (TLS != nil) { + OFString *certificateFile = + [[TLS attributeForName: @"cert"] stringValue]; + OFString *keyFile = + [[TLS attributeForName: @"key"] stringValue]; + + if (certificateFile == nil) + [self _invalidConfig: + @" has no cert attribute"]; + if (keyFile == nil) + [self _invalidConfig: + @" has no key attribute"]; + + [listenConfig setTLSCertificateFile: certificateFile]; + [listenConfig setTLSKeyFile: keyFile]; + } + + [listenConfigs addObject: listenConfig]; } - [listenHosts makeImmutable]; - _listenHosts = [listenHosts copy]; + [listenConfigs makeImmutable]; + _listenConfigs = [listenConfigs copy]; } - (void)_parseModules: (OFArray OF_GENERIC(OFXMLElement *) *)elements { OFMutableArray OF_GENERIC(OFXMLElement *) *modules = Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -1,10 +1,10 @@ all: - @objfw-compile --package ObjOpenSSL -o ObjWebServer \ - ConfigParser.m \ + @objfw-compile -Werror --package ObjOpenSSL -o ObjWebServer \ + ConfigParser.m \ ObjWebServer.m @mkdir -p modules @objfw-compile --plugin -o modules/static StaticModule.m clean: rm -fr modules rm -f ObjWebServer *.o *~ Index: ObjWebServer.m ================================================================== --- ObjWebServer.m +++ ObjWebServer.m @@ -30,12 +30,11 @@ *_modules; } - (OFPlugin *)loadModuleAtPath: (OFString *)path withConfig: (OFXMLElement *)config; -- (void)startWebserverOnHost: (OFString *)host - port: (uint16_t)port; +- (void)startWebserverWithListenConfig: (ListenConfig *)listenConfig; @end OF_APPLICATION_DELEGATE(ObjWebServer) @implementation ObjWebServer @@ -60,18 +59,12 @@ secondObject: module]]; } [modules makeImmutable]; _modules = [modules copy]; - for (OFPair OF_GENERIC(OFString *, OFNumber *) *listenHost in - [_config listenHosts]) { - OFString *host = [listenHost firstObject]; - OFNumber *port = [listenHost secondObject]; - - [self startWebserverOnHost: host - port: [port uInt16Value]]; - } + for (ListenConfig *listenConfig in [_config listenConfigs]) + [self startWebserverWithListenConfig: listenConfig]; } - (OFPlugin *)loadModuleAtPath: (OFString *)path withConfig: (OFXMLElement *)config { @@ -83,20 +76,28 @@ [module parseConfig: config]; return module; } -- (void)startWebserverOnHost: (OFString *)host - port: (uint16_t)port +- (void)startWebserverWithListenConfig: (ListenConfig *)listenConfig { OFHTTPServer *server = [OFHTTPServer server]; - [server setHost: host]; - [server setPort: port]; - [server setDelegate: self]; + [server setHost: [listenConfig host]]; + [server setPort: [listenConfig port]]; + + if ([listenConfig TLSCertificateFile] != nil && + [listenConfig TLSKeyFile] != nil) { + [server setUsesTLS: true]; + [server setCertificateFile: [listenConfig TLSCertificateFile]]; + [server setPrivateKeyFile: [listenConfig TLSKeyFile]]; + } + [server setNumberOfThreads: [OFSystemInfo numberOfCPUs] + 1]; + [server setDelegate: self]; - of_log(@"Starting server on host %@ port %" PRIu16, host, port); + of_log(@"Starting server on host %@ port %" PRIu16, + [listenConfig host], [listenConfig port]); [server start]; } - (void)server: (OFHTTPServer *)server @@ -113,6 +114,14 @@ if ([[module secondObject] handleRequest: request requestBody: requestBody response: response]) return; } + +- (bool)server: (OFHTTPServer *)server + didReceiveExceptionOnListeningSocket: (id)exception +{ + of_log(@"Exception on listening socket: %@", exception); + + return true; +} @end Index: ObjWebServer.xml ================================================================== --- ObjWebServer.xml +++ ObjWebServer.xml @@ -1,12 +1,12 @@ - - + + - - - + htdocs