|
42 | 42 | -export([map/2, map/3]). |
43 | 43 | -export([either/2, and_then/2, non_empty/1]). |
44 | 44 | -export([options/1, options/2]). |
| 45 | +%% Auxiliary |
| 46 | +-export([parse_uri/1, parse_uri/2]). |
45 | 47 |
|
46 | 48 | -define(is_validator(Term), is_function(Term, 1)). |
47 | 49 | -ifndef(deprecated_stacktrace). |
@@ -362,18 +364,19 @@ url(Schemes) -> |
362 | 364 | fun(Val) -> |
363 | 365 | URL = to_binary(Val), |
364 | 366 | case parse_uri(URL) of |
365 | | - {ok, _, Host, _} when Host == ""; Host == <<"">> -> |
| 367 | + {ok, _, _, Host, _, _, _} when Host == ""; Host == <<"">> -> |
366 | 368 | fail({bad_url, empty_host, URL}); |
367 | | - {ok, _, _, Port} when Port /= undefined, |
| 369 | + {ok, _, _, _, Port, _, _} when Port /= undefined, |
368 | 370 | Port =< 0 orelse Port >= 65536 -> |
369 | 371 | fail({bad_url, bad_port, URL}); |
370 | | - {ok, Scheme, _, _} when Schemes /= [] -> |
| 372 | + {ok, SchemeString, _, _, _, _, _} when Schemes /= [] -> |
| 373 | + Scheme = to_atom(SchemeString), |
371 | 374 | case lists:member(Scheme, Schemes) of |
372 | 375 | true -> URL; |
373 | 376 | false -> |
374 | 377 | fail({bad_url, {unsupported_scheme, Scheme}, URL}) |
375 | 378 | end; |
376 | | - {ok, _, _, _} -> |
| 379 | + {ok, _, _, _, _, _, _} -> |
377 | 380 | URL; |
378 | 381 | {error, Why} -> |
379 | 382 | fail({bad_url, Why, URL}) |
@@ -1163,32 +1166,41 @@ parse_ip_netmask(S) -> |
1163 | 1166 | error |
1164 | 1167 | end. |
1165 | 1168 |
|
1166 | | --spec parse_uri(term()) -> {ok, atom(), binary(), integer() | undefined} | |
1167 | | - {error, term()}. |
1168 | 1169 | -ifdef(USE_OLD_HTTP_URI). |
1169 | | -parse_uri(URL) when is_binary(URL) -> |
1170 | | - parse_uri(to_string(URL)); % OTP =< 19's http_uri:parse/1 expects strings. |
1171 | 1170 | parse_uri(URL) -> |
1172 | | - case http_uri:parse(URL) of |
1173 | | - {ok, {Scheme, _UserInfo, Host, Port0, _Path, _Query}} -> |
| 1171 | + parse_uri(URL, []). |
| 1172 | + |
| 1173 | +parse_uri(URL, Protocols) -> |
| 1174 | + case http_uri:parse(URL, [{scheme_defaults, Protocols}]) of |
| 1175 | + {ok, {Scheme, UserInfo, Host, Port0, Path, Query}} -> |
1174 | 1176 | Port = if is_integer(Port0) -> Port0; |
1175 | 1177 | true -> undefined |
1176 | 1178 | end, |
1177 | | - {ok, Scheme, Host, Port}; |
1178 | | - {error, Reason} -> |
1179 | | - {error, Reason} |
| 1179 | + {ok, atom_to_list(Scheme), UserInfo, Host, Port, Path, Query}; |
| 1180 | + {error, _} = E -> |
| 1181 | + E |
1180 | 1182 | end. |
| 1183 | + |
1181 | 1184 | -else. |
1182 | | -parse_uri(URL0) -> |
| 1185 | +parse_uri(URL) -> |
| 1186 | + parse_uri(URL, [{http, 80}, {https, 443}]). |
| 1187 | + |
| 1188 | +parse_uri(URL, Protocols) when is_binary(URL) -> |
| 1189 | + parse_uri(binary_to_list(URL), Protocols); |
| 1190 | +parse_uri(URL0, Protocols) -> |
1183 | 1191 | URL = re:replace(URL0, <<"@[A-Z]+@">>, <<"MACRO">>, [{return, binary}]), |
1184 | 1192 | case uri_string:parse(URL) of |
1185 | | - URIMap when is_map(URIMap) -> |
1186 | | - Scheme = maps:get(scheme, URIMap, <<>>), |
1187 | | - Host = maps:get(host, URIMap, <<>>), |
1188 | | - Port = maps:get(port, URIMap, undefined), |
1189 | | - {ok, to_atom(Scheme), Host, Port}; |
1190 | | - {error, Reason, _Info} -> |
1191 | | - {error, Reason} |
| 1193 | + #{scheme := Scheme, host := Host, port := Port, path := Path} = M1 -> |
| 1194 | + {ok, Scheme, maps:get(userinfo, M1, ""), Host, Port, Path, maps:get(query, M1, "")}; |
| 1195 | + #{scheme := Scheme, host := Host, path := Path} = M2 -> |
| 1196 | + case lists:keyfind(to_atom(Scheme), 1, Protocols) of |
| 1197 | + {_, Port} -> |
| 1198 | + {ok, Scheme, maps:get(userinfo, M2, ""), Host, Port, Path, maps:get(query, M2, "")}; |
| 1199 | + _ -> |
| 1200 | + {error, unknown_protocol} |
| 1201 | + end; |
| 1202 | + {error, Atom, _} -> |
| 1203 | + {error, Atom} |
1192 | 1204 | end. |
1193 | 1205 | -endif. |
1194 | 1206 |
|
|
0 commit comments