diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-12 07:37:51 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-12 07:37:51 +0200 |
commit | 072805e251cbe451d22c04c433b4c63d8a82301d (patch) | |
tree | a164d2139b441a8fc19673528fa0bcec09f18932 /src | |
parent | a3c6810225a1637f1e4d147c7a0d6f967eddf1b2 (diff) |
IDN applies to all network schemes
But not "file" or "about".
Diffstat (limited to 'src')
-rw-r--r-- | src/gmrequest.c | 1 | ||||
-rw-r--r-- | src/gmutil.c | 41 |
2 files changed, 34 insertions, 8 deletions
diff --git a/src/gmrequest.c b/src/gmrequest.c index 41b97620..991485bc 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -505,6 +505,7 @@ void submit_GmRequest(iGmRequest *d) { | |||
505 | set_Atomic(&d->allowUpdate, iTrue); | 505 | set_Atomic(&d->allowUpdate, iTrue); |
506 | iGmResponse *resp = d->resp; | 506 | iGmResponse *resp = d->resp; |
507 | clear_GmResponse(resp); | 507 | clear_GmResponse(resp); |
508 | // printf("[GmRequest] URL: %s\n", cstr_String(&d->url)); | ||
508 | iUrl url; | 509 | iUrl url; |
509 | init_Url(&url, &d->url); | 510 | init_Url(&url, &d->url); |
510 | /* Check for special schemes. */ | 511 | /* Check for special schemes. */ |
diff --git a/src/gmutil.c b/src/gmutil.c index 67b0d939..68525be9 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -132,6 +132,25 @@ static iBool isAbsolutePath_(iRangecc path) { | |||
132 | return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); | 132 | return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); |
133 | } | 133 | } |
134 | 134 | ||
135 | static iString *punyDecodeHost_(iRangecc host) { | ||
136 | iString *result = new_String(); | ||
137 | iRangecc label = iNullRange; | ||
138 | while (nextSplit_Rangecc(host, ".", &label)) { | ||
139 | if (!isEmpty_String(result)) { | ||
140 | appendChar_String(result, '.'); | ||
141 | } | ||
142 | if (startsWithCase_Rangecc(label, "xn--")) { | ||
143 | iString *dec = punyDecode_Rangecc((iRangecc){ label.start + 4, label.end }); | ||
144 | if (!isEmpty_String(dec)) { | ||
145 | append_String(result, dec); | ||
146 | continue; | ||
147 | } | ||
148 | } | ||
149 | appendRange_String(result, label); | ||
150 | } | ||
151 | return result; | ||
152 | } | ||
153 | |||
135 | const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { | 154 | const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { |
136 | iUrl orig; | 155 | iUrl orig; |
137 | iUrl rel; | 156 | iUrl rel; |
@@ -152,9 +171,12 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat | |||
152 | } | 171 | } |
153 | iString *absolute = collectNew_String(); | 172 | iString *absolute = collectNew_String(); |
154 | appendRange_String(absolute, scheme); | 173 | appendRange_String(absolute, scheme); |
155 | appendCStr_String(absolute, "://"); { | 174 | appendCStr_String(absolute, "://"); |
175 | /* Authority. */ { | ||
156 | const iUrl *selHost = isDef_(rel.host) ? &rel : &orig; | 176 | const iUrl *selHost = isDef_(rel.host) ? &rel : &orig; |
157 | appendRange_String(absolute, selHost->host); | 177 | iString *decHost = punyDecodeHost_(selHost->host); |
178 | append_String(absolute, decHost); | ||
179 | delete_String(decHost); | ||
158 | if (!isEmpty_Range(&selHost->port)) { | 180 | if (!isEmpty_Range(&selHost->port)) { |
159 | appendCStr_String(absolute, ":"); | 181 | appendCStr_String(absolute, ":"); |
160 | appendRange_String(absolute, selHost->port); | 182 | appendRange_String(absolute, selHost->port); |
@@ -204,23 +226,26 @@ void punyEncodeUrlHost_String(iString *d) { | |||
204 | /* `d` should be an absolute URL. */ | 226 | /* `d` should be an absolute URL. */ |
205 | iUrl url; | 227 | iUrl url; |
206 | init_Url(&url, d); | 228 | init_Url(&url, d); |
229 | if (isEmpty_Range(&url.host)) { | ||
230 | return; | ||
231 | } | ||
207 | iString *encoded = new_String(); | 232 | iString *encoded = new_String(); |
208 | setRange_String(encoded, (iRangecc){ url.scheme.start, url.host.start }); | 233 | setRange_String(encoded, (iRangecc){ url.scheme.start, url.host.start }); |
209 | /* The domain name needs to be split into segments. */ { | 234 | /* The domain name needs to be split into labels. */ { |
210 | iRangecc seg = iNullRange; | 235 | iRangecc label = iNullRange; |
211 | iBool isFirst = iTrue; | 236 | iBool isFirst = iTrue; |
212 | while (nextSplit_Rangecc(url.host, ".", &seg)) { | 237 | while (nextSplit_Rangecc(url.host, ".", &label)) { |
213 | if (!isFirst) { | 238 | if (!isFirst) { |
214 | appendChar_String(encoded, '.'); | 239 | appendChar_String(encoded, '.'); |
215 | } | 240 | } |
216 | isFirst = iFalse; | 241 | isFirst = iFalse; |
217 | iString *puny = punyEncode_Rangecc(seg); | 242 | iString *puny = punyEncode_Rangecc(label); |
218 | if (!isEmpty_String(puny) && !equalPuny_(puny, seg)) { | 243 | if (!isEmpty_String(puny) && !equalPuny_(puny, label)) { |
219 | appendCStr_String(encoded, "xn--"); | 244 | appendCStr_String(encoded, "xn--"); |
220 | append_String(encoded, puny); | 245 | append_String(encoded, puny); |
221 | } | 246 | } |
222 | else { | 247 | else { |
223 | appendRange_String(encoded, seg); | 248 | appendRange_String(encoded, label); |
224 | } | 249 | } |
225 | delete_String(puny); | 250 | delete_String(puny); |
226 | } | 251 | } |