Fix the retry-on-broken-connection codepath for SoupRequest
[platform/upstream/libsoup.git] / tests / timeout-test.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 #include "test-utils.h"
4
5 static void
6 do_message_to_session (SoupSession *session, const char *uri,
7                        const char *comment, guint expected_status)
8 {
9         SoupMessage *msg;
10
11         debug_printf (1, "    %s\n", comment);
12         msg = soup_message_new ("GET", uri);
13         soup_session_send_message (session, msg);
14
15         if (msg->status_code != expected_status) {
16                 debug_printf (1, "      FAILED: %d %s (expected %d %s)\n",
17                               msg->status_code, msg->reason_phrase,
18                               expected_status,
19                               soup_status_get_phrase (expected_status));
20                 errors++;
21         }
22
23         if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) &&
24             !soup_message_is_keepalive (msg)) {
25                 debug_printf (1, "      ERROR: message is not keepalive!");
26                 errors++;
27         }
28
29         g_object_unref (msg);
30 }
31
32 static void
33 request_started_cb (SoupSession *session, SoupMessage *msg,
34                     SoupSocket *socket, gpointer user_data)
35 {
36         SoupSocket **ret = user_data;
37
38         *ret = socket;
39 }
40
41 static void
42 do_tests_for_session (SoupSession *timeout_session,
43                       SoupSession *idle_session,
44                       SoupSession *plain_session,
45                       char *fast_uri, char *slow_uri)
46 {
47         SoupSocket *ret, *idle_first, *idle_second;
48         SoupSocket *plain_first, *plain_second;
49
50         if (idle_session) {
51                 g_signal_connect (idle_session, "request-started",
52                                   G_CALLBACK (request_started_cb), &ret);
53                 do_message_to_session (idle_session, fast_uri, "fast to idle", SOUP_STATUS_OK);
54                 idle_first = ret;
55         }
56
57         if (plain_session) {
58                 g_signal_connect (plain_session, "request-started",
59                                   G_CALLBACK (request_started_cb), &ret);
60                 do_message_to_session (plain_session, fast_uri, "fast to plain", SOUP_STATUS_OK);
61                 plain_first = ret;
62         }
63
64         do_message_to_session (timeout_session, fast_uri, "fast to timeout", SOUP_STATUS_OK);
65         do_message_to_session (timeout_session, slow_uri, "slow to timeout", SOUP_STATUS_IO_ERROR);
66
67         if (idle_session) {
68                 do_message_to_session (idle_session, fast_uri, "fast to idle", SOUP_STATUS_OK);
69                 idle_second = ret;
70                 g_signal_handlers_disconnect_by_func (idle_session,
71                                                       (gpointer)request_started_cb,
72                                                       &ret);
73
74                 if (idle_first == idle_second) {
75                         debug_printf (1, "      ERROR: idle_session did not close first connection\n");
76                         errors++;
77                 }
78         }
79
80         if (plain_session) {
81                 do_message_to_session (plain_session, fast_uri, "fast to plain", SOUP_STATUS_OK);
82                 plain_second = ret;
83                 g_signal_handlers_disconnect_by_func (plain_session,
84                                                       (gpointer)request_started_cb,
85                                                       &ret);
86
87                 if (plain_first != plain_second) {
88                         debug_printf (1, "      ERROR: plain_session closed connection\n");
89                         errors++;
90                 }
91         }
92 }
93
94 static void
95 do_timeout_tests (char *fast_uri, char *slow_uri)
96 {
97         SoupSession *timeout_session, *idle_session, *plain_session;
98
99         debug_printf (1, "  async\n");
100         timeout_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
101                                          SOUP_SESSION_TIMEOUT, 1,
102                                          NULL);
103         idle_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
104                                               SOUP_SESSION_IDLE_TIMEOUT, 1,
105                                               NULL);
106         /* The "plain" session also has an idle timeout, but it's longer
107          * than the test takes, so for our purposes it should behave like
108          * it has no timeout.
109          */
110         plain_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
111                                                SOUP_SESSION_IDLE_TIMEOUT, 2,
112                                                NULL);
113         do_tests_for_session (timeout_session, idle_session, plain_session,
114                               fast_uri, slow_uri);
115         soup_test_session_abort_unref (timeout_session);
116         soup_test_session_abort_unref (idle_session);
117         soup_test_session_abort_unref (plain_session);
118
119         debug_printf (1, "  sync\n");
120         timeout_session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
121                                                  SOUP_SESSION_TIMEOUT, 1,
122                                                  NULL);
123         /* SOUP_SESSION_TIMEOUT doesn't work with sync sessions */
124         plain_session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
125                                                NULL);
126         do_tests_for_session (timeout_session, NULL, plain_session, fast_uri, slow_uri);
127         soup_test_session_abort_unref (timeout_session);
128         soup_test_session_abort_unref (plain_session);
129 }
130
131 static gboolean
132 timeout_finish_message (gpointer msg)
133 {
134         SoupServer *server = g_object_get_data (G_OBJECT (msg), "server");
135
136         soup_server_unpause_message (server, msg);
137         return FALSE;
138 }
139
140 static void
141 server_handler (SoupServer        *server,
142                 SoupMessage       *msg, 
143                 const char        *path,
144                 GHashTable        *query,
145                 SoupClientContext *client,
146                 gpointer           user_data)
147 {
148         soup_message_set_status (msg, SOUP_STATUS_OK);
149         soup_message_set_response (msg, "text/plain",
150                                    SOUP_MEMORY_STATIC,
151                                    "ok\r\n", 4);
152
153         if (!strcmp (path, "/slow")) {
154                 soup_server_pause_message (server, msg);
155                 g_object_set_data (G_OBJECT (msg), "server", server);
156                 soup_add_timeout (soup_server_get_async_context (server),
157                                   1100, timeout_finish_message, msg);
158         }
159 }
160
161 int
162 main (int argc, char **argv)
163 {
164         SoupServer *server;
165         char *fast_uri, *slow_uri;
166
167         test_init (argc, argv, NULL);
168
169         debug_printf (1, "http\n");
170         server = soup_test_server_new (TRUE);
171         soup_server_add_handler (server, NULL, server_handler, NULL, NULL);
172         fast_uri = g_strdup_printf ("http://127.0.0.1:%u/",
173                                     soup_server_get_port (server));
174         slow_uri = g_strdup_printf ("http://127.0.0.1:%u/slow",
175                                     soup_server_get_port (server));
176         do_timeout_tests (fast_uri, slow_uri);
177         g_free (fast_uri);
178         g_free (slow_uri);
179         soup_test_server_quit_unref (server);
180
181         if (tls_available) {
182                 debug_printf (1, "\nhttps\n");
183                 server = soup_test_server_new_ssl (TRUE);
184                 soup_server_add_handler (server, NULL, server_handler, NULL, NULL);
185                 fast_uri = g_strdup_printf ("https://127.0.0.1:%u/",
186                                             soup_server_get_port (server));
187                 slow_uri = g_strdup_printf ("https://127.0.0.1:%u/slow",
188                                             soup_server_get_port (server));
189                 do_timeout_tests (fast_uri, slow_uri);
190                 g_free (fast_uri);
191                 g_free (slow_uri);
192                 soup_test_server_quit_unref (server);
193         }
194
195         test_cleanup ();
196         return errors != 0;
197 }