/
http.gleam
130 lines (118 loc) · 2.91 KB
/
http.gleam
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//// Functions for working with HTTP data structures in Gleam.
////
//// This module makes it easy to create and modify Requests and Responses, data types.
//// A general HTTP message type is defined that enables functions to work on both requests and responses.
////
//// This module does not implement a HTTP client or HTTP server, but it can be used as a base for them.
import gleam/bit_string
import gleam/dynamic.{DecodeError, Dynamic}
import gleam/int
import gleam/list
import gleam/option
import gleam/regex
import gleam/result
import gleam/string
import gleam/string_builder
import gleam/uri
/// HTTP standard method as defined by [RFC 2616](https://tools.ietf.org/html/rfc2616),
/// and PATCH which is defined by [RFC 5789](https://tools.ietf.org/html/rfc5789).
pub type Method {
Get
Post
Head
Put
Delete
Trace
Connect
Options
Patch
/// Non-standard but valid HTTP methods.
Other(String)
}
// TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the
// spec) and return Ok(Other(s)) if so.
pub fn parse_method(s) -> Result(Method, Nil) {
case string.lowercase(s) {
"connect" -> Ok(Connect)
"delete" -> Ok(Delete)
"get" -> Ok(Get)
"head" -> Ok(Head)
"options" -> Ok(Options)
"patch" -> Ok(Patch)
"post" -> Ok(Post)
"put" -> Ok(Put)
"trace" -> Ok(Trace)
_ -> Error(Nil)
}
}
pub fn method_to_string(method: Method) -> String {
case method {
Connect -> "connect"
Delete -> "delete"
Get -> "get"
Head -> "head"
Options -> "options"
Patch -> "patch"
Post -> "post"
Put -> "put"
Trace -> "trace"
Other(s) -> s
}
}
/// The two URI schemes for HTTP
///
pub type Scheme {
Http
Https
}
/// Convert a scheme into a string.
///
/// # Examples
///
/// > scheme_to_string(Http)
/// "http"
///
/// > scheme_to_string(Https)
/// "https"
///
pub fn scheme_to_string(scheme: Scheme) -> String {
case scheme {
Http -> "http"
Https -> "https"
}
}
/// Parse a HTTP scheme from a string
///
/// # Examples
///
/// > scheme_to_string("http")
/// Ok(Http)
///
/// > scheme_to_string("ftp")
/// Error(Nil)
///
pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) {
case string.lowercase(scheme) {
"http" -> Ok(Http)
"https" -> Ok(Https)
_ -> Error(Nil)
}
}
pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) {
case do_method_from_dynamic(value) {
Ok(method) -> Ok(method)
Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])])
}
}
if erlang {
external fn do_method_from_dynamic(Dynamic) -> Result(Method, nil) =
"gleam_http_native" "decode_method"
}
if javascript {
external fn do_method_from_dynamic(Dynamic) -> Result(Method, Nil) =
"../gleam_http_native.mjs" "decode_method"
}
/// A HTTP header is a key-value pair. Header keys should be all lowercase
/// characters.
pub type Header =
#(String, String)