From 125527f7054c6052ef145d1e66621a1d551210d2 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sat, 24 Jan 2015 00:34:06 +0100 Subject: [PATCH 1/4] Add support for HTTPS --- lib/src/serve.dart | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/src/serve.dart b/lib/src/serve.dart index 773c50e..1242991 100644 --- a/lib/src/serve.dart +++ b/lib/src/serve.dart @@ -2,7 +2,20 @@ part of vane; -void serve({Level logLevel: Level.CONFIG, +/** + * Start serving requests. + * + * Regarding SSL support, consult the documentation of [SecureSocket.initialize] + * for information on the parameters. + */ +void serve({String host: "127.0.0.1", + int port: 9090, + String sslCertificateName, + String sslCertificateDatabase, + String sslCertificateDatabasePassword, + int sslPort: 9091, + bool sslOnly: false, + Level logLevel: Level.CONFIG, String mongoUri: ""}) { // Setup logger Logger.root.level = logLevel; @@ -26,17 +39,17 @@ void serve({Level logLevel: Level.CONFIG, // Parse scan code for handlers and create a router Router router = new Router(); - // Serve incomming requests - runZoned(() { - // Server port assignment - var portEnv = Platform.environment['PORT']; - var port = portEnv != null ? int.parse(portEnv) : 9090; - - Logger.root.info("Starting vane server: 127.0.0.1:${port}"); + // Server port assignment + var portEnv = Platform.environment['PORT']; + port = portEnv != null ? int.parse(portEnv) : port; + var httpsPortEnv = Platform.environment['PORT_SSL']; + sslPort = httpsPortEnv != null ? int.parse(httpsPortEnv) : sslPort; - HttpServer.bind("127.0.0.1", port).then((server) { + // Serve incoming requests + runZoned(() { + // Function that sets up the server binding + Function serverBinding = (HttpServer server) { RouteMatch match; - server.listen((HttpRequest request) { // See if we have a match for the request match = router.matchRequest(request); @@ -49,7 +62,20 @@ void serve({Level logLevel: Level.CONFIG, request.response.close(); } }); - }); + }; + + // Check if SSL is configured correctly and start HTTPS binding if so + if(sslCertificateName != null && sslCertificateDatabase != null && sslCertificateDatabasePassword != null) { + Logger.root.info("Starting Vane server on HTTPS: ${host}:${port}"); + SecureSocket.initialize(database: sslCertificateDatabase, password: sslCertificateDatabasePassword); + HttpServer.bindSecure(host, sslPort, certificateName: sslCertificateName).then(serverBinding); + } + + // Start regular HTTP binding + if(!sslOnly) { + Logger.root.info("Starting Vane server on HTTP: ${host}:${port}"); + HttpServer.bind(host, port).then(serverBinding); + } }, onError: (e, stackTrace) { Logger.root.warning(e.toString()); From acbdc13ffe516a4a2642c652eb4d6e02d95b4663 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sat, 24 Jan 2015 00:45:38 +0100 Subject: [PATCH 2/4] Allow automatic redirect of HTTP to HTTPS --- lib/src/serve.dart | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/src/serve.dart b/lib/src/serve.dart index 1242991..e9bd5de 100644 --- a/lib/src/serve.dart +++ b/lib/src/serve.dart @@ -7,6 +7,8 @@ part of vane; * * Regarding SSL support, consult the documentation of [SecureSocket.initialize] * for information on the parameters. + * + * If [redirectHTTP] is true, HTTP traffic will be redirected to HTTPS. */ void serve({String host: "127.0.0.1", int port: 9090, @@ -15,6 +17,7 @@ void serve({String host: "127.0.0.1", String sslCertificateDatabasePassword, int sslPort: 9091, bool sslOnly: false, + bool redirectHTTP: false, Level logLevel: Level.CONFIG, String mongoUri: ""}) { // Setup logger @@ -69,10 +72,28 @@ void serve({String host: "127.0.0.1", Logger.root.info("Starting Vane server on HTTPS: ${host}:${port}"); SecureSocket.initialize(database: sslCertificateDatabase, password: sslCertificateDatabasePassword); HttpServer.bindSecure(host, sslPort, certificateName: sslCertificateName).then(serverBinding); + + // Redirect HTTP traffic to HTTPS when redirectHTTP is true + if(redirectHTTP) { + HttpServer.bind(host, port).then((HttpServer server) { + server.listen((HttpRequest request) { + Uri httpsUri = new Uri(scheme: "https", + userInfo: request.uri.userInfo, + host: request.uri.host, + port: request.uri.port, + path: request.uri.path, + pathSegments: request.uri.pathSegments, + query: request.uri.query, + queryParameters: request.uri.queryParameters, + fragment: request.uri.fragment); + request.response.redirect(httpsUri, status: HttpStatus.MOVED_PERMANENTLY); + }); + }); + } } // Start regular HTTP binding - if(!sslOnly) { + if(!sslOnly && !redirectHTTP) { Logger.root.info("Starting Vane server on HTTP: ${host}:${port}"); HttpServer.bind(host, port).then(serverBinding); } From 044dfa4a097d48d0e2e7c04f12d0407cf83d2a18 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sat, 24 Jan 2015 02:05:20 +0100 Subject: [PATCH 3/4] Allow all SSL parameters to be passed through environment variables --- lib/src/serve.dart | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/src/serve.dart b/lib/src/serve.dart index e9bd5de..cc2bf94 100644 --- a/lib/src/serve.dart +++ b/lib/src/serve.dart @@ -12,10 +12,11 @@ part of vane; */ void serve({String host: "127.0.0.1", int port: 9090, + bool enableSSL: false, + int sslPort: 9091, String sslCertificateName, String sslCertificateDatabase, String sslCertificateDatabasePassword, - int sslPort: 9091, bool sslOnly: false, bool redirectHTTP: false, Level logLevel: Level.CONFIG, @@ -42,11 +43,18 @@ void serve({String host: "127.0.0.1", // Parse scan code for handlers and create a router Router router = new Router(); - // Server port assignment - var portEnv = Platform.environment['PORT']; - port = portEnv != null ? int.parse(portEnv) : port; - var httpsPortEnv = Platform.environment['PORT_SSL']; - sslPort = httpsPortEnv != null ? int.parse(httpsPortEnv) : sslPort; + // Server port assignment (parameter overwrites environment) + if(port == null) + port = int.parse(Platform.environment['PORT']); + if(sslPort = null) + sslPort = int.parse(Platform.environment['PORT_SSL']); + // SSL config using environment + if(sslCertificateName == null) + sslCertificateName = Platform.environment['SSL_CERT_NAME']; + if(sslCertificateDatabase == null) + sslCertificateDatabase = Platform.environment['SSL_CERT_DB']; + if(sslCertificateDatabasePassword == null) + sslCertificateDatabasePassword = Platform.environment['SSL_CERT_DB_PASS']; // Serve incoming requests runZoned(() { @@ -68,9 +76,12 @@ void serve({String host: "127.0.0.1", }; // Check if SSL is configured correctly and start HTTPS binding if so - if(sslCertificateName != null && sslCertificateDatabase != null && sslCertificateDatabasePassword != null) { + if(enableSSL) { + // Configuring SSL when all parameters are given + if(sslCertificateName != null && sslCertificateDatabase != null && sslCertificateDatabasePassword != null) { + SecureSocket.initialize(database: sslCertificateDatabase, password: sslCertificateDatabasePassword); + } Logger.root.info("Starting Vane server on HTTPS: ${host}:${port}"); - SecureSocket.initialize(database: sslCertificateDatabase, password: sslCertificateDatabasePassword); HttpServer.bindSecure(host, sslPort, certificateName: sslCertificateName).then(serverBinding); // Redirect HTTP traffic to HTTPS when redirectHTTP is true From afb3127b2e81e1f08036dda3a435f97c0bb20ef3 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sun, 25 Jan 2015 00:58:58 +0100 Subject: [PATCH 4/4] Some of the changes suggested by Robert --- lib/src/serve.dart | 62 ++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/lib/src/serve.dart b/lib/src/serve.dart index cc2bf94..ba268ce 100644 --- a/lib/src/serve.dart +++ b/lib/src/serve.dart @@ -10,14 +10,14 @@ part of vane; * * If [redirectHTTP] is true, HTTP traffic will be redirected to HTTPS. */ -void serve({String host: "127.0.0.1", - int port: 9090, - bool enableSSL: false, - int sslPort: 9091, - String sslCertificateName, - String sslCertificateDatabase, - String sslCertificateDatabasePassword, - bool sslOnly: false, +void serve({String host, + int port, + bool enableTLS: false, + int tlsPort, + String tlsCertificateName, + String tlsCertificateDb, + String tlsCertificateDbPassword, + bool tlsOnly: false, bool redirectHTTP: false, Level logLevel: Level.CONFIG, String mongoUri: ""}) { @@ -44,22 +44,21 @@ void serve({String host: "127.0.0.1", Router router = new Router(); // Server port assignment (parameter overwrites environment) - if(port == null) - port = int.parse(Platform.environment['PORT']); - if(sslPort = null) - sslPort = int.parse(Platform.environment['PORT_SSL']); + var hostEnv = Platform.environment['HOST']; + host = host != null ? host : (hostEnv != null ? hostEnv : "127.0.0.1"); + var portEnv = Platform.environment['PORT']; + port = port != null ? port : portEnv != null ? int.parse(portEnv) : 80; // default HTTP port + var tlsPortEnv = Platform.environment['PORT_SSL']; + tlsPort = tlsPort != null ? tlsPort : tlsPortEnv != null ? int.parse(tlsPortEnv) : 443; // default HTTPS port // SSL config using environment - if(sslCertificateName == null) - sslCertificateName = Platform.environment['SSL_CERT_NAME']; - if(sslCertificateDatabase == null) - sslCertificateDatabase = Platform.environment['SSL_CERT_DB']; - if(sslCertificateDatabasePassword == null) - sslCertificateDatabasePassword = Platform.environment['SSL_CERT_DB_PASS']; + tlsCertificateName = tlsCertificateName != null ? tlsCertificateName : Platform.environment['SSL_CERT_NAME']; + tlsCertificateDb = tlsCertificateDb != null ? tlsCertificateDb : Platform.environment['SSL_CERT_DB']; + tlsCertificateDbPassword = tlsCertificateDbPassword != null ? tlsCertificateDbPassword : Platform.environment['SSL_CERT_DB_PASS']; // Serve incoming requests runZoned(() { // Function that sets up the server binding - Function serverBinding = (HttpServer server) { + void serverBinding (HttpServer server) { RouteMatch match; server.listen((HttpRequest request) { // See if we have a match for the request @@ -76,27 +75,20 @@ void serve({String host: "127.0.0.1", }; // Check if SSL is configured correctly and start HTTPS binding if so - if(enableSSL) { + if(enableTLS == true) { // Configuring SSL when all parameters are given - if(sslCertificateName != null && sslCertificateDatabase != null && sslCertificateDatabasePassword != null) { - SecureSocket.initialize(database: sslCertificateDatabase, password: sslCertificateDatabasePassword); + if(tlsCertificateName != null && tlsCertificateDb != null && tlsCertificateDbPassword != null) { + SecureSocket.initialize(database: tlsCertificateDb, password: tlsCertificateDbPassword); } - Logger.root.info("Starting Vane server on HTTPS: ${host}:${port}"); - HttpServer.bindSecure(host, sslPort, certificateName: sslCertificateName).then(serverBinding); + Logger.root.info("Starting Vane server on HTTPS: ${host}:${tlsPort}"); + HttpServer.bindSecure(host, tlsPort, certificateName: tlsCertificateName).then(serverBinding); // Redirect HTTP traffic to HTTPS when redirectHTTP is true - if(redirectHTTP) { + if(redirectHTTP == true) { + Logger.root.info("Starting HTTP server to redirect to HTTPS on ${host}:${port}"); HttpServer.bind(host, port).then((HttpServer server) { server.listen((HttpRequest request) { - Uri httpsUri = new Uri(scheme: "https", - userInfo: request.uri.userInfo, - host: request.uri.host, - port: request.uri.port, - path: request.uri.path, - pathSegments: request.uri.pathSegments, - query: request.uri.query, - queryParameters: request.uri.queryParameters, - fragment: request.uri.fragment); + Uri httpsUri = request.uri.replace(scheme: "https"); request.response.redirect(httpsUri, status: HttpStatus.MOVED_PERMANENTLY); }); }); @@ -104,7 +96,7 @@ void serve({String host: "127.0.0.1", } // Start regular HTTP binding - if(!sslOnly && !redirectHTTP) { + if(tlsOnly == false && redirectHTTP == false) { Logger.root.info("Starting Vane server on HTTP: ${host}:${port}"); HttpServer.bind(host, port).then(serverBinding); }