diff options
| author | 2025-02-15 14:37:36 +0100 | |
|---|---|---|
| committer | 2025-02-15 14:37:36 +0100 | |
| commit | 7611a6bee4bcbad2f1710aafa99aba730e5cf995 (patch) | |
| tree | 33ab7bee30379e16f6869b2efda5494be8aeb858 /xs_url.h | |
| parent | enforce tls when supported && add tests (diff) | |
| parent | Version 2.72 RELEASED. (diff) | |
| download | snac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.tar.gz snac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.tar.xz snac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.zip | |
Merge tag '2.72' into curl-smtp
Version 2.72 RELEASED.
Diffstat (limited to 'xs_url.h')
| -rw-r--r-- | xs_url.h | 117 |
1 files changed, 80 insertions, 37 deletions
| @@ -11,18 +11,57 @@ 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 | ||
| 14 | char *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 | |||
| 14 | xs_str *xs_url_dec(const char *str) | 47 | xs_str *xs_url_dec(const char *str) |
| 15 | /* decodes an URL */ | 48 | /* decodes an URL */ |
| 16 | { | 49 | { |
| 17 | xs_str *s = xs_str_new(NULL); | 50 | xs_str *s = xs_str_new(NULL); |
| 18 | 51 | ||
| 19 | while (*str) { | 52 | while (*str) { |
| 53 | if (!xs_is_string(str)) | ||
| 54 | break; | ||
| 55 | |||
| 20 | if (*str == '%') { | 56 | if (*str == '%') { |
| 21 | unsigned int i; | 57 | unsigned int i; |
| 22 | 58 | ||
| 23 | if (sscanf(str + 1, "%02x", &i) == 1) { | 59 | if (sscanf(str + 1, "%02x", &i) == 1) { |
| 24 | unsigned char uc = i; | 60 | unsigned char uc = i; |
| 25 | 61 | ||
| 62 | if (!xs_is_string((char *)&uc)) | ||
| 63 | break; | ||
| 64 | |||
| 26 | s = xs_append_m(s, (char *)&uc, 1); | 65 | s = xs_append_m(s, (char *)&uc, 1); |
| 27 | str += 2; | 66 | str += 2; |
| 28 | } | 67 | } |
| @@ -69,43 +108,45 @@ xs_dict *xs_url_vars(const char *str) | |||
| 69 | 108 | ||
| 70 | vars = xs_dict_new(); | 109 | vars = xs_dict_new(); |
| 71 | 110 | ||
| 72 | if (str != NULL) { | 111 | if (xs_is_string(str)) { |
| 73 | /* split by arguments */ | 112 | xs *dup = xs_dup(str); |
| 74 | xs *args = xs_split(str, "&"); | 113 | char *k; |
| 75 | 114 | char *saveptr; | |
| 76 | const xs_val *v; | 115 | for (k = strtok_r(dup, "&", &saveptr); |
| 77 | 116 | k; | |
| 78 | xs_list_foreach(args, v) { | 117 | k = strtok_r(NULL, "&", &saveptr)) { |
| 79 | xs *dv = xs_url_dec(v); | 118 | char *v = strchr(k, '='); |
| 80 | xs *kv = xs_split_n(dv, "=", 1); | 119 | if (!v) |
| 81 | 120 | continue; | |
| 82 | if (xs_list_len(kv) == 2) { | 121 | *v++ = '\0'; |
| 83 | const char *key = xs_list_get(kv, 0); | 122 | k = xs_url_dec_in(k, 1); |
| 84 | const char *pv = xs_dict_get(vars, key); | 123 | v = xs_url_dec_in(v, 1); |
| 85 | 124 | if (!xs_is_string(k) || !xs_is_string(v)) | |
| 86 | if (!xs_is_null(pv)) { | 125 | continue; |
| 87 | /* there is a previous value: convert to a list and append */ | 126 | |
| 88 | xs *vlist = NULL; | 127 | const char *pv = xs_dict_get(vars, k); |
| 89 | if (xs_type(pv) == XSTYPE_LIST) | 128 | if (!xs_is_null(pv)) { |
| 90 | vlist = xs_dup(pv); | 129 | /* there is a previous value: convert to a list and append */ |
| 91 | else { | 130 | xs *vlist = NULL; |
| 92 | vlist = xs_list_new(); | 131 | if (xs_type(pv) == XSTYPE_LIST) |
| 93 | vlist = xs_list_append(vlist, pv); | 132 | vlist = xs_dup(pv); |
| 94 | } | ||
| 95 | |||
| 96 | vlist = xs_list_append(vlist, xs_list_get(kv, 1)); | ||
| 97 | vars = xs_dict_set(vars, key, vlist); | ||
| 98 | } | ||
| 99 | else { | 133 | else { |
| 100 | /* ends with []? force to always be a list */ | 134 | vlist = xs_list_new(); |
| 101 | if (xs_endswith(key, "[]")) { | 135 | vlist = xs_list_append(vlist, pv); |
| 102 | xs *vlist = xs_list_new(); | 136 | } |
| 103 | vlist = xs_list_append(vlist, xs_list_get(kv, 1)); | 137 | |
| 104 | vars = xs_dict_append(vars, key, vlist); | 138 | vlist = xs_list_append(vlist, v); |
| 105 | } | 139 | vars = xs_dict_set(vars, k, vlist); |
| 106 | else | 140 | } |
| 107 | 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); | ||
| 108 | } | 147 | } |
| 148 | else | ||
| 149 | vars = xs_dict_append(vars, k, v); | ||
| 109 | } | 150 | } |
| 110 | } | 151 | } |
| 111 | } | 152 | } |
| @@ -233,7 +274,8 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea | |||
| 233 | l1 = xs_list_append(l1, vpo); | 274 | l1 = xs_list_append(l1, vpo); |
| 234 | l1 = xs_list_append(l1, vps); | 275 | l1 = xs_list_append(l1, vps); |
| 235 | 276 | ||
| 236 | p_vars = xs_dict_append(p_vars, vn, l1); | 277 | if (xs_is_string(vn)) |
| 278 | p_vars = xs_dict_append(p_vars, vn, l1); | ||
| 237 | } | 279 | } |
| 238 | else { | 280 | else { |
| 239 | /* regular variable; just copy */ | 281 | /* regular variable; just copy */ |
| @@ -241,7 +283,8 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea | |||
| 241 | memcpy(vc, payload + po, ps); | 283 | memcpy(vc, payload + po, ps); |
| 242 | vc[ps] = '\0'; | 284 | vc[ps] = '\0'; |
| 243 | 285 | ||
| 244 | p_vars = xs_dict_append(p_vars, vn, vc); | 286 | if (xs_is_string(vn) && xs_is_string(vc)) |
| 287 | p_vars = xs_dict_append(p_vars, vn, vc); | ||
| 245 | } | 288 | } |
| 246 | 289 | ||
| 247 | /* move on */ | 290 | /* move on */ |