1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2012 Igalia S.L.
4 */
5
6 #include "test-utils.h"
7
8 SoupBuffer *index_buffer;
9
10 typedef struct {
11 GString *body;
12 char buffer[1024];
13 GMainLoop *loop;
14 } AsyncRequestData;
15
16 static void
stream_closed(GObject * source,GAsyncResult * result,gpointer user_data)17 stream_closed (GObject *source, GAsyncResult *result, gpointer user_data)
18 {
19 GInputStream *in = G_INPUT_STREAM (source);
20 AsyncRequestData *data = user_data;
21 GError *error = NULL;
22
23 g_input_stream_close_finish (in, result, &error);
24 g_assert_no_error (error);
25 g_main_loop_quit (data->loop);
26 g_object_unref (in);
27 }
28
29 static void
test_read_ready(GObject * source,GAsyncResult * result,gpointer user_data)30 test_read_ready (GObject *source, GAsyncResult *result, gpointer user_data)
31 {
32 GInputStream *in = G_INPUT_STREAM (source);
33 AsyncRequestData *data = user_data;
34 gssize nread;
35 GError *error = NULL;
36
37 nread = g_input_stream_read_finish (in, result, &error);
38 if (nread == -1) {
39 g_assert_no_error (error);
40 g_clear_error (&error);
41 g_input_stream_close (in, NULL, NULL);
42 g_object_unref (in);
43 return;
44 } else if (nread == 0) {
45 g_input_stream_close_async (in, G_PRIORITY_DEFAULT, NULL,
46 stream_closed, data);
47 return;
48 }
49
50 g_string_append_len (data->body, data->buffer, nread);
51 g_input_stream_read_async (in, data->buffer, sizeof (data->buffer),
52 G_PRIORITY_DEFAULT, NULL,
53 test_read_ready, data);
54 }
55
56 static void
async_request_sent(GObject * source,GAsyncResult * result,gpointer user_data)57 async_request_sent (GObject *source, GAsyncResult *result, gpointer user_data)
58 {
59 GInputStream *in;
60 AsyncRequestData *data = user_data;
61 GError *error = NULL;
62
63 in = soup_request_send_finish (SOUP_REQUEST (source), result, &error);
64 if (!in) {
65 g_assert_no_error (error);
66 g_clear_error (&error);
67 return;
68 }
69
70 g_input_stream_read_async (in, data->buffer, sizeof (data->buffer),
71 G_PRIORITY_DEFAULT, NULL,
72 test_read_ready, data);
73 }
74
75 static void
do_async_request(SoupRequest * request)76 do_async_request (SoupRequest *request)
77 {
78 AsyncRequestData data;
79
80 data.body = g_string_new (NULL);
81 soup_request_send_async (request, NULL, async_request_sent, &data);
82
83 data.loop = g_main_loop_new (soup_session_get_async_context (soup_request_get_session (request)), TRUE);
84 g_main_loop_run (data.loop);
85 g_main_loop_unref (data.loop);
86
87 soup_assert_cmpmem (data.body->str, data.body->len,
88 index_buffer->data, index_buffer->length);
89 g_string_free (data.body, TRUE);
90 }
91
92 static void
do_sync_request(SoupRequest * request)93 do_sync_request (SoupRequest *request)
94 {
95 GInputStream *in;
96 GString *body;
97 char buffer[1024];
98 gssize nread;
99 GError *error = NULL;
100
101 in = soup_request_send (request, NULL, &error);
102 if (!in) {
103 g_assert_no_error (error);
104 g_clear_error (&error);
105 return;
106 }
107
108 body = g_string_new (NULL);
109 do {
110 nread = g_input_stream_read (in, buffer, sizeof (buffer),
111 NULL, &error);
112 if (nread == -1) {
113 g_assert_no_error (error);
114 g_clear_error (&error);
115 break;
116 }
117 g_string_append_len (body, buffer, nread);
118 } while (nread > 0);
119
120 g_input_stream_close (in, NULL, &error);
121 g_assert_no_error (error);
122 g_clear_error (&error);
123 g_object_unref (in);
124
125 soup_assert_cmpmem (body->str, body->len, index_buffer->data, index_buffer->length);
126 g_string_free (body, TRUE);
127 }
128
129 static void
do_request(const char * uri_string,gconstpointer type)130 do_request (const char *uri_string, gconstpointer type)
131 {
132 SoupSession *session;
133 SoupRequest *request;
134 GError *error = NULL;
135
136 session = soup_test_session_new (GPOINTER_TO_SIZE (type),
137 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
138 NULL);
139
140 request = soup_session_request (session, uri_string, &error);
141 g_assert_no_error (error);
142
143 if (SOUP_IS_SESSION_ASYNC (session))
144 do_async_request (request);
145 else
146 do_sync_request (request);
147
148 g_object_unref (request);
149 soup_test_session_abort_unref (session);
150 }
151
152 static void
do_request_file_test(gconstpointer type)153 do_request_file_test (gconstpointer type)
154 {
155 GFile *index;
156 char *uri_string;
157
158 index = g_file_new_for_path (g_test_get_filename (G_TEST_DIST, "index.txt", NULL));
159 uri_string = g_file_get_uri (index);
160 g_object_unref (index);
161
162 do_request (uri_string, type);
163 g_free (uri_string);
164 }
165
166 static void
do_request_data_test(gconstpointer type)167 do_request_data_test (gconstpointer type)
168 {
169 gchar *base64;
170 char *uri_string;
171
172 base64 = g_base64_encode ((const guchar *)index_buffer->data, index_buffer->length);
173 uri_string = g_strdup_printf ("data:text/plain;charset=utf8;base64,%s", base64);
174 g_free (base64);
175
176 do_request (uri_string, type);
177 g_free (uri_string);
178 }
179
180 static void
do_request_gresource_test(gconstpointer type)181 do_request_gresource_test (gconstpointer type)
182 {
183 do_request ("resource:///org/gnome/libsoup/tests/index.txt", type);
184 }
185
186 int
main(int argc,char ** argv)187 main (int argc, char **argv)
188 {
189 int ret;
190
191 test_init (argc, argv, NULL);
192
193 index_buffer = soup_test_get_index ();
194 soup_test_register_resources ();
195
196 g_test_add_data_func ("/resource/sync/file",
197 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_SYNC),
198 do_request_file_test);
199 g_test_add_data_func ("/resource/sync/data",
200 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_SYNC),
201 do_request_data_test);
202 g_test_add_data_func ("/resource/sync/gresource",
203 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_SYNC),
204 do_request_gresource_test);
205
206 g_test_add_data_func ("/resource/async/file",
207 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_ASYNC),
208 do_request_file_test);
209 g_test_add_data_func ("/resource/async/data",
210 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_ASYNC),
211 do_request_data_test);
212 g_test_add_data_func ("/resource/async/gresource",
213 GSIZE_TO_POINTER (SOUP_TYPE_SESSION_ASYNC),
214 do_request_gresource_test);
215
216 ret = g_test_run ();
217
218 test_cleanup ();
219 return ret;
220 }
221