diff options
Diffstat (limited to 'xs_url.h')
| -rw-r--r-- | xs_url.h | 64 |
1 files changed, 43 insertions, 21 deletions
| @@ -8,7 +8,6 @@ xs_str *xs_url_dec(const char *str); | |||
| 8 | xs_dict *xs_url_vars(const char *str); | 8 | xs_dict *xs_url_vars(const char *str); |
| 9 | xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *header); | 9 | xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *header); |
| 10 | 10 | ||
| 11 | |||
| 12 | #ifdef XS_IMPLEMENTATION | 11 | #ifdef XS_IMPLEMENTATION |
| 13 | 12 | ||
| 14 | xs_str *xs_url_dec(const char *str) | 13 | xs_str *xs_url_dec(const char *str) |
| @@ -126,6 +125,7 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea | |||
| 126 | xs *l1 = NULL; | 125 | xs *l1 = NULL; |
| 127 | const char *vn = NULL; | 126 | const char *vn = NULL; |
| 128 | const char *fn = NULL; | 127 | const char *fn = NULL; |
| 128 | const char *ct = NULL; | ||
| 129 | char *q; | 129 | char *q; |
| 130 | int po, ps; | 130 | int po, ps; |
| 131 | 131 | ||
| @@ -138,32 +138,47 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea | |||
| 138 | /* skip the \r\n */ | 138 | /* skip the \r\n */ |
| 139 | p += 2; | 139 | p += 2; |
| 140 | 140 | ||
| 141 | /* now on a Content-Disposition... line; get it */ | 141 | /* Tokodon sends also a Content-Type headers, |
| 142 | q = strchr(p, '\r'); | 142 | let's use it to determine the file type */ |
| 143 | s1 = xs_realloc(NULL, q - p + 1); | 143 | do { |
| 144 | memcpy(s1, p, q - p); | 144 | if (p[0] == 13 && p[1] == 10) |
| 145 | s1[q - p] = '\0'; | 145 | break; |
| 146 | 146 | q = strchr(p, '\r'); | |
| 147 | /* move on (over a \r\n) */ | 147 | s1 = xs_realloc(NULL, q - p + 1); |
| 148 | p = q; | 148 | memcpy(s1, p, q - p); |
| 149 | 149 | s1[q - p] = '\0'; | |
| 150 | /* split by " like a primitive man */ | 150 | |
| 151 | l1 = xs_split(s1, "\""); | 151 | if (xs_startswith(s1, "Content-Disposition")) { |
| 152 | /* split by " like a primitive man */ | ||
| 153 | l1 = xs_split(s1, "\""); | ||
| 154 | |||
| 155 | /* get the variable name */ | ||
| 156 | vn = xs_list_get(l1, 1); | ||
| 157 | |||
| 158 | /* is it an attached file? */ | ||
| 159 | if (xs_list_len(l1) >= 4 && strcmp(xs_list_get(l1, 2), "; filename=") == 0) { | ||
| 160 | /* get the file name */ | ||
| 161 | fn = xs_list_get(l1, 3); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | else | ||
| 165 | if (xs_startswith(s1, "Content-Type")) { | ||
| 166 | l1 = xs_split(s1, ":"); | ||
| 152 | 167 | ||
| 153 | /* get the variable name */ | 168 | if (xs_list_len(l1) >= 2) { |
| 154 | vn = xs_list_get(l1, 1); | 169 | ct = xs_lstrip_chars_i(xs_dup(xs_list_get(l1, 1)), " "); |
| 170 | } | ||
| 171 | } | ||
| 155 | 172 | ||
| 156 | /* is it an attached file? */ | 173 | p += (q - p); |
| 157 | if (xs_list_len(l1) >= 4 && strcmp(xs_list_get(l1, 2), "; filename=") == 0) { | 174 | p += 2; // Skip /r/n |
| 158 | /* get the file name */ | 175 | } while (1); |
| 159 | fn = xs_list_get(l1, 3); | ||
| 160 | } | ||
| 161 | 176 | ||
| 162 | /* find the start of the part content */ | 177 | /* find the start of the part content */ |
| 163 | if ((p = xs_memmem(p, p_size - (p - payload), "\r\n\r\n", 4)) == NULL) | 178 | if ((p = xs_memmem(p, p_size - (p - payload), "\r\n", 2)) == NULL) |
| 164 | break; | 179 | break; |
| 165 | 180 | ||
| 166 | p += 4; | 181 | p += 2; // Skip empty line |
| 167 | 182 | ||
| 168 | /* find the next boundary */ | 183 | /* find the next boundary */ |
| 169 | if ((q = xs_memmem(p, p_size - (p - payload), boundary, bsz)) == NULL) | 184 | if ((q = xs_memmem(p, p_size - (p - payload), boundary, bsz)) == NULL) |
| @@ -175,6 +190,13 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea | |||
| 175 | /* is it a filename? */ | 190 | /* is it a filename? */ |
| 176 | if (fn != NULL) { | 191 | if (fn != NULL) { |
| 177 | /* p_var value is a list */ | 192 | /* p_var value is a list */ |
| 193 | /* if filename has no extension and content-type is image, attach extension to the filename */ | ||
| 194 | if (strchr(fn, '.') == NULL && xs_startswith(ct, "image/")) { | ||
| 195 | char *ext = strchr(ct, '/'); | ||
| 196 | ext++; | ||
| 197 | fn = xs_str_cat(xs_str_new(""), fn, ".", ext); | ||
| 198 | } | ||
| 199 | |||
| 178 | xs *l1 = xs_list_new(); | 200 | xs *l1 = xs_list_new(); |
| 179 | xs *vpo = xs_number_new(po); | 201 | xs *vpo = xs_number_new(po); |
| 180 | xs *vps = xs_number_new(ps); | 202 | xs *vps = xs_number_new(ps); |