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