tests: fix a few leaks, update valgrind suppressions file
[platform/upstream/libsoup.git] / tests / requester-test.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2011 Red Hat, Inc.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #define LIBSOUP_USE_UNSTABLE_REQUEST_API
11 #include <libsoup/soup.h>
12 #include <libsoup/soup-requester.h>
13 #include <libsoup/soup-request-http.h>
14
15 #include "test-utils.h"
16
17 SoupServer *server;
18 GMainLoop *loop;
19 char buf[1024];
20
21 SoupBuffer *response;
22
23 static void
24 get_index (void)
25 {
26         char *contents;
27         gsize length;
28         GError *error = NULL;
29
30         if (!g_file_get_contents (SRCDIR "/index.txt", &contents, &length, &error)) {
31                 fprintf (stderr, "Could not read index.txt: %s\n",
32                          error->message);
33                 exit (1);
34         }
35
36         response = soup_buffer_new (SOUP_MEMORY_TAKE, contents, length);
37 }
38
39 static void
40 server_callback (SoupServer *server, SoupMessage *msg,
41                  const char *path, GHashTable *query,
42                  SoupClientContext *context, gpointer data)
43 {
44         soup_message_set_status (msg, SOUP_STATUS_OK);
45         soup_message_set_response (msg, "text/plain",
46                                    SOUP_MEMORY_STATIC, NULL, 0);
47         soup_message_body_append_buffer (msg->response_body, response);
48 }
49
50 static void
51 test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
52 {
53         GInputStream *stream = G_INPUT_STREAM (source);
54         GString *body = user_data;
55         GError *error = NULL;
56         gsize nread;
57
58         nread = g_input_stream_read_finish (stream, res, &error);
59         if (nread == -1) {
60                 debug_printf (1, "  read_async failed: %s", error->message);
61                 errors++;
62                 g_object_unref (stream);
63                 g_main_loop_quit (loop);
64                 return;
65         } else if (nread == 0) {
66                 g_object_unref (stream);
67                 g_main_loop_quit (loop);
68                 return;
69         }
70
71         g_string_append_len (body, buf, nread);
72         g_input_stream_read_async (stream, buf, sizeof (buf),
73                                    G_PRIORITY_DEFAULT, NULL,
74                                    test_read_ready, body);
75 }
76
77 static void
78 test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
79 {
80         GString *body = user_data;
81         GInputStream *stream;
82         GError *error = NULL;
83         SoupMessage *msg;
84
85         stream = soup_request_send_finish (SOUP_REQUEST (source), res, &error);
86         if (!stream) {
87                 debug_printf (1, "  send_async failed: %s", error->message);
88                 errors++;
89                 g_main_loop_quit (loop);
90                 return;
91         }
92
93         msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (source));
94         if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
95                 debug_printf (1, "  GET failed: %d %s", msg->status_code,
96                               msg->reason_phrase);
97                 errors++;
98                 g_main_loop_quit (loop);
99                 return;
100         }
101         g_object_unref (msg);
102
103         g_input_stream_read_async (stream, buf, sizeof (buf),
104                                    G_PRIORITY_DEFAULT, NULL,
105                                    test_read_ready, body);
106 }
107
108 static void
109 do_test_for_thread_and_context (SoupSession *session, const char *uri)
110 {
111         SoupRequester *requester;
112         SoupRequest *request;
113         GString *body;
114
115         requester = soup_requester_new ();
116         soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester));
117         g_object_unref (requester);
118
119         body = g_string_new (NULL);
120
121         request = soup_requester_request (requester, uri, NULL);
122         soup_request_send_async (request, NULL, test_sent, body);
123         g_object_unref (request);
124
125         loop = g_main_loop_new (soup_session_get_async_context (session), TRUE);
126         g_main_loop_run (loop);
127         g_main_loop_unref (loop);
128
129         if (body->len != response->length) {
130                 debug_printf (1, "  body length mismatch: expected %d, got %d\n",
131                               (int)response->length, (int)body->len);
132                 errors++;
133         } else if (memcmp (body->str, response->data, response->length) != 0) {
134                 debug_printf (1, "  body data mismatch\n");
135                 errors++;
136         }
137
138         g_string_free (body, TRUE);
139 }
140
141 static void
142 do_simple_test (const char *uri)
143 {
144         SoupSession *session;
145
146         debug_printf (1, "Simple streaming test\n");
147
148         session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
149         do_test_for_thread_and_context (session, uri);
150         soup_test_session_abort_unref (session);
151 }
152
153 static gpointer
154 do_test_with_context (const char *uri)
155 {
156         GMainContext *async_context;
157         SoupSession *session;
158
159         async_context = g_main_context_new ();
160         g_main_context_push_thread_default (async_context);
161
162         session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
163                                          SOUP_SESSION_ASYNC_CONTEXT, async_context,
164                                          NULL);
165
166         do_test_for_thread_and_context (session, uri);
167         soup_test_session_abort_unref (session);
168
169         g_main_context_pop_thread_default (async_context);
170         g_main_context_unref (async_context);
171         return NULL;
172 }
173
174 static void
175 do_context_test (const char *uri)
176 {
177         debug_printf (1, "Streaming with a non-default-context\n");
178         do_test_with_context (uri);
179 }
180
181 static void
182 do_thread_test (const char *uri)
183 {
184         GThread *thread;
185
186         debug_printf (1, "Streaming in another thread\n");
187
188         thread = g_thread_create ((GThreadFunc)do_test_with_context,
189                                   (gpointer)uri, TRUE, NULL);
190         g_thread_join (thread);
191 }
192
193 int
194 main (int argc, char **argv)
195 {
196         char *uri;
197
198         test_init (argc, argv, NULL);
199         get_index ();
200
201         server = soup_test_server_new (TRUE);
202         soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
203         uri = g_strdup_printf ("http://127.0.0.1:%u/", soup_server_get_port (server));
204
205         do_simple_test (uri);
206         do_thread_test (uri);
207         do_context_test (uri);
208
209         g_free (uri);
210         soup_buffer_free (response);
211         soup_test_server_quit_unref (server);
212
213         test_cleanup ();
214         return errors != 0;
215 }