Git init
[profile/ivi/libsoup2.4.git] / tests / coding-test.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007 Red Hat, Inc.
4  */
5
6 #include <ctype.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 #include <glib.h>
17 #include <libsoup/soup.h>
18
19 #include "test-utils.h"
20
21 SoupServer *server;
22 SoupURI *base_uri;
23
24 static void
25 server_callback (SoupServer *server, SoupMessage *msg,
26                  const char *path, GHashTable *query,
27                  SoupClientContext *context, gpointer data)
28 {
29         const char *accept_encoding, *options;
30         GSList *codings;
31         char *file = NULL, *contents;
32         gsize length;
33
34         options = soup_message_headers_get_one (msg->request_headers,
35                                                 "X-Test-Options");
36         if (!options)
37                 options = "";
38
39         accept_encoding = soup_message_headers_get_list (msg->request_headers,
40                                                          "Accept-Encoding");
41         if (accept_encoding && !soup_header_contains (options, "force-encode"))
42                 codings = soup_header_parse_quality_list (accept_encoding, NULL);
43         else
44                 codings = NULL;
45
46         if (codings && g_slist_find_custom (codings, "gzip", (GCompareFunc)g_ascii_strcasecmp)) {
47                 file = g_strdup_printf (SRCDIR "/resources%s.gz", path);
48                 if (g_file_test (file, G_FILE_TEST_EXISTS)) {
49                         soup_message_headers_append (msg->response_headers,
50                                                      "Content-Encoding",
51                                                      "gzip");
52                 } else {
53                         g_free (file);
54                         file = NULL;
55                 }
56         }
57         soup_header_free_list (codings);
58
59         if (!file)
60                 file = g_strdup_printf (SRCDIR "/resources%s", path);
61         if (!g_file_get_contents (file, &contents, &length, NULL)) {
62                 /* If path.gz exists but can't be read, we'll send back
63                  * the error with "Content-Encoding: gzip" but there's
64                  * no body, so, eh.
65                  */
66                 g_free (file);
67                 soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
68                 return;
69         }
70         g_free (file);
71
72         if (soup_header_contains (options, "force-encode")) {
73                 soup_message_headers_replace (msg->response_headers,
74                                               "Content-Encoding",
75                                               "gzip");
76         }
77
78         /* Content-Type matches the "real" format, not the sent format */
79         if (g_str_has_suffix (path, ".gz")) {
80                 soup_message_headers_append (msg->response_headers,
81                                              "Content-Type",
82                                              "application/gzip");
83         } else {
84                 soup_message_headers_append (msg->response_headers,
85                                              "Content-Type",
86                                              "text/plain");
87         }
88
89         soup_message_set_status (msg, SOUP_STATUS_OK);
90         soup_message_body_append (msg->response_body,
91                                   SOUP_MEMORY_TAKE, contents, length);
92
93         if (soup_header_contains (options, "trailing-junk")) {
94                 soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY,
95                                           options, strlen (options));
96         }
97 }
98
99 static void
100 do_coding_test (void)
101 {
102         SoupSession *session;
103         SoupMessage *msg, *msgz, *msgj, *msge;
104         SoupURI *uri;
105         const char *coding, *type;
106
107         session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
108         uri = soup_uri_new_with_base (base_uri, "/mbox");
109
110
111         debug_printf (1, "GET /mbox, plain\n");
112         msg = soup_message_new_from_uri ("GET", uri);
113         soup_session_send_message (session, msg);
114         if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
115                 debug_printf (1, "  Unexpected status %d %s\n",
116                               msg->status_code, msg->reason_phrase);
117                 errors++;
118         }
119         coding = soup_message_headers_get_one (msg->response_headers, "Content-Encoding");
120         if (coding) {
121                 debug_printf (1, "  Unexpected Content-Encoding: %s\n",
122                               coding);
123                 errors++;
124         }
125         if (soup_message_get_flags (msg) & SOUP_MESSAGE_CONTENT_DECODED) {
126                 debug_printf (1, "  SOUP_MESSAGE_CONTENT_DECODED set!\n");
127                 errors++;
128         }
129         type = soup_message_headers_get_one (msg->response_headers, "Content-Type");
130         if (!type || g_ascii_strcasecmp (type, "text/plain") != 0) {
131                 debug_printf (1, "  Unexpected Content-Type: %s\n",
132                               type ? type : "(none)");
133                 errors++;
134         }
135
136         debug_printf (1, "GET /mbox, Accept-Encoding: gzip\n");
137         soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
138         msgz = soup_message_new_from_uri ("GET", uri);
139         soup_session_send_message (session, msgz);
140         if (!SOUP_STATUS_IS_SUCCESSFUL (msgz->status_code)) {
141                 debug_printf (1, "  Unexpected status %d %s\n",
142                               msgz->status_code, msgz->reason_phrase);
143                 errors++;
144         }
145         coding = soup_message_headers_get_one (msgz->response_headers, "Content-Encoding");
146         if (!coding || g_ascii_strcasecmp (coding, "gzip") != 0) {
147                 debug_printf (1, "  Unexpected Content-Encoding: %s\n",
148                               coding ? coding : "(none)");
149                 errors++;
150         }
151         if (!(soup_message_get_flags (msgz) & SOUP_MESSAGE_CONTENT_DECODED)) {
152                 debug_printf (1, "  SOUP_MESSAGE_CONTENT_DECODED not set!\n");
153                 errors++;
154         }
155         type = soup_message_headers_get_one (msgz->response_headers, "Content-Type");
156         if (!type || g_ascii_strcasecmp (type, "text/plain") != 0) {
157                 debug_printf (1, "  Unexpected Content-Type: %s\n",
158                               type ? type : "(none)");
159                 errors++;
160         }
161
162         if (msg->response_body->length != msgz->response_body->length) {
163                 debug_printf (1, "  Message length mismatch: %lu (plain) vs %lu (compressed)\n",
164                               (gulong)msg->response_body->length,
165                               (gulong)msgz->response_body->length);
166                 errors++;
167         } else if (memcmp (msg->response_body->data,
168                            msgz->response_body->data,
169                            msg->response_body->length) != 0) {
170                 debug_printf (1, "  Message data mismatch (plain/compressed)\n");
171                 errors++;
172         }
173
174
175         debug_printf (1, "GET /mbox, Accept-Encoding: gzip, plus trailing junk\n");
176         msgj = soup_message_new_from_uri ("GET", uri);
177         soup_message_headers_append (msgj->request_headers,
178                                      "X-Test-Options", "trailing-junk");
179         soup_session_send_message (session, msgj);
180         if (!SOUP_STATUS_IS_SUCCESSFUL (msgj->status_code)) {
181                 debug_printf (1, "  Unexpected status %d %s\n",
182                               msgj->status_code, msgj->reason_phrase);
183                 errors++;
184         }
185         coding = soup_message_headers_get_one (msgj->response_headers, "Content-Encoding");
186         if (!coding || g_ascii_strcasecmp (coding, "gzip") != 0) {
187                 debug_printf (1, "  Unexpected Content-Encoding: %s\n",
188                               coding ? coding : "(none)");
189                 errors++;
190         }
191         if (!(soup_message_get_flags (msgj) & SOUP_MESSAGE_CONTENT_DECODED)) {
192                 debug_printf (1, "  SOUP_MESSAGE_CONTENT_DECODED not set!\n");
193                 errors++;
194         }
195         type = soup_message_headers_get_one (msgj->response_headers, "Content-Type");
196         if (!type || g_ascii_strcasecmp (type, "text/plain") != 0) {
197                 debug_printf (1, "  Unexpected Content-Type: %s\n",
198                               type ? type : "(none)");
199                 errors++;
200         }
201
202         if (msg->response_body->length != msgj->response_body->length) {
203                 debug_printf (1, "  Message length mismatch: %lu (plain) vs %lu (compressed w/ junk)\n",
204                               (gulong)msg->response_body->length,
205                               (gulong)msgj->response_body->length);
206                 errors++;
207         } else if (memcmp (msg->response_body->data,
208                            msgj->response_body->data,
209                            msg->response_body->length) != 0) {
210                 debug_printf (1, "  Message data mismatch (plain/compressed w/ junk)\n");
211                 errors++;
212         }
213
214
215         debug_printf (1, "GET /mbox, Accept-Encoding: gzip, with server error\n");
216         msge = soup_message_new_from_uri ("GET", uri);
217         soup_message_headers_append (msge->request_headers,
218                                      "X-Test-Options", "force-encode");
219         soup_session_send_message (session, msge);
220         if (!SOUP_STATUS_IS_SUCCESSFUL (msge->status_code)) {
221                 debug_printf (1, "  Unexpected status %d %s\n",
222                               msge->status_code, msge->reason_phrase);
223                 errors++;
224         }
225         coding = soup_message_headers_get_one (msge->response_headers, "Content-Encoding");
226         if (!coding || g_ascii_strcasecmp (coding, "gzip") != 0) {
227                 debug_printf (1, "  Unexpected Content-Encoding: %s\n",
228                               coding ? coding : "(none)");
229                 errors++;
230         }
231         /* Since the content wasn't actually gzip-encoded, decoding it
232          * should have failed and so the flag won't be set.
233          */
234         if (soup_message_get_flags (msge) & SOUP_MESSAGE_CONTENT_DECODED) {
235                 debug_printf (1, "  SOUP_MESSAGE_CONTENT_DECODED set!\n");
236                 errors++;
237         }
238         type = soup_message_headers_get_one (msge->response_headers, "Content-Type");
239         if (!type || g_ascii_strcasecmp (type, "text/plain") != 0) {
240                 debug_printf (1, "  Unexpected Content-Type: %s\n",
241                               type ? type : "(none)");
242                 errors++;
243         }
244
245         /* Failed content-decoding should have left the body untouched
246          * from what the server sent... which happens to be the
247          * uncompressed data.
248          */
249         if (msg->response_body->length != msge->response_body->length) {
250                 debug_printf (1, "  Message length mismatch: %lu (plain) vs %lu (mis-encoded)\n",
251                               (gulong)msg->response_body->length,
252                               (gulong)msge->response_body->length);
253                 errors++;
254         } else if (memcmp (msg->response_body->data,
255                            msge->response_body->data,
256                            msg->response_body->length) != 0) {
257                 debug_printf (1, "  Message data mismatch (plain/misencoded)\n");
258                 errors++;
259         }
260
261
262         g_object_unref (msg);
263         g_object_unref (msgz);
264         g_object_unref (msgj);
265         g_object_unref (msge);
266         soup_uri_free (uri);
267
268
269         uri = soup_uri_new_with_base (base_uri, "/mbox.gz");
270
271         debug_printf (1, "GET /mbox.gz, Accept-Encoding: gzip\n");
272         soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
273         msgz = soup_message_new_from_uri ("GET", uri);
274         soup_session_send_message (session, msgz);
275         if (!SOUP_STATUS_IS_SUCCESSFUL (msgz->status_code)) {
276                 debug_printf (1, "  Unexpected status %d %s\n",
277                               msgz->status_code, msgz->reason_phrase);
278                 errors++;
279         }
280         coding = soup_message_headers_get_one (msgz->response_headers, "Content-Encoding");
281         if (coding) {
282                 debug_printf (1, "  Unexpected Content-Encoding: %s\n", coding);
283                 errors++;
284         }
285         type = soup_message_headers_get_one (msgz->response_headers, "Content-Type");
286         if (!type || g_ascii_strcasecmp (type, "application/gzip") != 0) {
287                 debug_printf (1, "  Unexpected Content-Type: %s\n",
288                               type ? type : "(none)");
289                 errors++;
290         }
291
292
293         debug_printf (1, "GET /mbox.gz, Accept-Encoding: gzip, with server error\n");
294         msge = soup_message_new_from_uri ("GET", uri);
295         soup_message_headers_append (msge->request_headers,
296                                      "X-Test-Options", "force-encode");
297         soup_session_send_message (session, msge);
298         if (!SOUP_STATUS_IS_SUCCESSFUL (msge->status_code)) {
299                 debug_printf (1, "  Unexpected status %d %s\n",
300                               msge->status_code, msge->reason_phrase);
301                 errors++;
302         }
303         coding = soup_message_headers_get_one (msge->response_headers, "Content-Encoding");
304         if (!coding || g_ascii_strcasecmp (coding, "gzip") != 0) {
305                 debug_printf (1, "  Unexpected Content-Encoding: %s\n",
306                               coding ? coding : "(none)");
307                 errors++;
308         }
309         /* SoupContentDecoder should have recognized the bug and thus
310          * not decoded it
311          */
312         if (soup_message_get_flags (msge) & SOUP_MESSAGE_CONTENT_DECODED) {
313                 debug_printf (1, "  SOUP_MESSAGE_CONTENT_DECODED set!\n");
314                 errors++;
315         }
316         type = soup_message_headers_get_one (msge->response_headers, "Content-Type");
317         if (!type || g_ascii_strcasecmp (type, "application/gzip") != 0) {
318                 debug_printf (1, "  Unexpected Content-Type: %s\n",
319                               type ? type : "(none)");
320                 errors++;
321         }
322
323         if (msgz->response_body->length != msge->response_body->length) {
324                 debug_printf (1, "  Message length mismatch: %lu (.gz) vs %lu (mis-encoded)\n",
325                               (gulong)msgz->response_body->length,
326                               (gulong)msge->response_body->length);
327                 errors++;
328         } else if (memcmp (msgz->response_body->data,
329                            msge->response_body->data,
330                            msgz->response_body->length) != 0) {
331                 debug_printf (1, "  Message data mismatch (gz/misencoded)\n");
332                 errors++;
333         }
334
335
336         g_object_unref (msgz);
337         g_object_unref (msge);
338         soup_uri_free (uri);
339
340         soup_test_session_abort_unref (session);
341 }
342
343 int
344 main (int argc, char **argv)
345 {
346         test_init (argc, argv, NULL);
347
348         server = soup_test_server_new (TRUE);
349         soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
350         base_uri = soup_uri_new ("http://127.0.0.1/");
351         soup_uri_set_port (base_uri, soup_server_get_port (server));
352
353         do_coding_test ();
354
355         soup_uri_free (base_uri);
356         soup_test_server_quit_unref (server);
357
358         test_cleanup ();
359         return errors != 0;
360 }