summaryrefslogtreecommitdiff
path: root/xs_url.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_url.h')
-rw-r--r--xs_url.h72
1 files changed, 50 insertions, 22 deletions
diff --git a/xs_url.h b/xs_url.h
index 606c3e4..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)
@@ -107,7 +106,13 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
107 if (xs_list_len(l1) != 2) 106 if (xs_list_len(l1) != 2)
108 return NULL; 107 return NULL;
109 108
110 boundary = xs_fmt("--%s", xs_list_get(l1, 1)); 109 boundary = xs_dup(xs_list_get(l1, 1));
110
111 /* Tokodon sends the boundary header with double quotes surrounded */
112 if (xs_starts_and_ends("\"", boundary, "\"") != 0)
113 boundary = xs_strip_chars_i(boundary, "\"");
114
115 boundary = xs_fmt("--%s", boundary);
111 } 116 }
112 117
113 bsz = strlen(boundary); 118 bsz = strlen(boundary);
@@ -120,6 +125,7 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
120 xs *l1 = NULL; 125 xs *l1 = NULL;
121 const char *vn = NULL; 126 const char *vn = NULL;
122 const char *fn = NULL; 127 const char *fn = NULL;
128 const char *ct = NULL;
123 char *q; 129 char *q;
124 int po, ps; 130 int po, ps;
125 131
@@ -132,32 +138,47 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
132 /* skip the \r\n */ 138 /* skip the \r\n */
133 p += 2; 139 p += 2;
134 140
135 /* now on a Content-Disposition... line; get it */ 141 /* Tokodon sends also a Content-Type headers,
136 q = strchr(p, '\r'); 142 let's use it to determine the file type */
137 s1 = xs_realloc(NULL, q - p + 1); 143 do {
138 memcpy(s1, p, q - p); 144 if (p[0] == 13 && p[1] == 10)
139 s1[q - p] = '\0'; 145 break;
140 146 q = strchr(p, '\r');
141 /* move on (over a \r\n) */ 147 s1 = xs_realloc(NULL, q - p + 1);
142 p = q; 148 memcpy(s1, p, q - p);
143 149 s1[q - p] = '\0';
144 /* split by " like a primitive man */ 150
145 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, ":");
146 167
147 /* get the variable name */ 168 if (xs_list_len(l1) >= 2) {
148 vn = xs_list_get(l1, 1); 169 ct = xs_lstrip_chars_i(xs_dup(xs_list_get(l1, 1)), " ");
170 }
171 }
149 172
150 /* is it an attached file? */ 173 p += (q - p);
151 if (xs_list_len(l1) >= 4 && strcmp(xs_list_get(l1, 2), "; filename=") == 0) { 174 p += 2; // Skip /r/n
152 /* get the file name */ 175 } while (1);
153 fn = xs_list_get(l1, 3);
154 }
155 176
156 /* find the start of the part content */ 177 /* find the start of the part content */
157 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)
158 break; 179 break;
159 180
160 p += 4; 181 p += 2; // Skip empty line
161 182
162 /* find the next boundary */ 183 /* find the next boundary */
163 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)
@@ -169,6 +190,13 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
169 /* is it a filename? */ 190 /* is it a filename? */
170 if (fn != NULL) { 191 if (fn != NULL) {
171 /* 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
172 xs *l1 = xs_list_new(); 200 xs *l1 = xs_list_new();
173 xs *vpo = xs_number_new(po); 201 xs *vpo = xs_number_new(po);
174 xs *vps = xs_number_new(ps); 202 xs *vps = xs_number_new(ps);