qt: playlist: use item title if available
[vlc.git] / modules / access / http / message_test.c
blob8f9f2633db67a6225adb35dbff108c2a16b92efe
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 const char vlc_module_name[] = "test_http_msg";
39 static void check_req(const struct vlc_http_msg *m)
41 const char *str;
43 assert(vlc_http_msg_get_status(m) < 0);
44 str = vlc_http_msg_get_method(m);
45 assert(str != NULL && !strcmp(str, "GET"));
46 str = vlc_http_msg_get_scheme(m);
47 assert(str != NULL && !strcmp(str, "http"));
48 str = vlc_http_msg_get_authority(m);
49 assert(str != NULL && !strcmp(str, "www.example.com"));
50 str = vlc_http_msg_get_path(m);
51 assert(str != NULL && !strcmp(str, "/"));
52 assert(vlc_http_msg_get_size(m) == 0);
54 str = vlc_http_msg_get_header(m, "Cache-Control");
55 assert(str != NULL && !strcmp(str, "no-cache"));
56 str = vlc_http_msg_get_header(m, "Custom-Key");
57 assert(str != NULL && !strcmp(str, "custom-value"));
59 str = vlc_http_msg_get_header(m, "Date");
60 assert(str == NULL);
63 static void check_resp(const struct vlc_http_msg *m)
65 const char *str;
67 assert(vlc_http_msg_get_status(m) == 200);
68 str = vlc_http_msg_get_method(m);
69 assert(str == NULL);
70 str = vlc_http_msg_get_scheme(m);
71 assert(str == NULL);
72 str = vlc_http_msg_get_authority(m);
73 assert(str == NULL);
74 str = vlc_http_msg_get_path(m);
75 assert(str == NULL);
77 str = vlc_http_msg_get_header(m, "Cache-Control");
78 assert(str != NULL && !strcmp(str, "private"));
79 str = vlc_http_msg_get_header(m, "Date");
80 assert(str != NULL && !strcmp(str, "Mon, 21 Oct 2013 20:13:22 GMT"));
81 str = vlc_http_msg_get_header(m, "Location");
82 assert(str != NULL && !strcmp(str, "https://www.example.com"));
83 str = vlc_http_msg_get_header(m, "Content-Encoding");
84 assert(str != NULL && !strcmp(str, "gzip"));
85 str = vlc_http_msg_get_header(m, "Set-Cookie");
86 assert(str != NULL && !strcmp(str, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; "
87 "max-age=3600; version=1"));
89 str = vlc_http_msg_get_header(m, "Custom-Key");
90 assert(str == NULL);
93 static void check_connect(const struct vlc_http_msg *m)
95 const char *str;
97 assert(vlc_http_msg_get_status(m) < 0);
98 str = vlc_http_msg_get_method(m);
99 assert(str != NULL && !strcmp(str, "CONNECT"));
100 str = vlc_http_msg_get_scheme(m);
101 assert(str == NULL);
102 str = vlc_http_msg_get_authority(m);
103 assert(str != NULL && !strcmp(str, "www.example.com"));
104 str = vlc_http_msg_get_path(m);
105 assert(str == NULL);
107 str = vlc_http_msg_get_header(m, "Custom-Key");
108 assert(str == NULL);
111 static void check_msg(struct vlc_http_msg *in,
112 void (*cb)(const struct vlc_http_msg *))
114 struct vlc_http_msg *out;
115 char *m1;
116 size_t len;
118 cb(in);
120 m1 = vlc_http_msg_format(in, &len, false, true);
121 assert(m1 != NULL);
122 assert(strlen(m1) == len);
123 out = vlc_http_msg_headers(m1);
124 fprintf(stderr, "%s", m1);
125 free(m1);
126 /* XXX: request parsing not implemented/needed yet */
127 if (vlc_http_msg_get_status(in) >= 0)
129 assert(out != NULL);
130 cb(out);
131 vlc_http_msg_destroy(out);
134 out = (struct vlc_http_msg *)vlc_http_msg_h2_frame(in, 1, true);
135 assert(out != NULL);
136 cb(out);
137 assert(vlc_http_msg_read(out) == NULL);
138 vlc_http_msg_destroy(out);
140 cb(in);
141 vlc_http_msg_destroy(in);
144 static time_t parse_date(const char *str)
146 struct vlc_http_msg *m;
147 time_t t1, t2;
149 m = vlc_http_req_create("GET", "http", "www.example.com", "/");
150 assert(m != NULL);
151 assert(vlc_http_msg_add_header(m, "Date", "%s", str) == 0);
152 t1 = vlc_http_msg_get_atime(m);
153 assert(vlc_http_msg_add_header(m, "Last-Modified", "%s", str) == 0);
154 t2 = vlc_http_msg_get_mtime(m);
155 assert(vlc_http_msg_get_retry_after(m) == 0);
156 assert(vlc_http_msg_add_header(m, "Retry-After", "%s", str) == 0);
157 vlc_http_msg_get_retry_after(m);
158 vlc_http_msg_destroy(m);
160 assert(t1 == t2);
161 return t1;
164 static const char *check_realm(const char *line, const char *realm)
166 struct vlc_http_msg *m;
167 char *value;
169 m = vlc_http_resp_create(401);
170 assert(m != NULL);
171 assert(vlc_http_msg_add_header(m, "WWW-Authenticate", "%s", line) == 0);
172 value = vlc_http_msg_get_basic_realm(m);
173 if (realm == NULL)
174 assert(value == NULL);
175 else
177 assert(value != NULL);
178 assert(!strcmp(value, realm));
179 free(value);
181 vlc_http_msg_destroy(m);
182 return realm;
185 int main(void)
187 struct vlc_http_msg *m;
188 const char *str;
189 int ret;
191 /* Formatting and parsing */
192 m = vlc_http_req_create("GET", "http", "www.example.com", "/");
193 assert(m != NULL);
194 ret = vlc_http_msg_add_header(m, "Cache-Control", "no-cache");
195 assert(ret == 0);
196 vlc_http_msg_add_header(m, "Custom-Key", "%s", "custom-value");
197 assert(ret == 0);
198 check_msg(m, check_req);
200 m = vlc_http_resp_create(200);
201 assert(m != NULL);
202 ret = vlc_http_msg_add_header(m, "cache-control", "private");
203 assert(ret == 0);
204 ret = vlc_http_msg_add_header(m, "date", "Mon, 21 Oct 2013 20:13:22 GMT");
205 assert(ret == 0);
206 ret = vlc_http_msg_add_header(m, "location", "https://www.example.com");
207 assert(ret == 0);
208 ret = vlc_http_msg_add_header(m, "content-encoding", "gzip");
209 assert(ret == 0);
210 ret = vlc_http_msg_add_header(m, "set-cookie", "foo=%s; max-age=%u; "
211 "version=%u", "ASDJKHQKBZXOQWEOPIUAXQWEOIU",
212 3600, 1);
213 assert(ret == 0);
214 check_msg(m, check_resp);
216 m = vlc_http_req_create("CONNECT", NULL, "www.example.com", NULL);
217 assert(m != NULL);
218 check_msg(m, check_connect);
220 /* Helpers */
221 assert(parse_date("Sun, 06 Nov 1994 08:49:37 GMT") == 784111777);
222 assert(parse_date("Sunday, 06-Nov-94 08:49:37 GMT") == 784111777);
223 assert(parse_date("Sun Nov 6 08:49:37 1994") == 784111777);
224 assert(parse_date("Sunday, 06-Nov-14 08:49:37 GMT") == 1415263777);
225 assert(parse_date("Sun, 06 Bug 1994 08:49:37 GMT") == -1);
226 assert(parse_date("bogus") == -1);
228 assert(check_realm("Basic realm=\"kingdom\"", "kingdom"));
229 assert(check_realm("BaSiC REALM= \"kingdom\"", "kingdom"));
230 assert(check_realm("basic Realm\t=\"kingdom\"", "kingdom"));
231 assert(check_realm("Basic charset=\"utf-8\", realm=\"kingdom\"",
232 "kingdom"));
233 assert(check_realm("Basic realm=\"Realm is \\\"Hello world!\\\"\"",
234 "Realm is \"Hello world!\""));
235 assert(check_realm("Basic", NULL) == NULL);
237 m = vlc_http_req_create("PRI", "https", "*", NULL);
238 assert(m != NULL);
240 assert(vlc_http_msg_add_agent(m, "Foo") == 0);
241 assert(vlc_http_msg_add_agent(m, "Foo/1.0") == 0);
242 assert(vlc_http_msg_add_agent(m, "Foo/1.0 (Hello world) Bar/2.3") == 0);
243 assert(vlc_http_msg_add_agent(m, "Foo/1.0 (compatible (\\(!))") == 0);
245 assert(vlc_http_msg_add_atime(m) == 0);
246 time_t t = vlc_http_msg_get_atime(m);
247 assert(t != (time_t)-1);
248 assert(vlc_http_msg_add_time(m, "Last-Modified", &t) == 0);
249 assert(t == vlc_http_msg_get_mtime(m));
251 assert(vlc_http_msg_add_creds_basic(m, false,
252 "Aladdin", "open sesame") == 0);
253 assert(vlc_http_msg_add_creds_basic(m, true, "test", "123£") == 0);
254 str = vlc_http_msg_get_header(m, "Authorization");
255 assert(str != NULL && !strcmp(str, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="));
256 str = vlc_http_msg_get_header(m, "Proxy-Authorization");
257 assert(str != NULL && !strcmp(str, "Basic dGVzdDoxMjPCow=="));
259 vlc_http_msg_add_header(m, "Content-Length", "1234");
260 assert(vlc_http_msg_get_size(m) == 1234);
262 /* Folding */
263 vlc_http_msg_add_header(m, "X-Folded", "Hello\n\tworld!");
264 str = vlc_http_msg_get_header(m, "x-folded");
265 assert(str != NULL && !strcmp(str, "Hello \tworld!"));
267 vlc_http_msg_add_header(m, "TE", "gzip");
268 vlc_http_msg_add_header(m, "TE", "deflate");
269 vlc_http_msg_add_header(m, "Pragma", " features=\"broadcast,playlist\"");
270 vlc_http_msg_add_header(m, "Pragma", " client-id=123456789 ");
271 vlc_http_msg_add_header(m, "Pragma", "evulz=\"foo \\\"\\ bar\"");
272 vlc_http_msg_add_header(m, "Pragma", "no-cache ");
274 str = vlc_http_msg_get_header(m, "TE");
275 assert(str != NULL && !strcmp(str, "gzip, deflate"));
276 str = vlc_http_msg_get_token(m, "TE", "gzip");
277 assert(str != NULL && !strncmp(str, "gzip", 4));
278 str = vlc_http_msg_get_token(m, "TE", "deflate");
279 assert(str != NULL && !strncmp(str, "deflate", 7));
280 str = vlc_http_msg_get_token(m, "TE", "compress");
281 assert(str == NULL);
282 str = vlc_http_msg_get_token(m, "TE", "zip");
283 assert(str == NULL);
284 str = vlc_http_msg_get_token(m, "TE", "late");
285 assert(str == NULL);
286 str = vlc_http_msg_get_token(m, "Accept-Encoding", "gzip");
287 assert(str == NULL);
288 str = vlc_http_msg_get_token(m, "Pragma", "features");
289 assert(str != NULL && !strncmp(str, "features=\"", 10));
290 str = vlc_http_msg_get_token(m, "Pragma", "broadcast");
291 assert(str == NULL);
292 str = vlc_http_msg_get_token(m, "Pragma", "playlist");
293 assert(str == NULL);
294 str = vlc_http_msg_get_token(m, "Pragma", "client-id");
295 assert(str != NULL && !strncmp(str, "client-id=", 10));
296 str = vlc_http_msg_get_token(m, "Pragma", "123456789");
297 assert(str == NULL);
298 str = vlc_http_msg_get_token(m, "Pragma", "no-cache");
299 assert(str != NULL && !strcmp(str, "no-cache"));
301 vlc_http_msg_add_header(m, "Cookie", "a=1");
302 vlc_http_msg_add_header(m, "Cookie", "b=2");
303 str = vlc_http_msg_get_header(m, "Cookie");
304 assert(str != NULL && !strcmp(str, "a=1; b=2"));
306 /* Error cases */
307 assert(vlc_http_msg_add_header(m, "/naughty", "header") == -1);
308 assert(vlc_http_msg_add_header(m, "", "void") == -1);
310 assert(vlc_http_msg_add_agent(m, "") != 0);
311 assert(vlc_http_msg_add_agent(m, "/1.0") != 0);
312 assert(vlc_http_msg_add_agent(m, "Bad/1.0\"") != 0);
313 assert(vlc_http_msg_add_agent(m, "Bad/1.0 (\\)") != 0);
314 assert(vlc_http_msg_add_agent(m, "Bad/1.0 (\\\x08)") != 0);
315 assert(vlc_http_msg_add_agent(m, "Bad/1.0 \"Evil\"") != 0);
316 assert(vlc_http_msg_add_agent(m, "(Hello world)") != 0);
318 assert(vlc_http_msg_add_creds_basic(m, false, "User:name", "12345") != 0);
319 assert(vlc_http_msg_add_creds_basic(m, false, "Alice\nand\nbob", "") != 0);
320 assert(vlc_http_msg_add_creds_basic(m, false, "john", "asdfg\x7f") != 0);
322 vlc_http_msg_destroy(m);
324 const char *bad1[][2] = {
325 { ":status", "200" },
326 { ":status", "200" },
327 { "Server", "BigBad/1.0" },
330 m = vlc_http_msg_h2_headers(3, bad1);
331 assert(m == NULL);
333 /* HTTP 1.x parser error cases */
334 assert(vlc_http_msg_headers("") == NULL);
335 assert(vlc_http_msg_headers("\r\n") == NULL);
336 assert(vlc_http_msg_headers("HTTP/1.1 200 OK") == NULL);
337 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\nH: V\r\n") == NULL);
338 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\n"
339 ":status: 200\r\n\r\n") == NULL);
340 assert(vlc_http_msg_headers("HTTP/1.1 200 OK\r\n"
341 "/naughty: invalid\r\n\r\n") == NULL);
343 return 0;
346 /* Callback for vlc_http_msg_h2_frame */
347 struct vlc_h2_frame *
348 vlc_h2_frame_headers(uint_fast32_t id, uint_fast32_t mtu, bool eos,
349 unsigned count, const char *const tab[][2])
351 struct vlc_http_msg *m;
353 assert(id == 1);
354 assert(mtu == VLC_H2_DEFAULT_MAX_FRAME);
355 assert(eos);
357 const char *headers[VLC_H2_MAX_HEADERS][2];
359 for (unsigned i = 0; i < count; i++)
361 headers[i][0] = tab[i][0];
362 headers[i][1] = tab[i][1];
365 m = vlc_http_msg_h2_headers(count, headers);
366 return (struct vlc_h2_frame *)m; /* gruik */