ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / test / test-callback.c
1 #include <config.h>
2
3 #include <gmodule.h>
4 #include <libgnomevfs/gnome-vfs-async-ops.h>
5 #include <libgnomevfs/gnome-vfs-init.h>
6 #include <libgnomevfs/gnome-vfs-ops.h>
7 #include <libgnomevfs/gnome-vfs-module-callback.h>
8 #include <libgnomevfs/gnome-vfs-standard-callbacks.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13
14 static gboolean authentication_callback_called = FALSE;
15
16 /* For this test case to function, these two URI's should
17  * require a username/password (set in authentication_username, authentication_password below)
18  * and AUTHENTICATION_URI_CHILD should be a child of AUTHENTICATION_URI
19  */
20 #define AUTHENTICATION_URI_CHILD "http://localhost/~mikef/protected/index.html"
21 #define AUTHENTICATION_URI "http://localhost/~mikef/protected/"
22
23 static const char *authentication_username = "foo";
24 static const char *authentication_password = "foo";
25
26 static void /* GnomeVFSModuleCallback */
27 authentication_callback (gconstpointer in, size_t in_size, gpointer out, size_t out_size, gpointer user_data)
28 {
29         GnomeVFSModuleCallbackAuthenticationIn *in_real;
30         GnomeVFSModuleCallbackAuthenticationOut *out_real;
31
32         /* printf ("in authentication_callback\n"); */
33         
34         g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size
35                 && sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
36
37         g_return_if_fail (in != NULL);
38         g_return_if_fail (out != NULL);
39
40         in_real = (GnomeVFSModuleCallbackAuthenticationIn *)in;
41         out_real = (GnomeVFSModuleCallbackAuthenticationOut *)out;
42
43         /* printf ("in uri: %s realm: %s\n", in_real->uri, in_real->realm); */
44         
45         out_real->username = g_strdup (authentication_username);
46         out_real->password = g_strdup (authentication_password);
47
48         authentication_callback_called = TRUE;
49 }
50
51 static gboolean destroy_notify_occurred = FALSE;
52
53 static void /*GDestroyNotify*/
54 destroy_notify (gpointer user_data)
55 {
56         destroy_notify_occurred = TRUE;
57 }
58
59 static volatile gboolean open_callback_occurred = FALSE;
60
61 static GnomeVFSResult open_callback_result_expected = GNOME_VFS_OK;
62
63 static void /* GnomeVFSAsyncOpenCallback */
64 open_callback (GnomeVFSAsyncHandle *handle,
65                GnomeVFSResult result,
66                gpointer callback_data)
67 {
68         g_assert (result == open_callback_result_expected);
69
70         open_callback_occurred = TRUE;
71 }
72
73 static volatile gboolean close_callback_occurred = FALSE;
74
75 static void /* GnomeVFSAsyncOpenCallback */
76 close_callback (GnomeVFSAsyncHandle *handle,
77                 GnomeVFSResult result,
78                 gpointer callback_data)
79 {
80         close_callback_occurred = TRUE;
81 }
82
83 static void
84 stop_after_log (const char *domain, GLogLevelFlags level, 
85         const char *message, gpointer data)
86 {
87         void (* saved_handler) (int);
88         
89         g_log_default_handler (domain, level, message, data);
90
91         saved_handler = signal (SIGINT, SIG_IGN);
92         raise (SIGINT);
93         signal (SIGINT, saved_handler);
94 }
95
96 static void
97 make_asserts_break (const char *domain)
98 {
99         g_log_set_handler
100                 (domain, 
101                  (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING),
102                  stop_after_log, NULL);
103 }
104
105 static void (*flush_credentials_func)(void);
106
107 int
108 main (int argc, char **argv)
109 {
110         GnomeVFSHandle *handle;
111         GnomeVFSResult result;
112         GnomeVFSAsyncHandle *async_handle;
113         char *module_path;
114         char *authentication_uri, *authentication_uri_child;
115         GModule *module;
116         guint i;
117
118         make_asserts_break ("GLib");
119         make_asserts_break ("GnomeVFS");
120
121         if (argc == 2) {
122                 authentication_uri = argv[1];
123                 authentication_uri_child = g_strdup_printf("%s/./", authentication_uri);
124         } else if (argc == 3) {
125                 authentication_uri = argv[1];
126                 authentication_uri_child = argv[2];
127         } else {
128                 authentication_uri = AUTHENTICATION_URI;
129                 authentication_uri_child = AUTHENTICATION_URI_CHILD;
130         }
131
132         gnome_vfs_init ();
133
134         /* Load http module so we can snag the test hook */
135         module_path = g_module_build_path (MODULES_PATH, "http");
136         module = g_module_open (module_path, G_MODULE_BIND_LAZY);
137         g_free (module_path);
138         module_path = NULL;
139
140         if (module == NULL) {
141                 fprintf (stderr, "Couldn't load http module \n");
142                 exit (-1);
143         }
144
145         g_module_symbol (module, "http_authentication_test_flush_credentials", (gpointer *) &flush_credentials_func);
146
147         if (flush_credentials_func == NULL) {
148                 fprintf (stderr, "Couldn't find http_authentication_test_flush_credentials\n");
149                 exit (-1);
150         }
151
152         /* Test 1: Attempt to access a URI requiring authentication w/o a callback registered */
153
154         result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ);
155         g_assert (result == GNOME_VFS_ERROR_ACCESS_DENIED);
156         handle = NULL;
157
158         /* Test 2: Attempt an async open that requires http authentication */
159
160         gnome_vfs_module_callback_set_default (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
161                                                authentication_callback, 
162                                                NULL,
163                                                NULL);
164
165         authentication_callback_called = FALSE;
166         
167         open_callback_occurred = FALSE;
168         open_callback_result_expected = GNOME_VFS_OK;
169
170         gnome_vfs_async_open (
171                 &async_handle, 
172                 authentication_uri,
173                 GNOME_VFS_OPEN_READ,
174                 0,
175                 open_callback,
176                 NULL);
177
178         while (!open_callback_occurred) {
179                 g_main_context_iteration (NULL, TRUE);
180         }
181
182         close_callback_occurred = FALSE;
183         gnome_vfs_async_close (async_handle, close_callback, NULL);
184
185         while (!close_callback_occurred) {
186                 g_main_context_iteration (NULL, TRUE);
187         }
188
189         g_assert (authentication_callback_called);
190
191         /* Test 3: Attempt a sync call to the same location;
192          * credentials should be stored so the authentication_callback function
193          * should not be called
194          */
195         
196         authentication_callback_called = FALSE;
197         result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ);
198         g_assert (result == GNOME_VFS_OK);
199         gnome_vfs_close (handle);
200         handle = NULL;
201         /* The credentials should be in the cache, so we shouldn't have been called */
202         g_assert (authentication_callback_called == FALSE);
203
204         /* Test 4: Attempt a sync call to something deeper in the namespace.
205          * which should work without a callback too
206          */
207
208         authentication_callback_called = FALSE;
209         result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ);
210         g_assert (result == GNOME_VFS_OK);
211         gnome_vfs_close (handle);
212         handle = NULL;
213         /* The credentials should be in the cache, so we shouldn't have been called */
214         g_assert (authentication_callback_called == FALSE);
215
216         /* Test 5: clear the credential store and try again in reverse order */
217
218         flush_credentials_func();
219
220         authentication_callback_called = FALSE;
221         result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ);
222         g_assert (result == GNOME_VFS_OK);
223         gnome_vfs_close (handle);
224         handle = NULL;
225         g_assert (authentication_callback_called == TRUE);
226
227         /* Test 6: Try something higher in the namespace, which should
228          * cause the callback to happen again
229          */
230
231         authentication_callback_called = FALSE;
232         result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ);
233         g_assert (result == GNOME_VFS_OK);
234         gnome_vfs_close (handle);
235         handle = NULL;
236         g_assert (authentication_callback_called == TRUE);
237
238         /* Test 7: Try same URL as in test 4, make sure callback doesn't get called */
239
240         authentication_callback_called = FALSE;
241         result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ);
242         g_assert (result == GNOME_VFS_OK);
243         gnome_vfs_close (handle);
244         handle = NULL;
245         g_assert (authentication_callback_called == FALSE);
246
247         /* Test 8: clear the credential store ensure that passing a username as NULL
248          * cancels the operation, resulting in a ACCESS_DENIED error */
249
250         flush_credentials_func();
251
252         authentication_username = NULL;
253
254         authentication_callback_called = FALSE;
255         result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ);
256         g_assert (result == GNOME_VFS_ERROR_ACCESS_DENIED);
257         handle = NULL;
258         g_assert (authentication_callback_called == TRUE);
259
260
261         /* Test 9: exercise the "destroy notify" functionality */
262         /* Note that job doesn't end until a "close" is called, so the inherited
263          * callback isn't released until then
264          */
265
266         flush_credentials_func();
267         authentication_username = "foo";
268
269         gnome_vfs_module_callback_push (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
270                                         authentication_callback, 
271                                         NULL,
272                                         destroy_notify);
273
274         authentication_callback_called = FALSE;
275         
276         open_callback_occurred = FALSE;
277         open_callback_result_expected = GNOME_VFS_OK;
278
279         destroy_notify_occurred = FALSE;
280
281         gnome_vfs_async_open (
282                 &async_handle, 
283                 authentication_uri,
284                 GNOME_VFS_OPEN_READ,
285                 0,
286                 open_callback,
287                 NULL);
288
289         gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION);
290
291         g_assert (!destroy_notify_occurred);
292
293         while (!open_callback_occurred) {
294                 g_main_context_iteration (NULL, TRUE);
295         }
296
297         close_callback_occurred = FALSE;
298         gnome_vfs_async_close (async_handle, close_callback, NULL);
299
300         while (!close_callback_occurred) {
301                 g_main_context_iteration (NULL, TRUE);
302         }
303
304         for (i = 0 ; i<100 ; i++) {
305                 g_main_context_iteration (NULL, FALSE);
306                 usleep (10);
307         }
308
309         g_assert (authentication_callback_called);
310         g_assert (destroy_notify_occurred);
311
312         gnome_vfs_shutdown ();
313
314         return 0;
315 }