Commit Diff


commit - 5c2e310edececfc9ef67946c1bf7df6bcdbe8931
commit + 30008a68d322f837c12467a26d1bea2215a5a669
blob - 03c547a2e7cbc5e26c46aa25c177be72ba8b6579 (mode 644)
blob + /dev/null
--- iri_test.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2020 Omar Polo <op@omarpolo.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "gmid.h"
-
-#define TEST(iri, fail, exp, descr)				\
-	if (!run_test(iri, fail, exp)) {			\
-		fprintf(stderr, "%s:%d: error: %s\n",		\
-		    __FILE__, __LINE__, descr);			\
-		exit(1);					\
-	}
-
-#define IRI(schema, host, port, path, query, frag)		\
-	((struct iri){schema, host, port, 0, path, query, frag})
-
-#define DIFF(wanted, got, field)					\
-	if (wanted->field == NULL || got->field == NULL ||		\
-	    strcmp(wanted->field, got->field)) {			\
-		fprintf(stderr, #field ":\n\tgot: %s\n\twanted: %s\n",	\
-		    got->field, wanted->field);				\
-		return 0;						\
-	}
-
-#define PASS 0
-#define FAIL 1
-
-int
-diff_iri(struct iri *p, struct iri *exp)
-{
-        DIFF(p, exp, schema);
-        DIFF(p, exp, host);
-        DIFF(p, exp, port);
-        DIFF(p, exp, path);
-        DIFF(p, exp, query);
-        DIFF(p, exp, fragment);
-	return 1;
-}
-
-int
-run_test(const char *iri, int should_fail, struct iri expected)
-{
-	int failed, ok = 1;
-	char *iri_copy;
-	struct iri parsed;
-	const char *error;
-
-	if ((iri_copy = strdup(iri)) == NULL)
-		err(1, "strdup");
-
-	fprintf(stderr, "=> %s\n", iri);
-	failed = !parse_iri(iri_copy, &parsed, &error);
-
-	if (failed && should_fail)
-		goto done;
-
-	if (error != NULL)
-		fprintf(stderr, "> %s\n", error);
-
-	ok = !failed && !should_fail;
-	if (ok)
-		ok = diff_iri(&expected, &parsed);
-
-done:
-	free(iri_copy);
-	return ok;
-}
-
-int
-main(void)
-{
-	struct iri empty = {"", "", "", PASS, "", "", ""};
-
-	TEST("http://omarpolo.com",
-	    PASS,
-	    IRI("http", "omarpolo.com", "", "", "", ""),
-	    "can parse iri with empty path");
-
-	/* schema */
-	TEST("omarpolo.com", FAIL, empty, "FAIL when the schema is missing");
-	TEST("gemini:/omarpolo.com", FAIL, empty, "FAIL with invalid marker");
-	TEST("gemini//omarpolo.com", FAIL, empty, "FAIL with invalid marker");
-	TEST("h!!p://omarpolo.com", FAIL, empty, "FAIL with invalid schema");
-	TEST("GEMINI://omarpolo.com",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "Schemas are case insensitive.");
-
-	/* authority */
-	TEST("gemini://omarpolo.com",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "can parse authority with empty path");
-	TEST("gemini://omarpolo.com/",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "can parse authority with empty path (alt)")
-	TEST("gemini://omarpolo.com:1965",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "1965", "", "", ""),
-	    "can parse with port and empty path");
-	TEST("gemini://omarpolo.com:1965/",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "1965", "", "", ""),
-	    "can parse with port and empty path")
-	TEST("gemini://omarpolo.com:196s",
-	    FAIL,
-	    empty,
-	    "FAIL with invalid port number");
-	TEST("gemini://OmArPoLo.CoM",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "host is case-insensitive");
-
-	/* path */
-	TEST("gemini://omarpolo.com/foo/bar/baz",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "foo/bar/baz", "", ""),
-	    "parse simple paths");
-	TEST("gemini://omarpolo.com/foo//bar///baz",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "foo/bar/baz", "", ""),
-	    "parse paths with multiple slashes");
-	TEST("gemini://omarpolo.com/foo/./bar/./././baz",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "foo/bar/baz", "", ""),
-	    "parse paths with . elements");
-	TEST("gemini://omarpolo.com/foo/bar/../bar/baz",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "foo/bar/baz", "", ""),
-	    "parse paths with .. elements");
-	TEST("gemini://omarpolo.com/foo/../foo/bar/../bar/baz/../baz",
-	    PASS,
-	    IRI("gemini", "omarpolo.com", "", "foo/bar/baz", "", ""),
-	    "parse paths with multiple .. elements");
-	TEST("gemini://omarpolo.com/foo/..",
-	    PASS,
-            IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "parse paths with a trailing ..");
-	TEST("gemini://omarpolo.com/foo/../",
-	    PASS,
-            IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "parse paths with a trailing ..");
-	TEST("gemini://omarpolo.com/foo/../..",
-	    FAIL,
-            empty,
-	    "reject paths that would escape the root");
-	TEST("gemini://omarpolo.com/foo/../../",
-	    FAIL,
-            empty,
-	    "reject paths that would escape the root")
-	TEST("gemini://omarpolo.com/foo/../foo/../././/bar/baz/.././.././/",
-	    PASS,
-            IRI("gemini", "omarpolo.com", "", "", "", ""),
-	    "parse path with lots of cleaning available");
-	TEST("gemini://omarpolo.com//foo",
-	    PASS,
-            IRI("gemini", "omarpolo.com", "", "foo", "", ""),
-	    "Trim initial slashes");
-	TEST("gemini://omarpolo.com/////foo",
-	    PASS,
-            IRI("gemini", "omarpolo.com", "", "foo", "", ""),
-	    "Trim initial slashes (pt. 2)");
-
-	/* query */
-	TEST("foo://example.com/foo/?gne",
-	    PASS,
-	    IRI("foo", "example.com", "", "foo/", "gne", ""),
-	    "parse query strings");
-	TEST("foo://example.com/foo/?gne&foo",
-	    PASS,
-	    IRI("foo", "example.com", "", "foo/", "gne&foo", ""),
-	    "parse query strings");
-	TEST("foo://example.com/foo/?gne%2F",
-	    PASS,
-	    IRI("foo", "example.com", "", "foo/", "gne/", ""),
-	    "parse query strings");
-
-	/* fragment */
-	TEST("foo://bar.co/#foo",
-	    PASS,
-	    IRI("foo", "bar.co", "", "", "", "foo"),
-	    "can recognize fragments");
-
-	/* percent encoding */
-	TEST("foo://bar.com/caf%C3%A8.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "cafè.gmi", "", ""),
-	    "can decode");
-	TEST("foo://bar.com/caff%C3%A8%20macchiato.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "caffè macchiato.gmi", "", ""),
-	    "can decode");
-	TEST("foo://bar.com/caff%C3%A8+macchiato.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "caffè+macchiato.gmi", "", ""),
-	    "can decode");
-	TEST("foo://bar.com/foo%2F..%2F..",
-	    FAIL,
-	    empty,
-	    "conversion and checking are done in the correct order");
-	TEST("foo://bar.com/foo%00?baz",
-	    FAIL,
-	    empty,
-	    "rejects %00");
-
-	/* IRI */
-        TEST("foo://bar.com/cafè.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "cafè.gmi", "" , ""),
-	    "decode IRI (with a 2-byte utf8 seq)");
-	TEST("foo://bar.com/世界.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "世界.gmi", "" , ""),
-	    "decode IRI");
-	TEST("foo://bar.com/😼.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "😼.gmi", "" , ""),
-	    "decode IRI (with a 3-byte utf8 seq)");
-	TEST("foo://bar.com/😼/𤭢.gmi",
-	    PASS,
-	    IRI("foo", "bar.com", "", "😼/𤭢.gmi", "" , ""),
-	    "decode IRI (with a 3-byte and a 4-byte utf8 seq)");
-	TEST("foo://bar.com/世界/\xC0\x80",
-	    FAIL,
-	    empty,
-	    "reject invalid sequence (overlong NUL)");
-
-	return 0;
-}
blob - e152c8f6939333552ec23361edb3f70897535f3b (mode 644)
blob + /dev/null
--- test/cert.pem
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEpDCCAowCCQDkH9rq5++pQzANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
-b2NhbGhvc3QwHhcNMjEwMTE3MTA0MzMzWhcNMjIwMTE3MTA0MzMzWjAUMRIwEAYD
-VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCp
-YzeKNqZequOdFjv/YiPgTLcAA4WQZavRbej1dDqgusRcc8/zk9hwzESeI+u87GTE
-knryxYHrGuW7ZVZWPgjQ8f7KZrvN0WlZo1eL2dqyOZDr+wZh7E9H8VFR/Gu6NzXX
-9/pQPvIWj71hc4WhzwnS950lv7vzp92ul4NeqzTQKwcd+nwLMsOg2iAt6Ncw7uKc
-36hWr/gXOvZBciqjb2r1o8Kf5rBFPexMi97IRrM1JQDV74lLTxuGSAdIpYnF9CcG
-gxvzPj3ws3WW/x3rQaqJEfjm31Mvf+Rr0ZSNcLstBpj9LaRojYCneEjB8xj3ClV9
-szl5yarAItfLti/tj0SQ0rqJGyUgKZYkfIB+DbnSjYXo4YsQ+Be5q2AmHRcChFuL
-zkjLpPLAgS2bXjANKntA60PC9fAhz4sNMglaWC1PnIdGsE+1RjZ64ItQPmTRGWPS
-FC7GP6RQSYLStdfscl6/WGYU3ey97Q9V2Z1HpOQzxGiUhejZJeUjIUdQEkjCaMkl
-RffGEQyHJVjokb7owxTmaGNG9+I7yXWXiYXaA3QIKC9nGT04kLqOeJEqljhjmhiL
-coC7nZzRHWCtLU3o4mSB4DGNnzrOLichpZrB+3qP2lL4NiEoHUb+/NSZULtUt4XN
-acg1T4+skXVO9W/efTvw67Sfv2L857z6rjXjOgX/ywIDAQABMA0GCSqGSIb3DQEB
-CwUAA4ICAQBE1XFORAn8v16EanSHYcdep05V1ouPuI1Zpw6pgKdFkJoFt/Wz6dw4
-XyOMDxiUpXUz0rDwmL5hFnv0cHue22JECgwynpyE88GANEvE1qn9WeZI22h6+nE9
-0H02f5mq2JKifRtLvSltjrhrmoL82RH4bD16v8tybygupetIcFcmRUM98vfPTYxc
-+xHdeJpfrHEn0GAuy59oypGKsa4IjHFGSCt1sFCjfVJauqrvswcbk2FABAlyYHQ6
-h8ldtvEnuDSmH5otYg7TRlJqjoK7gFlG+Yt8bcK5ZSOtx5nFk2+uqKUem7iA9cW/
-caPG6Lllv8B0hBS9dwO9oFalee2fYdzF5GjnEqkllg4DOlr/fblGSpg1U9xLn5ur
-+KmYtUipeT1Oz1wbsAsI+lUNIFo60JZMEGmwpf0Hcdahtm6lZzbhvzH7SGXivzV5
-ALUf0vy8hnpWDzMBy7pHde3CSoLWSEOhPt6Tx2DOfA/ZvrOiOxpYovQGx/Gs7zLY
-Luemesq7Vzd1hLFacCVnYin1b2VGjUT1ibs210WRzZ1C6XaflcB/eQUmGZXisO0k
-vqWQGNykjN1V4shDRt8q3dqbcVIIAITYgh3mIq6UQZY1uzEfZYc0lJs4/n64y2jG
-ORdRlwBgFCNise1UrxUsNdYw/tTClqZ36E6bntKR4pkZczqeVH66pQ==
------END CERTIFICATE-----
blob - a8d7319d2ede1b89cf6c018ddfeef7cc9d9a728a (mode 644)
blob + /dev/null
--- test/cgi.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-daemon off
-ipv6 off
-port 10965
-
-server "localhost" {
-	cert "cert.pem"
-	key  "key.pem"
-	root "docs"
-	cgi  ""
-}
blob - 2be7c65ae93b54b988416f280298b0b8b5f20385 (mode 644)
blob + /dev/null
--- test/docs/index.gmi
+++ /dev/null
@@ -1 +0,0 @@
-# hello world
blob - 98b3d77b9ccb342fbc06650b40436dc25c1b61ed (mode 755)
blob + /dev/null
--- test/docs/script
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-printf "20 text/gemini\r\n"
-printf "# hello world\n"
blob - bd2de8b0c80891dbcad7a3f6eb89c3e11415da26 (mode 755)
blob + /dev/null
--- test/gg.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-
-# GeminiGet, aka gg
-# USAGE: ./gg path [port]
-
-import os
-import socket
-import ssl
-import urllib.parse
-import sys
-
-hostname = 'localhost'
-path = sys.argv[1]
-
-port = 1965
-if len(sys.argv) > 2:
-    port = int(sys.argv[2])
-
-s = socket.create_connection((hostname, port))
-context = ssl.SSLContext()
-context.check_hostname = False
-context.verify_mode = ssl.CERT_NONE
-s = context.wrap_socket(s, server_hostname = hostname)
-s.sendall(("gemini://" + hostname + ":" + str(port) + path + "\r\n").encode('UTF-8'))
-
-fp = s.makefile("rb")
-for line in fp.read().splitlines():
-    print(line.decode('UTF-8'))
blob - ad9723a1c440ca4eef62866bfd1c85bc0469397d (mode 644)
blob + /dev/null
--- test/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-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
-PqNUZ1DUexadHtagYSo/hhWDNPDt
------END PRIVATE KEY-----
blob - 9e38f0c01060135718ea7ada9b87590fcd4f1c8a (mode 644)
blob + /dev/null
--- test/no-cgi.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-daemon off
-ipv6 off
-port 10965
-
-server "localhost" {
-	cert "cert.pem"
-	key  "key.pem"
-	root "docs"
-}
blob - f7eda8aad700e666d9c51b9f5c8ec48e7e970c78 (mode 755)
blob + /dev/null
--- test/test.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-# sha256 of "20 text/gemini\r\n# hello world\n"
-ok_res=6989d9b0e082c79edb8f625ebb77ddcb07764d3dd0c7c5ae60a27a50a33f6a15
-
-# sha256 of docs/script
-script_res=00bf8349336a4a1896f9e98dda67c8264f70b767343351247db96b4546f8d872
-
-get() {
-	./gg.py "$1" 10965
-}
-
-# check "path" "expected-sha256"
-check() {
-	got=`get "$1" | $sha | awk '{print \$1}'`
-	if [ "$got" '!=' "$2" ]; then
-		echo "FAIL $1 (with_cgi: $with_cgi)"
-		quit
-	else
-		echo "PASS $1"
-	fi
-}
-
-quit() {
-	pkill gmid
-	exit ${1:-1}
-}
-
-# check for sha256sum (linux) or sha256 (OpenBSD)
-if which sha256sum >/dev/null; then
-	sha=sha256sum
-elif which sha256 >/dev/null; then
-	sha=sha256
-else
-	echo "No sha256/sha256sum binary available"
-	exit 1
-fi
-
-with_cgi="no"
-./../gmid -c no-cgi.conf 2>/dev/null &
-
-check "/" $ok_res
-check "/index.gmi" $ok_res
-check "/script" $script_res
-
-if ! pkill gmid; then
-	echo "Is gmid still running?"
-	exit 1
-fi
-
-wait
-
-with_cgi="yes"
-./../gmid -c cgi.conf 2>/dev/null &
-
-check "/" $ok_res
-check "/index.gmi" $ok_res
-check "/script" $ok_res
-
-quit 0