summaryrefslogtreecommitdiff
path: root/xs_url.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_url.h')
-rw-r--r--xs_url.h64
1 files changed, 43 insertions, 21 deletions
diff --git a/xs_url.h b/xs_url.h
index 3a063cd..9deda38 100644
--- a/xs_url.h
+++ b/xs_url.h
@@ -8,7 +8,6 @@ xs_str *xs_url_dec(const char *str);
8xs_dict *xs_url_vars(const char *str); 8xs_dict *xs_url_vars(const char *str);
9xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *header); 9xs_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
14xs_str *xs_url_dec(const char *str) 13xs_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);