Files
2026-09-07 00:45:35 +02:00

106 lines
5.1 KiB
Markdown

# tester42 — official 42 webserv testers
Binaries attached to the intra evaluation scale, plus the fixtures they require.
All of them are Go programs, not stripped, so their expectations can be read out of the
binaries directly — `strings`, `nm`, and `go tool objdump`, which still shows the original
source file and line numbers. Nothing below is guesswork, and the whole sequence has also
been executed once against a probe stub.
## Layout and provenance
```
official/ tester, cgi_tester ← downloaded from intra. THE ONLY TRUSTED ONES.
YoupiBanane/ the fixture tree the tester requires (contents dictated by the tester
itself — see its printed instructions below, so it is reconstructable)
```
Both official binaries are **Linux ELF x86-64** and cannot run on macOS. They run in the
project's Linux container, which is also the platform the school VMs use.
## What the tester requires (verbatim from the binary)
```
- Download the cgi_test executable on the host
- Create a directory YoupiBanane with:
- A file name youpi.bad_extension
- A file name youpi.bla
- A sub directory called nop
- A file name youpi.bad_extension in nop
- A file name other.pouic in nop
- A sub directory called Yeah
- A file name not_happy.bad_extension in Yeah
- / must answer to GET request ONLY
- /directory/ must answer to GET request and the root of it would be the repository
YoupiBanane and if no file are requested, it should search for youpi.bad_extension files
- /post_body must answer anything to POST request with a maxBody of 100
- Any file with .bla as extension must answer to POST request by calling the cgi_test executable
```
## Test cases found in the binary
The complete executed order has now been verified against a passing probe stub.
| Area | Evidence in binary |
|---|---|
| `Test GET` | `GET on /directory/nop`, `directory/Yeah/not_happy.bad_extension`, `directory/nop/other.pouic` |
| 404 paths | `directory/oulalala`, `directory/nop/other.pouac` |
| `Test HEAD` | `HEAD /` is exercised and must return `405`; general HEAD support is not tested |
| `Test POST` | `/post_body` with `maxBody 100` |
| CGI | `Post on /directory/youpi.bla with size 100000000` (100 MB body into CGI), `bad cgi returned body content` |
| Concurrency | `Test multiple workers(%d) doing multiple times(%d)`, `client disconnected` |
`FATAL ERROR ON LAST TEST:` is the message printed when a case fails.
## CGI environment the cgi_tester reads
```
REQUEST_METHOD SERVER_PROTOCOL CONTENT_LENGTH CONTENT_TYPE
QUERY_STRING PATH_INFO HTTP_HOST HTTP_<any request header>
```
The binary vendors Go's `net/http/cgi`, so the contract is that package's, not folklore.
Three of these are failure modes rather than niceties:
- **`SERVER_PROTOCOL` is mandatory.** `RequestFromMap` calls `http.ParseHTTPVersion` on it and
aborts with `cgi: invalid SERVER_PROTOCOL version` if it is missing. The CGI never runs.
- **`PATH_INFO` must equal the request path**, with `SCRIPT_NAME` left empty. The handler
compares `os.Getenv("PATH_INFO")` against `r.URL.Path` and answers `500 PATH_INFO incorrect`
otherwise. Splitting them the way RFC 3875 prescribes **fails this tester**.
- **Arbitrary headers must be exported as `HTTP_*`** (uppercase, dashes to underscores). One
test reads `X-SECRET-HEADER-FOR-TEST`, so `HTTP_X_SECRET_HEADER_FOR_TEST` has to be there.
- `CONTENT_LENGTH` must be exact — including for the 100 MB POST. Wrong value gives
`cgi: bad CONTENT_LENGTH in environment`; a missing one makes the CGI read zero bytes,
because `Request()` wraps stdin in `io.LimitReader(os.Stdin, r.ContentLength)`.
- `CONTENT_TYPE` arrives as `test/file`. Not a real MIME type — forward it verbatim.
Its output starts with a `Status: NNN Text` header, which the server must turn into the HTTP
status line rather than forward. No `Content-Length` is emitted: EOF ends the body.
## Scope implications
Passing this tester requires more than the subject text asks for:
- **location matched by extension** (`*.bla`), not only by path prefix, and taking precedence
over the prefix match so that `POST /directory/youpi.bla` reaches the CGI while
`GET` on the same path serves the file
- **`alias` semantics** distinct from `root`: `/directory/` maps onto `YoupiBanane`, which has
no `directory/` subtree, so plain `root` cannot express it
- **per-location body limit** (`/post_body`, 100 bytes), enforced on the **decoded** body —
every POST the tester sends is chunked, so there is no `Content-Length` to check
- a 100 MB request body streamed into a CGI without buffering it all in memory
Nested `location` blocks are *not* required by this binary; they are kept in the config
grammar because the grammar is expensive to change later, not because a test needs them.
This official binary does **not** execute PUT or DELETE. DELETE and uploads remain mandatory
because the subject and evaluation checklist require them; they need project-owned tests.
## Running
```bash
# inside the Linux container, from the directory that contains YoupiBanane
./official/tester http://localhost:8000
```
The config must point the `.bla` CGI at `official/cgi_tester`.