summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-05-13 08:53:07 +0300
committerLars Wirzenius <liw@liw.fi>2020-05-13 08:57:51 +0300
commit5d1c903638335cf5397ef34500c1a61f62586bd3 (patch)
tree7ad539c1c908df24e51fcaabc89aee744b9fe163
parentd32125b1bfcd360d70b68a2db5942848ac6c6dcf (diff)
downloadewww-5d1c903638335cf5397ef34500c1a61f62586bd3.tar.gz
feat: use TLS unconditionally
Later on, we'll need to support non-TLS as well, for Let's Encrypt, but this'll do for now.
-rw-r--r--ewww.md20
-rw-r--r--ewww.py94
-rw-r--r--ewww.yaml2
-rw-r--r--src/main.rs5
4 files changed, 73 insertions, 48 deletions
diff --git a/ewww.md b/ewww.md
index 2232e75..8e60f8b 100644
--- a/ewww.md
+++ b/ewww.md
@@ -88,21 +88,23 @@ for static content only. Every other method returns an error.
## Minimal smoke test
~~~scenario
-given a running server using config file minimal.yaml
-when I request GET http://example.com/
+given a self-signed certificate as snakeoil.pem, using key snakeoil.key
+and a running server using config file minimal.yaml
+when I request GET https://example.com/
then I get status code 200
~~~
~~~{#minimal.yaml .file .yaml}
-hosts:
- - example.com
+tls_key: snakeoil.key
+tls_cert: snakeoil.pem
~~~
## Smoke test
~~~scenario
-given a running server using config file smoke.yaml
+given a self-signed certificate as snakeoil.pem, using key snakeoil.key
+and a running server using config file smoke.yaml
when I create webroot/foo with "hello, world"
and I request GET https://example.com/foo
then I get status code 200
@@ -143,12 +145,8 @@ scaffolding adds randomly chosen port numbers so that the test can run
without being root.
~~~{#smoke.yaml .file .yaml .numberLines}
-webroot: webroot
-hosts:
- - example.com
- - www.example.com
-tlscert: snakeoil.pem
-tlskey: snakeoil.key
+tls_cert: snakeoil.pem
+tls_key: snakeoil.key
~~~
## Performance test
diff --git a/ewww.py b/ewww.py
index 8e179be..2e45aa9 100644
--- a/ewww.py
+++ b/ewww.py
@@ -5,6 +5,7 @@ import json
import os
import random
import re
+import shutil
import subprocess
import time
import urllib.parse
@@ -16,36 +17,36 @@ import yaml
def _run(ctx, argv):
p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate("")
- ctx['argv'] = argv
- ctx['stdout'] = stdout.decode('utf-8')
- ctx['stderr'] = stderr.decode('utf-8')
- ctx['exit'] = p.returncode
+ ctx["argv"] = argv
+ ctx["stdout"] = stdout.decode("utf-8")
+ ctx["stderr"] = stderr.decode("utf-8")
+ ctx["exit"] = p.returncode
# Check that latest call of _run ended with an specific exit code.
def _run_exit(ctx, expected):
- if ctx['exit'] != expected:
- print('ctx:', ctx.as_dict())
- assert_eq(ctx['exit'], expected)
+ if ctx["exit"] != expected:
+ print("ctx:", ctx.as_dict())
+ assert_eq(ctx["exit"], expected)
# Name of Rust binary, debug-build.
def _binary(name):
- return os.path.abspath(os.path.join(srcdir, 'target', 'debug', name))
+ return os.path.abspath(os.path.join(srcdir, "target", "debug", name))
# Write a file with given content.
def _write(filename, content):
- open(filename, 'w').write(content)
+ open(filename, "w").write(content)
# Construct a URL that points to server running on localhost by
# replacing the actual scheme and host with ones that work for test.
def _url(ctx, url):
- port = ctx['config']['port']
+ port = ctx["config"]["port"]
c = urllib.parse.urlparse(url)
host = c[1]
- c = ('http', 'localhost:{}'.format(port)) + c[2:]
+ c = (c[0], "localhost:{}".format(port)) + c[2:]
return urllib.parse.urlunparse(c), host
@@ -57,59 +58,80 @@ def _url(ctx, url):
def fixme(*args, **kwargs):
assert 0
+
# Create a file.
def create_file(ctx, filename=None, content=None):
dirname = os.path.dirname(filename)
os.makedirs(dirname)
_write(filename, content)
+
+# Copy test certificate from source tree, where it's been created previously by
+# ./check.
+def copy_test_certificate(ctx, cert=None, key=None):
+ shutil.copy(os.path.join(srcdir, "test.pem"), cert)
+ shutil.copy(os.path.join(srcdir, "test.key"), key)
+
+
# Start server using named configuration file.
def start_server(ctx, filename=None):
- config = get_file(filename).decode('UTF-8')
+ config = get_file(filename).decode("UTF-8")
config = yaml.safe_load(config)
- config['port'] = random.randint(2000, 30000)
- ctx['config'] = config
+ config["port"] = random.randint(2000, 30000)
+ ctx["config"] = config
config = yaml.safe_dump(config)
_write(filename, config)
- _run(ctx, [
- '/usr/sbin/daemonize',
- '-c', os.getcwd(),
- '-p', 'ewww.pid',
- '-o', 'ewww.stdout',
- '-e', 'ewww.stderr',
- _binary('ewww'),
- filename
- ])
+ _run(
+ ctx,
+ [
+ "/usr/sbin/daemonize",
+ "-c",
+ os.getcwd(),
+ "-p",
+ "ewww.pid",
+ "-o",
+ "ewww.stdout",
+ "-e",
+ "ewww.stderr",
+ _binary("ewww"),
+ filename,
+ ],
+ )
_run_exit(ctx, 0)
- ctx['pid'] = open('ewww.pid').read()
+ ctx["pid"] = open("ewww.pid").read()
+
# Make a HTTP request.
def request(ctx, method=None, url=None):
url, host = _url(ctx, url)
- _run(ctx, ['curl', '-sv', '-X', method, '-HHost: {}'.format(host), url])
+ print(url)
+ _run(ctx, ["curl", "-ksv", "-X", method, "-HHost: {}".format(host), url])
_run_exit(ctx, 0)
+
# Check status code of latest HTTP request.
def status_code_is(ctx, code=None):
- pattern = '\n< HTTP/1.1 {} '.format(code)
- assert_eq(pattern in ctx['stderr'], True)
+ pattern = "\n< HTTP/2 {} ".format(code)
+ assert_eq(pattern in ctx["stderr"], True)
+
# Check a HTTP response header for latest request has a given value.
def http_header_is(ctx, header=None, value=None):
- s = ctx['stderr']
- pattern = '\n< {}: {}'.format(header, value)
+ s = ctx["stderr"]
+ pattern = "\n< {}: {}".format(header, value)
if pattern not in s:
- print('stderr:', repr(s))
- print('pattern:', repr(pattern))
+ print("stderr:", repr(s))
+ print("pattern:", repr(pattern))
assert_eq(pattern in s, True)
-
+
+
# Check a HTTP body response for latest request has a given value.
def http_body_is(ctx, body=None):
- s = ctx['stdout']
- body = body.encode('UTF8').decode('unicode-escape')
+ s = ctx["stdout"]
+ body = body.encode("UTF8").decode("unicode-escape")
if body != s:
- print('stdout:', repr(s))
- prin('pattern:', repr(body))
+ print("stdout:", repr(s))
+ prin("pattern:", repr(body))
assert_eq(body, s)
diff --git a/ewww.yaml b/ewww.yaml
index 56be410..94c33c1 100644
--- a/ewww.yaml
+++ b/ewww.yaml
@@ -1,5 +1,5 @@
- given: a self-signed certificate as {cert}, using key {key}
- function: fixme
+ function: copy_test_certificate
- given: a running server using config file {filename}
function: start_server
diff --git a/src/main.rs b/src/main.rs
index 35728a9..c6e22ab 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,6 +6,8 @@ use warp::Filter;
#[derive(Debug, Deserialize)]
struct Config {
port: u16,
+ tls_key: PathBuf,
+ tls_cert: PathBuf,
}
#[derive(Debug, StructOpt)]
@@ -25,6 +27,9 @@ async fn main() {
eprintln!("starting server: {:?}", config);
warp::serve(hello)
+ .tls()
+ .key_path(config.tls_key)
+ .cert_path(config.tls_cert)
.run(([127, 0, 0, 1], config.port))
.await;
}