In my previous post I discussed using Let’s Encrypt to generate a CA-signed certificate for use in q to run an HTTPS server. At the tail end of that post, I mentioned redirecting HTTP requests to run over HTTPS. Since then, I have written & published a small package to do exactly that.

This package (available at the GitHub repo) overwrites .z.ph & .z.pp to check if the current request is HTTP (checking .z.e to determine this), & if so, returns a 301 Permanently Moved HTTP response, redirecting the client to HTTPS. If the connection is already HTTPS, the exisitng .z.ph or .z.pp definition is called as usual.

The package can easily be installed using conda e.g.

$ conda install -c jmcmurray https-redirect

I think this is a fairly straightforward & easy-to-use module, which “should” require no interaction other than loading:

jonny@grizzly ~/git/qwebapi (master) $ q -E 1 -p 8100
KDB+ 3.6 2018.05.17 Copyright (C) 1993-2018 Kx Systems
l32/ 2()core 1944MB jonny grizzly 127.0.1.1 NONEXPIRE

q).utl.require"webapi"
q)\l example.q
q).utl.require"https-redir"

NOTE: We need to use -E 1 to allow HTTP connections, which can then be redirected to HTTPS. With -E 2, HTTP connections will signal in a way we can’t catch & respond to

Also note that we load webapi module first; https-redir requires any other definitions of .z.ph & .z.pp to be set before loading.

Following this, any HTTP request will automatically be redirected to HTTPS.

For example, using reQ in verbose mode, we can see the flow of requests & responses. Note that due to how q sends server SSL certificates (see note in previous post) we have to disable SSL server verfication for q - other clients such as web browsers will download intermediate certificates & this will not be an issue.

jonny@grizzly ~ $ export SSL_VERIFY_SERVER=NO
jonny@grizzly ~ $ q
KDB+ 3.6 2018.05.17 Copyright (C) 1993-2018 Kx Systems
l32/ 2()core 1944MB jonny grizzly 127.0.1.1 NONEXPIRE

q).utl.require"req"
q).req.VERBOSE:1b
q).req.g"http://jmcmurray.hopto.org:8100/gettime"
-- REQUEST --
:http://jmcmurray.hopto.org:8100
GET /gettime HTTP/1.1
Host: jmcmurray.hopto.org:8100
Connection: Close
User-Agent: kdb+/3.6
Accept: */*


-- RESPONSE --
HTTP/1.1 301 Moved Permanently
Content-Type: text/html
Content-Length: 227
Connection: close
Location: https://jmcmurray.hopto.org:8100/gettime

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><head><title>301 Moved Permanently</title></head><body><h1>Moved Permanently</h1><p>The document has moved <a href="https://jmcmurray.hopto.org:8100/gettime">here</a></p></body>
-- REQUEST --
:https://jmcmurray.hopto.org:8100
GET /gettime HTTP/1.1
Host: jmcmurray.hopto.org:8100
Connection: Close
User-Agent: kdb+/3.6
Accept: */*


-- RESPONSE --
HTTP/1.1 200 OK
Content-Type: application/json
Connection: close
Content-Length: 40

{"time":"2018-12-10T13:07:41.900367000"}
time| "2018-12-10T13:07:41.900367000"

We see here that the first request recieves a 301 status & the redirect is followed automatically by reQ to send the request to the HTTPS URL.