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