-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevtserve1-handle-half-closed.rkt
55 lines (48 loc) · 1.65 KB
/
evtserve1-handle-half-closed.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#lang racket
;; Tony Garnock-Jones, https://groups.google.com/g/racket-users/c/H43jr8QuM-4
;; ". . . if the connection breaks, the ports will be closed as usual. . . ."
;; ". . . Ah, sorry, try `eof-evt` instead of `port-closed-evt`."
(define (handle-by-event in out k)
; Discard the HTTP request header (up to blank line):
(regexp-match #rx"(\r\n|^)\r\n" in)
(displayln "request received")
(flush-output (current-output-port))
;; Detect half-closed TCP connections with eof-evt on the input port
(let ((evt (sync/timeout 10 (eof-evt in))))
(if evt
(begin
(displayln "Error: Detected half-closed TCP connection.")
(k))
(begin
(displayln "about to send response")
(flush-output (current-output-port))
(display "HTTP/1.0 200 Okay\r\n" out)
(display "Server: k\r\nContent-Type: text/html\r\n\r\n" out)
(display "<html><body>Hello, world!</body></html>" out)
(k)))))
(define (accept-and-handle listener)
(define-values (in out) (tcp-accept listener))
(handle-by-event in out (lambda ()
(displayln "request processing completed")
))
(close-input-port in)
(close-output-port out))
(define (serve port-no)
(define max-num-connections-to-wait 5)
(define listener (tcp-listen port-no max-num-connections-to-wait #t))
(define (loop)
(accept-and-handle listener)
(loop))
(loop))
(serve 8000)
#|
Test with curl and GNU coreutils timeout:
timeout --foreground 3s curl http://127.0.0.1:8000
output:
request received
got evt
request processing completed
Tested on:
Racket v8.0 cs
on Ubuntu 20.04.4 LTS
|#