diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-07-19 10:32:08 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-07-19 10:32:08 +0000 |
commit | f06b0bccfdb7459be0947a6fd6f726eba4bcf92d (patch) | |
tree | 7fafc5f2d22eaf68c9dcfea5a74fe03d6b0676c8 | |
parent | f1590591451f135ca903e20f24ca5a9d0e7fba14 (diff) | |
parent | b130e74f187b2ba22db6654508a6e7e4c721a16e (diff) | |
download | ewww-f06b0bccfdb7459be0947a6fd6f726eba4bcf92d.tar.gz |
Merge branch 'serve-files' into 'master'
Serve files
See merge request larswirzenius/ewww!7
-rwxr-xr-x | check | 20 | ||||
-rw-r--r-- | daemon.py | 9 | ||||
-rw-r--r-- | ewww.md | 54 | ||||
-rw-r--r-- | ewww.py | 21 | ||||
-rw-r--r-- | http.py | 4 | ||||
-rw-r--r-- | src/main.rs | 14 |
6 files changed, 63 insertions, 59 deletions
@@ -3,14 +3,21 @@ set -eu verbose=false -if [ "$#" -gt 0 ] -then +runtest=true +moar=true +while [ "$#" -gt 0 ] && $moar +do case "$1" in verbose | -v | --verbose) verbose=true + shift 1 + ;; + -c | --codegen) + runtest=false + shift 1 ;; esac -fi +done hideok= if command -v chronic > /dev/null @@ -26,7 +33,12 @@ fi codegen() { - $hideok sp-codegen "$1" --output "$2" --run + local run= + if $runtest + then + run=--run + fi + $hideok sp-codegen "$1" --output "$2" $run } docgen() { @@ -65,5 +65,10 @@ def process_exists(pid): # Terminate process. -def terminate_process(pid, signal): - os.kill(pid, signal) +def terminate_process(pid, signalno): + logging.debug(f"Terminating process {pid} with signal {signalno}") + try: + os.kill(pid, signalno) + except ProcessLookupError: + logging.debug("Process did not actually exist (anymore?)") + pass @@ -85,59 +85,16 @@ for static content only. Every other method returns an error. # Acceptance criteria -## Minimal smoke test - -~~~scenario -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} -tls_key: snakeoil.key -tls_cert: snakeoil.pem -~~~ - - ## Smoke test ~~~scenario 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 -and header content-type is "text/plain" -and body is "hello, world\n" -~~~ - -~~~scenario-disabled -given a self-signed certificate as snakeoil.pem, using key snakeoil.key -and a running server using config file smoke.yaml - -when I request GET http://example.com/ -then I am redirected to https://example.com/ - -when I request GET http://example.com/.well-known/foo -then I get status code 404 - -when I create webroot/foo -and I request GET http://example.com/.well-known/foo +when I create webroot/foo.html with "this is your web page" +given a running server using config file smoke.yaml +when I request GET https://example.com/foo.html then I get status code 200 -and content-type is "application/octet-stream" - -when I request HEAD http://example.com/.well-known/foo -then I get status code 200 - -when I request GET https://example.com/ -then I get status code 200 - -when I request HEAD https://example.com/ -then I get status code 200 - -when I request GET https://www.example.com/ -then I am redirected to https://example.com/ +and header content-type is "text/html" +and body is "this is your web page" ~~~ The following config file does not specify port numbers. The test @@ -145,6 +102,7 @@ scaffolding adds randomly chosen port numbers so that the test can run without being root. ~~~{#smoke.yaml .file .yaml .numberLines} +webroot: webroot tls_cert: snakeoil.pem tls_key: snakeoil.key ~~~ @@ -8,6 +8,7 @@ import random import re import shutil import signal +import socket import subprocess import time import urllib.parse @@ -82,7 +83,7 @@ def start_server(ctx, filename=None): logging.debug(f"Starting ewww with config file {filename}") config = get_file(filename).decode("UTF-8") config = yaml.safe_load(config) - config["port"] = random.randint(2000, 30000) + port = config["port"] = random.randint(2000, 30000) logging.debug(f"Picked randomly port for ewww: {config['port']}") ctx["config"] = config config = yaml.safe_dump(config) @@ -90,6 +91,24 @@ def start_server(ctx, filename=None): start_daemon(ctx, "ewww", [_binary("ewww"), filename]) + if not port_open("localhost", port, 5.0): + stderr = open(ctx["daemon"]["ewww"]["stderr"]).read() + logging.debug(f"Stderr from daemon: {stderr!r}") + + +# Wait for a port to be open +def port_open(host, port, timeout): + logging.debug(f"Waiting for port localhost:{port} to be available") + started = time.time() + while time.time() < started + timeout: + try: + socket.create_connection((host, port), timeout=timeout) + return True + except socket.error: + pass + logging.error(f"Port localhost:{port} is not open") + return False + # Stop previously started server. def stop_server(ctx): @@ -24,7 +24,8 @@ def http_request(ctx, host=None, method=None, url=None): # Check status code of latest HTTP request. def http_status_code_is(ctx, code=None): - logging.debug(f"Verifying status code of previous HTTP request is {code}") + logging.debug(f"Verifying status code of previous HTTP request is {code}") + logging.debug(f" stderr={ctx['stderr']}") pattern = f"\n< HTTP/2 {code} " assert_eq(pattern in ctx["stderr"], True) @@ -40,6 +41,7 @@ def http_header_is(ctx, header=None, value=None): # Check a HTTP body response for latest request has a given value. def http_body_is(ctx, body=None): logging.debug(f"Verifying response body is {body!r}") + logging.debug(f" actual body={ctx['stdout']!r}") s = ctx["stdout"] body = body.encode("UTF8").decode("unicode-escape") assert_eq(body, s) diff --git a/src/main.rs b/src/main.rs index d74a148..37e60d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use warp::Filter; #[derive(Debug, Deserialize)] struct Config { + webroot: PathBuf, port: u16, tls_key: PathBuf, tls_cert: PathBuf, @@ -19,6 +20,9 @@ struct Opt { #[derive(Debug, thiserror::Error)] enum EwwwError { + #[error("Web root {0} does not exist")] + WebrootNotFound(PathBuf), + #[error("TLS certificate {0} does not exist")] TlsCertNotFound(PathBuf), @@ -33,11 +37,12 @@ async fn main() { let opt = Opt::from_args(); let config = read_config(&opt.config).unwrap(); - let hello = warp::any() - .map(|| "hello, world\n".to_string()); + let webroot = config.webroot.canonicalize().unwrap(); + eprintln!("webroot: {:?}", webroot); + let webroot = warp::any().and(warp::fs::dir(webroot)); eprintln!("starting server: {:?}", config); - warp::serve(hello) + warp::serve(webroot) .tls() .key_path(config.tls_key) .cert_path(config.tls_cert) @@ -53,6 +58,9 @@ fn read_config(filename: &Path) -> anyhow::Result<Config> { } fn check_config(config: &Config) -> anyhow::Result<()> { + if !config.webroot.exists() { + return Err(EwwwError::WebrootNotFound(config.webroot.clone()).into()); + } if !config.tls_cert.exists() { return Err(EwwwError::TlsCertNotFound(config.tls_cert.clone()).into()); } |