v2 / vlib / veb / tests / veb_test_server.v
180 lines · 151 sloc · 4.4 KB · bae41912ce9b9802bc977b05a89be18a80da5f8d
Raw
1module main
2
3import os
4import veb
5import time
6
7const known_users = ['bilbo', 'kent']
8
9struct ServerContext {
10 veb.Context
11}
12
13// Custom 404 page
14pub fn (mut ctx ServerContext) not_found() veb.Result {
15 ctx.res.set_status(.not_found)
16 return ctx.html('404 on "${ctx.req.url}"')
17}
18
19pub struct ServerApp {
20mut:
21 server &veb.Server = unsafe { nil }
22 port int
23 timeout int
24 global_config Config
25}
26
27struct Config {
28 max_ping int
29}
30
31fn exit_after_timeout(timeout_in_ms int) {
32 time.sleep(timeout_in_ms * time.millisecond)
33 println('>> webserver: pid: ${os.getpid()}, exiting ...')
34 exit(0)
35}
36
37fn main() {
38 if os.args.len != 3 {
39 panic('Usage: `veb_test_server.exe PORT TIMEOUT_IN_MILLISECONDS`')
40 }
41 http_port := os.args[1].int()
42 assert http_port > 0
43 timeout := os.args[2].int()
44 assert timeout > 0
45 spawn exit_after_timeout(timeout)
46
47 mut app := &ServerApp{
48 port: http_port
49 timeout: timeout
50 global_config: Config{
51 max_ping: 50
52 }
53 }
54 eprintln('>> webserver: pid: ${os.getpid()}, started on http://localhost:${app.port}/ , with maximum runtime of ${app.timeout} milliseconds.')
55 veb.run_at[ServerApp, ServerContext](mut app,
56 host: 'localhost'
57 port: http_port
58 family: .ip
59 timeout_in_seconds: 2
60 )!
61}
62
63// init_server stores the veb server handle when lifecycle control is available.
64pub fn (mut app ServerApp) init_server(server &veb.Server) {
65 app.server = server
66}
67
68pub fn (mut app ServerApp) index(mut ctx ServerContext) veb.Result {
69 assert app.global_config.max_ping == 50
70 return ctx.text('Welcome to veb')
71}
72
73pub fn (mut app ServerApp) simple(mut ctx ServerContext) veb.Result {
74 return ctx.text('A simple result')
75}
76
77pub fn (mut app ServerApp) html_page(mut ctx ServerContext) veb.Result {
78 return ctx.html('<h1>ok</h1>')
79}
80
81// the following serve custom routes
82@['/:user/settings']
83pub fn (mut app ServerApp) settings(mut ctx ServerContext, username string) veb.Result {
84 if username !in known_users {
85 return ctx.not_found()
86 }
87 return ctx.html('username: ${username}')
88}
89
90@['/:user/:repo/settings']
91pub fn (mut app ServerApp) user_repo_settings(mut ctx ServerContext, username string, repository string) veb.Result {
92 if username !in known_users {
93 return ctx.not_found()
94 }
95 return ctx.html('username: ${username} | repository: ${repository}')
96}
97
98@['/json_echo'; post]
99pub fn (mut app ServerApp) json_echo(mut ctx ServerContext) veb.Result {
100 ctx.set_content_type(ctx.req.header.get(.content_type) or { '' })
101 return ctx.ok(ctx.req.data)
102}
103
104@['/login'; post]
105pub fn (mut app ServerApp) login_form(mut ctx ServerContext, username string, password string) veb.Result {
106 return ctx.html('username: x${username}x | password: x${password}x')
107}
108
109@['/form_echo'; post]
110pub fn (mut app ServerApp) form_echo(mut ctx ServerContext) veb.Result {
111 ctx.set_content_type(ctx.req.header.get(.content_type) or { '' })
112 return ctx.ok(ctx.form['foo'])
113}
114
115@['/file_echo'; post]
116pub fn (mut app ServerApp) file_echo(mut ctx ServerContext) veb.Result {
117 if 'file' !in ctx.files {
118 ctx.res.set_status(.internal_server_error)
119 return ctx.text('no file')
120 }
121
122 return ctx.text(ctx.files['file'][0].data)
123}
124
125@['/query_echo']
126pub fn (mut app ServerApp) query_echo(mut ctx ServerContext, a string, b int) veb.Result {
127 return ctx.text('a: x${a}x | b: x${b}x')
128}
129
130// Make sure [post] works without the path
131@[post]
132pub fn (mut app ServerApp) json(mut ctx ServerContext) veb.Result {
133 ctx.set_content_type(ctx.req.header.get(.content_type) or { '' })
134 return ctx.ok(ctx.req.data)
135}
136
137@[host: 'example.com']
138@['/with_host']
139pub fn (mut app ServerApp) with_host(mut ctx ServerContext) veb.Result {
140 return ctx.ok('')
141}
142
143@['/empty_response_body']
144pub fn (mut app ServerApp) empty_response_body(mut ctx ServerContext) veb.Result {
145 return ctx.ok('')
146}
147
148pub fn (mut app ServerApp) shutdown(mut ctx ServerContext) veb.Result {
149 session_key := ctx.get_cookie('skey') or { return ctx.not_found() }
150 if session_key != 'superman' {
151 return ctx.not_found()
152 }
153 spawn app.exit_gracefully()
154 return ctx.ok('good bye')
155}
156
157fn (mut app ServerApp) exit_gracefully() {
158 eprintln('>> webserver: exit_gracefully')
159 time.sleep(100 * time.millisecond)
160 exit(0)
161}
162
163pub fn (mut app ServerApp) large_response(mut ctx ServerContext) veb.Result {
164 struct Tick {
165 date_time string
166 timestamp i64
167 value f64
168 }
169
170 mut arr := []Tick{}
171 for i in 0 .. 16000 {
172 arr << Tick{
173 date_time: i.str()
174 timestamp: i
175 value: i
176 }
177 }
178
179 return ctx.json(arr)
180}
181