diff options
Diffstat (limited to 'src/gmutil.c')
-rw-r--r-- | src/gmutil.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/src/gmutil.c b/src/gmutil.c index 70a3608e..98e4d4d6 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -253,6 +253,17 @@ iRangecc urlRoot_String(const iString *d) { | |||
253 | return (iRangecc){ constBegin_String(d), rootEnd }; | 253 | return (iRangecc){ constBegin_String(d), rootEnd }; |
254 | } | 254 | } |
255 | 255 | ||
256 | const iBlock *urlThemeSeed_String(const iString *url) { | ||
257 | if (equalCase_Rangecc(urlScheme_String(url), "file")) { | ||
258 | return collect_Block(new_Block(0)); | ||
259 | } | ||
260 | const iRangecc user = urlUser_String(url); | ||
261 | if (isEmpty_Range(&user)) { | ||
262 | return collect_Block(newRange_Block(urlHost_String(url))); | ||
263 | } | ||
264 | return collect_Block(newRange_Block(user)); | ||
265 | } | ||
266 | |||
256 | static iBool isAbsolutePath_(iRangecc path) { | 267 | static iBool isAbsolutePath_(iRangecc path) { |
257 | return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); | 268 | return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); |
258 | } | 269 | } |
@@ -319,6 +330,28 @@ void urlEncodePath_String(iString *d) { | |||
319 | delete_String(encoded); | 330 | delete_String(encoded); |
320 | } | 331 | } |
321 | 332 | ||
333 | void urlEncodeQuery_String(iString *d) { | ||
334 | iUrl url; | ||
335 | init_Url(&url, d); | ||
336 | if (isEmpty_Range(&url.query)) { | ||
337 | return; | ||
338 | } | ||
339 | iString encoded; | ||
340 | init_String(&encoded); | ||
341 | appendRange_String(&encoded, (iRangecc){ constBegin_String(d), url.query.start }); | ||
342 | iString query; | ||
343 | url.query.start++; /* omit the question mark */ | ||
344 | initRange_String(&query, url.query); | ||
345 | iString *encQuery = urlEncode_String(&query); /* fully encoded */ | ||
346 | appendCStr_String(&encoded, "?"); | ||
347 | append_String(&encoded, encQuery); | ||
348 | delete_String(encQuery); | ||
349 | deinit_String(&query); | ||
350 | appendRange_String(&encoded, (iRangecc){ url.query.end, constEnd_String(d) }); | ||
351 | set_String(d, &encoded); | ||
352 | deinit_String(&encoded); | ||
353 | } | ||
354 | |||
322 | iBool isKnownScheme_Rangecc(iRangecc scheme) { | 355 | iBool isKnownScheme_Rangecc(iRangecc scheme) { |
323 | if (isKnownUrlScheme_Rangecc(scheme)) { | 356 | if (isKnownUrlScheme_Rangecc(scheme)) { |
324 | return iTrue; | 357 | return iTrue; |
@@ -651,25 +684,25 @@ const iString *withSpacesEncoded_String(const iString *d) { | |||
651 | const iString *canonicalUrl_String(const iString *d) { | 684 | const iString *canonicalUrl_String(const iString *d) { |
652 | /* The "canonical" form, used for internal storage and comparisons, is: | 685 | /* The "canonical" form, used for internal storage and comparisons, is: |
653 | - all non-reserved characters decoded (i.e., it's an IRI) | 686 | - all non-reserved characters decoded (i.e., it's an IRI) |
654 | - expect for spaces, which are always `%20` | 687 | - except spaces, which are always `%20` |
655 | This means a canonical URL can be used on a gemtext link line without modifications. */ | 688 | This means a canonical URL can be used on a gemtext link line without modifications. */ |
656 | iString *canon = NULL; | 689 | iString *canon = NULL; |
657 | iUrl parts; | 690 | iUrl parts; |
658 | init_Url(&parts, d); | 691 | init_Url(&parts, d); |
659 | /* Colons are in decoded form in the URL path. */ | 692 | /* Colons (0x3a) are in decoded form in the URL path. */ |
660 | if (iStrStrN(parts.path.start, "%3A", size_Range(&parts.path)) || | 693 | if (iStrStrN(parts.path.start, "%3A", size_Range(&parts.path)) || |
661 | iStrStrN(parts.path.start, "%3a", size_Range(&parts.path))) { | 694 | iStrStrN(parts.path.start, "%3a", size_Range(&parts.path))) { |
662 | /* This is done separately to avoid the copy if %3A is not present; it's rare. */ | 695 | /* This is done separately to avoid the copy if %3A is not present; it's rare. */ |
663 | canon = copy_String(d); | 696 | canon = copy_String(d); |
664 | urlDecodePath_String(canon); | 697 | urlDecodePath_String(canon); |
665 | iString *dec = maybeUrlDecodeExclude_String(canon, "%/?:;#&+= "); /* decode everything else in all parts */ | 698 | iString *dec = maybeUrlDecodeExclude_String(canon, "% " URL_RESERVED_CHARS); /* decode everything else in all parts */ |
666 | if (dec) { | 699 | if (dec) { |
667 | set_String(canon, dec); | 700 | set_String(canon, dec); |
668 | delete_String(dec); | 701 | delete_String(dec); |
669 | } | 702 | } |
670 | } | 703 | } |
671 | else { | 704 | else { |
672 | canon = maybeUrlDecodeExclude_String(d, "%/?:;#&+= "); | 705 | canon = maybeUrlDecodeExclude_String(d, "% " URL_RESERVED_CHARS); |
673 | } | 706 | } |
674 | /* `canon` may now be NULL if nothing was decoded. */ | 707 | /* `canon` may now be NULL if nothing was decoded. */ |
675 | if (indexOfCStr_String(canon ? canon : d, " ") != iInvalidPos || | 708 | if (indexOfCStr_String(canon ? canon : d, " ") != iInvalidPos || |
@@ -678,7 +711,7 @@ const iString *canonicalUrl_String(const iString *d) { | |||
678 | canon = copy_String(d); | 711 | canon = copy_String(d); |
679 | } | 712 | } |
680 | urlEncodeSpaces_String(canon); | 713 | urlEncodeSpaces_String(canon); |
681 | } | 714 | } |
682 | return canon ? collect_String(canon) : d; | 715 | return canon ? collect_String(canon) : d; |
683 | } | 716 | } |
684 | 717 | ||