diff options
Diffstat (limited to 'src/gmutil.c')
-rw-r--r-- | src/gmutil.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/gmutil.c b/src/gmutil.c index 4b144097..52fe6b28 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -27,6 +27,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
27 | #include <the_Foundation/path.h> | 27 | #include <the_Foundation/path.h> |
28 | 28 | ||
29 | void init_Url(iUrl *d, const iString *text) { | 29 | void init_Url(iUrl *d, const iString *text) { |
30 | /* Handle "file:" as a special case since it only has the path part. */ | ||
31 | if (startsWithCase_String(text, "file://")) { | ||
32 | iZap(*d); | ||
33 | const char *cstr = constBegin_String(text); | ||
34 | d->scheme = (iRangecc){ cstr, cstr + 4 }; | ||
35 | d->path = (iRangecc){ cstr + 7, constEnd_String(text) }; | ||
36 | return; | ||
37 | } | ||
30 | static iRegExp *absoluteUrlPattern_; | 38 | static iRegExp *absoluteUrlPattern_; |
31 | static iRegExp *relativeUrlPattern_; | 39 | static iRegExp *relativeUrlPattern_; |
32 | if (!absoluteUrlPattern_) { | 40 | if (!absoluteUrlPattern_) { |
@@ -98,8 +106,11 @@ void cleanUrlPath_String(iString *d) { | |||
98 | else if (equal_Rangecc(seg, ".")) { | 106 | else if (equal_Rangecc(seg, ".")) { |
99 | /* Skip it. */ | 107 | /* Skip it. */ |
100 | } | 108 | } |
101 | else { | 109 | else if (!isEmpty_Range(&seg)) { |
102 | appendCStr_String(&clean, "/"); | 110 | /* Ensure the cleaned path starts with a slash if the original does. */ |
111 | if (!isEmpty_String(&clean) || startsWith_Rangecc(parts.path, "/")) { | ||
112 | appendCStr_String(&clean, "/"); | ||
113 | } | ||
103 | appendRange_String(&clean, seg); | 114 | appendRange_String(&clean, seg); |
104 | } | 115 | } |
105 | } | 116 | } |
@@ -127,6 +138,10 @@ iRangecc urlHost_String(const iString *d) { | |||
127 | return url.host; | 138 | return url.host; |
128 | } | 139 | } |
129 | 140 | ||
141 | static iBool isAbsolutePath_(iRangecc path) { | ||
142 | return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); | ||
143 | } | ||
144 | |||
130 | const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { | 145 | const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { |
131 | iUrl orig; | 146 | iUrl orig; |
132 | iUrl rel; | 147 | iUrl rel; |
@@ -155,7 +170,7 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat | |||
155 | appendRange_String(absolute, selHost->port); | 170 | appendRange_String(absolute, selHost->port); |
156 | } | 171 | } |
157 | } | 172 | } |
158 | if (isDef_(rel.scheme) || isDef_(rel.host) || startsWith_Rangecc(rel.path, "/")) { | 173 | if (isDef_(rel.scheme) || isDef_(rel.host) || isAbsolutePath_(rel.path)) { |
159 | appendRange_String(absolute, isDef_(rel.path) ? rel.path : range_CStr("/")); /* absolute path */ | 174 | appendRange_String(absolute, isDef_(rel.path) ? rel.path : range_CStr("/")); /* absolute path */ |
160 | } | 175 | } |
161 | else { | 176 | else { |
@@ -180,10 +195,15 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat | |||
180 | iString *makeFileUrl_String(const iString *localFilePath) { | 195 | iString *makeFileUrl_String(const iString *localFilePath) { |
181 | iString *url = cleaned_Path(localFilePath); | 196 | iString *url = cleaned_Path(localFilePath); |
182 | replace_Block(&url->chars, '\\', '/'); /* in case it's a Windows path */ | 197 | replace_Block(&url->chars, '\\', '/'); /* in case it's a Windows path */ |
198 | set_String(url, collect_String(urlEncodeExclude_String(url, "/"))); | ||
183 | prependCStr_String(url, "file://"); | 199 | prependCStr_String(url, "file://"); |
184 | return url; | 200 | return url; |
185 | } | 201 | } |
186 | 202 | ||
203 | const char *makeFileUrl_CStr(const char *localFilePath) { | ||
204 | return cstrCollect_String(makeFileUrl_String(collectNewCStr_String(localFilePath))); | ||
205 | } | ||
206 | |||
187 | void urlEncodeSpaces_String(iString *d) { | 207 | void urlEncodeSpaces_String(iString *d) { |
188 | for (;;) { | 208 | for (;;) { |
189 | const size_t pos = indexOfCStr_String(d, " "); | 209 | const size_t pos = indexOfCStr_String(d, " "); |