3 int is_urlschemechar(int first_flag
, int ch
)
6 * The set of valid URL schemes, as per STD66 (RFC3986) is
7 * '[A-Za-z][A-Za-z0-9+.-]*'. But use sightly looser check
8 * of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
9 * of check used '[A-Za-z0-9]+' so not to break any remote
12 int alphanumeric
, special
;
13 alphanumeric
= ch
> 0 && isalnum(ch
);
14 special
= ch
== '+' || ch
== '-' || ch
== '.';
15 return alphanumeric
|| (!first_flag
&& special
);
18 int is_url(const char *url
)
20 const char *url2
, *first_slash
;
25 first_slash
= strchr(url
, '/');
27 /* Input with no slash at all or slash first can't be URL. */
28 if (!first_slash
|| first_slash
== url
)
30 /* Character before must be : and next must be /. */
31 if (first_slash
[-1] != ':' || first_slash
[1] != '/')
33 /* There must be something before the :// */
34 if (first_slash
== url
+ 1)
37 * Check all characters up to first slash - 1. Only alphanum
41 while (url2
< first_slash
- 1) {
42 if (!is_urlschemechar(url2
== url
, (unsigned char)*url2
))
51 static int url_decode_char(const char *q
)
54 unsigned char val
= 0;
55 for (i
= 0; i
< 2; i
++) {
56 unsigned char c
= *q
++;
58 if (c
>= '0' && c
<= '9')
60 else if (c
>= 'a' && c
<= 'f')
62 else if (c
>= 'A' && c
<= 'F')
70 static char *url_decode_internal(const char **query
, const char *stop_at
, struct strbuf
*out
)
72 const char *q
= *query
;
79 if (stop_at
&& strchr(stop_at
, c
)) {
85 int val
= url_decode_char(q
+ 1);
87 strbuf_addch(out
, val
);
94 strbuf_addch(out
, ' ');
100 return strbuf_detach(out
, NULL
);
103 char *url_decode(const char *url
)
105 struct strbuf out
= STRBUF_INIT
;
106 const char *slash
= strchr(url
, '/');
108 /* Skip protocol part if present */
109 if (slash
&& url
< slash
) {
110 strbuf_add(&out
, url
, slash
- url
);
113 return url_decode_internal(&url
, NULL
, &out
);
116 char *url_decode_parameter_name(const char **query
)
118 struct strbuf out
= STRBUF_INIT
;
119 return url_decode_internal(query
, "&=", &out
);
122 char *url_decode_parameter_value(const char **query
)
124 struct strbuf out
= STRBUF_INIT
;
125 return url_decode_internal(query
, "&", &out
);