Based on the documentation, it seems like one can only create a regular HTTP server or a full, 24-7 HTTPS server. Is that correct? Is there any way to configure certain endpoints (like /login) require HTTPS, but continue to allow regular HTTP for other endpoints? Or would I need to run two server to achieve that?
On Fri, 02 May 2014 23:54:28 GMT, Chris Williams wrote:
Based on the documentation, it seems like one can only create a regular HTTP server or a full, 24-7 HTTPS server. Is that correct? Is there any way to configure certain endpoints (like /login) require HTTPS, but continue to allow regular HTTP for other endpoints? Or would I need to run two server to achieve that?
Exactly, you need to call listenHTTP
twice for that. You could then use the same router for both as a target and perform a check for the critical paths:
shared static this()
{
// share the same router
auto router = new URLRouter;
router.get("/", &home);
router.post("/login", &login);
// listen once without encryption
HTTPServerSettings settings;
settings.sessionStore = new MemorySessionStore; // gets shared with the SSL server
listenHTTP(settings, &router);
// and once with SSL/TLS
HTTPServerSettings sslsettings = settings.dup; // start with a clone of the non-SSL settings
sslsettings.port = 443;
sslsettings.sslContext = createSSLContext(...);
listenHTTP(sslsettings, &router);
}
void login(HTTPServerRequest req, HTTPServerResponse res)
{
enforceEncryption(req);
// perform login
}
void home(HTTPServerRequest req, HTTPServerResponse res)
{
res.render!("home.dt");
}
void enforceEncryption(HTTPServerRequest req)
{
enforceHTTP(req.ssl, HTTPStatus.forbidden);
}
You could also use the router to make the check, if there are many routes that need encryption:
shared static this()
{
// ...
router.get("/", &home);
// ... add other routes without required encryption ...
// catch all requests and thus require encryption for
// all following routes
router.any("*", &enforceEncryption);
router.post("/login", &login);
// ... add other routes with required encryption ...
// ...
}
void login(HTTPServerRequest req, HTTPServerResponse res)
{
// just perform login, already made sure to have encryption
}
void enforceEncryption(HTTPServerRequest req, HTTPServerResponse res)
{
enforceHTTP(req.ssl, HTTPStatus.forbidden);
}