1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright 2007-2012 Red Hat, Inc.
6 #include "test-utils.h"
13 forget_close (SoupMessage *msg, gpointer user_data)
15 soup_message_headers_remove (msg->response_headers, "Connection");
19 close_socket (SoupMessage *msg, gpointer user_data)
21 SoupSocket *sock = user_data;
24 /* Actually calling soup_socket_disconnect() here would cause
25 * us to leak memory, so just shutdown the socket instead.
27 sockfd = soup_socket_get_fd (sock);
29 shutdown (sockfd, SD_SEND);
31 shutdown (sockfd, SHUT_WR);
34 /* Then add the missing data to the message now, so SoupServer
35 * can clean up after itself properly.
37 soup_message_body_append (msg->response_body, SOUP_MEMORY_STATIC,
42 timeout_socket (SoupSocket *sock, gpointer user_data)
44 soup_socket_disconnect (sock);
48 timeout_request_started (SoupServer *server, SoupMessage *msg,
49 SoupClientContext *client, gpointer user_data)
52 GMainContext *context = soup_server_get_async_context (server);
55 sock = soup_client_context_get_socket (client);
56 readable = g_signal_connect (sock, "readable",
57 G_CALLBACK (timeout_socket), NULL);
58 while (soup_socket_is_connected (sock))
59 g_main_context_iteration (context, TRUE);
60 g_signal_handler_disconnect (sock, readable);
61 g_signal_handlers_disconnect_by_func (server, timeout_request_started, NULL);
65 setup_timeout_persistent (SoupServer *server, SoupSocket *sock)
70 /* In order for the test to work correctly, we have to
71 * close the connection *after* the client side writes
72 * the request. To ensure that this happens reliably,
73 * regardless of thread scheduling, we:
75 * 1. Try to read off the socket now, knowing it will
76 * fail (since the client is waiting for us to
77 * return a response). This will cause it to
78 * emit "readable" later.
79 * 2. Connect to the server's request-started signal.
80 * 3. Run an inner main loop from that signal handler
81 * until the socket emits "readable". (If we don't
82 * do this then it's possible the client's next
83 * request would be ready before we returned to
84 * the main loop, and so the signal would never be
86 * 4. Close the socket.
89 soup_socket_read (sock, buf, 1, &nread, NULL, NULL);
90 g_signal_connect (server, "request-started",
91 G_CALLBACK (timeout_request_started), NULL);
95 server_callback (SoupServer *server, SoupMessage *msg,
96 const char *path, GHashTable *query,
97 SoupClientContext *context, gpointer data)
99 /* The way this gets used in the tests, we don't actually
100 * need to hold it through the whole function, so it's simpler
101 * to just release it right away.
103 g_mutex_lock (&server_mutex);
104 g_mutex_unlock (&server_mutex);
106 if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
107 soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
111 if (g_str_has_prefix (path, "/content-length/")) {
112 gboolean too_long = strcmp (path, "/content-length/long") == 0;
113 gboolean no_close = strcmp (path, "/content-length/noclose") == 0;
115 soup_message_set_status (msg, SOUP_STATUS_OK);
116 soup_message_set_response (msg, "text/plain",
117 SOUP_MEMORY_STATIC, "foobar", 6);
119 soup_message_headers_set_content_length (msg->response_headers, 9);
120 soup_message_headers_append (msg->response_headers,
121 "Connection", "close");
126 /* soup-message-io will wait for us to add
127 * another chunk after the first, to fill out
128 * the declared Content-Length. Instead, we
129 * forcibly close the socket at that point.
131 sock = soup_client_context_get_socket (context);
132 g_signal_connect (msg, "wrote-chunk",
133 G_CALLBACK (close_socket), sock);
134 } else if (no_close) {
135 /* Remove the 'Connection: close' after writing
136 * the headers, so that when we check it after
137 * writing the body, we'll think we aren't
138 * supposed to close it.
140 g_signal_connect (msg, "wrote-headers",
141 G_CALLBACK (forget_close), NULL);
146 if (!strcmp (path, "/timeout-persistent")) {
149 sock = soup_client_context_get_socket (context);
150 setup_timeout_persistent (server, sock);
153 soup_message_set_status (msg, SOUP_STATUS_OK);
154 soup_message_set_response (msg, "text/plain",
155 SOUP_MEMORY_STATIC, "index", 5);
160 do_content_length_framing_test (void)
162 SoupSession *session;
164 SoupURI *request_uri;
165 goffset declared_length;
167 debug_printf (1, "\nInvalid Content-Length framing tests\n");
169 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
171 debug_printf (1, " Content-Length larger than message body length\n");
172 request_uri = soup_uri_new_with_base (base_uri, "/content-length/long");
173 msg = soup_message_new_from_uri ("GET", request_uri);
174 soup_session_send_message (session, msg);
175 if (msg->status_code != SOUP_STATUS_OK) {
176 debug_printf (1, " Unexpected response: %d %s\n",
177 msg->status_code, msg->reason_phrase);
180 declared_length = soup_message_headers_get_content_length (msg->response_headers);
181 debug_printf (2, " Content-Length: %lu, body: %s\n",
182 (gulong)declared_length, msg->response_body->data);
183 if (msg->response_body->length >= declared_length) {
184 debug_printf (1, " Body length %lu >= declared length %lu\n",
185 (gulong)msg->response_body->length,
186 (gulong)declared_length);
190 soup_uri_free (request_uri);
191 g_object_unref (msg);
193 debug_printf (1, " Server claims 'Connection: close' but doesn't\n");
194 request_uri = soup_uri_new_with_base (base_uri, "/content-length/noclose");
195 msg = soup_message_new_from_uri ("GET", request_uri);
196 soup_session_send_message (session, msg);
197 if (msg->status_code != SOUP_STATUS_OK) {
198 debug_printf (1, " Unexpected response: %d %s\n",
199 msg->status_code, msg->reason_phrase);
202 declared_length = soup_message_headers_get_content_length (msg->response_headers);
203 debug_printf (2, " Content-Length: %lu, body: %s\n",
204 (gulong)declared_length, msg->response_body->data);
205 if (msg->response_body->length != declared_length) {
206 debug_printf (1, " Body length %lu != declared length %lu\n",
207 (gulong)msg->response_body->length,
208 (gulong)declared_length);
212 soup_uri_free (request_uri);
213 g_object_unref (msg);
215 soup_test_session_abort_unref (session);
219 request_started_socket_collector (SoupSession *session, SoupMessage *msg,
220 SoupSocket *socket, gpointer user_data)
222 SoupSocket **sockets = user_data;
225 debug_printf (2, " msg %p => socket %p\n", msg, socket);
226 for (i = 0; i < 4; i++) {
228 /* We ref the socket to make sure that even if
229 * it gets disconnected, it doesn't get freed,
230 * since our checks would get messed up if the
231 * slice allocator reused the same address for
232 * two consecutive sockets.
234 sockets[i] = g_object_ref (socket);
239 debug_printf (1, " socket queue overflowed!\n");
244 do_timeout_test_for_session (SoupSession *session)
247 SoupSocket *sockets[4] = { NULL, NULL, NULL, NULL };
248 SoupURI *timeout_uri;
251 g_signal_connect (session, "request-started",
252 G_CALLBACK (request_started_socket_collector),
255 debug_printf (1, " First message\n");
256 timeout_uri = soup_uri_new_with_base (base_uri, "/timeout-persistent");
257 msg = soup_message_new_from_uri ("GET", timeout_uri);
258 soup_uri_free (timeout_uri);
259 soup_session_send_message (session, msg);
260 if (msg->status_code != SOUP_STATUS_OK) {
261 debug_printf (1, " Unexpected response: %d %s\n",
262 msg->status_code, msg->reason_phrase);
266 debug_printf (1, " Message was retried??\n");
268 sockets[1] = sockets[2] = sockets[3] = NULL;
270 g_object_unref (msg);
272 debug_printf (1, " Second message\n");
273 msg = soup_message_new_from_uri ("GET", base_uri);
274 soup_session_send_message (session, msg);
275 if (msg->status_code != SOUP_STATUS_OK) {
276 debug_printf (1, " Unexpected response: %d %s\n",
277 msg->status_code, msg->reason_phrase);
280 if (sockets[1] != sockets[0]) {
281 debug_printf (1, " Message was not retried on existing connection\n");
283 } else if (!sockets[2]) {
284 debug_printf (1, " Message was not retried after disconnect\n");
286 } else if (sockets[2] == sockets[1]) {
287 debug_printf (1, " Message was retried on closed connection??\n");
289 } else if (sockets[3]) {
290 debug_printf (1, " Message was retried again??\n");
293 g_object_unref (msg);
295 for (i = 0; sockets[i]; i++)
296 g_object_unref (sockets[i]);
300 do_timeout_req_test_for_session (SoupSession *session)
303 SoupRequestHTTP *http;
304 GInputStream *stream;
305 SoupSocket *sockets[4] = { NULL, NULL, NULL, NULL };
306 SoupURI *timeout_uri;
307 GError *error = NULL;
310 g_signal_connect (session, "request-started",
311 G_CALLBACK (request_started_socket_collector),
314 debug_printf (1, " First request\n");
315 timeout_uri = soup_uri_new_with_base (base_uri, "/timeout-persistent");
316 req = soup_session_request_uri (session, timeout_uri, NULL);
317 soup_uri_free (timeout_uri);
319 stream = soup_test_request_send (req, NULL, &error);
321 debug_printf (1, " Unexpected error on send: %s\n",
324 g_clear_error (&error);
326 soup_test_request_close_stream (req, stream, NULL, &error);
328 debug_printf (1, " Unexpected error on close: %s\n",
331 g_clear_error (&error);
333 g_object_unref (stream);
337 debug_printf (1, " Message was retried??\n");
339 sockets[1] = sockets[2] = sockets[3] = NULL;
341 g_object_unref (req);
343 debug_printf (1, " Second request\n");
344 req = soup_session_request_uri (session, base_uri, NULL);
346 stream = soup_test_request_send (req, NULL, &error);
348 debug_printf (1, " Unexpected error on send: %s\n",
351 g_clear_error (&error);
353 soup_test_request_close_stream (req, stream, NULL, &error);
355 debug_printf (1, " Unexpected error on close: %s\n",
358 g_clear_error (&error);
360 g_object_unref (stream);
363 http = SOUP_REQUEST_HTTP (req);
364 if (http->status_code != SOUP_STATUS_OK) {
365 debug_printf (1, " Unexpected response: %d %s\n",
366 http->status_code, http->reason_phrase);
369 if (sockets[1] != sockets[0]) {
370 debug_printf (1, " Message was not retried on existing connection\n");
372 } else if (!sockets[2]) {
373 debug_printf (1, " Message was not retried after disconnect\n");
375 } else if (sockets[2] == sockets[1]) {
376 debug_printf (1, " Message was retried on closed connection??\n");
378 } else if (sockets[3]) {
379 debug_printf (1, " Message was retried again??\n");
382 g_object_unref (req);
384 for (i = 0; sockets[i]; i++)
385 g_object_unref (sockets[i]);
389 do_persistent_connection_timeout_test (void)
391 SoupSession *session;
393 debug_printf (1, "\nUnexpected timing out of persistent connections\n");
395 debug_printf (1, " Async session, message API\n");
396 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
397 do_timeout_test_for_session (session);
398 soup_test_session_abort_unref (session);
400 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
401 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
403 do_timeout_req_test_for_session (session);
404 soup_test_session_abort_unref (session);
406 debug_printf (1, " Sync session, message API\n");
407 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
408 do_timeout_test_for_session (session);
409 soup_test_session_abort_unref (session);
411 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
412 do_timeout_req_test_for_session (session);
413 soup_test_session_abort_unref (session);
416 static GMainLoop *max_conns_loop;
417 static int msgs_done;
418 static guint quit_loop_timeout;
420 #define TEST_CONNS (MAX_CONNS * 2)
423 idle_start_server (gpointer data)
425 g_mutex_unlock (&server_mutex);
430 quit_loop (gpointer data)
432 quit_loop_timeout = 0;
433 g_main_loop_quit (max_conns_loop);
438 max_conns_request_started (SoupSession *session, SoupMessage *msg,
439 SoupSocket *socket, gpointer user_data)
441 if (++msgs_done == MAX_CONNS) {
442 if (quit_loop_timeout)
443 g_source_remove (quit_loop_timeout);
444 quit_loop_timeout = g_timeout_add (100, quit_loop, NULL);
449 max_conns_message_complete (SoupSession *session, SoupMessage *msg, gpointer user_data)
451 if (++msgs_done == TEST_CONNS)
452 g_main_loop_quit (max_conns_loop);
456 do_max_conns_test_for_session (SoupSession *session)
458 SoupMessage *msgs[TEST_CONNS];
461 max_conns_loop = g_main_loop_new (NULL, TRUE);
463 g_mutex_lock (&server_mutex);
465 g_signal_connect (session, "request-started",
466 G_CALLBACK (max_conns_request_started), NULL);
468 for (i = 0; i < TEST_CONNS; i++) {
469 msgs[i] = soup_message_new_from_uri ("GET", base_uri);
470 g_object_ref (msgs[i]);
471 soup_session_queue_message (session, msgs[i],
472 max_conns_message_complete, NULL);
475 g_main_loop_run (max_conns_loop);
476 if (msgs_done != MAX_CONNS) {
477 debug_printf (1, " Queued %d connections out of max %d?",
478 msgs_done, MAX_CONNS);
481 g_signal_handlers_disconnect_by_func (session, max_conns_request_started, NULL);
484 g_idle_add (idle_start_server, NULL);
485 quit_loop_timeout = g_timeout_add (1000, quit_loop, NULL);
486 g_main_loop_run (max_conns_loop);
488 for (i = 0; i < TEST_CONNS; i++) {
489 if (!SOUP_STATUS_IS_SUCCESSFUL (msgs[i]->status_code)) {
490 debug_printf (1, " Message %d failed? %d %s\n",
491 i, msgs[i]->status_code,
492 msgs[i]->reason_phrase ? msgs[i]->reason_phrase : "-");
497 if (msgs_done != TEST_CONNS) {
498 /* Clean up so we don't get a spurious "Leaked
501 for (i = 0; i < TEST_CONNS; i++)
502 soup_session_cancel_message (session, msgs[i], SOUP_STATUS_CANCELLED);
503 g_main_loop_run (max_conns_loop);
506 g_main_loop_unref (max_conns_loop);
507 if (quit_loop_timeout)
508 g_source_remove (quit_loop_timeout);
510 for (i = 0; i < TEST_CONNS; i++)
511 g_object_unref (msgs[i]);
515 do_max_conns_test (void)
517 SoupSession *session;
519 debug_printf (1, "\nExceeding max-conns\n");
521 debug_printf (1, " Async session\n");
522 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
523 SOUP_SESSION_MAX_CONNS, MAX_CONNS,
525 do_max_conns_test_for_session (session);
526 soup_test_session_abort_unref (session);
528 debug_printf (1, " Sync session\n");
529 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
530 SOUP_SESSION_MAX_CONNS, MAX_CONNS,
532 do_max_conns_test_for_session (session);
533 soup_test_session_abort_unref (session);
537 np_request_started (SoupSession *session, SoupMessage *msg,
538 SoupSocket *socket, gpointer user_data)
540 SoupSocket **save_socket = user_data;
542 *save_socket = g_object_ref (socket);
546 np_request_unqueued (SoupSession *session, SoupMessage *msg,
549 SoupSocket *socket = *(SoupSocket **)user_data;
551 if (soup_socket_is_connected (socket)) {
552 debug_printf (1, " socket is still connected\n");
558 np_request_finished (SoupSession *session, SoupMessage *msg,
561 GMainLoop *loop = user_data;
563 g_main_loop_quit (loop);
567 do_non_persistent_test_for_session (SoupSession *session)
570 SoupSocket *socket = NULL;
573 loop = g_main_loop_new (NULL, FALSE);
575 g_signal_connect (session, "request-started",
576 G_CALLBACK (np_request_started),
578 g_signal_connect (session, "request-unqueued",
579 G_CALLBACK (np_request_unqueued),
582 msg = soup_message_new_from_uri ("GET", base_uri);
583 soup_message_headers_append (msg->request_headers, "Connection", "close");
585 soup_session_queue_message (session, msg,
586 np_request_finished, loop);
587 g_main_loop_run (loop);
588 g_main_loop_unref (loop);
590 if (msg->status_code != SOUP_STATUS_OK) {
591 debug_printf (1, " Unexpected response: %d %s\n",
592 msg->status_code, msg->reason_phrase);
595 g_object_unref (msg);
596 g_object_unref (socket);
600 do_non_persistent_connection_test (void)
602 SoupSession *session;
604 debug_printf (1, "\nNon-persistent connections are closed immediately\n");
606 debug_printf (1, " Async session\n");
607 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
608 do_non_persistent_test_for_session (session);
609 soup_test_session_abort_unref (session);
611 debug_printf (1, " Sync session\n");
612 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
613 do_non_persistent_test_for_session (session);
614 soup_test_session_abort_unref (session);
618 do_non_idempotent_test_for_session (SoupSession *session)
621 SoupSocket *sockets[4] = { NULL, NULL, NULL, NULL };
624 g_signal_connect (session, "request-started",
625 G_CALLBACK (request_started_socket_collector),
628 debug_printf (2, " GET\n");
629 msg = soup_message_new_from_uri ("GET", base_uri);
630 soup_session_send_message (session, msg);
631 if (msg->status_code != SOUP_STATUS_OK) {
632 debug_printf (1, " Unexpected response: %d %s\n",
633 msg->status_code, msg->reason_phrase);
637 debug_printf (1, " Message was retried??\n");
639 sockets[1] = sockets[2] = sockets[3] = NULL;
641 g_object_unref (msg);
643 debug_printf (2, " POST\n");
644 msg = soup_message_new_from_uri ("POST", base_uri);
645 soup_session_send_message (session, msg);
646 if (msg->status_code != SOUP_STATUS_OK) {
647 debug_printf (1, " Unexpected response: %d %s\n",
648 msg->status_code, msg->reason_phrase);
651 if (sockets[1] == sockets[0]) {
652 debug_printf (1, " Message was sent on existing connection!\n");
656 debug_printf (1, " Too many connections used...\n");
659 g_object_unref (msg);
661 for (i = 0; sockets[i]; i++)
662 g_object_unref (sockets[i]);
666 do_non_idempotent_connection_test (void)
668 SoupSession *session;
670 debug_printf (1, "\nNon-idempotent methods are always sent on new connections\n");
672 debug_printf (1, " Async session\n");
673 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
674 do_non_idempotent_test_for_session (session);
675 soup_test_session_abort_unref (session);
677 debug_printf (1, " Sync session\n");
678 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
679 do_non_idempotent_test_for_session (session);
680 soup_test_session_abort_unref (session);
685 #define HTTP_SERVER "http://127.0.0.1:47524"
686 #define HTTPS_SERVER "https://127.0.0.1:47525"
687 #define HTTP_PROXY "http://127.0.0.1:47526"
689 static SoupConnectionState state_transitions[] = {
690 /* NEW -> */ SOUP_CONNECTION_CONNECTING,
691 /* CONNECTING -> */ SOUP_CONNECTION_IN_USE,
692 /* IDLE -> */ SOUP_CONNECTION_DISCONNECTED,
693 /* IN_USE -> */ SOUP_CONNECTION_IDLE,
695 /* REMOTE_DISCONNECTED */ -1,
696 /* DISCONNECTED */ -1,
699 static const char *state_names[] = {
700 "NEW", "CONNECTING", "IDLE", "IN_USE",
701 "REMOTE_DISCONNECTED", "DISCONNECTED"
705 connection_state_changed (GObject *object, GParamSpec *param,
708 SoupConnectionState *state = user_data;
709 SoupConnectionState new_state;
711 g_object_get (object, "state", &new_state, NULL);
712 if (state_transitions[*state] != new_state) {
713 debug_printf (1, " Unexpected transition: %s -> %s\n",
714 state_names[*state], state_names[new_state]);
717 debug_printf (2, " %s -> %s\n",
718 state_names[*state], state_names[new_state]);
725 connection_created (SoupSession *session, GObject *conn,
728 SoupConnectionState *state = user_data;
730 g_object_get (conn, "state", state, NULL);
731 if (*state != SOUP_CONNECTION_NEW) {
732 debug_printf (1, " Unexpected initial state: %d\n",
737 g_signal_connect (conn, "notify::state",
738 G_CALLBACK (connection_state_changed),
743 do_one_connection_state_test (SoupSession *session, const char *uri)
747 msg = soup_message_new ("GET", uri);
748 soup_session_send_message (session, msg);
749 if (msg->status_code != SOUP_STATUS_OK) {
750 debug_printf (1, " Unexpected response: %d %s\n",
751 msg->status_code, msg->reason_phrase);
754 g_object_unref (msg);
755 soup_session_abort (session);
759 do_connection_state_test_for_session (SoupSession *session)
761 SoupConnectionState state;
764 g_signal_connect (session, "connection-created",
765 G_CALLBACK (connection_created),
768 debug_printf (1, " http\n");
769 do_one_connection_state_test (session, HTTP_SERVER);
771 debug_printf (1, " https\n");
772 do_one_connection_state_test (session, HTTPS_SERVER);
774 proxy_uri = soup_uri_new (HTTP_PROXY);
775 g_object_set (G_OBJECT (session),
776 SOUP_SESSION_PROXY_URI, proxy_uri,
778 soup_uri_free (proxy_uri);
780 debug_printf (1, " http with proxy\n");
781 do_one_connection_state_test (session, HTTP_SERVER);
783 debug_printf (1, " https with proxy\n");
784 do_one_connection_state_test (session, HTTPS_SERVER);
788 do_connection_state_test (void)
790 SoupSession *session;
792 debug_printf (1, "\nConnection states\n");
794 debug_printf (1, " Async session\n");
795 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
796 do_connection_state_test_for_session (session);
797 soup_test_session_abort_unref (session);
799 debug_printf (1, " Sync session\n");
800 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
801 do_connection_state_test_for_session (session);
802 soup_test_session_abort_unref (session);
806 static const char *event_names[] = {
807 "RESOLVING", "RESOLVED", "CONNECTING", "CONNECTED",
808 "PROXY_NEGOTIATING", "PROXY_NEGOTIATED",
809 "TLS_HANDSHAKING", "TLS_HANDSHAKED", "COMPLETE"
812 static const char event_abbrevs[] = {
813 'r', 'R', 'c', 'C', 'p', 'P', 't', 'T', 'x', '\0'
817 event_name_from_abbrev (char abbrev)
821 for (evt = 0; event_abbrevs[evt]; evt++) {
822 if (event_abbrevs[evt] == abbrev)
823 return event_names[evt];
829 network_event (SoupMessage *msg, GSocketClientEvent event,
830 GIOStream *connection, gpointer user_data)
832 const char **events = user_data;
835 debug_printf (1, " Unexpected event: %s\n",
839 if (**events == event_abbrevs[event])
840 debug_printf (2, " %s\n", event_names[event]);
842 debug_printf (1, " Unexpected event: %s (expected %s)\n",
844 event_name_from_abbrev (**events));
847 *events = *events + 1;
852 do_one_connection_event_test (SoupSession *session, const char *uri,
857 msg = soup_message_new ("GET", uri);
858 g_signal_connect (msg, "network-event",
859 G_CALLBACK (network_event),
861 soup_session_send_message (session, msg);
862 if (msg->status_code != SOUP_STATUS_OK) {
863 debug_printf (1, " Unexpected response: %d %s\n",
864 msg->status_code, msg->reason_phrase);
868 debug_printf (1, " Expected %s\n",
869 event_name_from_abbrev (*events));
874 g_object_unref (msg);
875 soup_session_abort (session);
879 do_connection_event_test_for_session (SoupSession *session)
883 debug_printf (1, " http\n");
884 do_one_connection_event_test (session, HTTP_SERVER, "rRcCx");
886 debug_printf (1, " https\n");
887 do_one_connection_event_test (session, HTTPS_SERVER, "rRcCtTx");
889 proxy_uri = soup_uri_new (HTTP_PROXY);
890 g_object_set (G_OBJECT (session),
891 SOUP_SESSION_PROXY_URI, proxy_uri,
893 soup_uri_free (proxy_uri);
895 debug_printf (1, " http with proxy\n");
896 do_one_connection_event_test (session, HTTP_SERVER, "rRcCx");
898 debug_printf (1, " https with proxy\n");
899 do_one_connection_event_test (session, HTTPS_SERVER, "rRcCpPtTx");
903 do_connection_event_test (void)
905 SoupSession *session;
907 debug_printf (1, "\nConnection events\n");
909 debug_printf (1, " Async session\n");
910 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
911 do_connection_event_test_for_session (session);
912 soup_test_session_abort_unref (session);
914 debug_printf (1, " Sync session\n");
915 session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
916 do_connection_event_test_for_session (session);
917 soup_test_session_abort_unref (session);
923 main (int argc, char **argv)
925 test_init (argc, argv, NULL);
930 server = soup_test_server_new (TRUE);
931 soup_server_add_handler (server, NULL, server_callback, "http", NULL);
932 base_uri = soup_uri_new ("http://127.0.0.1/");
933 soup_uri_set_port (base_uri, soup_server_get_port (server));
935 do_content_length_framing_test ();
936 do_persistent_connection_timeout_test ();
937 do_max_conns_test ();
938 do_non_persistent_connection_test ();
939 do_non_idempotent_connection_test ();
941 do_connection_state_test ();
942 do_connection_event_test ();
945 soup_uri_free (base_uri);
946 soup_test_server_quit_unref (server);