summaryrefslogtreecommitdiff
path: root/src/gmutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gmutil.c')
-rw-r--r--src/gmutil.c43
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
256const 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
256static iBool isAbsolutePath_(iRangecc path) { 267static 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
333void 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
322iBool isKnownScheme_Rangecc(iRangecc scheme) { 355iBool 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) {
651const iString *canonicalUrl_String(const iString *d) { 684const 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