tangled
alpha
login
or
join now
keii.dev
/
wisp
3
fork
atom
🧚 A practical web framework for Gleam
3
fork
atom
overview
issues
pulls
pipelines
Update application
Louis Pilfold
2 years ago
1a26d9c4
02aaacd1
+55
-15
2 changed files
expand all
collapse all
unified
split
action
test
action_test.gleam
framework
src
framework.gleam
+3
-3
action/test/action_test.gleam
···
4
4
import action/web.{Context}
5
5
import action/database
6
6
import gleam/string
7
7
-
import gleam/http/request.{Request}
7
7
+
import gleam/http/request
8
8
import gleam/http.{Get, Method, Post}
9
9
import gleam/string_builder
10
10
import framework
···
20
20
}
21
21
22
22
// TODO: move this to a helper module
23
23
-
pub fn request(method: Method, path: String) -> Request(BitString) {
23
23
+
pub fn request(method: Method, path: String) -> framework.Request {
24
24
request.new()
25
25
|> request.set_method(method)
26
26
|> request.set_path(path)
27
27
-
|> request.set_body(<<>>)
27
27
+
|> request.set_body(framework.test_connection(<<>>))
28
28
}
29
29
30
30
// TODO: move this to a helper module
+52
-12
framework/src/framework.gleam
···
1
1
+
// - [ ] Test helpers
2
2
+
// - [ ] Body reading
3
3
+
// - [ ] Form data
4
4
+
// - [ ] Multipart
5
5
+
// - [ ] Json
6
6
+
// - [ ] String
7
7
+
// - [ ] Bit string
8
8
+
// - [ ] Body writing
9
9
+
// - [x] Html
10
10
+
// - [x] Json
11
11
+
// - [ ] Static files
12
12
+
// - [ ] Cookies
13
13
+
// - [ ] Signed cookies
14
14
+
// - [ ] Secret keys
15
15
+
// - [ ] Key rotation
16
16
+
// - [ ] Sessions
17
17
+
// - [ ] Flash messages
18
18
+
// - [ ] Websockets
19
19
+
// - [ ] CSRF
20
20
+
// - [ ] Project generators
21
21
+
// - [ ] Exception recovery
22
22
+
1
23
import gleam/string_builder.{StringBuilder}
2
24
import gleam/bit_builder.{BitBuilder}
3
25
import gleam/bit_string
···
15
37
// Running the server
16
38
//
17
39
40
40
+
// TODO: test
41
41
+
// TODO: document
18
42
pub fn mist_service(
19
43
service: fn(Request) -> Response,
20
44
) -> fn(HttpRequest(mist.Connection)) -> HttpResponse(mist.ResponseData) {
21
45
fn(request: HttpRequest(_)) {
22
22
-
let connection =
23
23
-
Connection(
24
24
-
reader: mist_body_reader(request),
25
25
-
max_body_size: 8_000_000,
26
26
-
max_files_size: 32_000_000,
27
27
-
read_chunk_size: 1_000_000,
28
28
-
)
46
46
+
let connection = make_connection(mist_body_reader(request))
29
47
request
30
48
|> request.set_body(connection)
31
49
|> service
···
33
51
}
34
52
}
35
53
54
54
+
fn make_connection(body_reader: Reader) -> Connection {
55
55
+
Connection(
56
56
+
reader: body_reader,
57
57
+
max_body_size: 8_000_000,
58
58
+
max_files_size: 32_000_000,
59
59
+
read_chunk_size: 1_000_000,
60
60
+
)
61
61
+
}
62
62
+
36
63
fn mist_body_reader(request: HttpRequest(mist.Connection)) -> Reader {
37
64
case mist.stream(request) {
38
65
Error(_) -> fn(_) { Ok(ReadingFinished) }
···
67
94
// Responses
68
95
//
69
96
70
70
-
pub type Body {
97
97
+
pub type ResponseBody {
71
98
Empty
72
99
Text(StringBuilder)
73
100
}
74
101
75
75
-
/// An alias for a HTTP response containing a `Body`.
102
102
+
/// An alias for a HTTP response containing a `ResponseBody`.
76
103
pub type Response =
77
77
-
HttpResponse(Body)
104
104
+
HttpResponse(ResponseBody)
78
105
79
106
// TODO: test
80
107
// TODO: document
···
120
147
121
148
// TODO: test
122
149
// TODO: document
123
123
-
pub fn body_to_string_builder(body: Body) -> StringBuilder {
150
150
+
pub fn body_to_string_builder(body: ResponseBody) -> StringBuilder {
124
151
case body {
125
152
Empty -> string_builder.new()
126
153
Text(text) -> text
···
129
156
130
157
// TODO: test
131
158
// TODO: document
132
132
-
pub fn body_to_bit_builder(body: Body) -> BitBuilder {
159
159
+
pub fn body_to_bit_builder(body: ResponseBody) -> BitBuilder {
133
160
case body {
134
161
Empty -> bit_builder.new()
135
162
Text(text) -> bit_builder.from_string_builder(text)
···
246
273
// TODO: document
247
274
// TODO: note you probably want a `require_` function
248
275
// TODO: note it'll hang if you call it twice
276
276
+
// TODO: note it respects the max body size
249
277
fn read_entire_body(request: Request) -> Result(BitString, Nil) {
250
278
let connection = request.body
251
279
read_body_loop(
···
298
326
Error(_) -> bad_request()
299
327
}
300
328
}
329
329
+
330
330
+
//
331
331
+
// Testing
332
332
+
//
333
333
+
334
334
+
// TODO: test
335
335
+
// TODO: document
336
336
+
pub fn test_connection(body: BitString) -> Connection {
337
337
+
make_connection(fn(_size) {
338
338
+
Ok(Chunk(body, fn(_size) { Ok(ReadingFinished) }))
339
339
+
})
340
340
+
}