summaryrefslogtreecommitdiff
path: root/xs_url.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_url.h')
-rw-r--r--xs_url.h103
1 files changed, 69 insertions, 34 deletions
diff --git a/xs_url.h b/xs_url.h
index 8e2e243..bb31779 100644
--- a/xs_url.h
+++ b/xs_url.h
@@ -11,6 +11,39 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
11 11
12#ifdef XS_IMPLEMENTATION 12#ifdef XS_IMPLEMENTATION
13 13
14char *xs_url_dec_in(char *str, int qs)
15{
16 char *w = str;
17 char *r;
18
19 for (r = str; *r != '\0'; r++) {
20 switch (*r) {
21 case '%': {
22 unsigned hex;
23 if (!r[1] || !r[2])
24 return NULL;
25 if (sscanf(r + 1, "%2x", &hex) != 1)
26 return NULL;
27 *w++ = hex;
28 r += 2;
29 break;
30 }
31
32 case '+':
33 if (qs) {
34 *w++ = ' ';
35 break;
36 }
37 /* fall-through */
38 default:
39 *w++ = *r;
40 }
41 }
42
43 *w++ = '\0';
44 return str;
45}
46
14xs_str *xs_url_dec(const char *str) 47xs_str *xs_url_dec(const char *str)
15/* decodes an URL */ 48/* decodes an URL */
16{ 49{
@@ -76,42 +109,44 @@ xs_dict *xs_url_vars(const char *str)
76 vars = xs_dict_new(); 109 vars = xs_dict_new();
77 110
78 if (xs_is_string(str)) { 111 if (xs_is_string(str)) {
79 /* split by arguments */ 112 xs *dup = xs_dup(str);
80 xs *args = xs_split(str, "&"); 113 char *k;
81 114 char *saveptr;
82 const xs_val *v; 115 for (k = strtok_r(dup, "&", &saveptr);
83 116 k;
84 xs_list_foreach(args, v) { 117 k = strtok_r(NULL, "&", &saveptr)) {
85 xs *dv = xs_url_dec(v); 118 char *v = strchr(k, '=');
86 xs *kv = xs_split_n(dv, "=", 1); 119 if (!v)
87 120 continue;
88 if (xs_list_len(kv) == 2) { 121 *v++ = '\0';
89 const char *key = xs_list_get(kv, 0); 122 k = xs_url_dec_in(k, 1);
90 const char *pv = xs_dict_get(vars, key); 123 v = xs_url_dec_in(v, 1);
91 124 if (!xs_is_string(k) || !xs_is_string(v))
92 if (!xs_is_null(pv)) { 125 continue;
93 /* there is a previous value: convert to a list and append */ 126
94 xs *vlist = NULL; 127 const char *pv = xs_dict_get(vars, k);
95 if (xs_type(pv) == XSTYPE_LIST) 128 if (!xs_is_null(pv)) {
96 vlist = xs_dup(pv); 129 /* there is a previous value: convert to a list and append */
97 else { 130 xs *vlist = NULL;
98 vlist = xs_list_new(); 131 if (xs_type(pv) == XSTYPE_LIST)
99 vlist = xs_list_append(vlist, pv); 132 vlist = xs_dup(pv);
100 }
101
102 vlist = xs_list_append(vlist, xs_list_get(kv, 1));
103 vars = xs_dict_set(vars, key, vlist);
104 }
105 else { 133 else {
106 /* ends with []? force to always be a list */ 134 vlist = xs_list_new();
107 if (xs_endswith(key, "[]")) { 135 vlist = xs_list_append(vlist, pv);
108 xs *vlist = xs_list_new(); 136 }
109 vlist = xs_list_append(vlist, xs_list_get(kv, 1)); 137
110 vars = xs_dict_append(vars, key, vlist); 138 vlist = xs_list_append(vlist, v);
111 } 139 vars = xs_dict_set(vars, k, vlist);
112 else 140 }
113 vars = xs_dict_append(vars, key, xs_list_get(kv, 1)); 141 else {
142 /* ends with []? force to always be a list */
143 if (xs_endswith(k, "[]")) {
144 xs *vlist = xs_list_new();
145 vlist = xs_list_append(vlist, v);
146 vars = xs_dict_append(vars, k, vlist);
114 } 147 }
148 else
149 vars = xs_dict_append(vars, k, v);
115 } 150 }
116 } 151 }
117 } 152 }