@@ -11,11 +11,21 @@ static auto const RE_COMPONENT =
11
11
Re::alnum () | '+'_re | '-'_re | '.'_re
12
12
);
13
13
14
- Url Url::parse (Io::SScan& s) {
14
+ static auto const RE_SCHEME = RE_COMPONENT & ' :' _re;
15
+
16
+ Url Url::parse (Io::SScan& s, Opt<Url> origin) {
15
17
Url url;
16
18
17
- url.scheme = s.token (RE_COMPONENT);
18
- s.skip (' :' );
19
+ if (s.ahead (RE_SCHEME)) {
20
+ url.scheme = s.token (RE_COMPONENT);
21
+ s.skip (' :' );
22
+ } else if (origin) {
23
+ url.scheme = origin->scheme ;
24
+ url.authority = origin->authority ;
25
+ url.host = origin->host ;
26
+ url.port = origin->port ;
27
+ url.path = origin->path ;
28
+ }
19
29
20
30
if (s.skip (" //" )) {
21
31
auto maybeHost = s.token (RE_COMPONENT);
@@ -33,6 +43,8 @@ Url Url::parse(Io::SScan& s) {
33
43
}
34
44
35
45
url.path = Path::parse (s, true );
46
+ if (not url.path .rooted and origin)
47
+ url.path = origin->path .join (url.path );
36
48
37
49
if (s.skip (' ?' ))
38
50
url.query = s.token (Re::until (' #' _re));
@@ -43,9 +55,9 @@ Url Url::parse(Io::SScan& s) {
43
55
return url;
44
56
}
45
57
46
- Url Url::parse (Str str) {
58
+ Url Url::parse (Str str, Opt<Url> origin ) {
47
59
Io::SScan s{str};
48
- return parse (s);
60
+ return parse (s, origin );
49
61
}
50
62
51
63
bool Url::isUrl (Str str) {
@@ -116,15 +128,15 @@ String Url::str() const {
116
128
return writer.str ();
117
129
}
118
130
119
- Res< Url> parseUrlOrPath (Str str) {
131
+ Url parseUrlOrPath (Str str, Opt<Url> origin ) {
120
132
if (Url::isUrl (str)) {
121
- return Ok ( Url::parse (str) );
133
+ return Url::parse (str, origin );
122
134
}
123
135
124
- Url url;
125
- url.scheme = " file " s ;
126
- url. path = Path::parse (str);
127
- return Ok ( url) ;
136
+ Url url = origin. unwrapOr ( " file: " _url) ;
137
+ url.path = url. path . join ( Path::parse (str)) ;
138
+
139
+ return url;
128
140
}
129
141
130
142
} // namespace Karm::Mime
0 commit comments