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