-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.pony
More file actions
103 lines (90 loc) · 2.92 KB
/
Copy pathmain.pony
File metadata and controls
103 lines (90 loc) · 2.92 KB
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use stallion = "../../stallion"
use lori = "lori"
actor Main
new create(env: Env) =>
let auth = lori.TCPListenAuth(env.root)
Listener(auth, "0.0.0.0", "8080", env.out)
actor Listener is lori.TCPListenerActor
"""
TCP listener that creates `StreamServer` actors for each connection.
"""
var _tcp_listener: lori.TCPListener = lori.TCPListener.none()
let _out: OutStream
let _config: stallion.ServerConfig
let _server_auth: lori.TCPServerAuth
new create(
auth: lori.TCPListenAuth,
host: String,
port: String,
out: OutStream)
=>
_out = out
_server_auth = lori.TCPServerAuth(auth)
_config = stallion.ServerConfig(host, port)
_tcp_listener = lori.TCPListener(auth, host, port, this)
fun ref _listener(): lori.TCPListener => _tcp_listener
fun ref _on_accept(fd: U32): lori.TCPConnectionActor =>
StreamServer(_server_auth, fd, _config)
fun ref _on_listening() =>
try
(let host, let port) = _tcp_listener.local_address().name()?
_out.print("Server listening on " + host + ":" + port)
else
_out.print("Server listening")
end
fun ref _on_listen_failure() =>
_out.print("Failed to start server")
fun ref _on_closed() =>
_out.print("Server closed")
actor StreamServer is stallion.HTTPServerActor
"""
Streams a five-chunk response using chunked transfer encoding.
"""
var _http: stallion.HTTPServer = stallion.HTTPServer.none()
var _responder: (stallion.Responder | None) = None
var _chunks_sent: USize = 0
new create(
auth: lori.TCPServerAuth,
fd: U32,
config: stallion.ServerConfig)
=>
_http = stallion.HTTPServer(auth, fd, this, config)
fun ref _http_connection(): stallion.HTTPServer => _http
fun ref on_request(
request': stallion.Request val,
responder: stallion.Responder)
=>
let headers =
recover val
stallion.Headers
.> set("content-type", "text/plain")
end
match \exhaustive\ responder.start_chunked_response(
stallion.StatusOK, headers)
| stallion.StreamingStarted =>
responder.send_chunk("chunk 1 of 5\n")
_responder = responder
_chunks_sent = 1
| stallion.ChunkedNotSupported =>
let body: String val = "Chunked encoding not supported"
let response = stallion.ResponseBuilder(stallion.StatusOK)
.add_header("content-type", "text/plain")
.add_header("Content-Length", body.size().string())
.finish_headers()
.add_chunk(body)
.build()
responder.respond(response)
| stallion.AlreadyResponded => None
| stallion.ConnectionClosed => None
end
fun ref on_chunk_sent(token: stallion.ChunkSendToken) =>
match _responder
| let r: stallion.Responder =>
_chunks_sent = _chunks_sent + 1
if _chunks_sent <= 5 then
r.send_chunk("chunk " + _chunks_sent.string() + " of 5\n")
end
if _chunks_sent == 5 then
r.finish_response()
end
end