std::net::url cleanups for lint check
This commit is contained in:
parent
b57f6b73ba
commit
21187206c3
1 changed files with 61 additions and 50 deletions
|
@ -30,8 +30,9 @@ type userinfo = {
|
|||
|
||||
type query = ~[(~str, ~str)];
|
||||
|
||||
fn url(-scheme: ~str, -user: option<userinfo>, -host: ~str, -port: option<~str>,
|
||||
-path: ~str, -query: query, -fragment: option<~str>) -> url {
|
||||
fn url(-scheme: ~str, -user: option<userinfo>, -host: ~str,
|
||||
-port: option<~str>, -path: ~str, -query: query,
|
||||
-fragment: option<~str>) -> url {
|
||||
{ scheme: scheme, user: user, host: host, port: port,
|
||||
path: path, query: query, fragment: fragment }
|
||||
}
|
||||
|
@ -79,9 +80,9 @@ fn encode_inner(s: ~str, full_url: bool) -> ~str {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a URI by replacing reserved characters with percent encoded character
|
||||
* sequences.
|
||||
/**
|
||||
* Encodes a URI by replacing reserved characters with percent encoded
|
||||
* character sequences.
|
||||
*
|
||||
* This function is compliant with RFC 3986.
|
||||
*/
|
||||
|
@ -89,9 +90,9 @@ fn encode(s: ~str) -> ~str {
|
|||
encode_inner(s, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a URI component by replacing reserved characters with percent encoded
|
||||
* character sequences.
|
||||
/**
|
||||
* Encodes a URI component by replacing reserved characters with percent
|
||||
* encoded character sequences.
|
||||
*
|
||||
* This function is compliant with RFC 3986.
|
||||
*/
|
||||
|
@ -139,14 +140,14 @@ fn decode_inner(s: ~str, full_url: bool) -> ~str {
|
|||
|
||||
/**
|
||||
* Decode a string encoded with percent encoding.
|
||||
*
|
||||
*
|
||||
* This will only decode escape sequences generated by encode_uri.
|
||||
*/
|
||||
fn decode(s: ~str) -> ~str {
|
||||
decode_inner(s, true)
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Decode a string encoded with percent encoding.
|
||||
*/
|
||||
fn decode_component(s: ~str) -> ~str {
|
||||
|
@ -172,7 +173,7 @@ fn encode_plus(s: ~str) -> ~str {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
|
||||
*/
|
||||
fn encode_form_urlencoded(m: hashmap<~str, @dvec<@~str>>) -> ~str {
|
||||
|
@ -190,18 +191,19 @@ fn encode_form_urlencoded(m: hashmap<~str, @dvec<@~str>>) -> ~str {
|
|||
first = false;
|
||||
}
|
||||
|
||||
out += #fmt("%s=%s", key, encode_plus(*value));
|
||||
out += #fmt("%s=%s", key, encode_plus(*value));
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Decode a string encoded with the 'application/x-www-form-urlencoded' media
|
||||
* type into a hashmap.
|
||||
*/
|
||||
fn decode_form_urlencoded(s: ~[u8]) -> hashmap<~str, @dvec<@~str>> {
|
||||
fn decode_form_urlencoded(s: ~[u8]) ->
|
||||
map::hashmap<~str, @dvec::dvec<@~str>> {
|
||||
do io::with_bytes_reader(s) |rdr| {
|
||||
let m = str_hash();
|
||||
let mut key = ~"";
|
||||
|
@ -282,7 +284,8 @@ fn split_char_first(s: ~str, c: char) -> (~str, ~str) {
|
|||
if index+match_ == len {
|
||||
return (str::slice(s, 0, index), ~"");
|
||||
} else {
|
||||
return (str::slice(s, 0, index), str::slice(s, index + match_, str::len(s)));
|
||||
return (str::slice(s, 0, index),
|
||||
str::slice(s, index + match_, str::len(s)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,7 +358,7 @@ fn get_scheme(rawurl: ~str) -> result::result<(~str, ~str), @~str> {
|
|||
|
||||
// returns userinfo, host, port, and unparsed part, or an error
|
||||
// currently doesn't handle IPv6 addresses.
|
||||
fn get_authority(rawurl: ~str) ->
|
||||
fn get_authority(rawurl: ~str) ->
|
||||
result::result<(option<userinfo>, ~str, option<~str>, ~str), @~str> {
|
||||
if !str::starts_with(rawurl, ~"//") {
|
||||
// there is no authority.
|
||||
|
@ -373,7 +376,7 @@ fn get_authority(rawurl: ~str) ->
|
|||
enum input {
|
||||
digit, // all digits
|
||||
hex, // digits and letters a-f
|
||||
unreserved // all other legal characters in usernames, passwords, hosts
|
||||
unreserved // all other legal characters
|
||||
}
|
||||
let len = str::len(rawurl);
|
||||
let mut st : state = start;
|
||||
|
@ -399,8 +402,8 @@ fn get_authority(rawurl: ~str) ->
|
|||
alt c {
|
||||
'0' to '9' { }
|
||||
'A' to 'F' | 'a' to 'f' {
|
||||
if in == digit {
|
||||
in = hex;
|
||||
if in == digit {
|
||||
in = hex;
|
||||
}
|
||||
}
|
||||
'G' to 'Z' | 'g' to 'z' | '-' | '.' | '_' | '~' | '%' |
|
||||
|
@ -415,7 +418,7 @@ fn get_authority(rawurl: ~str) ->
|
|||
}
|
||||
}
|
||||
|
||||
// now state machine
|
||||
// now process states
|
||||
alt c {
|
||||
':' {
|
||||
colon_count += 1;
|
||||
|
@ -465,14 +468,14 @@ fn get_authority(rawurl: ~str) ->
|
|||
alt st {
|
||||
start {
|
||||
let user = str::slice(rawurl, begin, i);
|
||||
userinfo = option::some({user : user,
|
||||
userinfo = option::some({user : user,
|
||||
pass: option::none});
|
||||
st = in_host;
|
||||
}
|
||||
pass_host_port {
|
||||
let user = str::slice(rawurl, begin, pos);
|
||||
let pass = str::slice(rawurl, pos+1, i);
|
||||
userinfo = option::some({user: user,
|
||||
userinfo = option::some({user: user,
|
||||
pass: option::some(pass)});
|
||||
st = in_host;
|
||||
}
|
||||
|
@ -482,7 +485,7 @@ fn get_authority(rawurl: ~str) ->
|
|||
}
|
||||
begin = i+1;
|
||||
}
|
||||
|
||||
|
||||
'?' | '#' | '/' {
|
||||
break;
|
||||
}
|
||||
|
@ -517,14 +520,14 @@ fn get_authority(rawurl: ~str) ->
|
|||
}
|
||||
}
|
||||
|
||||
let rest = if i+1 == len { ~"" }
|
||||
let rest = if i+1 == len { ~"" }
|
||||
else { str::slice(rawurl, i, len) };
|
||||
return result::ok((userinfo, host, port, rest));
|
||||
}
|
||||
|
||||
|
||||
// returns the path and unparsed part of url, or an error
|
||||
fn get_path(rawurl: ~str, authority : bool) ->
|
||||
fn get_path(rawurl: ~str, authority : bool) ->
|
||||
result::result<(~str, ~str), @~str> {
|
||||
let len = str::len(rawurl);
|
||||
let mut end = len;
|
||||
|
@ -548,27 +551,27 @@ fn get_path(rawurl: ~str, authority : bool) ->
|
|||
'/' in presence of authority.");
|
||||
}
|
||||
}
|
||||
|
||||
return result::ok((decode_component(str::slice(rawurl, 0, end)),
|
||||
|
||||
return result::ok((decode_component(str::slice(rawurl, 0, end)),
|
||||
str::slice(rawurl, end, len)));
|
||||
}
|
||||
|
||||
// returns the parsed query and the fragment, if present
|
||||
fn get_query_fragment(rawurl: ~str) ->
|
||||
fn get_query_fragment(rawurl: ~str) ->
|
||||
result::result<(query, option<~str>), @~str> {
|
||||
if !str::starts_with(rawurl, ~"?") {
|
||||
if str::starts_with(rawurl, ~"#") {
|
||||
let f = decode_component(str::slice(rawurl,
|
||||
1,
|
||||
let f = decode_component(str::slice(rawurl,
|
||||
1,
|
||||
str::len(rawurl)));
|
||||
return result::ok((~[], option::some(f)));
|
||||
} else {
|
||||
return result::ok((~[], option::none));
|
||||
}
|
||||
}
|
||||
let (q, r) = split_char_first(str::slice(rawurl, 1,
|
||||
let (q, r) = split_char_first(str::slice(rawurl, 1,
|
||||
str::len(rawurl)), '#');
|
||||
let f = if str::len(r) != 0 {
|
||||
let f = if str::len(r) != 0 {
|
||||
option::some(decode_component(r)) } else { option::none };
|
||||
return result::ok((query_from_str(q), f));
|
||||
}
|
||||
|
@ -606,7 +609,7 @@ fn from_str(rawurl: ~str) -> result::result<url, ~str> {
|
|||
let mut pth = get_path(rest, has_authority);
|
||||
if result::is_err(pth) {
|
||||
return result::err(copy *result::get_err(pth));
|
||||
}
|
||||
}
|
||||
let (path, rest) = result::unwrap(pth);
|
||||
|
||||
// query and fragment
|
||||
|
@ -616,7 +619,7 @@ fn from_str(rawurl: ~str) -> result::result<url, ~str> {
|
|||
}
|
||||
let (query, fragment) = result::unwrap(qry);
|
||||
|
||||
return result::ok(url(scheme, userinfo, host,
|
||||
return result::ok(url(scheme, userinfo, host,
|
||||
port, path, query, fragment));
|
||||
}
|
||||
|
||||
|
@ -647,7 +650,8 @@ fn to_str(url: url) -> ~str {
|
|||
str::concat(~[~"?", query_to_str(url.query)])
|
||||
};
|
||||
let fragment = if option::is_some(url.fragment) {
|
||||
str::concat(~[~"#", encode_component(option::unwrap(copy url.fragment))])
|
||||
str::concat(~[~"#", encode_component(
|
||||
option::unwrap(copy url.fragment))])
|
||||
} else {
|
||||
~""
|
||||
};
|
||||
|
@ -674,7 +678,7 @@ mod tests {
|
|||
let (u,v) = split_char_first(~"hello, sweet world", ',');
|
||||
assert u == ~"hello";
|
||||
assert v == ~" sweet world";
|
||||
|
||||
|
||||
let (u,v) = split_char_first(~"hello sweet world", ',');
|
||||
assert u == ~"hello sweet world";
|
||||
assert v == ~"";
|
||||
|
@ -684,7 +688,7 @@ mod tests {
|
|||
fn test_get_authority() {
|
||||
let (u, h, p, r) = result::unwrap(get_authority(
|
||||
~"//user:pass@rust-lang.org/something"));
|
||||
assert u == option::some({user: ~"user",
|
||||
assert u == option::some({user: ~"user",
|
||||
pass: option::some(~"pass")});
|
||||
assert h == ~"rust-lang.org";
|
||||
assert option::is_none(p);
|
||||
|
@ -696,7 +700,7 @@ mod tests {
|
|||
assert h == ~"rust-lang.org";
|
||||
assert p == option::some(~"8000");
|
||||
assert r == ~"?something";
|
||||
|
||||
|
||||
let (u, h, p, r) = result::unwrap(get_authority(
|
||||
~"//rust-lang.org#blah"));
|
||||
assert option::is_none(u);
|
||||
|
@ -718,50 +722,57 @@ mod tests {
|
|||
~"//us:p@2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah"));
|
||||
assert u == option::some({user: ~"us", pass : option::some(~"p")});
|
||||
assert h == ~"2001:0db8:85a3:0042:0000:8a2e:0370:7334";
|
||||
assert p == option::some(~"8000");
|
||||
assert p == option::some(~"8000");
|
||||
|
||||
// invalid authorities;
|
||||
assert result::is_err(get_authority(~"//user:pass@rust-lang:something"));
|
||||
assert result::is_err(get_authority(~"//user@rust-lang:something:/path"));
|
||||
// invalid authorities;
|
||||
assert result::is_err(get_authority(
|
||||
~"//user:pass@rust-lang:something"));
|
||||
assert result::is_err(get_authority(
|
||||
~"//user@rust-lang:something:/path"));
|
||||
assert result::is_err(get_authority(
|
||||
~"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:800a"));
|
||||
assert result::is_err(get_authority(
|
||||
~"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000:00"));
|
||||
|
||||
// these parse as empty, because they don't start with '//'
|
||||
let (_, h, _, _) = result::unwrap(get_authority(~"user:pass@rust-lang"));
|
||||
let (_, h, _, _) = result::unwrap(
|
||||
get_authority(~"user:pass@rust-lang"));
|
||||
assert h == ~"";
|
||||
let (_, h, _, _) = result::unwrap(get_authority(~"rust-lang.org"));
|
||||
let (_, h, _, _) = result::unwrap(
|
||||
get_authority(~"rust-lang.org"));
|
||||
assert h == ~"";
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_path() {
|
||||
let (p, r) = result::unwrap(get_path(~"/something+%20orother", true));
|
||||
let (p, r) = result::unwrap(get_path(
|
||||
~"/something+%20orother", true));
|
||||
assert p == ~"/something+ orother";
|
||||
assert r == ~"";
|
||||
let (p, r) = result::unwrap(get_path(~"test@email.com#fragment", false));
|
||||
let (p, r) = result::unwrap(get_path(
|
||||
~"test@email.com#fragment", false));
|
||||
assert p == ~"test@email.com";
|
||||
assert r == ~"#fragment";
|
||||
let (p, r) = result::unwrap(get_path(~"/gen/:addr=?q=v", false));
|
||||
assert p == ~"/gen/:addr=";
|
||||
assert r == ~"?q=v";
|
||||
|
||||
|
||||
//failure cases
|
||||
assert result::is_err(get_path(~"something?q", true));
|
||||
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_url_parse() {
|
||||
let url = ~"http://user:pass@rust-lang.org/doc?s=v#something";
|
||||
|
||||
|
||||
let up = from_str(url);
|
||||
let u = result::unwrap(up);
|
||||
assert u.scheme == ~"http";
|
||||
assert option::unwrap(copy u.user).user == ~"user";
|
||||
assert option::unwrap(copy option::unwrap(copy u.user).pass) == ~"pass";
|
||||
assert option::unwrap(copy option::unwrap(copy u.user).pass)
|
||||
== ~"pass";
|
||||
assert u.host == ~"rust-lang.org";
|
||||
assert u.path == ~"/doc";
|
||||
assert u.query.find(|kv| kv.first() == ~"s").get().second() == ~"v";
|
||||
|
|
Loading…
Reference in a new issue