AtlatestRepositorysigil-http

sigil-http / tree / test / integrationkeepalive-range-server-main.sgl

1;;; (t4t2-server main) - integration test server for T4 (keep-alive + chunked)
2;;; and T2 (Range/206/416).
3;;;
4;;; Usage: t4t2-server <port> <asset-path>
5;;;
6;;; Routes:
7;;; /hello -> plain 200, known length (keep-alive eligible)
8;;; /chunked -> streaming procedure body WITHOUT Content-Length
9;;; (server frames it as Transfer-Encoding: chunked)
10;;; /file -> http-response/file wired to the request Range header
11;;; (200 full, 206 partial, or 416 unsatisfiable)
12;;;
13;;; Started as a BARE http-serve (no with-async) so the T1 self-scheduler
14;;; keeps working alongside keep-alive.
16(define-library (t4t2-server main)
17 (import (sigil core)
18 (sigil io)
19 (sigil process)
20 (sigil http server)
21 (sigil http request)
22 (sigil http response))
24 (export main)
26 (begin
28 (define *asset-path* (make-parameter "/dev/null"))
30 (define (handler request)
31 (let ((path (http-request-path request)))
32 (cond
33 ((string=? path "/hello")
34 (http-response/text HTTP-OK "Hello, World!"))
35 ;; Streaming body, unknown length -> chunked transfer-encoding.
36 ((string=? path "/chunked")
37 (http-response
38 status: HTTP-OK
39 headers: #{ content-type: "text/plain" }
40 body: (lambda (write-chunk close)
41 (write-chunk "chunk-A")
42 (write-chunk "chunk-B")
43 (write-chunk "chunk-C")
44 (close))))
45 ;; File with Range wiring (T2).
46 ((string=? path "/file")
47 (http-response/file (*asset-path*)
48 range: (http-request-header request "Range")))
49 (else (http-response/not-found)))))
51 (define (main)
52 (let* ((args (cdr (command-line)))
53 (port (string->number (list-ref args 0)))
54 (asset (list-ref args 1)))
55 (*asset-path* asset)
56 (http-serve handler port: port host: "127.0.0.1")))))