4 int is_urlschemechar(int first_flag
, int ch
)
7 * The set of valid URL schemes, as per STD66 (RFC3986) is
8 * '[A-Za-z][A-Za-z0-9+.-]*'. But use sightly looser check
9 * of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
10 * of check used '[A-Za-z0-9]+' so not to break any remote
13 int alphanumeric
, special
;
14 alphanumeric
= ch
> 0 && isalnum(ch
);
15 special
= ch
== '+' || ch
== '-' || ch
== '.';
16 return alphanumeric
|| (!first_flag
&& special
);
19 int is_url(const char *url
)
21 /* Is "scheme" part reasonable? */
22 if (!url
|| !is_urlschemechar(1, *url
++))
24 while (*url
&& *url
!= ':') {
25 if (!is_urlschemechar(0, *url
++))
28 /* We've seen "scheme"; we want colon-slash-slash */
29 return (url
[0] == ':' && url
[1] == '/' && url
[2] == '/');
32 static char *url_decode_internal(const char **query
, int len
,
33 const char *stop_at
, struct strbuf
*out
,
36 const char *q
= *query
;
43 if (stop_at
&& strchr(stop_at
, c
)) {
50 int val
= hex2chr(q
+ 1);
52 strbuf_addch(out
, val
);
59 if (decode_plus
&& c
== '+')
60 strbuf_addch(out
, ' ');
67 return strbuf_detach(out
, NULL
);
70 char *url_decode(const char *url
)
72 return url_decode_mem(url
, strlen(url
));
75 char *url_decode_mem(const char *url
, int len
)
77 struct strbuf out
= STRBUF_INIT
;
78 const char *colon
= memchr(url
, ':', len
);
80 /* Skip protocol part if present */
81 if (colon
&& url
< colon
) {
82 strbuf_add(&out
, url
, colon
- url
);
86 return url_decode_internal(&url
, len
, NULL
, &out
, 0);
89 char *url_decode_parameter_name(const char **query
)
91 struct strbuf out
= STRBUF_INIT
;
92 return url_decode_internal(query
, -1, "&=", &out
, 1);
95 char *url_decode_parameter_value(const char **query
)
97 struct strbuf out
= STRBUF_INIT
;
98 return url_decode_internal(query
, -1, "&", &out
, 1);
101 void end_url_with_slash(struct strbuf
*buf
, const char *url
)
103 strbuf_addstr(buf
, url
);
104 strbuf_complete(buf
, '/');
107 void str_end_url_with_slash(const char *url
, char **dest
) {
108 struct strbuf buf
= STRBUF_INIT
;
109 end_url_with_slash(&buf
, url
);
111 *dest
= strbuf_detach(&buf
, NULL
);