Current section
34 Versions
Jump to
Current section
34 Versions
Compare versions
12
files changed
+507
additions
-315
deletions
| @@ -8,12 +8,12 @@ Types and functions for HTTP clients and servers! | |
| 8 8 | import gleam/http/elli |
| 9 9 | import gleam/http/response.{type Response} |
| 10 10 | import gleam/http/request.{type Request} |
| 11 | - import gleam/bytes_builder.{type BytesBuilder} |
| 11 | + import gleam/bytes_tree.{type BytesTree} |
| 12 12 | |
| 13 13 | // Define a HTTP service |
| 14 14 | // |
| 15 | - pub fn my_service(_request: Request(t)) -> Response(BytesBuilder) { |
| 16 | - let body = bytes_builder.from_string("Hello, world!") |
| 15 | + pub fn my_service(_request: Request(t)) -> Response(BytesTree) { |
| 16 | + let body = bytes_tree.from_string("Hello, world!") |
| 17 17 | |
| 18 18 | response.new(200) |
| 19 19 | |> response.prepend_header("made-with", "Gleam") |
| @@ -1,5 +1,5 @@ | |
| 1 1 | name = "gleam_http" |
| 2 | - version = "3.7.2" |
| 2 | + version = "4.0.0" |
| 3 3 | licences = ["Apache-2.0"] |
| 4 4 | description = "Types and functions for Gleam HTTP clients and servers" |
| 5 5 | gleam = ">= 1.0.0" |
| @@ -1,6 +1,6 @@ | |
| 1 1 | {<<"name">>, <<"gleam_http">>}. |
| 2 2 | {<<"app">>, <<"gleam_http">>}. |
| 3 | - {<<"version">>, <<"3.7.2">>}. |
| 3 | + {<<"version">>, <<"4.0.0">>}. |
| 4 4 | {<<"description">>, <<"Types and functions for Gleam HTTP clients and servers"/utf8>>}. |
| 5 5 | {<<"licenses">>, [<<"Apache-2.0">>]}. |
| 6 6 | {<<"build_tools">>, [<<"gleam">>]}. |
| @@ -37,7 +37,5 @@ | |
| 37 37 | <<"src/gleam@http@request.erl">>, |
| 38 38 | <<"src/gleam@http@response.erl">>, |
| 39 39 | <<"src/gleam@http@service.erl">>, |
| 40 | - <<"src/gleam_http.app.src">>, |
| 41 | - <<"src/gleam_http_native.erl">>, |
| 42 | - <<"src/gleam_http_native.mjs">> |
| 40 | + <<"src/gleam_http.app.src">> |
| 43 41 | ]}. |
| @@ -7,7 +7,6 @@ | |
| 7 7 | |
| 8 8 | import gleam/bit_array |
| 9 9 | import gleam/bool |
| 10 | - import gleam/dynamic.{type DecodeError, type Dynamic, DecodeError} |
| 11 10 | import gleam/list |
| 12 11 | import gleam/result |
| 13 12 | import gleam/string |
| @@ -29,34 +28,81 @@ pub type Method { | |
| 29 28 | Other(String) |
| 30 29 | } |
| 31 30 | |
| 31 | + // A token is defined as: |
| 32 | + // |
| 33 | + // token = 1*tchar |
| 34 | + // |
| 35 | + // tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" |
| 36 | + // / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" |
| 37 | + // / DIGIT / ALPHA |
| 38 | + // ; any VCHAR, except delimiters |
| 39 | + // |
| 40 | + // (From https://www.rfc-editor.org/rfc/rfc9110.html#name-tokens) |
| 41 | + // |
| 42 | + // Where DIGIT = %x30-39 |
| 43 | + // ALPHA = %x41-5A / %x61-7A |
| 44 | + // (%xXX is a hexadecimal ASCII value) |
| 45 | + // |
| 46 | + // (From https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1) |
| 47 | + // |
| 48 | + fn is_valid_token(s: String) -> Bool { |
| 49 | + bit_array.from_string(s) |
| 50 | + |> do_is_valid_token(True) |
| 51 | + } |
| 52 | + |
| 53 | + fn do_is_valid_token(bytes: BitArray, acc: Bool) { |
| 54 | + case bytes, acc { |
| 55 | + <<char, rest:bytes>>, True -> do_is_valid_token(rest, is_valid_tchar(char)) |
| 56 | + _, _ -> acc |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + fn is_valid_tchar(ch: Int) -> Bool { |
| 61 | + case ch { |
| 62 | + // "!" | "#" | "$" | "%" | "&" | "'" | "*" | "+" | "-" |
| 63 | + // | "." | "^" | "_" | "`" | "|" | "~" |
| 64 | + 33 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 45 | 46 | 94 | 95 | 96 | 124 | 126 -> |
| 65 | + True |
| 66 | + // DIGIT |
| 67 | + ch if ch >= 0x30 && ch <= 0x39 -> True |
| 68 | + // ALPHA |
| 69 | + ch if ch >= 0x41 && ch <= 0x5A || ch >= 0x61 && ch <= 0x7A -> True |
| 70 | + _ -> False |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 32 74 | // TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the |
| 33 75 | // spec) and return Ok(Other(s)) if so. |
| 34 76 | pub fn parse_method(s) -> Result(Method, Nil) { |
| 35 | - case string.lowercase(s) { |
| 36 | - "connect" -> Ok(Connect) |
| 37 | - "delete" -> Ok(Delete) |
| 38 | - "get" -> Ok(Get) |
| 39 | - "head" -> Ok(Head) |
| 40 | - "options" -> Ok(Options) |
| 41 | - "patch" -> Ok(Patch) |
| 42 | - "post" -> Ok(Post) |
| 43 | - "put" -> Ok(Put) |
| 44 | - "trace" -> Ok(Trace) |
| 45 | - _ -> Error(Nil) |
| 77 | + case s { |
| 78 | + "CONNECT" -> Ok(Connect) |
| 79 | + "DELETE" -> Ok(Delete) |
| 80 | + "GET" -> Ok(Get) |
| 81 | + "HEAD" -> Ok(Head) |
| 82 | + "OPTIONS" -> Ok(Options) |
| 83 | + "PATCH" -> Ok(Patch) |
| 84 | + "POST" -> Ok(Post) |
| 85 | + "PUT" -> Ok(Put) |
| 86 | + "TRACE" -> Ok(Trace) |
| 87 | + s -> |
| 88 | + case is_valid_token(s) { |
| 89 | + True -> Ok(Other(s)) |
| 90 | + False -> Error(Nil) |
| 91 | + } |
| 46 92 | } |
| 47 93 | } |
| 48 94 | |
| 49 95 | pub fn method_to_string(method: Method) -> String { |
| 50 96 | case method { |
| 51 | - Connect -> "connect" |
| 52 | - Delete -> "delete" |
| 53 | - Get -> "get" |
| 54 | - Head -> "head" |
| 55 | - Options -> "options" |
| 56 | - Patch -> "patch" |
| 57 | - Post -> "post" |
| 58 | - Put -> "put" |
| 59 | - Trace -> "trace" |
| 97 | + Connect -> "CONNECT" |
| 98 | + Delete -> "DELETE" |
| 99 | + Get -> "GET" |
| 100 | + Head -> "HEAD" |
| 101 | + Options -> "OPTIONS" |
| 102 | + Patch -> "PATCH" |
| 103 | + Post -> "POST" |
| 104 | + Put -> "PUT" |
| 105 | + Trace -> "TRACE" |
| 60 106 | Other(s) -> s |
| 61 107 | } |
| 62 108 | } |
| @@ -103,13 +149,6 @@ pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) { | |
| 103 149 | } |
| 104 150 | } |
| 105 151 | |
| 106 | - pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) { |
| 107 | - case do_method_from_dynamic(value) { |
| 108 | - Ok(method) -> Ok(method) |
| 109 | - Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])]) |
| 110 | - } |
| 111 | - } |
| 112 | - |
| 113 152 | pub type MultipartHeaders { |
| 114 153 | /// The headers for the part have been fully parsed. |
| 115 154 | /// Header keys are all lowercase. |
| @@ -553,10 +592,6 @@ fn more_please_body( | |
| 553 592 | |> Ok |
| 554 593 | } |
| 555 594 | |
| 556 | - @external(erlang, "gleam_http_native", "decode_method") |
| 557 | - @external(javascript, "../gleam_http_native.mjs", "decode_method") |
| 558 | - fn do_method_from_dynamic(a: Dynamic) -> Result(Method, Nil) |
| 559 | - |
| 560 595 | /// A HTTP header is a key-value pair. Header keys must be all lowercase |
| 561 596 | /// characters. |
| 562 597 | pub type Header = |
| @@ -1,9 +1,26 @@ | |
| 1 1 | -module(gleam@http). |
| 2 2 | -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). |
| 3 3 | |
| 4 | - -export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, parse_content_disposition/1, parse_multipart_body/2, method_from_dynamic/1, parse_multipart_headers/2]). |
| 4 | + -export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, parse_content_disposition/1, parse_multipart_body/2, parse_multipart_headers/2]). |
| 5 5 | -export_type([method/0, scheme/0, multipart_headers/0, multipart_body/0, content_disposition/0]). |
| 6 6 | |
| 7 | + -if(?OTP_RELEASE >= 27). |
| 8 | + -define(MODULEDOC(Str), -moduledoc(Str)). |
| 9 | + -define(DOC(Str), -doc(Str)). |
| 10 | + -else. |
| 11 | + -define(MODULEDOC(Str), -compile([])). |
| 12 | + -define(DOC(Str), -compile([])). |
| 13 | + -endif. |
| 14 | + |
| 15 | + ?MODULEDOC( |
| 16 | + " Functions for working with HTTP data structures in Gleam.\n" |
| 17 | + "\n" |
| 18 | + " This module makes it easy to create and modify Requests and Responses, data types.\n" |
| 19 | + " A general HTTP message type is defined that enables functions to work on both requests and responses.\n" |
| 20 | + "\n" |
| 21 | + " This module does not implement a HTTP client or HTTP server, but it can be used as a base for them.\n" |
| 22 | + ). |
| 23 | + |
| 7 24 | -type method() :: get | |
| 8 25 | post | |
| 9 26 | head | |
| @@ -32,77 +49,170 @@ | |
| 32 49 | binary(), |
| 33 50 | list({binary(), binary()})}. |
| 34 51 | |
| 35 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 34). |
| 36 | - -spec parse_method(binary()) -> {ok, method()} | {error, nil}. |
| 37 | - parse_method(S) -> |
| 38 | - case string:lowercase(S) of |
| 39 | - <<"connect"/utf8>> -> |
| 40 | - {ok, connect}; |
| 52 | + -file("src/gleam/http.gleam", 60). |
| 53 | + -spec is_valid_tchar(integer()) -> boolean(). |
| 54 | + is_valid_tchar(Ch) -> |
| 55 | + case Ch of |
| 56 | + 33 -> |
| 57 | + true; |
| 41 58 | |
| 42 | - <<"delete"/utf8>> -> |
| 43 | - {ok, delete}; |
| 59 | + 35 -> |
| 60 | + true; |
| 44 61 | |
| 45 | - <<"get"/utf8>> -> |
| 46 | - {ok, get}; |
| 62 | + 36 -> |
| 63 | + true; |
| 47 64 | |
| 48 | - <<"head"/utf8>> -> |
| 49 | - {ok, head}; |
| 65 | + 37 -> |
| 66 | + true; |
| 50 67 | |
| 51 | - <<"options"/utf8>> -> |
| 52 | - {ok, options}; |
| 68 | + 38 -> |
| 69 | + true; |
| 53 70 | |
| 54 | - <<"patch"/utf8>> -> |
| 55 | - {ok, patch}; |
| 71 | + 39 -> |
| 72 | + true; |
| 56 73 | |
| 57 | - <<"post"/utf8>> -> |
| 58 | - {ok, post}; |
| 74 | + 42 -> |
| 75 | + true; |
| 59 76 | |
| 60 | - <<"put"/utf8>> -> |
| 61 | - {ok, put}; |
| 77 | + 43 -> |
| 78 | + true; |
| 62 79 | |
| 63 | - <<"trace"/utf8>> -> |
| 64 | - {ok, trace}; |
| 80 | + 45 -> |
| 81 | + true; |
| 82 | + |
| 83 | + 46 -> |
| 84 | + true; |
| 85 | + |
| 86 | + 94 -> |
| 87 | + true; |
| 88 | + |
| 89 | + 95 -> |
| 90 | + true; |
| 91 | + |
| 92 | + 96 -> |
| 93 | + true; |
| 94 | + |
| 95 | + 124 -> |
| 96 | + true; |
| 97 | + |
| 98 | + 126 -> |
| 99 | + true; |
| 100 | + |
| 101 | + Ch@1 when (Ch@1 >= 16#30) andalso (Ch@1 =< 16#39) -> |
| 102 | + true; |
| 103 | + |
| 104 | + Ch@2 when ((Ch@2 >= 16#41) andalso (Ch@2 =< 16#5A)) orelse ((Ch@2 >= 16#61) andalso (Ch@2 =< 16#7A)) -> |
| 105 | + true; |
| 65 106 | |
| 66 107 | _ -> |
| 67 | - {error, nil} |
| 108 | + false |
| 68 109 | end. |
| 69 110 | |
| 70 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 49). |
| 111 | + -file("src/gleam/http.gleam", 53). |
| 112 | + -spec do_is_valid_token(bitstring(), boolean()) -> boolean(). |
| 113 | + do_is_valid_token(Bytes, Acc) -> |
| 114 | + case {Bytes, Acc} of |
| 115 | + {<<Char, Rest/binary>>, true} -> |
| 116 | + do_is_valid_token(Rest, is_valid_tchar(Char)); |
| 117 | + |
| 118 | + {_, _} -> |
| 119 | + Acc |
| 120 | + end. |
| 121 | + |
| 122 | + -file("src/gleam/http.gleam", 48). |
| 123 | + -spec is_valid_token(binary()) -> boolean(). |
| 124 | + is_valid_token(S) -> |
| 125 | + _pipe = gleam_stdlib:identity(S), |
| 126 | + do_is_valid_token(_pipe, true). |
| 127 | + |
| 128 | + -file("src/gleam/http.gleam", 76). |
| 129 | + -spec parse_method(binary()) -> {ok, method()} | {error, nil}. |
| 130 | + parse_method(S) -> |
| 131 | + case S of |
| 132 | + <<"CONNECT"/utf8>> -> |
| 133 | + {ok, connect}; |
| 134 | + |
| 135 | + <<"DELETE"/utf8>> -> |
| 136 | + {ok, delete}; |
| 137 | + |
| 138 | + <<"GET"/utf8>> -> |
| 139 | + {ok, get}; |
| 140 | + |
| 141 | + <<"HEAD"/utf8>> -> |
| 142 | + {ok, head}; |
| 143 | + |
| 144 | + <<"OPTIONS"/utf8>> -> |
| 145 | + {ok, options}; |
| 146 | + |
| 147 | + <<"PATCH"/utf8>> -> |
| 148 | + {ok, patch}; |
| 149 | + |
| 150 | + <<"POST"/utf8>> -> |
| 151 | + {ok, post}; |
| 152 | + |
| 153 | + <<"PUT"/utf8>> -> |
| 154 | + {ok, put}; |
| 155 | + |
| 156 | + <<"TRACE"/utf8>> -> |
| 157 | + {ok, trace}; |
| 158 | + |
| 159 | + S@1 -> |
| 160 | + case is_valid_token(S@1) of |
| 161 | + true -> |
| 162 | + {ok, {other, S@1}}; |
| 163 | + |
| 164 | + false -> |
| 165 | + {error, nil} |
| 166 | + end |
| 167 | + end. |
| 168 | + |
| 169 | + -file("src/gleam/http.gleam", 95). |
| 71 170 | -spec method_to_string(method()) -> binary(). |
| 72 171 | method_to_string(Method) -> |
| 73 172 | case Method of |
| 74 173 | connect -> |
| 75 | - <<"connect"/utf8>>; |
| 174 | + <<"CONNECT"/utf8>>; |
| 76 175 | |
| 77 176 | delete -> |
| 78 | - <<"delete"/utf8>>; |
| 177 | + <<"DELETE"/utf8>>; |
| 79 178 | |
| 80 179 | get -> |
| 81 | - <<"get"/utf8>>; |
| 180 | + <<"GET"/utf8>>; |
| 82 181 | |
| 83 182 | head -> |
| 84 | - <<"head"/utf8>>; |
| 183 | + <<"HEAD"/utf8>>; |
| 85 184 | |
| 86 185 | options -> |
| 87 | - <<"options"/utf8>>; |
| 186 | + <<"OPTIONS"/utf8>>; |
| 88 187 | |
| 89 188 | patch -> |
| 90 | - <<"patch"/utf8>>; |
| 189 | + <<"PATCH"/utf8>>; |
| 91 190 | |
| 92 191 | post -> |
| 93 | - <<"post"/utf8>>; |
| 192 | + <<"POST"/utf8>>; |
| 94 193 | |
| 95 194 | put -> |
| 96 | - <<"put"/utf8>>; |
| 195 | + <<"PUT"/utf8>>; |
| 97 196 | |
| 98 197 | trace -> |
| 99 | - <<"trace"/utf8>>; |
| 198 | + <<"TRACE"/utf8>>; |
| 100 199 | |
| 101 200 | {other, S} -> |
| 102 201 | S |
| 103 202 | end. |
| 104 203 | |
| 105 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 81). |
| 204 | + -file("src/gleam/http.gleam", 127). |
| 205 | + ?DOC( |
| 206 | + " Convert a scheme into a string.\n" |
| 207 | + "\n" |
| 208 | + " # Examples\n" |
| 209 | + "\n" |
| 210 | + " > scheme_to_string(Http)\n" |
| 211 | + " \"http\"\n" |
| 212 | + "\n" |
| 213 | + " > scheme_to_string(Https)\n" |
| 214 | + " \"https\"\n" |
| 215 | + ). |
| 106 216 | -spec scheme_to_string(scheme()) -> binary(). |
| 107 217 | scheme_to_string(Scheme) -> |
| 108 218 | case Scheme of |
| @@ -113,7 +223,18 @@ scheme_to_string(Scheme) -> | |
| 113 223 | <<"https"/utf8>> |
| 114 224 | end. |
| 115 225 | |
| 116 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 98). |
| 226 | + -file("src/gleam/http.gleam", 144). |
| 227 | + ?DOC( |
| 228 | + " Parse a HTTP scheme from a string\n" |
| 229 | + "\n" |
| 230 | + " # Examples\n" |
| 231 | + "\n" |
| 232 | + " > scheme_from_string(\"http\")\n" |
| 233 | + " Ok(Http)\n" |
| 234 | + "\n" |
| 235 | + " > scheme_from_string(\"ftp\")\n" |
| 236 | + " Error(Nil)\n" |
| 237 | + ). |
| 117 238 | -spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}. |
| 118 239 | scheme_from_string(Scheme) -> |
| 119 240 | case string:lowercase(Scheme) of |
| @@ -127,7 +248,7 @@ scheme_from_string(Scheme) -> | |
| 127 248 | {error, nil} |
| 128 249 | end. |
| 129 250 | |
| 130 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 337). |
| 251 | + -file("src/gleam/http.gleam", 376). |
| 131 252 | -spec skip_whitespace(bitstring()) -> bitstring(). |
| 132 253 | skip_whitespace(Data) -> |
| 133 254 | case Data of |
| @@ -141,7 +262,7 @@ skip_whitespace(Data) -> | |
| 141 262 | Data |
| 142 263 | end. |
| 143 264 | |
| 144 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 427). |
| 265 | + -file("src/gleam/http.gleam", 466). |
| 145 266 | -spec more_please_headers( |
| 146 267 | fun((bitstring()) -> {ok, multipart_headers()} | {error, nil}), |
| 147 268 | bitstring() |
| @@ -159,7 +280,7 @@ more_please_headers(Continuation, Existing) -> | |
| 159 280 | ) |
| 160 281 | end}}. |
| 161 282 | |
| 162 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 508). |
| 283 | + -file("src/gleam/http.gleam", 547). |
| 163 284 | -spec parse_rfc_2045_parameter_quoted_value(binary(), binary(), binary()) -> {ok, |
| 164 285 | {{binary(), binary()}, binary()}} | |
| 165 286 | {error, nil}. |
| @@ -192,7 +313,7 @@ parse_rfc_2045_parameter_quoted_value(Header, Name, Value) -> | |
| 192 313 | ) |
| 193 314 | end. |
| 194 315 | |
| 195 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 525). |
| 316 | + -file("src/gleam/http.gleam", 564). |
| 196 317 | -spec parse_rfc_2045_parameter_unquoted_value(binary(), binary(), binary()) -> {{binary(), |
| 197 318 | binary()}, |
| 198 319 | binary()}. |
| @@ -218,7 +339,7 @@ parse_rfc_2045_parameter_unquoted_value(Header, Name, Value) -> | |
| 218 339 | ) |
| 219 340 | end. |
| 220 341 | |
| 221 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 496). |
| 342 | + -file("src/gleam/http.gleam", 535). |
| 222 343 | -spec parse_rfc_2045_parameter_value(binary(), binary()) -> {ok, |
| 223 344 | {{binary(), binary()}, binary()}} | |
| 224 345 | {error, nil}. |
| @@ -235,7 +356,7 @@ parse_rfc_2045_parameter_value(Header, Name) -> | |
| 235 356 | parse_rfc_2045_parameter_unquoted_value(Rest@1, Name, Grapheme)} |
| 236 357 | end. |
| 237 358 | |
| 238 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 485). |
| 359 | + -file("src/gleam/http.gleam", 524). |
| 239 360 | -spec parse_rfc_2045_parameter(binary(), binary()) -> {ok, |
| 240 361 | {{binary(), binary()}, binary()}} | |
| 241 362 | {error, nil}. |
| @@ -257,7 +378,7 @@ parse_rfc_2045_parameter(Header, Name) -> | |
| 257 378 | end |
| 258 379 | ). |
| 259 380 | |
| 260 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 467). |
| 381 | + -file("src/gleam/http.gleam", 506). |
| 261 382 | -spec parse_rfc_2045_parameters(binary(), list({binary(), binary()})) -> {ok, |
| 262 383 | list({binary(), binary()})} | |
| 263 384 | {error, nil}. |
| @@ -286,7 +407,7 @@ parse_rfc_2045_parameters(Header, Parameters) -> | |
| 286 407 | ) |
| 287 408 | end. |
| 288 409 | |
| 289 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 449). |
| 410 | + -file("src/gleam/http.gleam", 488). |
| 290 411 | -spec parse_content_disposition_type(binary(), binary()) -> {ok, |
| 291 412 | content_disposition()} | |
| 292 413 | {error, nil}. |
| @@ -323,13 +444,13 @@ parse_content_disposition_type(Header, Name) -> | |
| 323 444 | ) |
| 324 445 | end. |
| 325 446 | |
| 326 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 443). |
| 447 | + -file("src/gleam/http.gleam", 482). |
| 327 448 | -spec parse_content_disposition(binary()) -> {ok, content_disposition()} | |
| 328 449 | {error, nil}. |
| 329 450 | parse_content_disposition(Header) -> |
| 330 451 | parse_content_disposition_type(Header, <<""/utf8>>). |
| 331 452 | |
| 332 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 543). |
| 453 | + -file("src/gleam/http.gleam", 582). |
| 333 454 | -spec more_please_body( |
| 334 455 | fun((bitstring()) -> {ok, multipart_body()} | {error, nil}), |
| 335 456 | bitstring(), |
| @@ -346,7 +467,7 @@ more_please_body(Continuation, Chunk, Existing) -> | |
| 346 467 | _pipe@1 = {more_required_for_body, Chunk, _pipe}, |
| 347 468 | {ok, _pipe@1}. |
| 348 469 | |
| 349 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 216). |
| 470 | + -file("src/gleam/http.gleam", 255). |
| 350 471 | -spec parse_body_loop(bitstring(), bitstring(), bitstring()) -> {ok, |
| 351 472 | multipart_body()} | |
| 352 473 | {error, nil}. |
| @@ -394,10 +515,10 @@ parse_body_loop(Data, Boundary, Body) -> | |
| 394 515 | message => <<"unreachable"/utf8>>, |
| 395 516 | module => <<"gleam/http"/utf8>>, |
| 396 517 | function => <<"parse_body_loop"/utf8>>, |
| 397 | - line => 257}) |
| 518 | + line => 296}) |
| 398 519 | end. |
| 399 520 | |
| 400 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 204). |
| 521 | + -file("src/gleam/http.gleam", 243). |
| 401 522 | -spec parse_body_with_bit_array(bitstring(), bitstring()) -> {ok, |
| 402 523 | multipart_body()} | |
| 403 524 | {error, nil}. |
| @@ -412,7 +533,20 @@ parse_body_with_bit_array(Data, Boundary) -> | |
| 412 533 | parse_body_loop(Data, Boundary, <<>>) |
| 413 534 | end. |
| 414 535 | |
| 415 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 195). |
| 536 | + -file("src/gleam/http.gleam", 234). |
| 537 | + ?DOC( |
| 538 | + " Parse the body for part of a multipart message, as defined in RFC 2045. The\n" |
| 539 | + " body is everything until the next boundary. This function is generally to be\n" |
| 540 | + " called after calling `parse_multipart_headers` for a given part.\n" |
| 541 | + "\n" |
| 542 | + " This function will accept input of any size, it is up to the caller to limit\n" |
| 543 | + " it if needed.\n" |
| 544 | + "\n" |
| 545 | + " To enable streaming parsing of multipart messages, this function will return\n" |
| 546 | + " a continuation if there is not enough data to fully parse the body, along\n" |
| 547 | + " with the data that has been parsed so far. Further information is available\n" |
| 548 | + " in the documentation for `MultipartBody`.\n" |
| 549 | + ). |
| 416 550 | -spec parse_multipart_body(bitstring(), binary()) -> {ok, multipart_body()} | |
| 417 551 | {error, nil}. |
| 418 552 | parse_multipart_body(Data, Boundary) -> |
| @@ -420,23 +554,7 @@ parse_multipart_body(Data, Boundary) -> | |
| 420 554 | _pipe@1 = gleam_stdlib:identity(_pipe), |
| 421 555 | parse_body_with_bit_array(Data, _pipe@1). |
| 422 556 | |
| 423 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 106). |
| 424 | - -spec method_from_dynamic(gleam@dynamic:dynamic_()) -> {ok, method()} | |
| 425 | - {error, list(gleam@dynamic:decode_error())}. |
| 426 | - method_from_dynamic(Value) -> |
| 427 | - case gleam_http_native:decode_method(Value) of |
| 428 | - {ok, Method} -> |
| 429 | - {ok, Method}; |
| 430 | - |
| 431 | - {error, _} -> |
| 432 | - {error, |
| 433 | - [{decode_error, |
| 434 | - <<"HTTP method"/utf8>>, |
| 435 | - gleam_stdlib:classify_dynamic(Value), |
| 436 | - []}]} |
| 437 | - end. |
| 438 | - |
| 439 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 380). |
| 557 | + -file("src/gleam/http.gleam", 419). |
| 440 558 | -spec parse_header_value( |
| 441 559 | bitstring(), |
| 442 560 | list({binary(), binary()}), |
| @@ -497,7 +615,7 @@ parse_header_value(Data, Headers, Name, Value) -> | |
| 497 615 | {error, nil} |
| 498 616 | end. |
| 499 617 | |
| 500 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 361). |
| 618 | + -file("src/gleam/http.gleam", 400). |
| 501 619 | -spec parse_header_name(bitstring(), list({binary(), binary()}), bitstring()) -> {ok, |
| 502 620 | multipart_headers()} | |
| 503 621 | {error, nil}. |
| @@ -518,7 +636,7 @@ parse_header_name(Data, Headers, Name) -> | |
| 518 636 | ) |
| 519 637 | end. |
| 520 638 | |
| 521 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 345). |
| 639 | + -file("src/gleam/http.gleam", 384). |
| 522 640 | -spec do_parse_headers(bitstring()) -> {ok, multipart_headers()} | {error, nil}. |
| 523 641 | do_parse_headers(Data) -> |
| 524 642 | case Data of |
| @@ -538,7 +656,7 @@ do_parse_headers(Data) -> | |
| 538 656 | {error, nil} |
| 539 657 | end. |
| 540 658 | |
| 541 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 261). |
| 659 | + -file("src/gleam/http.gleam", 300). |
| 542 660 | -spec parse_headers_after_prelude(bitstring(), bitstring()) -> {ok, |
| 543 661 | multipart_headers()} | |
| 544 662 | {error, nil}. |
| @@ -602,7 +720,7 @@ parse_headers_after_prelude(Data, Boundary) -> | |
| 602 720 | end |
| 603 721 | ). |
| 604 722 | |
| 605 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 303). |
| 723 | + -file("src/gleam/http.gleam", 342). |
| 606 724 | -spec skip_preamble(bitstring(), bitstring()) -> {ok, multipart_headers()} | |
| 607 725 | {error, nil}. |
| 608 726 | skip_preamble(Data, Boundary) -> |
| @@ -641,10 +759,23 @@ skip_preamble(Data, Boundary) -> | |
| 641 759 | message => <<"unreachable"/utf8>>, |
| 642 760 | module => <<"gleam/http"/utf8>>, |
| 643 761 | function => <<"skip_preamble"/utf8>>, |
| 644 | - line => 333}) |
| 762 | + line => 372}) |
| 645 763 | end. |
| 646 764 | |
| 647 | - -file("/Users/louis/src/gleam/http/src/gleam/http.gleam", 167). |
| 765 | + -file("src/gleam/http.gleam", 206). |
| 766 | + ?DOC( |
| 767 | + " Parse the headers for part of a multipart message, as defined in RFC 2045.\n" |
| 768 | + "\n" |
| 769 | + " This function skips any preamble before the boundary. The preamble may be\n" |
| 770 | + " retrieved using `parse_multipart_body`.\n" |
| 771 | + "\n" |
| 772 | + " This function will accept input of any size, it is up to the caller to limit\n" |
| 773 | + " it if needed.\n" |
| 774 | + "\n" |
| 775 | + " To enable streaming parsing of multipart messages, this function will return\n" |
| 776 | + " a continuation if there is not enough data to fully parse the headers.\n" |
| 777 | + " Further information is available in the documentation for `MultipartBody`.\n" |
| 778 | + ). |
| 648 779 | -spec parse_multipart_headers(bitstring(), binary()) -> {ok, |
| 649 780 | multipart_headers()} | |
| 650 781 | {error, nil}. |
Loading more files…