1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Red Hat, Inc.
4 * Copyright (C) 2011 Igalia, S.L.
18 #include <libsoup/soup.h>
20 #include "test-utils.h"
26 server_callback (SoupServer *server, SoupMessage *msg,
27 const char *path, GHashTable *query,
28 SoupClientContext *context, gpointer data)
30 const char *accept_encoding, *options;
32 char *file = NULL, *contents;
35 options = soup_message_headers_get_one (msg->request_headers,
40 accept_encoding = soup_message_headers_get_list (msg->request_headers,
42 if (accept_encoding && !soup_header_contains (options, "force-encode"))
43 codings = soup_header_parse_quality_list (accept_encoding, NULL);
48 gboolean claim_deflate, claim_gzip;
49 const char *file_path = NULL, *encoding = NULL;
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;
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";
59 } else if (claim_deflate) {
60 if (soup_header_contains (options, "prefer-deflate-raw")) {
61 file_path = SRCDIR "/resources%s.raw";
64 file_path = SRCDIR "/resources%s.zlib";
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,
81 soup_header_free_list (codings);
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
91 soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
96 if (soup_header_contains (options, "force-encode")) {
97 const gchar *encoding = "gzip";
99 if (soup_header_contains (options, "prefer-deflate-zlib") ||
100 soup_header_contains (options, "prefer-deflate-raw"))
101 encoding = "deflate";
103 soup_message_headers_replace (msg->response_headers,
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,
114 soup_message_headers_append (msg->response_headers,
119 soup_message_set_status (msg, SOUP_STATUS_OK);
120 soup_message_body_append (msg->response_body,
121 SOUP_MEMORY_TAKE, contents, length);
123 if (soup_header_contains (options, "trailing-junk")) {
124 soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY,
125 options, strlen (options));
133 } MessageContentStatus;
136 do_single_coding_test (SoupSession *session,
138 const char *expected_encoding,
139 const char *expected_content_type,
140 MessageContentStatus status)
142 const char *coding, *type;
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);
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)");
159 debug_printf (1, " Unexpected Content-Encoding: %s\n",
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");
171 if (soup_message_get_flags (msg) & SOUP_MESSAGE_CONTENT_DECODED) {
172 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED set!\n");
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)");
186 check_msg_bodies (SoupMessage *msg1,
188 const char *msg1_type,
189 const char *msg2_type)
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,
195 (gulong)msg2->response_body->length,
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);
208 do_coding_test (void)
210 SoupSession *session;
211 SoupMessage *msg, *msgz, *msgj, *msge, *msgzl, *msgzlj, *msgzle, *msgzlr, *msgzlre;
214 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
215 uri = soup_uri_new_with_base (base_uri, "/mbox");
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);
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");
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");
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);
244 /* Failed content-decoding should have left the body untouched
245 * from what the server sent... which happens to be the
248 check_msg_bodies (msg, msge, "plain", "mis-encoded");
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");
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");
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");
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");
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");
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);
301 soup_test_session_abort_unref (session);
305 main (int argc, char **argv)
307 test_init (argc, argv, NULL);
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));
316 soup_uri_free (base_uri);
317 soup_test_server_quit_unref (server);