Skip to content

Commit c524bcb

Browse files
authored
Merge pull request #3 from aosasona/2-fix-lowercase-headers
Lowercase all header keys and prefer opt timeout
2 parents c4ca9b1 + 52b1574 commit c524bcb

File tree

7 files changed

+53
-23
lines changed

7 files changed

+53
-23
lines changed

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ jobs:
1313
- uses: erlef/setup-beam@v1
1414
with:
1515
otp-version: "26.0.2"
16-
gleam-version: "0.34.1"
16+
gleam-version: "1.0.0"
1717
rebar3-version: "3"
1818
- run: gleam publish --yes

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- uses: erlef/setup-beam@v1
1414
with:
1515
otp-version: "26.0.2"
16-
gleam-version: "0.34.1"
16+
gleam-version: "1.0.0"
1717
rebar3-version: "3"
1818
- run: gleam format --check src test
1919
- run: gleam deps download

gleam.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
name = "falcon"
2-
version = "1.0.1"
3-
gleam = ">= 0.33.0"
2+
version = "1.1.0"
3+
gleam = ">= 0.34.0"
44

55
# Fill out these fields if you intend to generate HTML documentation or publish
66
# your project to the Hex package manager.
77
#
8-
description = "A smoother way to send HTTP requests in Gleam with Axios-like APIs; an abstraction over Hackney."
8+
description = "A smoother way to send HTTP requests in Gleam with Axios-like APIs"
99
licences = ["Apache-2.0"]
1010
repository = { type = "github", user = "trulyao", repo = "falcon" }
1111
# links = [{ title = "Website", href = "https://gleam.run" }]
1212

1313
[dependencies]
1414
gleam_stdlib = "~> 0.34 or ~> 1.0"
15-
gleam_http = "~> 3.5"
15+
gleam_http = "~> 3.6"
16+
gleam_json = "~> 1.0"
1617
hackney = "~> 1.20"
17-
gleam_json = "~> 0.7"
1818

1919
[dev-dependencies]
2020
gleeunit = "~> 1.0"

