tryParseURL

Parse a URL from a string.

This attempts to parse a wide range of URLs as people might actually type them. Some mistakes may be made. However, any URL in a correct format will be parsed correctly.

@safe
bool
tryParseURL
(
string value
,
out URL url
)

Examples

1 {
2 	// Basic.
3 	URL url;
4 	with (url) {
5 		scheme = "https";
6 		host = "example.org";
7 		path = "/foo/bar";
8 		queryParams.add("hello", "world");
9 		queryParams.add("gibe", "clay");
10 		fragment = "frag";
11 	}
12 	assert(
13 			// Not sure what order it'll come out in.
14 			url.toString == "https://example.org/foo/bar?hello=world&gibe=clay#frag" ||
15 			url.toString == "https://example.org/foo/bar?gibe=clay&hello=world#frag",
16 			url.toString);
17 }
18 {
19 	// Passing an array of query values.
20 	URL url;
21 	with (url) {
22 		scheme = "https";
23 		host = "example.org";
24 		path = "/foo/bar";
25 		queryParams.add("hello", "world");
26 		queryParams.add("hello", "aether");
27 		fragment = "frag";
28 	}
29 	assert(
30 			// Not sure what order it'll come out in.
31 			url.toString == "https://example.org/foo/bar?hello=world&hello=aether#frag" ||
32 			url.toString == "https://example.org/foo/bar?hello=aether&hello=world#frag",
33 			url.toString);
34 }
35 {
36 	// Percent encoded.
37 	URL url;
38 	with (url) {
39 		scheme = "https";
40 		host = "example.org";
41 		path = "/f☃o";
42 		queryParams.add("❄", "❀");
43 		queryParams.add("[", "]");
44 		fragment = "ş";
45 	}
46 	assert(
47 			// Not sure what order it'll come out in.
48 			url.toString == "https://example.org/f%E2%98%83o?%E2%9D%84=%E2%9D%80&%5B=%5D#%C5%9F" ||
49 			url.toString == "https://example.org/f%E2%98%83o?%5B=%5D&%E2%9D%84=%E2%9D%80#%C5%9F",
50 			url.toString);
51 }
52 {
53 	// Port, user, pass.
54 	URL url;
55 	with (url) {
56 		scheme = "https";
57 		host = "example.org";
58 		user = "dhasenan";
59 		pass = "itsasecret";
60 		port = 17;
61 	}
62 	assert(
63 			url.toString == "https://dhasenan:itsasecret@example.org:17/",
64 			url.toString);
65 }
66 {
67 	// Query with no path.
68 	URL url;
69 	with (url) {
70 		scheme = "https";
71 		host = "example.org";
72 		queryParams.add("hi", "bye");
73 	}
74 	assert(
75 			url.toString == "https://example.org/?hi=bye",
76 			url.toString);
77 }
// There's an existing path.
auto url = parseURL("http://example.org/foo");
// No slash? Assume it needs a slash.
assert((url ~ "bar").toString == "http://example.org/foo/bar");
// With slash? Don't add another.
assert((url ~ "/bar").toString == "http://example.org/foo/bar");
url ~= "bar";
assert(url.toString == "http://example.org/foo/bar");

// Path already ends with a slash; don't add another.
url = parseURL("http://example.org/foo/");
assert((url ~ "bar").toString == "http://example.org/foo/bar");
// Still don't add one even if you're appending with a slash.
assert((url ~ "/bar").toString == "http://example.org/foo/bar");
url ~= "/bar";
assert(url.toString == "http://example.org/foo/bar");

// No path.
url = parseURL("http://example.org");
assert((url ~ "bar").toString == "http://example.org/bar");
assert((url ~ "/bar").toString == "http://example.org/bar");
url ~= "bar";
assert(url.toString == "http://example.org/bar");

// Path is just a slash.
url = parseURL("http://example.org/");
assert((url ~ "bar").toString == "http://example.org/bar");
assert((url ~ "/bar").toString == "http://example.org/bar");
url ~= "bar";
assert(url.toString == "http://example.org/bar", url.toString);

// No path, just fragment.
url = "ircs://irc.freenode.com/#d".parseURL;
assert(url.toString == "ircs://irc.freenode.com/#d", url.toString);

Meta