1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Red Hat, Inc.
17 #include <libsoup/soup.h>
19 #include "test-utils.h"
25 server_callback (SoupServer *server, SoupMessage *msg,
26 const char *path, GHashTable *query,
27 SoupClientContext *context, gpointer data)
29 const char *accept_encoding, *options;
31 char *file = NULL, *contents;
34 options = soup_message_headers_get_one (msg->request_headers,
39 accept_encoding = soup_message_headers_get_list (msg->request_headers,
41 if (accept_encoding && !soup_header_contains (options, "force-encode"))
42 codings = soup_header_parse_quality_list (accept_encoding, NULL);
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,
57 soup_header_free_list (codings);
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
67 soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
72 if (soup_header_contains (options, "force-encode")) {
73 soup_message_headers_replace (msg->response_headers,
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,
84 soup_message_headers_append (msg->response_headers,
89 soup_message_set_status (msg, SOUP_STATUS_OK);
90 soup_message_body_append (msg->response_body,
91 SOUP_MEMORY_TAKE, contents, length);
93 if (soup_header_contains (options, "trailing-junk")) {
94 soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY,
95 options, strlen (options));
100 do_coding_test (void)
102 SoupSession *session;
103 SoupMessage *msg, *msgz, *msgj, *msge;
105 const char *coding, *type;
107 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
108 uri = soup_uri_new_with_base (base_uri, "/mbox");
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);
119 coding = soup_message_headers_get_one (msg->response_headers, "Content-Encoding");
121 debug_printf (1, " Unexpected Content-Encoding: %s\n",
125 if (soup_message_get_flags (msg) & SOUP_MESSAGE_CONTENT_DECODED) {
126 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED set!\n");
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)");
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);
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)");
151 if (!(soup_message_get_flags (msgz) & SOUP_MESSAGE_CONTENT_DECODED)) {
152 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED not set!\n");
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)");
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);
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");
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);
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)");
191 if (!(soup_message_get_flags (msgj) & SOUP_MESSAGE_CONTENT_DECODED)) {
192 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED not set!\n");
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)");
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);
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");
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);
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)");
231 /* Since the content wasn't actually gzip-encoded, decoding it
232 * should have failed and so the flag won't be set.
234 if (soup_message_get_flags (msge) & SOUP_MESSAGE_CONTENT_DECODED) {
235 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED set!\n");
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)");
245 /* Failed content-decoding should have left the body untouched
246 * from what the server sent... which happens to be the
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);
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");
262 g_object_unref (msg);
263 g_object_unref (msgz);
264 g_object_unref (msgj);
265 g_object_unref (msge);
269 uri = soup_uri_new_with_base (base_uri, "/mbox.gz");
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);
280 coding = soup_message_headers_get_one (msgz->response_headers, "Content-Encoding");
282 debug_printf (1, " Unexpected Content-Encoding: %s\n", coding);
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)");
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);
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)");
309 /* SoupContentDecoder should have recognized the bug and thus
312 if (soup_message_get_flags (msge) & SOUP_MESSAGE_CONTENT_DECODED) {
313 debug_printf (1, " SOUP_MESSAGE_CONTENT_DECODED set!\n");
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)");
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);
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");
336 g_object_unref (msgz);
337 g_object_unref (msge);
340 soup_test_session_abort_unref (session);
344 main (int argc, char **argv)
346 test_init (argc, argv, NULL);
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));
355 soup_uri_free (base_uri);
356 soup_test_server_quit_unref (server);