contrib: soxr: enable by default
[vlc.git] / modules / access / http / message_test.c
blob003f14a3467108c87d9c199f2e8f604d0ba306f1
1 /*****************************************************************************
2 * message_test.c: HTTP request/response test
3 *****************************************************************************
4 * Copyright (C) 2015 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #undef NDEBUG
27 #include <assert.h>
28 #include <errno.h>
29 #include <stdbool.h>
30 #include <stdlib.h>
31 #include <string.h>
33 #include <vlc_common.h>
34 #include "message.h"
35 #include "h2frame.h"
37 static void check_req(const struct vlc_http_msg *m)
39 const char *str;
41 assert(vlc_http_msg_get_status(m) < 0);
42 str = vlc_http_msg_get_method(m);
43 assert(str != NULL && !strcmp(str, "GET"));
44 str = vlc_http_msg_get_scheme(m);
45 assert(str != NULL && !strcmp(str, "http"));
46 str = vlc_http_msg_get_authority(m);
47 assert(str != NULL && !strcmp(str, "www.example.com"));
48 str = vlc_http_msg_get_path(m);
49 assert(str != NULL && !strcmp(str, "/"));
50 assert(vlc_http_msg_get_size(m) == 0);
52 str = vlc_http_msg_get_header(m, "Cache-Control");
53 assert(str != NULL && !strcmp(str, "no-cache"));
54 str = vlc_http_msg_get_header(m, "Custom-Key");
55 assert(str != NULL && !strcmp(str, "custom-value"));
57 str = vlc_http_msg_get_header(m, "Date");
58 assert(str == NULL);
61 static void check_resp(const struct vlc_http_msg *m)
63 const char *str;
65 assert(vlc_http_msg_get_status(m) == 200);
66 str = vlc_http_msg_get_method(m);
67 assert(str == NULL);
68 str = vlc_http_msg_get_scheme(m);
69 assert(str == NULL);
70 str = vlc_http_msg_get_authority(m);
71 assert(str == NULL);
72 str = vlc_http_msg_get_path(m);
73 assert(str == NULL);
75 str = vlc_http_msg_get_header(m, "Cache-Control");
76 assert(str != NULL && !strcmp(str, "private"));
77 str = vlc_http_msg_get_header(m, "Date");
78 assert(str != NULL && !strcmp(str, "Mon, 21 Oct 2013 20:13:22 GMT"));
79 str = vlc_http_msg_get_header(m, "Location");
80 assert(str != NULL && !strcmp(str, "https://www.example.com"));
81 str = vlc_http_msg_get_header(m, "Content-Encoding");
82 assert(str != NULL && !strcmp(str, "gzip"));
83 str = vlc_http_msg_get_header(m, "Set-Cookie");
84 assert(str != NULL && !strcmp(str, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; "
85 "max-age=3600; version=1"));
87 str = vlc_http_msg_get_header(m, "Custom-Key");
88 assert(str == NULL);
91 static void check_connect(const struct vlc_http_msg *m)
93 const char *str;
95 assert(vlc_http_msg_get_status(m) < 0);
96 str = vlc_http_msg_get_method(m);
97 assert(str != NULL && !strcmp(str, "CONNECT"));
98 str = vlc_http_msg_get_scheme(m);
99 assert(str == NULL);
100 str = vlc_http_msg_get_authority(m);
101 assert(str != NULL && !strcmp(str, "www.example.com"));
102 str = vlc_http_msg_get_path(m);
103 assert(str == NULL);
105 str = vlc_http_msg_get_header(m, "Custom-Key");
106 assert(str == NULL);
109 static void check_msg(struct vlc_http_msg *in,
110 void (*cb)(const struct vlc_http_msg *))
112 struct vlc_http_msg *out;
113 char *m1;
114 size_t len;
116 cb(in);
118 m1 = vlc_http_msg_format(in, &len, false);
119 assert(m1 != NULL);
120 assert(strlen(m1) == len);
121 out = vlc_http_msg_headers(m1);
122 fprintf(stderr, "%s", m1);
123 free(m1);
124 /* XXX: request parsing not implemented/needed yet */
125 if (vlc_http_msg_get_status(in) >= 0)
127 assert(out != NULL);
128 cb(out);
129 vlc_http_msg_destroy(out);
132 out = (struct vlc_http_msg *)vlc_http_msg_h2_frame(in, 1, true);
133 assert(out != NULL);
134 cb(out);
135 assert(vlc_http_msg_read(out) == NULL);
136 vlc_http_msg_destroy(out);
138 cb(in);
139 vlc_http_msg_destroy(in);
142 static time_t parse_date(const char *str)
144 struct vlc_http_msg *m;
145 time_t t1, t2;
147 m = vlc_http_req_create("GET", "http", "www.example.com", "/");
148 assert(m != NULL);
149 assert(vlc_http_msg_add_header(m, "Date", "%s", str) == 0);
150 t1 = vlc_http_msg_get_atime(m);
151 assert(vlc_http_msg_add_header(m, "Last-Modified", "%s", str) == 0);
152 t2 = vlc_http_msg_get_mtime(m);
153 assert(vlc_http_msg_get_retry_after(m) == 0);
154 assert(vlc_http_msg_add_header(m, "Retry-After", "%s", str) == 0);
155 vlc_http_msg_get_retry_after(m);
156 vlc_http_msg_destroy(m);
158 assert(t1 == t2);
159 return t1;
162 static const char *check_realm(const char *line, const char *realm)
164 struct vlc_http_msg *m;
165 char *value;
167 m = vlc_http_resp_create(401);
168 assert(m != NULL);
169 assert(vlc_http_msg_add_header(m, "WWW-Authenticate", "%s", line) == 0);
170 value = vlc_http_msg_get_basic_realm(m);
171 if (realm == NULL)
172 assert(value == NULL);
173 else
175 assert(value != NULL);
176 assert(!strcmp(value, realm));
177 free(value);
179 vlc_http_msg_destroy(m);
180 return realm;
183 int main(void)
185 struct vlc_http_msg *m;
186 const char *str;
187 int ret;
189 /* Formatting and parsing */
190 m = vlc_http_req_create("GET", "http", "www.example.com", "/");
191 assert(m != NULL);
192 ret = vlc_http_msg_add_header(m, "Cache-Control", "no-cache");
193 assert(ret == 0);
194 vlc_http_msg_add_header(m, "Custom-Key", "%s", "custom-value");
195 assert(ret == 0);
196 check_msg(m, check_req);
198 m = vlc_http_resp_create(200);
199 assert(m != NULL);
200 ret = vlc_http_msg_add_header(m, "cache-control", "private");
201 assert(ret == 0);
202 ret = vlc_http_msg_add_header(m, "date", "Mon, 21 Oct 2013 20:13:22 GMT");
203 assert(ret == 0);
204 ret = vlc_http_msg_add_header(m, "location", "https://www.example.com");
205 assert(ret == 0);
206 ret = vlc_http_msg_add_header(m, "content-encoding", "gzip");
207 assert(ret == 0);
208 ret = vlc_http_msg_add_header(m, "set-cookie", "foo=%s; max-age=%u; "
209 "version=%u", "ASDJKHQKBZXOQWEOPIUAXQWEOIU",
210 3600, 1);
211 assert(ret == 0);
212 check_msg(m, check_resp);
214 m = vlc_http_req_create("CONNECT", NULL, "www.example.com", NULL);
215 assert(m != NULL);
216 check_msg(m, check_connect);
218 /* Helpers */
219 assert(parse_date("Sun, 06 Nov 1994 08:49:37 GMT") == 784111777);
220 assert(parse_date("Sunday, 06-Nov-94 08:49:37 GMT") == 784111777);
221 assert(parse_date("Sun Nov 6 08:49:37 1994") == 784111777);
222 assert(parse_date("Sunday, 06-Nov-14 08:49:37 GMT") == 1415263777);
223 assert(parse_date("Sun, 06 Bug 1994 08:49:37 GMT") == -1);
224 assert(parse_date("bogus") == -1);
226 assert(check_realm("Basic realm=\"kingdom\"", "kingdom"));
227 assert(check_realm("BaSiC REALM= \"kingdom\"", "kingdom"));
228 assert(check_realm("basic Realm\t=\"kingdom\"", "kingdom"));
229 assert(check_realm("Basic charset=\"utf-8\", realm=\"kingdom\"",
230 "kingdom"));
231 assert(check_realm("Basic realm=\"Realm is \\\"Hello world!\\\"\"",
232 "Realm is \"Hello world!\""));
233 assert(check_realm("Basic", NULL) == NULL);
235 m = vlc_http_req_create("PRI", "https", "*", NULL);
236 assert(m != NULL);
238 assert(vlc_http_msg_add_agent(m, "Foo") == 0);
239 assert(vlc_http_msg_add_agent(m, "Foo/1.0") == 0);
240 assert(vlc_http_msg_add_agent(m, "Foo/1.0 (Hello world) Bar/2.3") == 0);
241 assert(vlc_http_msg_add_agent(m, "Foo/1.0 (compatible (\\(!))") == 0);
243 assert(vlc_http_msg_add_atime(m) == 0);
244 time_t t = vlc_http_msg_get_atime(m);
245 assert(t != (time_t)-1);
246 assert(vlc_http_msg_add_time(m, "Last-Modified", &t) == 0);
247 assert(t == vlc_http_msg_get_mtime(m));
249 assert(vlc_http_msg_add_creds_basic(m, false,
250 "Aladdin", "open sesame") == 0);
251 assert(vlc_http_msg_add_creds_basic(m, true, "test", "123£") == 0);
252 str = vlc_http_msg_get_header(m, "Authorization");
253 assert(str != NULL && !strcmp(str, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="));
254 str = vlc_http_msg_get_header(m, "Proxy-Authorization");
255 assert(str != NULL && !strcmp(str, "Basic dGVzdDoxMjPCow=="));
257 vlc_http_msg_add_header(m, "Content-Length", "1234");
258 assert(vlc_http_msg_get_size(m) == 1234);
260 /* Folding */
261 vlc_http_msg_add_header(m, "X-Folded", "Hello\n\tworld!");
262 str = vlc_http_msg_get_header(m, "x-folded");
263 assert(str != NULL && !strcmp(str, "Hello \tworld!"));
265 vlc_http_msg_add_header(m, "TE", "gzip");
266 vlc_http_msg_add_header(m, "TE", "deflate");
267 vlc_http_msg_add_header(m, "Pragma", " features=\"broadcast,playlist\"");
268 vlc_http_msg_add_header(m, "Pragma", " client-id=123456789 ");
269 vlc_http_msg_add_header(m, "Pragma", "evulz=\"foo \\\"\\ bar\"");
270 vlc_http_msg_add_header(m, "Pragma", "no-cache ");
272 str = vlc_http_msg_get_header(m, "TE");
273 assert(str != NULL && !strcmp(str, "gzip, deflate"));
274 str = vlc_http_msg_get_token(m, "TE", "gzip");
275 assert(str != NULL && !strncmp(str, "gzip", 4));
276 str = vlc_http_msg_get_token(m, "TE", "deflate");
277 assert(str != NULL && !strncmp(str, "deflate", 7));
278 str = vlc_http_msg_get_token(m, "TE", "compress");
279 assert(str == NULL);
280 str = vlc_http_msg_get_token(m, "TE", "zip");
281 assert(str == NULL);
282 str = vlc_http_msg_get_token(m, "TE", "late");
283 assert(str == NULL);
284 str = vlc_http_msg_get_token(m, "Accept-Encoding", "gzip");
285 assert(str == NULL);
286 str = vlc_http_msg_get_token(m, "Pragma", "features");
287 assert(str != NULL && !strncmp(str, "features=\"", 10));
288 str = vlc_http_msg_get_token(m, "Pragma", "broadcast");
289 assert(str == NULL);
290 str = vlc_http_msg_get_token(m, "Pragma", "playlist");
291 assert(str == NULL);
292 str = vlc_http_msg_get_token(m, "Pragma", "client-id");
293 assert(str != NULL && !strncmp(str, "client-id=", 10));
294 str = vlc_http_msg_get_token(m, "Pragma", "123456789");
295 assert(str == NULL);
296 str = vlc_http_msg_get_token(m, "Pragma", "no-cache");
297 assert(str != NULL && !strcmp(str, "no-cache"));
299 vlc_http_msg_add_header(m, "Cookie", "a=1");
300 vlc_http_msg_add_header(m, "Cookie", "b=2");
301 str = vlc_http_msg_get_header(m, "Cookie");
302 assert(str != NULL && !strcmp(str, "a=1; b=2"));
304 /* Error cases */
305 assert(vlc_http_msg_add_header(m, "/naughty", "header") == -1);
306 assert(vlc_http_msg_add_header(m, "", "void") == -1);
308 assert(vlc_http_msg_add_agent(m, "") != 0);
309 assert(vlc_http_msg_add_agent(m, "/1.0") != 0);
310 assert(vlc_http_msg_add_agent(m, "Bad/1.0\"") != 0);
311 assert(vlc_http_msg_add_agent(m, "Bad/1.0 (\\)") != 0);
312 assert(vlc_http_msg_add_agent(m, "Bad/1.0 (\\\x08)") != 0);
313 assert(vlc_http_msg_add_agent(m, "Bad/1.0 \"Evil\"") != 0);
314 assert(vlc_http_msg_add_agent(m, "(Hello world)") != 0);
316 assert(vlc_http_msg_add_creds_basic(m, false, "User:name", "12345") != 0);
317 assert(vlc_http_msg_add_creds_basic(m, false, "Alice\nand\nbob", "") != 0);
318 assert(vlc_http_msg_add_creds_basic(m, false, "john", "asdfg\x7f") != 0);
320 vlc_http_msg_destroy(m);
322 const char *bad1[][2] = {
323 { ":status", "200" },
324 { ":status", "200" },
325 { "Server", "BigBad/1.0" },
328 m = vlc_http_msg_h2_headers(3, bad1);
329 assert(m == NULL);
331 /* HTTP 1.x parser error cases */
332 assert(vlc_http_msg_headers("") == NULL);
333 assert(vlc_http_msg_headers("\r\n") == NULL);
334 assert(vlc_http_msg_headers("HTTP/1.1 200 OK") == NULL);
335 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\nH: V\r\n") == NULL);
336 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\n"
337 ":status: 200\r\n\r\n") == NULL);
338 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\n"
339 "/naughty: invalid\r\n\r\n") == NULL);
341 return 0;
344 /* Callback for vlc_http_msg_h2_frame */
345 struct vlc_h2_frame *
346 vlc_h2_frame_headers(uint_fast32_t id, uint_fast32_t mtu, bool eos,
347 unsigned count, const char *const tab[][2])
349 struct vlc_http_msg *m;
351 assert(id == 1);
352 assert(mtu == VLC_H2_DEFAULT_MAX_FRAME);
353 assert(eos);
355 const char *headers[VLC_H2_MAX_HEADERS][2];
357 for (unsigned i = 0; i < count; i++)
359 headers[i][0] = tab[i][0];
360 headers[i][1] = tab[i][1];
363 m = vlc_http_msg_h2_headers(count, headers);
364 return (struct vlc_h2_frame *)m; /* gruik */