summaryrefslogtreecommitdiff
path: root/src/gmutil.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-12-11 20:40:32 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-12-11 20:40:32 +0200
commit7f8f6f3305161706d44884cccd4961ba4f0490bf (patch)
tree4b0dc4b492119b7d15c5abb72cc01aa8f3de9a03 /src/gmutil.c
parent413f8b95e62a33671e166badd8789a1bbf1248ef (diff)
GmRequest: Punycode for domain names
To support Internationalized Domain Names, we need to encode domain names using Punycode. IssueID #73
Diffstat (limited to 'src/gmutil.c')
-rw-r--r--src/gmutil.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/gmutil.c b/src/gmutil.c
index 477d0f17..67b0d939 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -185,10 +185,51 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat
185 appendRange_String(absolute, orig.path); 185 appendRange_String(absolute, orig.path);
186 } 186 }
187 appendRange_String(absolute, rel.query); 187 appendRange_String(absolute, rel.query);
188 normalize_String(absolute);
188 cleanUrlPath_String(absolute); 189 cleanUrlPath_String(absolute);
189 return absolute; 190 return absolute;
190} 191}
191 192
193static iBool equalPuny_(const iString *d, iRangecc orig) {
194 if (!endsWith_String(d, "-")) {
195 return iFalse; /* This is a sufficient condition? */
196 }
197 if (size_String(d) != size_Range(&orig) + 1) {
198 return iFalse;
199 }
200 return iCmpStrN(cstr_String(d), orig.start, size_Range(&orig)) == 0;
201}
202
203void punyEncodeUrlHost_String(iString *d) {
204 /* `d` should be an absolute URL. */
205 iUrl url;
206 init_Url(&url, d);
207 iString *encoded = new_String();
208 setRange_String(encoded, (iRangecc){ url.scheme.start, url.host.start });
209 /* The domain name needs to be split into segments. */ {
210 iRangecc seg = iNullRange;
211 iBool isFirst = iTrue;
212 while (nextSplit_Rangecc(url.host, ".", &seg)) {
213 if (!isFirst) {
214 appendChar_String(encoded, '.');
215 }
216 isFirst = iFalse;
217 iString *puny = punyEncode_Rangecc(seg);
218 if (!isEmpty_String(puny) && !equalPuny_(puny, seg)) {
219 appendCStr_String(encoded, "xn--");
220 append_String(encoded, puny);
221 }
222 else {
223 appendRange_String(encoded, seg);
224 }
225 delete_String(puny);
226 }
227 }
228 appendRange_String(encoded, (iRangecc){ url.host.end, constEnd_String(d) });
229 set_String(d, encoded);
230 delete_String(encoded);
231}
232
192iString *makeFileUrl_String(const iString *localFilePath) { 233iString *makeFileUrl_String(const iString *localFilePath) {
193 iString *url = cleaned_Path(localFilePath); 234 iString *url = cleaned_Path(localFilePath);
194 replace_Block(&url->chars, '\\', '/'); /* in case it's a Windows path */ 235 replace_Block(&url->chars, '\\', '/'); /* in case it's a Windows path */