manifest.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
packages = [
55
{ name = "certifi", version = "2.12.0", build_tools = ["rebar3"], requirements = [], otp_app = "certifi", source = "hex", outer_checksum = "EE68D85DF22E554040CDB4BE100F33873AC6051387BAF6A8F6CE82272340FF1C" },
6-
{ name = "gleam_http", version = "3.5.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "C2FC3322203B16F897C1818D9810F5DEFCE347F0751F3B44421E1261277A7373" },
7-
{ name = "gleam_json", version = "0.7.0", build_tools = ["gleam"], requirements = ["thoas", "gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "CB405BD93A8828BCD870463DE29375E7B2D252D9D124C109E5B618AAC00B86FC" },
6+
{ name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" },
7+
{ name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" },
88
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
99
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
10-
{ name = "hackney", version = "1.20.1", build_tools = ["rebar3"], requirements = ["metrics", "mimerl", "ssl_verify_fun", "certifi", "parse_trans", "unicode_util_compat", "idna"], otp_app = "hackney", source = "hex", outer_checksum = "FE9094E5F1A2A2C0A7D10918FEE36BFEC0EC2A979994CFF8CFE8058CD9AF38E3" },
10+
{ name = "hackney", version = "1.20.1", build_tools = ["rebar3"], requirements = ["certifi", "idna", "metrics", "mimerl", "parse_trans", "ssl_verify_fun", "unicode_util_compat"], otp_app = "hackney", source = "hex", outer_checksum = "FE9094E5F1A2A2C0A7D10918FEE36BFEC0EC2A979994CFF8CFE8058CD9AF38E3" },
1111
{ name = "idna", version = "6.1.1", build_tools = ["rebar3"], requirements = ["unicode_util_compat"], otp_app = "idna", source = "hex", outer_checksum = "92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA" },
1212
{ name = "metrics", version = "1.0.1", build_tools = ["rebar3"], requirements = [], otp_app = "metrics", source = "hex", outer_checksum = "69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16" },
1313
{ name = "mimerl", version = "1.2.0", build_tools = ["rebar3"], requirements = [], otp_app = "mimerl", source = "hex", outer_checksum = "F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323" },
@@ -18,8 +18,8 @@ packages = [
1818
]
1919

2020
[requirements]
21-
gleam_http = { version = "~> 3.5" }
22-
gleam_json = { version = "~> 0.7" }
21+
gleam_http = { version = "~> 3.6" }
22+
gleam_json = { version = "~> 1.0" }
2323
gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
2424
gleeunit = { version = "~> 1.0" }
25-
hackney = { version = "~> 1.20" }
25+
hackney = { version = "~> 1.20"}

src/falcon.gleam

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import falcon/core.{
33
}
44
import gleam/bool
55
import gleam/list
6+
import gleam/string
7+
import gleam/result
68
import gleam/http.{type Method, Delete, Get, Patch, Post, Put}
79
import gleam/option.{type Option, None, Some}
810
import falcon/hackney.{Timeout}
@@ -28,7 +30,8 @@ pub fn new(
2830
headers headers: Pairs,
2931
timeout timeout: Option(Int),
3032
) -> Client {
31-
Client(base_url: base_url, headers: headers, timeout: timeout)
33+
let normalized_headers = normalise_headers(headers)
34+
Client(base_url: base_url, headers: normalized_headers, timeout: timeout)
3235
}
3336

3437
fn filter_opts(opts: Opts, keep_headers keep_headers: Bool) -> Opts {
@@ -46,6 +49,10 @@ fn filter_opts(opts: Opts, keep_headers keep_headers: Bool) -> Opts {
4649
})
4750
}
4851

52+
fn normalise_headers(headers: Pairs) -> Pairs {
53+
list.map(headers, with: fn(pair) { #(string.lowercase(pair.0), pair.1) })
54+
}
55+
4956
pub fn extract_headers(opts: Opts) -> List(#(String, String)) {
5057
opts
5158
|> list.map(fn(opt) {
@@ -59,17 +66,29 @@ pub fn extract_headers(opts: Opts) -> List(#(String, String)) {
5966

6067
/// This is used internally to merge the client options with the request options, it is only exposed for testing purposes
6168
pub fn merge_opts(client: Client, opts: Opts) -> Opts {
62-
// There is a chance this will cause problems if you pass in a timeout in the client and another timeout in the options simply because we are not filtering out duplicates at the moment seeing as it might be too expensive to do that with every single request (it is nested - we'd have to look into opts and then filter out timeout from every single client options before putting them back together)
6369
let new_opts = case client.timeout {
64-
Some(timeout) -> list.concat([[ClientOptions([Timeout(timeout)])], opts])
70+
Some(timeout) -> {
71+
// If there is a timeout in the client options, we want to ignore it if there is a timeout in the request options
72+
let has_timeout =
73+
list.find(opts, fn(opt) {
74+
case opt {
75+
ClientOptions([Timeout(_)]) -> True
76+
_ -> False
77+
}
78+
})
79+
|> result.is_ok
80+
81+
use <- bool.guard(when: has_timeout, return: opts)
82+
list.concat([[ClientOptions([Timeout(timeout)])], opts])
83+
}
6584
None -> opts
6685
}
6786

68-
// Merge all headers into one list
6987
let headers =
7088
new_opts
7189
|> filter_opts(keep_headers: True)
7290
|> extract_headers
91+
|> normalise_headers
7392
|> fn(headers) { list.concat([client.headers, headers]) }
7493

7594
// Remove all headers from the original list and replace with the merged list

src/falcon/core.gleam

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,21 @@ pub fn error_to_string(err: FalconError) -> String {
9393
}
9494

9595
fn with_leading_slash(path: String) -> String {
96-
{
96+
let path = {
9797
use <- bool.guard(when: string.starts_with(path, "/"), return: path)
9898
"/" <> path
9999
}
100-
|> string.trim
100+
101+
string.trim(path)
101102
}
102103

103104
fn without_trailing_slash(path: String) -> String {
104-
{
105+
let path = {
105106
use <- bool.guard(when: !string.ends_with(path, "/"), return: path)
106107
string.slice(path, 0, string.length(path) - 1)
107108
}
108-
|> string.trim
109+
110+
string.trim(path)
109111
}
110112

111113
pub fn append_path(url: Url, path: String) -> Url {

test/falcon_test.gleam

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub fn merge_opts_test() {
237237
|> result.unwrap(None)
238238
|> should.equal(None)
239239

240-
// Test that all timeouts are kept if set
240+
// Test that only the new timeout is used
241241
let new_opts =
242242
new(Url("http://example.com"), [], Some(15_000))
243243
|> merge_opts([ClientOptions([Timeout(30_000)])])
@@ -248,12 +248,21 @@ pub fn merge_opts_test() {
248248

249249
new_opts
250250
|> extract_timeouts
251-
|> should.equal([Some(15_000), Some(30_000)])
251+
|> should.equal([Some(30_000)])
252252

253253
// Test that the last timeout provided by the user in the request itself is used instead of the default
254254
new(Url("http://example.com"), [], Some(15_000))
255255
|> merge_opts([ClientOptions([Timeout(30_000), Timeout(10_000)])])
256256
|> extract_timeouts
257257
|> list.last
258258
|> should.equal(Ok(Some(10_000)))
259+
260+
// Test for case sensitivity in headers
261+
let new_opts =
262+
new(Url("http://example.com"), [#("X-Api-Key", "default")], Some(5000))
263+
|> merge_opts([Headers([#("X-AnoTher-Mixed-Case", "test")])])
264+
265+
new_opts
266+
|> extract_headers
267+
|> should.equal([#("x-api-key", "default"), #("x-another-mixed-case", "test")])
259268
}

0 commit comments

Comments
 (0)