Tclcurl tiny web server

TclCurl Test Suite

The repository now has two distinct kinds of files under tests/:

Last update: 2026-05-16

Running the suite

tests/all.tcl tries to load TclCurl from the build tree first and falls back to an installed package if needed.

By default, tests/all.tcl enables tcltest’s start verbosity, so each test prints a line when it begins running. You can still override that from the command line with -verbose.

To run the server-backed suite from a normal working tree, use this sequence:

  1. Start the local test servers in one terminal:
tclsh testservers/testserver.tcl
  1. Run the suite in a second terminal from the repository root:
tclsh tests/all.tcl
  1. To run only one test file, add -file:
tclsh tests/all.tcl -file http.test
  1. If you want the test runner to shut down the HTTP test server when it finishes, add -exitserver:
tclsh tests/all.tcl -exitserver

If one of the configured protocol endpoints is not reachable, the corresponding server-backed tests are skipped.

testservers/testserver.tcl

The local server framework accepts the following general command form:

tclsh testservers/testserver.tcl \
                  ?--host host? \
                  ?--httpport port? ?--httpsport port? ?--ftpport port? ?--proxyport port? \
                  ?--certfile path? ?--keyfile path? \
                  ?--service protocol:port? ... \
                  ?--docroot path? ?--ftproot path? ?--keepdocroot? \
                  ?--logfile path? \
                  ?--startservers protocol[,protocol,...]|all? \
                  ?--quiet? ?--debug?

By default, testservers/testserver.tcl starts four services:

The HTTP test server keeps its explicit dynamic routes for protocol behaviors such as redirects, request inspection, and authentication. For GET and HEAD requests that do not match one of those routes, it falls back to static file serving rooted at TCLCURL_TEST_DOC_ROOT or --docroot.

Unless --keepdocroot is given, the server removes the configured document root when it shuts down.

The server framework appends timestamped per-request log lines to /tmp/tclcurl.log by default. Override that path with --logfile when you want to keep the request log elsewhere.

tests/all.tcl

tests/all.tcl accepts a small set of TclCurl-specific options together with the usual tcltest command-line filters and output controls. The general form is:

tclsh tests/all.tcl \
                  ?--httpserver path/to/server.tcl? \
                  ?--httpport port? ?--httpsport port? ?--ftpport port? ?--proxyport port? \
                  ?--docroot path? ?--ftproot path? \
                  ?--certfile path? ?--keyfile path? \
                  ?--exitserver? ?--debug? \
                  ?--file pattern? ?--notfile pattern? ?--match pattern? ?--skip pattern? \
                  ?--verbose level...?

When the Tcl HTTP test server is wired in, the server script path precedence is:

testservers/testserver.tcl accepts --httpport, --httpsport, --ftpport, and --proxyport to override the default ports 8990, 9443, 8991, and 8992.

tests/all.tcl accepts the same double-dash options --httpport, --httpsport, --ftpport, and --proxyport. It also accepts --docroot, --ftproot, --certfile, and --keyfile, and maps them to the corresponding TCLCURL_TEST_* environment overrides used by the test support layer. When you need both entry points to target the same services, pass matching values to each script.

The Tcl test support layer uses protocol-specific base URLs. You can override them before running make test or tclsh tests/all.tcl:

Running secure protocol tests

In order to test the https series of tests you have to create a self-signed pair of key/certificate to be stored in tests/certs

If you want to keep the credentials elsewhere, either:

 mkdir -p tests/certs

  openssl req   -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
                -keyout tests/certs/server.key \
                -out tests/certs/server.crt \
                -subj "/CN=localhost" \
                -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Shared transport scenarios

tests/http_common.tcl contains transport-oriented scenario helpers that are shared by http.test, https.test, redir.test, and cookies.test.

The common layer currently covers:

Tests that are primarily about easy-handle lifecycle or share-handle lifecycle stay in the protocol-specific files instead of being pulled into http_common.tcl.

Current server-backed coverage

tests/http.test focuses on TclCurl behaviors exercised over plain HTTP:

tests/output.test covers output routing:

tests/progress.test covers transfer callbacks and related controls:

tests/negotiation.test covers HTTP negotiation-oriented options:

tests/https.test covers the TLS-specific aspects of the same HTTP behaviors:

tests/ftp.test covers the local Tcl FTP server:

tests/redir.test and tests/cookies.test are thin wrappers around the shared transport scenarios, kept as separate files for readability and focused tcltest runs.

tests/mime.test currently covers multipart form submission through -httppost:

HTTPS setup

The HTTPS server requires:

You can override those paths:

These files are intentionally not required to live in the repository. When they are missing, HTTPS-backed tests are skipped.

One simple way to generate them locally is:

mkdir -p tests/certs

openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
  -keyout tests/certs/server.key \
  -out tests/certs/server.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Areas of Active Coverage Growth

The current suite already covers the core HTTP, HTTPS, and FTP behaviors used by TclCurl, but some areas are still being expanded. If you are looking for the parts of the option surface that are most likely to gain broader automated coverage next, the main groups are:

Other areas that are also expected to grow over time include:

Current Limitations

Although the local test framework now covers a substantial part of TclCurl’s single-transfer behavior, some categories still have more limited automated coverage.

The main remaining limitations are:

In practice, this means that the absence of a test in one of those areas does not necessarily indicate lack of support in TclCurl. It more often means that the local test framework has not yet been extended to exercise that behavior in a reproducible way.