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
Louis Pilfold
2 years ago
3962a615
f5f5bf38
+39
-43
5 changed files
expand all
collapse all
unified
split
.github
workflows
ci.yml
gleam.toml
manifest.toml
src
wisp
internal
logger.gleam
test
wisp_test.gleam
+1
-1
.github/workflows/ci.yml
···
14
14
- uses: erlef/setup-beam@v1
15
15
with:
16
16
otp-version: "26.0"
17
17
-
gleam-version: "0.32.4"
17
17
+
gleam-version: "0.34.0-rc2"
18
18
rebar3-version: "3"
19
19
# elixir-version: "1.14.2"
20
20
- run: gleam format --check src test
+1
-1
gleam.toml
···
11
11
12
12
[dependencies]
13
13
exception = "~> 1.0"
14
14
-
gleam_crypto = "~> 0.4"
14
14
+
gleam_crypto = "~> 1.0"
15
15
gleam_erlang = "~> 0.21"
16
16
gleam_http = "~> 3.5"
17
17
gleam_json = "~> 0.6"
+10
-11
manifest.toml
···
3
3
4
4
packages = [
5
5
{ name = "exception", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "5122A559032E971E060F0EB68FDCE5961506917D64612B4F7DD958B699BE4425" },
6
6
-
{ name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" },
7
7
-
{ name = "gleam_crypto", version = "0.5.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "B9F23F1902341FC94FA246FA21F11246665D9CE745D50CB3E719A16DA30AD569" },
8
8
-
{ name = "gleam_erlang", version = "0.23.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "DA7A8E5540948DE10EB01B530869F8FF2FF6CAD8CFDA87626CE6EF63EBBF87CB" },
9
9
-
{ name = "gleam_http", version = "3.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "0B09AAE8EB547C4F2F2D3F8917A0A4D2EF75DFF0232389332BAFE19DBBFDB92B" },
6
6
+
{ name = "gleam_crypto", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "DE1FC4E631CA374AB29CCAEAC043EE171B86114D7DC66DD483F0A93BF0C4C6FF" },
7
7
+
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
8
8
+
{ name = "gleam_http", version = "3.5.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "C2FC3322203B16F897C1818D9810F5DEFCE347F0751F3B44421E1261277A7373" },
10
9
{ name = "gleam_json", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "CB405BD93A8828BCD870463DE29375E7B2D252D9D124C109E5B618AAC00B86FC" },
11
11
-
{ name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" },
12
12
-
{ name = "gleam_stdlib", version = "0.32.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "ABF00CDCCB66FABBCE351A50060964C4ACE798F95A0D78622C8A7DC838792577" },
13
13
-
{ name = "gleeunit", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D3682ED8C5F9CAE1C928F2506DE91625588CC752495988CBE0F5653A42A6F334" },
14
14
-
{ name = "glisten", version = "0.9.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "glisten", source = "hex", outer_checksum = "C960B6CF25D4AABAB01211146E9B57E11827B9C49E4175217E0FB7EF5BCB0FF7" },
10
10
+
{ name = "gleam_otp", version = "0.9.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5FADBBEC5ECF3F8B6BE91101D432758503192AE2ADBAD5602158977341489F71" },
11
11
+
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
12
12
+
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
13
13
+
{ name = "glisten", version = "0.9.2", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_erlang", "gleam_otp"], otp_app = "glisten", source = "hex", outer_checksum = "C960B6CF25D4AABAB01211146E9B57E11827B9C49E4175217E0FB7EF5BCB0FF7" },
15
14
{ name = "marceau", version = "1.1.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "1AAD727A30BE0F95562C3403BB9B27C823797AD90037714255EEBF617B1CDA81" },
16
16
-
{ name = "mist", version = "0.14.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "glisten", "gleam_stdlib", "gleam_otp", "gleam_http"], otp_app = "mist", source = "hex", outer_checksum = "1AA0E3BB76A9B524800F31E1C94C4640FBB0890BC76B492DBAD541A392820BB3" },
17
17
-
{ name = "simplifile", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0BD6F0E7DA1A7E11D18B8AD48453225CAFCA4C8CFB4513D217B372D2866C501C" },
15
15
+
{ name = "mist", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_otp", "gleam_erlang", "gleam_http", "gleam_stdlib", "glisten"], otp_app = "mist", source = "hex", outer_checksum = "49F51DDB64D7B2832F72727CC9721C478D6B524C96EA444C601A19D01E023C03" },
16
16
+
{ name = "simplifile", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "359CD7006E2F69255025C858CCC6407C11A876EC179E6ED1E46809E8DC6B1AAD" },
18
17
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
19
18
]
20
19
21
20
[requirements]
22
21
exception = { version = "~> 1.0" }
23
23
-
gleam_crypto = { version = "~> 0.4" }
22
22
+
gleam_crypto = { version = "~> 1.0" }
24
23
gleam_erlang = { version = "~> 0.21" }
25
24
gleam_http = { version = "~> 3.5" }
26
25
gleam_json = { version = "~> 0.6" }
+5
-5
src/wisp/internal/logger.gleam
···
1
1
-
import gleam/map.{type Map}
1
1
+
import gleam/dict.{type Dict}
2
2
import gleam/erlang/atom.{type Atom}
3
3
import gleam/dynamic.{type Dynamic}
4
4
···
16
16
type DoNotLeak
17
17
18
18
pub fn configure_logger() -> Nil {
19
19
-
update_primary_config(map.from_list([
20
20
-
#(atom.create_from_string("level"), dynamic.from(Info)),
21
21
-
]))
19
19
+
update_primary_config(
20
20
+
dict.from_list([#(atom.create_from_string("level"), dynamic.from(Info))]),
21
21
+
)
22
22
Nil
23
23
}
24
24
25
25
@external(erlang, "logger", "update_primary_config")
26
26
-
fn update_primary_config(config: Map(Atom, Dynamic)) -> DoNotLeak
26
26
+
fn update_primary_config(config: Dict(Atom, Dynamic)) -> DoNotLeak
27
27
28
28
pub fn log(level: LogLevel, message: String) -> Nil {
29
29
erlang_log(level, message)
+22
-25
test/wisp_test.gleam
···
7
7
import gleam/http/response.{Response}
8
8
import gleam/int
9
9
import gleam/list
10
10
-
import gleam/map
10
10
+
import gleam/dict
11
11
import gleam/set
12
12
import gleam/string
13
13
import gleam/string_builder
···
513
513
|> request.set_header("content-type", "application/json")
514
514
|> json_handler(fn(json) {
515
515
json
516
516
-
|> should.equal(dynamic.from(map.from_list([#("one", 1), #("two", 2)])))
516
516
+
|> should.equal(dynamic.from(dict.from_list([#("one", 1), #("two", 2)])))
517
517
})
518
518
|> should.equal(wisp.ok())
519
519
}
···
678
678
}
679
679
680
680
pub fn multipart_form_files_too_big_test() {
681
681
-
let test = fn(limit, callback) {
681
681
+
let testcase = fn(limit, callback) {
682
682
"--theboundary\r
683
683
Content-Disposition: form-data; name=\"two\"; filename=\"file.txt\"\r
684
684
\r
···
702
702
|> form_handler(callback)
703
703
}
704
704
705
705
-
test(1, fn(_) { panic as "should be unreachable for limit of 1" })
705
705
+
testcase(1, fn(_) { panic as "should be unreachable for limit of 1" })
706
706
|> should.equal(Response(413, [], wisp.Empty))
707
707
708
708
-
test(2, fn(_) { panic as "should be unreachable for limit of 2" })
708
708
+
testcase(2, fn(_) { panic as "should be unreachable for limit of 2" })
709
709
|> should.equal(Response(413, [], wisp.Empty))
710
710
711
711
-
test(3, fn(_) { panic as "should be unreachable for limit of 3" })
711
711
+
testcase(3, fn(_) { panic as "should be unreachable for limit of 3" })
712
712
|> should.equal(Response(413, [], wisp.Empty))
713
713
714
714
-
test(4, fn(_) { Nil })
714
714
+
testcase(4, fn(_) { Nil })
715
715
|> should.equal(Response(200, [], wisp.Empty))
716
716
}
717
717
···
944
944
945
945
pub fn get_cookie_test() {
946
946
let request =
947
947
-
testing.get(
948
948
-
"/",
949
949
-
[
950
950
-
// Plain text
951
951
-
#("cookie", "plain=MTIz"),
952
952
-
// Signed
953
953
-
#(
954
954
-
"cookie",
955
955
-
"signed=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wA",
956
956
-
),
957
957
-
// Signed but tampered with
958
958
-
#(
959
959
-
"cookie",
960
960
-
"signed-and-tampered-with=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wAA",
961
961
-
),
962
962
-
],
963
963
-
)
947
947
+
testing.get("/", [
948
948
+
// Plain text
949
949
+
#("cookie", "plain=MTIz"),
950
950
+
// Signed
951
951
+
#(
952
952
+
"cookie",
953
953
+
"signed=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wA",
954
954
+
),
955
955
+
// Signed but tampered with
956
956
+
#(
957
957
+
"cookie",
958
958
+
"signed-and-tampered-with=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wAA",
959
959
+
),
960
960
+
])
964
961
965
962
request
966
963
|> wisp.get_cookie("plain", wisp.PlainText)
···
996
993
pub fn cookie_sign_roundtrip_test() {
997
994
use _ <- list.each(list.repeat(1, 10_000))
998
995
let message =
999
999
-
<<int.to_string(int.random(0, 1_000_000_000_000_000)):utf8>>
996
996
+
<<int.to_string(int.random(1_000_000_000_000_000)):utf8>>
1000
997
|> bit_array.base64_encode(True)
1001
998
let req = testing.get("/", [])
1002
999
let signed = wisp.sign_message(req, <<message:utf8>>, crypto.Sha512)