1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Novell, Inc.
6 #include "test-utils.h"
8 #define SHORT_BODY "This is a test.\r\n"
9 #define LONG_BODY (SHORT_BODY SHORT_BODY)
11 #define MAX_POST_LENGTH (sizeof (SHORT_BODY))
14 static GSList *events;
17 event (SoupMessage *msg, const char *side, const char *message)
19 char *data = g_strdup_printf ("%s-%s", side, message);
20 gboolean record_status =
21 (!strcmp (data, "server-wrote_headers") ||
22 !strcmp (data, "server-wrote_informational"));
24 debug_printf (2, " %s", data);
26 debug_printf (2, " (%s)", msg->reason_phrase);
27 debug_printf (2, "\n");
29 events = g_slist_append (events, data);
31 events = g_slist_append (events, GUINT_TO_POINTER (msg->status_code));
34 #define EVENT_HANDLER(name) \
36 name (SoupMessage *msg, gpointer side) \
38 event (msg, side, #name); \
41 EVENT_HANDLER (got_informational)
42 EVENT_HANDLER (got_headers)
43 EVENT_HANDLER (got_body)
44 EVENT_HANDLER (wrote_informational)
45 EVENT_HANDLER (wrote_headers)
46 EVENT_HANDLER (wrote_body)
47 EVENT_HANDLER (finished)
50 do_message (const char *path, gboolean long_body,
51 gboolean expect_continue, gboolean auth,
59 const char *expected_event;
61 int expected_status, actual_status;
64 debug_printf (1, "%d. /%s, %s body, %sExpect, %s password\n",
66 long_body ? "long" : "short",
67 expect_continue ? "" : "no ",
68 auth ? "with" : "without");
70 uri = g_strdup_printf ("http://%s127.0.0.1:%d/%s",
71 auth ? "user:pass@" : "",
73 msg = soup_message_new ("POST", uri);
76 body = long_body ? LONG_BODY : SHORT_BODY;
77 soup_message_set_request (msg, "text/plain", SOUP_MEMORY_STATIC,
79 soup_message_headers_append (msg->request_headers, "Connection", "close");
80 if (expect_continue) {
81 soup_message_headers_set_expectations (msg->request_headers,
82 SOUP_EXPECTATION_CONTINUE);
85 g_signal_connect (msg, "got_informational",
86 G_CALLBACK (got_informational), "client");
87 g_signal_connect (msg, "got_headers",
88 G_CALLBACK (got_headers), "client");
89 g_signal_connect (msg, "got_body",
90 G_CALLBACK (got_body), "client");
91 g_signal_connect (msg, "wrote_informational",
92 G_CALLBACK (wrote_informational), "client");
93 g_signal_connect (msg, "wrote_headers",
94 G_CALLBACK (wrote_headers), "client");
95 g_signal_connect (msg, "wrote_body",
96 G_CALLBACK (wrote_body), "client");
97 g_signal_connect (msg, "finished",
98 G_CALLBACK (finished), "client");
101 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
102 soup_session_send_message (session, msg);
103 soup_test_session_abort_unref (session);
106 while ((expected_event = va_arg (ap, const char *))) {
109 actual_event = g_strdup ("");
110 debug_printf (1, " Expected '%s', got end of list\n",
114 actual_event = events->data;
115 if (strcmp (expected_event, actual_event) != 0) {
116 debug_printf (1, " Expected '%s', got '%s'\n",
117 expected_event, actual_event);
120 events = g_slist_delete_link (events, events);
123 if (!strcmp (expected_event, "server-wrote_headers") ||
124 !strcmp (expected_event, "server-wrote_informational"))
125 expected_status = va_arg (ap, int);
127 expected_status = -1;
128 if (!strcmp (actual_event, "server-wrote_headers") ||
129 !strcmp (actual_event, "server-wrote_informational")) {
130 actual_status = GPOINTER_TO_INT (events->data);
131 events = g_slist_delete_link (events, events);
133 expected_status = -1;
135 if (expected_status != -1 && actual_status != -1 &&
136 expected_status != actual_status) {
137 debug_printf (1, " Expected status '%s', got '%s'\n",
138 soup_status_get_phrase (expected_status),
139 soup_status_get_phrase (actual_status));
143 g_free (actual_event);
147 actual_event = events->data;
148 debug_printf (1, " Expected to be done, got '%s'\n", actual_event);
150 events = g_slist_delete_link (events, events);
152 if (!strcmp (actual_event, "server-wrote_headers") ||
153 !strcmp (actual_event, "server-wrote_informational"))
154 events = g_slist_delete_link (events, events);
156 g_object_unref (msg);
162 do_message ("unauth", FALSE, FALSE, FALSE,
163 "client-wrote_headers",
165 "server-got_headers",
167 "server-wrote_headers", SOUP_STATUS_CREATED,
170 "client-got_headers",
174 do_message ("unauth", TRUE, FALSE, FALSE,
175 "client-wrote_headers",
177 "server-got_headers",
179 "server-wrote_headers", SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE,
182 "client-got_headers",
186 do_message ("unauth", FALSE, TRUE, FALSE,
187 "client-wrote_headers",
188 "server-got_headers",
189 "server-wrote_informational", SOUP_STATUS_CONTINUE,
190 "client-got_informational",
193 "server-wrote_headers", SOUP_STATUS_CREATED,
196 "client-got_headers",
200 do_message ("unauth", TRUE, TRUE, FALSE,
201 "client-wrote_headers",
202 "server-got_headers",
203 "server-wrote_headers", SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE,
206 "client-got_headers",
211 do_message ("auth", FALSE, FALSE, FALSE,
212 "client-wrote_headers",
214 "server-got_headers",
216 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
219 "client-got_headers",
223 do_message ("auth", TRUE, FALSE, FALSE,
224 "client-wrote_headers",
226 "server-got_headers",
228 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
231 "client-got_headers",
235 do_message ("auth", FALSE, TRUE, FALSE,
236 "client-wrote_headers",
237 "server-got_headers",
238 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
241 "client-got_headers",
245 do_message ("auth", TRUE, TRUE, FALSE,
246 "client-wrote_headers",
247 "server-got_headers",
248 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
251 "client-got_headers",
256 do_message ("auth", FALSE, FALSE, TRUE,
257 "client-wrote_headers",
259 "server-got_headers",
261 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
264 "client-got_headers",
266 "client-wrote_headers",
268 "server-got_headers",
270 "server-wrote_headers", SOUP_STATUS_CREATED,
273 "client-got_headers",
277 do_message ("auth", TRUE, FALSE, TRUE,
278 "client-wrote_headers",
280 "server-got_headers",
282 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
285 "client-got_headers",
287 "client-wrote_headers",
289 "server-got_headers",
291 "server-wrote_headers", SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE,
294 "client-got_headers",
298 do_message ("auth", FALSE, TRUE, TRUE,
299 "client-wrote_headers",
300 "server-got_headers",
301 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
304 "client-got_headers",
306 "client-wrote_headers",
307 "server-got_headers",
308 "server-wrote_informational", SOUP_STATUS_CONTINUE,
309 "client-got_informational",
312 "server-wrote_headers", SOUP_STATUS_CREATED,
315 "client-got_headers",
319 do_message ("auth", TRUE, TRUE, TRUE,
320 "client-wrote_headers",
321 "server-got_headers",
322 "server-wrote_headers", SOUP_STATUS_UNAUTHORIZED,
325 "client-got_headers",
327 "client-wrote_headers",
328 "server-got_headers",
329 "server-wrote_headers", SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE,
332 "client-got_headers",
342 server_got_headers (SoupMessage *msg, gpointer server)
345 if (msg->status_code != SOUP_STATUS_CONTINUE &&
346 msg->status_code != 0)
349 if (soup_message_headers_get_expectations (msg->request_headers) &
350 SOUP_EXPECTATION_CONTINUE) {
353 length = soup_message_headers_get_one (msg->request_headers,
355 if (length && atoi (length) > MAX_POST_LENGTH) {
356 soup_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE);
357 soup_message_headers_append (msg->response_headers, "Connection", "close");
363 request_started (SoupServer *server, SoupMessage *msg,
364 SoupClientContext *client, gpointer user_data)
366 g_signal_connect (msg, "got_headers",
367 G_CALLBACK (server_got_headers), server);
369 g_signal_connect (msg, "got_informational",
370 G_CALLBACK (got_informational), "server");
371 g_signal_connect (msg, "got_headers",
372 G_CALLBACK (got_headers), "server");
373 g_signal_connect (msg, "got_body",
374 G_CALLBACK (got_body), "server");
375 g_signal_connect (msg, "wrote_informational",
376 G_CALLBACK (wrote_informational), "server");
377 g_signal_connect (msg, "wrote_headers",
378 G_CALLBACK (wrote_headers), "server");
379 g_signal_connect (msg, "wrote_body",
380 G_CALLBACK (wrote_body), "server");
381 g_signal_connect (msg, "finished",
382 G_CALLBACK (finished), "server");
386 auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
387 const char *username, const char *password, gpointer user_data)
389 return !strcmp (username, "user") && !strcmp (password, "pass");
393 server_callback (SoupServer *server, SoupMessage *msg,
394 const char *path, GHashTable *query,
395 SoupClientContext *context, gpointer data)
397 if (msg->method != SOUP_METHOD_POST) {
398 soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
399 soup_message_headers_append (msg->response_headers, "Connection", "close");
400 } else if (msg->request_body->length > MAX_POST_LENGTH) {
401 soup_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE);
402 soup_message_headers_append (msg->response_headers, "Connection", "close");
404 soup_message_set_status (msg, SOUP_STATUS_CREATED);
411 SoupAuthDomain *auth_domain;
413 server = soup_test_server_new (FALSE);
415 g_signal_connect (server, "request-started",
416 G_CALLBACK (request_started), NULL);
418 soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
420 auth_domain = soup_auth_domain_basic_new (
421 SOUP_AUTH_DOMAIN_REALM, "continue-test",
422 SOUP_AUTH_DOMAIN_ADD_PATH, "/auth",
423 SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, auth_callback,
425 soup_server_add_auth_domain (server, auth_domain);
426 g_object_unref (auth_domain);
434 main (int argc, char **argv)
438 test_init (argc, argv, NULL);
440 server = setup_server ();
441 port = soup_server_get_port (server);
445 soup_test_server_quit_unref (server);