Skip to content

Commit abdf009

Browse files
committedJul 14, 2019
ws-conn-close-status and ws-conn-close-reason; closes tonyg#8.
1 parent 8dc59ce commit abdf009

File tree

10 files changed

+89
-5
lines changed

10 files changed

+89
-5
lines changed
 

‎net/rfc6455/conn-api.rkt

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
ws-conn-supports-payload-type?
1010
ws-conn-signals-status-on-close?
1111
ws-conn-closed?
12+
ws-conn-close-status
13+
ws-conn-close-reason
1214
ws-conn-line
1315
ws-conn-headers
1416
ws-send!
@@ -33,6 +35,8 @@
3335
(require web-server/http/request-structs)
3436

3537
(struct ws-conn-base ([closed? #:mutable]
38+
[close-status #:mutable]
39+
[close-reason #:mutable]
3640
line
3741
headers
3842
ip
@@ -52,6 +56,8 @@
5256
(ws-conn-supports-payload-type? ws-conn payload-type)
5357
(ws-conn-signals-status-on-close? ws-conn)
5458
(ws-conn-closed? ws-conn)
59+
(ws-conn-close-status ws-conn)
60+
(ws-conn-close-reason ws-conn)
5561
(ws-conn-line ws-conn)
5662
(ws-conn-headers ws-conn)
5763
(ws-send! ws-conn payload

‎net/rfc6455/examples/cat.rkt

+11-4
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@
99
(require (only-in racket/port read-line-evt))
1010

1111
(define server "ws://localhost:8081/")
12+
(define close-status 1000)
13+
(define close-reason "")
1214
(command-line #:once-each
13-
["--server" s
14-
"URL of Websocket server to contact"
15-
(set! server s)])
15+
["--server" URL "URL of Websocket server to contact"
16+
(set! server URL)]
17+
["--status" CODE "Status code to use during WebSocket close"
18+
(set! close-status (string->number CODE))]
19+
["--reason" MESSAGE "Explanatory text to use during close"
20+
(set! close-reason MESSAGE)])
1621

1722
(define c (ws-connect (string->url server)))
1823
(let loop ()
@@ -28,4 +33,6 @@
2833
(void)
2934
(begin (printf "~a\n" line)
3035
(loop)))))))
31-
(ws-close! c))
36+
(ws-close! c
37+
#:status close-status
38+
#:reason close-reason))

‎net/rfc6455/examples/echo-server.rkt

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#lang racket
2+
;; Echo server, demonstrating the ws-serve interface.
3+
;; Public Domain.
4+
5+
(module+ main
6+
(require "../../rfc6455.rkt")
7+
8+
(define port 8081)
9+
(define idle-timeout #f)
10+
(command-line #:once-each
11+
["--timeout" SECONDS "Set per-connection idle timeout"
12+
(set! idle-timeout (string->number SECONDS))]
13+
["--port" PORT "Set service port"
14+
(set! port (string->number PORT))])
15+
16+
(define (connection-handler c state)
17+
(define id (gensym 'conn))
18+
(printf "~a: Connection received\n" id)
19+
(let loop ()
20+
(match (ws-recv c #:payload-type 'text)
21+
[(? eof-object?) (void)]
22+
[m
23+
(printf "~a: Received: ~v\n" id m)
24+
(ws-send! c m)
25+
(loop)]))
26+
(printf "~a: Close status: ~v ~v\n"
27+
id
28+
(ws-conn-close-status c)
29+
(ws-conn-close-reason c))
30+
(ws-close! c)
31+
(printf "~a: Connection closed\n" id))
32+
33+
(when idle-timeout (ws-idle-timeout idle-timeout))
34+
(define stop-service (ws-serve #:port port connection-handler))
35+
(printf "Server running. Hit enter to stop service.\n")
36+
(void (read-line))
37+
(stop-service))

‎net/rfc6455/hybi00/client.rkt

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949

5050
(define conn (new-web-server-connection ip op))
5151
(ws-conn-start! (hybi00-conn #f
52+
#f
53+
#f
5254
sresponse
5355
rheaders
5456
ip

‎net/rfc6455/hybi00/conn.rkt

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@
102102
(define (ws-conn-supports-payload-type? c payload-type) (eq? payload-type 'text))
103103
(define (ws-conn-signals-status-on-close? c) #f)
104104
(define (ws-conn-closed? c) (ws-conn-base-closed? c))
105+
(define (ws-conn-close-status c) (ws-conn-base-close-status c))
106+
(define (ws-conn-close-reason c) (ws-conn-base-close-reason c))
105107
(define (ws-conn-line c) (ws-conn-base-line c))
106108
(define (ws-conn-headers c) (ws-conn-base-headers c))
107109
(define (ws-send! c payload

‎net/rfc6455/hybi00/dispatcher.rkt

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383

8484
(bump-connection-timeout! c)
8585
(conn-dispatch (ws-conn-start! (hybi00-conn #f
86+
#f
87+
#f
8688
cline
8789
headers
8890
ip

‎net/rfc6455/rfc6455/client.rkt

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262

6363
(define conn (new-web-server-connection ip op))
6464
(ws-conn-start! (rfc6455-conn #f
65+
#f
66+
#f
6567
response-line
6668
response-headers
6769
ip

‎net/rfc6455/rfc6455/conn.rkt

+7
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@
6767
[(8) ;; close; shutdown
6868
(unless (ws-conn-base-closed? c)
6969
(write-frame (rfc6455-frame #t 8 #"") (ws-conn-base-op c) (rfc6455-conn-mask? c))
70+
(when (>= (bytes-length payload) 2)
71+
(define status (integer-bytes->integer payload #f #t 0 2))
72+
(define reason (bytes->string/utf-8 (subbytes payload 2)))
73+
(set-ws-conn-base-close-status! c status)
74+
(set-ws-conn-base-close-reason! c reason))
7075
(set-ws-conn-base-closed?! c #t))
7176
eof]
7277
[(9) ;; ping; reply
@@ -139,6 +144,8 @@
139144
(memq payload-type '(text binary)))
140145
(define (ws-conn-signals-status-on-close? c) #t)
141146
(define (ws-conn-closed? c) (ws-conn-base-closed? c))
147+
(define (ws-conn-close-status c) (ws-conn-base-close-status c))
148+
(define (ws-conn-close-reason c) (ws-conn-base-close-reason c))
142149
(define (ws-conn-line c) (ws-conn-base-line c))
143150
(define (ws-conn-headers c) (ws-conn-base-headers c))
144151
(define (ws-send! c payload

‎net/rfc6455/rfc6455/dispatcher.rkt

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757

5858
(bump-connection-timeout! conn)
5959
(conn-dispatch (ws-conn-start! (rfc6455-conn #f
60+
#f
61+
#f
6062
request-line
6163
headers
6264
(connection-i-port conn)

‎net/rfc6455/scribblings/rfc6455.scrbl

+18-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
web-server/http/request-structs
77
net/rfc6455))
88

9-
@title[#:version "2.0.0"]{RFC 6455 WebSockets for Racket}
9+
@title[#:version "2.1.0"]{RFC 6455 WebSockets for Racket}
1010
@author[(author+email "Tony Garnock-Jones" "tonygarnockjones@gmail.com")]
1111

1212
@;@local-table-of-contents[]
@@ -48,6 +48,10 @@ This package has been developed against
4848

4949
@section{Changes}
5050

51+
Version 2.1.0 of this library introduces @racket[ws-conn-close-status]
52+
and @racket[ws-conn-close-reason] for retrieving information from
53+
close frames sent by remote peers.
54+
5155
Version 2.0.0 of this library introduces a new interface to streaming
5256
message reception, @racket[ws-recv-stream], and makes a breaking
5357
change to the way @racket[ws-conn?] values work as @(tech:event)s. The
@@ -173,6 +177,19 @@ Returns @racket[#t] if the given connection has been closed, and
173177

174178
}
175179

180+
@deftogether[(@defproc[(ws-conn-close-status [c ws-conn?]) (or/c #f number?)]
181+
@defproc[(ws-conn-close-reason [c ws-conn?]) (or/c #f string?)])]{
182+
183+
When @racket[ws-conn-closed?] returns @racket[#t], these procedures
184+
will respectively retrieve the "status code" and "reason" text from
185+
the close frame sent by the remote peer that caused the connection
186+
shutdown. If no such information is available, they will return
187+
@racket[#f]. Only RFC 6455 peers send information in their close
188+
frames; hybi-00 connections will always yield @racket[#f] from these
189+
procedures.
190+
191+
}
192+
176193
@defproc[(ws-connect [u (or/c ws-url? wss-url?)]
177194
[#:headers headers (listof header?) '()]
178195
[#:protocol protocol (or/c 'rfc6455 'hybi00) 'rfc6455])

0 commit comments

Comments
 (0)
Please sign in to comment.