1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 #include "test-utils.h"
5 static const char *base_uri;
6 static GMainLoop *loop;
9 /* Explanation of what you should see */
10 const char *explanation;
12 /* URL to test against */
15 /* Provided passwords, 1 character each. ('1', '2', and '3'
16 * mean the correct passwords for "realm1", "realm2", and
17 * "realm3" respectively. '4' means "use the wrong password".)
18 * The first password (if present) will be used by
19 * authenticate(), and the second (if present) will be used by
24 /* Whether to pass user and password in the URL or not.
28 /* Expected passwords, 1 character each. (As with the provided
29 * passwords, with the addition that '0' means "no
30 * Authorization header expected".) Used to verify that soup
31 * used the password it was supposed to at each step.
35 /* What the final status code should be. */
39 static SoupAuthTest main_tests[] = {
40 { "No auth available, should fail",
41 "Basic/realm1/", "", FALSE, "0", SOUP_STATUS_UNAUTHORIZED },
43 { "Should fail with no auth, fail again with bad password, and give up",
44 "Basic/realm2/", "4", FALSE, "04", SOUP_STATUS_UNAUTHORIZED },
46 { "Auth provided this time, so should succeed",
47 "Basic/realm1/", "1", FALSE, "01", SOUP_STATUS_OK },
49 { "Now should automatically reuse previous auth",
50 "Basic/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
52 { "Subdir should also automatically reuse auth",
53 "Basic/realm1/subdir/", "", FALSE, "1", SOUP_STATUS_OK },
55 { "Subdir should retry last auth, but will fail this time",
56 "Basic/realm1/realm2/", "", FALSE, "1", SOUP_STATUS_UNAUTHORIZED },
58 { "Now should use provided auth",
59 "Basic/realm1/realm2/", "2", FALSE, "02", SOUP_STATUS_OK },
61 { "Reusing last auth. Should succeed on first try",
62 "Basic/realm1/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
64 { "Reuse will fail, but 2nd try will succeed because it's a known realm",
65 "Basic/realm1/realm2/realm1/", "", FALSE, "21", SOUP_STATUS_OK },
67 { "Should succeed on first try. (Known realm with cached password)",
68 "Basic/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
70 { "Fail once, then use typoed password, then use right password",
71 "Basic/realm3/", "43", FALSE, "043", SOUP_STATUS_OK },
74 { "No auth available, should fail",
75 "Digest/realm1/", "", FALSE, "0", SOUP_STATUS_UNAUTHORIZED },
77 { "Should fail with no auth, fail again with bad password, and give up",
78 "Digest/realm2/", "4", FALSE, "04", SOUP_STATUS_UNAUTHORIZED },
80 { "Known realm, auth provided, so should succeed",
81 "Digest/realm1/", "1", FALSE, "01", SOUP_STATUS_OK },
83 { "Now should automatically reuse previous auth",
84 "Digest/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
86 { "Subdir should also automatically reuse auth",
87 "Digest/realm1/subdir/", "", FALSE, "1", SOUP_STATUS_OK },
89 { "Password provided, should succeed",
90 "Digest/realm2/", "2", FALSE, "02", SOUP_STATUS_OK },
92 { "Should already know correct domain and use provided auth on first try",
93 "Digest/realm1/realm2/", "2", FALSE, "2", SOUP_STATUS_OK },
95 { "Reusing last auth. Should succeed on first try",
96 "Digest/realm1/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
98 { "Should succeed on first try because of earlier domain directive",
99 "Digest/realm1/realm2/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
101 { "Fail once, then use typoed password, then use right password",
102 "Digest/realm3/", "43", FALSE, "043", SOUP_STATUS_OK },
105 { "Make sure we haven't forgotten anything",
106 "Basic/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
108 { "Make sure we haven't forgotten anything",
109 "Basic/realm1/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
111 { "Make sure we haven't forgotten anything",
112 "Basic/realm1/realm2/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
114 { "Make sure we haven't forgotten anything",
115 "Basic/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
117 { "Make sure we haven't forgotten anything",
118 "Basic/realm3/", "", FALSE, "3", SOUP_STATUS_OK },
121 { "Make sure we haven't forgotten anything",
122 "Digest/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
124 { "Make sure we haven't forgotten anything",
125 "Digest/realm1/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
127 { "Make sure we haven't forgotten anything",
128 "Digest/realm1/realm2/realm1/", "", FALSE, "1", SOUP_STATUS_OK },
130 { "Make sure we haven't forgotten anything",
131 "Digest/realm2/", "", FALSE, "2", SOUP_STATUS_OK },
133 { "Make sure we haven't forgotten anything",
134 "Digest/realm3/", "", FALSE, "3", SOUP_STATUS_OK },
136 { "Now the server will reject the formerly-good password",
137 "Basic/realm1/not/", "1", FALSE, /* should not be used */ "1", SOUP_STATUS_UNAUTHORIZED },
139 { "Make sure we've forgotten it",
140 "Basic/realm1/", "", FALSE, "0", SOUP_STATUS_UNAUTHORIZED },
142 { "Likewise, reject the formerly-good Digest password",
143 "Digest/realm1/not/", "1", FALSE, /* should not be used */ "1", SOUP_STATUS_UNAUTHORIZED },
145 { "Make sure we've forgotten it",
146 "Digest/realm1/", "", FALSE, "0", SOUP_STATUS_UNAUTHORIZED },
148 { "Fail with URI-embedded password, then use right password in the authenticate signal",
149 "Basic/realm3/", "43", TRUE, "43", SOUP_STATUS_OK },
154 static const char *auths[] = {
155 "no password", "password 1",
156 "password 2", "password 3",
157 "intentionally wrong password",
161 identify_auth (SoupMessage *msg)
166 header = soup_message_headers_get_one (msg->request_headers,
171 if (!g_ascii_strncasecmp (header, "Basic ", 6)) {
175 token = (char *)g_base64_decode (header + 6, &len);
176 num = token[len - 1] - '0';
181 user = strstr (header, "username=\"user");
183 num = user[14] - '0';
188 g_assert (num >= 0 && num <= 4);
194 handler (SoupMessage *msg, gpointer data)
196 char *expected = data;
199 auth = identify_auth (msg);
201 debug_printf (1, " %d %s (using %s)\n",
202 msg->status_code, msg->reason_phrase,
206 exp = *expected - '0';
207 soup_test_assert (auth == exp,
208 "expected %s", auths[exp]);
209 memmove (expected, expected + 1, strlen (expected));
211 soup_test_assert (*expected,
212 "expected to be finished");
217 authenticate (SoupSession *session, SoupMessage *msg,
218 SoupAuth *auth, gboolean retrying, gpointer data)
220 SoupAuthTest *test = data;
221 char *username, *password;
224 if (!test->provided[0])
227 if (!test->provided[1])
229 num = test->provided[1];
231 num = test->provided[0];
233 username = g_strdup_printf ("user%c", num);
234 password = g_strdup_printf ("realm%c", num);
235 soup_auth_authenticate (auth, username, password);
241 bug271540_sent (SoupMessage *msg, gpointer data)
243 int n = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (msg), "#"));
244 gboolean *authenticated = data;
245 int auth = identify_auth (msg);
247 soup_test_assert (*authenticated || !auth,
248 "using auth on message %d before authenticating", n);
249 soup_test_assert (!*authenticated || auth,
250 "sent unauthenticated message %d after authenticating", n);
254 bug271540_authenticate (SoupSession *session, SoupMessage *msg,
255 SoupAuth *auth, gboolean retrying, gpointer data)
257 int n = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (msg), "#"));
258 gboolean *authenticated = data;
260 if (strcmp (soup_auth_get_scheme_name (auth), "Basic") != 0 ||
261 strcmp (soup_auth_get_realm (auth), "realm1") != 0)
264 if (!*authenticated) {
265 debug_printf (1, " authenticating message %d\n", n);
266 soup_auth_authenticate (auth, "user1", "realm1");
267 *authenticated = TRUE;
269 soup_test_assert (!*authenticated,
270 "asked to authenticate message %d after authenticating", n);
275 bug271540_finished (SoupSession *session, SoupMessage *msg, gpointer data)
279 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
283 g_main_loop_quit (loop);
287 do_pipelined_auth_test (void)
289 SoupSession *session;
291 gboolean authenticated;
295 g_test_bug ("271540");
297 SOUP_TEST_SKIP_IF_NO_APACHE;
299 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
301 authenticated = FALSE;
302 g_signal_connect (session, "authenticate",
303 G_CALLBACK (bug271540_authenticate), &authenticated);
305 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
306 for (i = 0; i < 10; i++) {
307 msg = soup_message_new (SOUP_METHOD_GET, uri);
308 g_object_set_data (G_OBJECT (msg), "#", GINT_TO_POINTER (i + 1));
309 g_signal_connect (msg, "wrote_headers",
310 G_CALLBACK (bug271540_sent), &authenticated);
312 soup_session_queue_message (session, msg,
313 bug271540_finished, &i);
317 loop = g_main_loop_new (NULL, TRUE);
318 g_main_loop_run (loop);
319 g_main_loop_unref (loop);
321 soup_test_session_abort_unref (session);
324 /* We test two different things here:
326 * 1. If we get a 401 response with "WWW-Authenticate: Digest
327 * stale=true...", we should retry and succeed *without* the
328 * session asking for a password again.
330 * 2. If we get a successful response with "Authentication-Info:
331 * nextnonce=...", we should update the nonce automatically so as
332 * to avoid getting a stale nonce error on the next request.
334 * In our Apache config, /Digest/realm1 and /Digest/realm1/expire are
335 * set up to use the same auth info, but only the latter has an
336 * AuthDigestNonceLifetime (of 2 seconds). The way nonces work in
337 * Apache, a nonce received from /Digest/realm1 will still expire in
338 * /Digest/realm1/expire, but it won't issue a nextnonce for a request
339 * in /Digest/realm1. This lets us test both behaviors.
341 * The expected conversation is:
347 * WWW-Authenticate: Digest nonce=A
349 * [emit 'authenticate']
352 * Authorization: Digest nonce=A
355 * [No Authentication-Info]
357 * [sleep 2 seconds: nonce A is no longer valid, but we have no
358 * way of knowing that]
361 * GET /Digest/realm1/expire/
362 * Authorization: Digest nonce=A
365 * WWW-Authenticate: Digest stale=true nonce=B
367 * GET /Digest/realm1/expire/
368 * Authorization: Digest nonce=B
371 * Authentication-Info: nextnonce=C
376 * GET /Digest/realm1/expire/
377 * Authorization: Digest nonce=C
378 * [nonce=B would work here too]
381 * Authentication-Info: nextnonce=D
383 * [sleep 1 second; nonces B and C are no longer valid, but D is]
386 * GET /Digest/realm1/expire/
387 * Authorization: Digest nonce=D
390 * Authentication-Info: nextnonce=D
395 digest_nonce_authenticate (SoupSession *session, SoupMessage *msg,
396 SoupAuth *auth, gboolean retrying, gpointer data)
401 if (strcmp (soup_auth_get_scheme_name (auth), "Digest") != 0 ||
402 strcmp (soup_auth_get_realm (auth), "realm1") != 0)
405 soup_auth_authenticate (auth, "user1", "realm1");
409 digest_nonce_unauthorized (SoupMessage *msg, gpointer data)
411 gboolean *got_401 = data;
416 do_digest_nonce_test (SoupSession *session,
417 const char *nth, const char *uri, gboolean use_auth_cache,
418 gboolean expect_401, gboolean expect_signal)
423 msg = soup_message_new (SOUP_METHOD_GET, uri);
424 if (!use_auth_cache) {
425 SoupMessageFlags flags = soup_message_get_flags (msg);
427 soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
430 g_signal_connect (session, "authenticate",
431 G_CALLBACK (digest_nonce_authenticate),
434 soup_message_add_status_code_handler (msg, "got_headers",
435 SOUP_STATUS_UNAUTHORIZED,
436 G_CALLBACK (digest_nonce_unauthorized),
439 soup_session_send_message (session, msg);
440 soup_test_assert (got_401 == expect_401,
441 "%s request %s a 401 Unauthorized!\n", nth,
442 got_401 ? "got" : "did not get");
443 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
446 g_signal_handlers_disconnect_by_func (session,
447 G_CALLBACK (digest_nonce_authenticate),
451 g_object_unref (msg);
455 do_digest_expiration_test (void)
457 SoupSession *session;
460 SOUP_TEST_SKIP_IF_NO_APACHE;
462 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
464 uri = g_strconcat (base_uri, "Digest/realm1/", NULL);
465 do_digest_nonce_test (session, "First", uri, TRUE, TRUE, TRUE);
467 g_usleep (2 * G_USEC_PER_SEC);
468 uri = g_strconcat (base_uri, "Digest/realm1/expire/", NULL);
469 do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, FALSE);
470 g_usleep (1 * G_USEC_PER_SEC);
471 do_digest_nonce_test (session, "Third", uri, TRUE, FALSE, FALSE);
472 g_usleep (1 * G_USEC_PER_SEC);
473 do_digest_nonce_test (session, "Fourth", uri, TRUE, FALSE, FALSE);
476 soup_test_session_abort_unref (session);
479 /* Async auth test. We queue three requests to /Basic/realm1, ensuring
480 * that they are sent in order. The first and third ones will be
481 * paused from the authentication callback. The second will be allowed
482 * to fail. Shortly after the third one requests auth, we'll provide
483 * the auth and unpause the two remaining messages, allowing them to
488 async_authenticate (SoupSession *session, SoupMessage *msg,
489 SoupAuth *auth, gboolean retrying, gpointer data)
491 SoupAuth **saved_auth = data;
492 int id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (msg), "id"));
494 debug_printf (2, " async_authenticate msg%d\n", id);
496 /* The session will try to authenticate msg3 *before* sending
497 * it, because it already knows it's going to need the auth.
500 if (msg->status_code != SOUP_STATUS_UNAUTHORIZED) {
501 debug_printf (2, " (ignoring)\n");
505 soup_session_pause_message (session, msg);
507 *saved_auth = g_object_ref (auth);
508 g_main_loop_quit (loop);
512 async_finished (SoupSession *session, SoupMessage *msg, gpointer user_data)
514 int *remaining = user_data;
515 int id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (msg), "id"));
517 debug_printf (2, " async_finished msg%d\n", id);
521 g_main_loop_quit (loop);
525 async_authenticate_assert_once (SoupSession *session, SoupMessage *msg,
526 SoupAuth *auth, gboolean retrying, gpointer data)
528 gboolean *been_here = data;
530 debug_printf (2, " async_authenticate_assert_once\n");
532 soup_test_assert (!*been_here,
533 "async_authenticate_assert_once called twice");
538 async_authenticate_assert_once_and_stop (SoupSession *session, SoupMessage *msg,
539 SoupAuth *auth, gboolean retrying, gpointer data)
541 gboolean *been_here = data;
543 debug_printf (2, " async_authenticate_assert_once_and_stop\n");
545 soup_test_assert (!*been_here,
546 "async_authenticate_assert_once called twice");
549 soup_session_pause_message (session, msg);
550 g_main_loop_quit (loop);
554 do_async_auth_good_password_test (void)
556 SoupSession *session;
557 SoupMessage *msg1, *msg2, *msg3, msg2_bak;
560 SoupAuth *auth = NULL;
563 SOUP_TEST_SKIP_IF_NO_APACHE;
565 loop = g_main_loop_new (NULL, TRUE);
566 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
567 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
570 msg1 = soup_message_new ("GET", uri);
571 g_object_set_data (G_OBJECT (msg1), "id", GINT_TO_POINTER (1));
572 auth_id = g_signal_connect (session, "authenticate",
573 G_CALLBACK (async_authenticate), &auth);
576 soup_session_queue_message (session, msg1, async_finished, &remaining);
577 g_main_loop_run (loop);
578 g_signal_handler_disconnect (session, auth_id);
580 /* async_authenticate will pause msg1 and quit loop */
582 msg2 = soup_message_new ("GET", uri);
583 g_object_set_data (G_OBJECT (msg2), "id", GINT_TO_POINTER (2));
584 soup_session_send_message (session, msg2);
586 soup_test_assert_message_status (msg2, SOUP_STATUS_UNAUTHORIZED);
588 /* msg2 should be done at this point; assuming everything is
589 * working correctly, the session won't look at it again; we
590 * ensure that if it does, it will crash the test program.
592 memcpy (&msg2_bak, msg2, sizeof (SoupMessage));
593 memset (msg2, 0, sizeof (SoupMessage));
595 msg3 = soup_message_new ("GET", uri);
596 g_object_set_data (G_OBJECT (msg3), "id", GINT_TO_POINTER (3));
597 auth_id = g_signal_connect (session, "authenticate",
598 G_CALLBACK (async_authenticate), NULL);
601 soup_session_queue_message (session, msg3, async_finished, &remaining);
602 g_main_loop_run (loop);
603 g_signal_handler_disconnect (session, auth_id);
605 /* async_authenticate will pause msg3 and quit loop */
607 /* Now do the auth, and restart */
609 soup_auth_authenticate (auth, "user1", "realm1");
610 g_object_unref (auth);
611 soup_session_unpause_message (session, msg1);
612 soup_session_unpause_message (session, msg3);
614 g_main_loop_run (loop);
616 /* async_finished will quit the loop */
618 soup_test_assert (auth, "msg1 didn't get authenticate signal");
620 soup_test_assert_message_status (msg1, SOUP_STATUS_OK);
621 soup_test_assert_message_status (msg3, SOUP_STATUS_OK);
623 soup_test_session_abort_unref (session);
625 g_object_unref (msg1);
626 g_object_unref (msg3);
627 memcpy (msg2, &msg2_bak, sizeof (SoupMessage));
628 g_object_unref (msg2);
631 g_main_loop_unref (loop);
635 do_async_auth_bad_password_test (void)
637 SoupSession *session;
641 SoupAuth *auth = NULL;
645 /* Test that giving the wrong password doesn't cause multiple
646 * authenticate signals the second time.
648 g_test_bug ("522601");
650 SOUP_TEST_SKIP_IF_NO_APACHE;
652 loop = g_main_loop_new (NULL, TRUE);
653 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
654 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
658 msg = soup_message_new ("GET", uri);
659 g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (1));
660 auth_id = g_signal_connect (session, "authenticate",
661 G_CALLBACK (async_authenticate), &auth);
664 soup_session_queue_message (session, msg, async_finished, &remaining);
665 g_main_loop_run (loop);
666 g_signal_handler_disconnect (session, auth_id);
667 soup_auth_authenticate (auth, "user1", "wrong");
668 g_object_unref (auth);
669 soup_session_unpause_message (session, msg);
672 auth_id = g_signal_connect (session, "authenticate",
673 G_CALLBACK (async_authenticate_assert_once),
675 g_main_loop_run (loop);
676 g_signal_handler_disconnect (session, auth_id);
678 soup_test_assert (been_there,
679 "authenticate not emitted");
681 soup_test_session_abort_unref (session);
682 g_object_unref (msg);
685 g_main_loop_unref (loop);
689 do_async_auth_no_password_test (void)
691 SoupSession *session;
698 /* Test that giving no password doesn't cause multiple
699 * authenticate signals the second time.
701 g_test_bug ("583462");
703 SOUP_TEST_SKIP_IF_NO_APACHE;
705 loop = g_main_loop_new (NULL, TRUE);
706 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
707 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
710 /* Send a message that doesn't actually authenticate
712 msg = soup_message_new ("GET", uri);
713 g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (1));
714 auth_id = g_signal_connect (session, "authenticate",
715 G_CALLBACK (async_authenticate), NULL);
718 soup_session_queue_message (session, msg, async_finished, &remaining);
719 g_main_loop_run (loop);
720 g_signal_handler_disconnect (session, auth_id);
721 soup_session_unpause_message (session, msg);
722 g_main_loop_run (loop);
725 /* Now send a second message */
726 msg = soup_message_new ("GET", uri);
727 g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (2));
730 auth_id = g_signal_connect (session, "authenticate",
731 G_CALLBACK (async_authenticate_assert_once_and_stop),
734 soup_session_queue_message (session, msg, async_finished, &remaining);
735 g_main_loop_run (loop);
736 soup_session_unpause_message (session, msg);
738 g_main_loop_run (loop);
739 g_signal_handler_disconnect (session, auth_id);
741 soup_test_session_abort_unref (session);
742 g_object_unref (msg);
745 g_main_loop_unref (loop);
749 const char *password;
752 const char *response;
757 select_auth_authenticate (SoupSession *session, SoupMessage *msg,
758 SoupAuth *auth, gboolean retrying, gpointer data)
760 SelectAuthData *sad = data;
761 const char *header, *basic, *digest;
762 int round = retrying ? 1 : 0;
764 header = soup_message_headers_get_list (msg->response_headers,
766 basic = strstr (header, "Basic");
767 digest = strstr (header, "Digest");
768 if (basic && digest) {
770 sad->round[round].headers = "Basic, Digest";
772 sad->round[round].headers = "Digest, Basic";
774 sad->round[round].headers = "Basic";
776 sad->round[round].headers = "Digest";
778 sad->round[round].response = soup_auth_get_scheme_name (auth);
779 if (sad->password && !retrying)
780 soup_auth_authenticate (auth, "user", sad->password);
784 select_auth_test_one (SoupURI *uri,
785 gboolean disable_digest, const char *password,
786 const char *first_headers, const char *first_response,
787 const char *second_headers, const char *second_response,
792 SoupSession *session;
794 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
796 soup_session_remove_feature_by_type (session, SOUP_TYPE_AUTH_DIGEST);
798 g_signal_connect (session, "authenticate",
799 G_CALLBACK (select_auth_authenticate), &sad);
800 memset (&sad, 0, sizeof (sad));
801 sad.password = password;
803 msg = soup_message_new_from_uri ("GET", uri);
804 soup_session_send_message (session, msg);
806 soup_test_assert (strcmp (sad.round[0].headers, first_headers) == 0,
807 "Header order wrong: expected %s, got %s",
808 first_headers, sad.round[0].headers);
809 soup_test_assert (strcmp (sad.round[0].response, first_response) == 0,
810 "Selected auth type wrong: expected %s, got %s",
811 first_response, sad.round[0].response);
813 soup_test_assert (sad.round[1].headers || !second_headers,
814 "Expected a second round");
815 soup_test_assert (!sad.round[1].headers || second_headers,
816 "Didn't expect a second round");
817 if (second_headers && second_response) {
818 soup_test_assert (strcmp (sad.round[1].headers, second_headers) == 0,
819 "Second round header order wrong: expected %s, got %s\n",
820 second_headers, sad.round[1].headers);
821 soup_test_assert (strcmp (sad.round[1].response, second_response) == 0,
822 "Second round selected auth type wrong: expected %s, got %s\n",
823 second_response, sad.round[1].response);
826 soup_test_assert_message_status (msg, final_status);
828 g_object_unref (msg);
829 soup_test_session_abort_unref (session);
833 server_callback (SoupServer *server, SoupMessage *msg,
834 const char *path, GHashTable *query,
835 SoupClientContext *context, gpointer data)
837 soup_message_set_response (msg, "text/plain",
840 soup_message_set_status (msg, SOUP_STATUS_OK);
844 server_basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
845 const char *username, const char *password, gpointer data)
847 if (strcmp (username, "user") != 0)
849 return strcmp (password, "good-basic") == 0;
853 server_digest_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
854 const char *username, gpointer data)
856 if (strcmp (username, "user") != 0)
858 return soup_auth_domain_digest_encode_password ("user",
864 do_select_auth_test (void)
867 SoupAuthDomain *basic_auth_domain, *digest_auth_domain;
870 g_test_bug ("562339");
872 /* It doesn't seem to be possible to configure Apache to serve
873 * multiple auth types for a single URL. So we have to use
874 * SoupServer here. We know that SoupServer handles the server
875 * side of this scenario correctly, because we test it against
876 * curl in server-auth-test.
878 server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
879 soup_server_add_handler (server, NULL,
880 server_callback, NULL, NULL);
881 uri = soup_test_server_get_uri (server, "http", NULL);
883 basic_auth_domain = soup_auth_domain_basic_new (
884 SOUP_AUTH_DOMAIN_REALM, "auth-test",
885 SOUP_AUTH_DOMAIN_ADD_PATH, "/",
886 SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, server_basic_auth_callback,
888 soup_server_add_auth_domain (server, basic_auth_domain);
890 digest_auth_domain = soup_auth_domain_digest_new (
891 SOUP_AUTH_DOMAIN_REALM, "auth-test",
892 SOUP_AUTH_DOMAIN_ADD_PATH, "/",
893 SOUP_AUTH_DOMAIN_DIGEST_AUTH_CALLBACK, server_digest_auth_callback,
895 soup_server_add_auth_domain (server, digest_auth_domain);
897 debug_printf (1, " Testing with no auth\n");
898 select_auth_test_one (uri, FALSE, NULL,
899 "Basic, Digest", "Digest",
901 SOUP_STATUS_UNAUTHORIZED);
903 debug_printf (1, " Testing with bad password\n");
904 select_auth_test_one (uri, FALSE, "bad",
905 "Basic, Digest", "Digest",
906 "Basic, Digest", "Digest",
907 SOUP_STATUS_UNAUTHORIZED);
909 debug_printf (1, " Testing with good password\n");
910 select_auth_test_one (uri, FALSE, "good",
911 "Basic, Digest", "Digest",
915 /* Test with Digest disabled in the client. */
916 debug_printf (1, " Testing without Digest with no auth\n");
917 select_auth_test_one (uri, TRUE, NULL,
918 "Basic, Digest", "Basic",
920 SOUP_STATUS_UNAUTHORIZED);
922 debug_printf (1, " Testing without Digest with bad password\n");
923 select_auth_test_one (uri, TRUE, "bad",
924 "Basic, Digest", "Basic",
925 "Basic, Digest", "Basic",
926 SOUP_STATUS_UNAUTHORIZED);
928 debug_printf (1, " Testing without Digest with good password\n");
929 select_auth_test_one (uri, TRUE, "good-basic",
930 "Basic, Digest", "Basic",
934 /* Now flip the order of the domains, verify that this flips
935 * the order of the headers, and make sure that digest auth
939 soup_server_remove_auth_domain (server, basic_auth_domain);
940 soup_server_remove_auth_domain (server, digest_auth_domain);
941 soup_server_add_auth_domain (server, digest_auth_domain);
942 soup_server_add_auth_domain (server, basic_auth_domain);
944 debug_printf (1, " Testing flipped with no auth\n");
945 select_auth_test_one (uri, FALSE, NULL,
946 "Digest, Basic", "Digest",
948 SOUP_STATUS_UNAUTHORIZED);
950 debug_printf (1, " Testing flipped with bad password\n");
951 select_auth_test_one (uri, FALSE, "bad",
952 "Digest, Basic", "Digest",
953 "Digest, Basic", "Digest",
954 SOUP_STATUS_UNAUTHORIZED);
956 debug_printf (1, " Testing flipped with good password\n");
957 select_auth_test_one (uri, FALSE, "good",
958 "Digest, Basic", "Digest",
962 g_object_unref (basic_auth_domain);
963 g_object_unref (digest_auth_domain);
965 soup_test_server_quit_unref (server);
969 sneakily_close_connection (SoupMessage *msg, gpointer user_data)
971 /* Sneakily close the connection after the response, by
972 * tricking soup-message-io into thinking that had been
973 * the plan all along.
975 soup_message_headers_append (msg->response_headers,
976 "Connection", "close");
980 auth_close_request_started (SoupServer *server, SoupMessage *msg,
981 SoupClientContext *client, gpointer user_data)
983 g_signal_connect (msg, "wrote-headers",
984 G_CALLBACK (sneakily_close_connection), NULL);
988 SoupSession *session;
994 auth_close_idle_authenticate (gpointer user_data)
996 AuthCloseData *acd = user_data;
998 soup_auth_authenticate (acd->auth, "user", "good-basic");
999 soup_session_unpause_message (acd->session, acd->msg);
1001 g_object_unref (acd->auth);
1006 auth_close_authenticate (SoupSession *session, SoupMessage *msg,
1007 SoupAuth *auth, gboolean retrying, gpointer data)
1009 AuthCloseData *acd = data;
1011 soup_session_pause_message (session, msg);
1012 acd->auth = g_object_ref (auth);
1013 g_idle_add (auth_close_idle_authenticate, acd);
1017 do_auth_close_test (void)
1020 SoupAuthDomain *basic_auth_domain;
1024 server = soup_test_server_new (SOUP_TEST_SERVER_DEFAULT);
1025 soup_server_add_handler (server, NULL,
1026 server_callback, NULL, NULL);
1028 uri = soup_test_server_get_uri (server, "http", NULL);
1029 soup_uri_set_path (uri, "/close");
1031 basic_auth_domain = soup_auth_domain_basic_new (
1032 SOUP_AUTH_DOMAIN_REALM, "auth-test",
1033 SOUP_AUTH_DOMAIN_ADD_PATH, "/",
1034 SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, server_basic_auth_callback,
1036 soup_server_add_auth_domain (server, basic_auth_domain);
1037 g_object_unref (basic_auth_domain);
1039 g_signal_connect (server, "request-started",
1040 G_CALLBACK (auth_close_request_started), NULL);
1042 acd.session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
1043 g_signal_connect (acd.session, "authenticate",
1044 G_CALLBACK (auth_close_authenticate), &acd);
1046 acd.msg = soup_message_new_from_uri ("GET", uri);
1047 soup_uri_free (uri);
1048 soup_session_send_message (acd.session, acd.msg);
1050 soup_test_assert_message_status (acd.msg, SOUP_STATUS_OK);
1052 g_object_unref (acd.msg);
1053 soup_test_session_abort_unref (acd.session);
1054 soup_test_server_quit_unref (server);
1058 infinite_cancel (gpointer session)
1060 soup_session_abort (session);
1065 infinite_authenticate (SoupSession *session, SoupMessage *msg,
1066 SoupAuth *auth, gboolean retrying, gpointer data)
1068 soup_auth_authenticate (auth, "user", "bad");
1072 do_infinite_auth_test (void)
1074 SoupSession *session;
1079 SOUP_TEST_SKIP_IF_NO_APACHE;
1081 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
1082 g_signal_connect (session, "authenticate",
1083 G_CALLBACK (infinite_authenticate), NULL);
1085 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
1086 msg = soup_message_new ("GET", uri);
1089 timeout = g_timeout_add (500, infinite_cancel, session);
1090 g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING,
1091 "*stuck in infinite loop*");
1092 soup_session_send_message (session, msg);
1093 g_test_assert_expected_messages ();
1095 soup_test_assert (msg->status_code != SOUP_STATUS_CANCELLED,
1096 "Got stuck in loop");
1097 soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
1099 g_source_remove (timeout);
1100 soup_test_session_abort_unref (session);
1101 g_object_unref (msg);
1105 disappear_request_read (SoupServer *server, SoupMessage *msg,
1106 SoupClientContext *context, gpointer user_data)
1108 /* Remove the WWW-Authenticate header if this was a failed attempt */
1109 if (soup_message_headers_get_one (msg->request_headers, "Authorization") &&
1110 msg->status_code == SOUP_STATUS_UNAUTHORIZED)
1111 soup_message_headers_remove (msg->response_headers, "WWW-Authenticate");
1115 disappear_authenticate (SoupSession *session, SoupMessage *msg,
1116 SoupAuth *auth, gboolean retrying, gpointer data)
1118 int *counter = data;
1122 soup_auth_authenticate (auth, "user", "bad");
1126 do_disappearing_auth_test (void)
1129 SoupAuthDomain *auth_domain;
1132 SoupSession *session;
1135 g_test_bug_base ("https://bugzilla.redhat.com/");
1136 g_test_bug ("916224");
1138 server = soup_test_server_new (FALSE);
1139 soup_server_add_handler (server, NULL,
1140 server_callback, NULL, NULL);
1141 uri = soup_test_server_get_uri (server, "http", NULL);
1143 auth_domain = soup_auth_domain_basic_new (
1144 SOUP_AUTH_DOMAIN_REALM, "auth-test",
1145 SOUP_AUTH_DOMAIN_ADD_PATH, "/",
1146 SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, server_basic_auth_callback,
1148 soup_server_add_auth_domain (server, auth_domain);
1149 g_signal_connect (server, "request-read",
1150 G_CALLBACK (disappear_request_read), NULL);
1152 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
1155 g_signal_connect (session, "authenticate",
1156 G_CALLBACK (disappear_authenticate), &counter);
1158 msg = soup_message_new_from_uri ("GET", uri);
1159 soup_session_send_message (session, msg);
1161 soup_test_assert (counter <= 2,
1162 "Got stuck in loop");
1163 soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
1165 g_object_unref (msg);
1166 soup_test_session_abort_unref (session);
1168 g_object_unref (auth_domain);
1169 soup_uri_free (uri);
1170 soup_test_server_quit_unref (server);
1173 static SoupAuthTest relogin_tests[] = {
1174 { "Auth provided via URL, should succeed",
1175 "Basic/realm12/", "1", TRUE, "01", SOUP_STATUS_OK },
1177 { "Now should automatically reuse previous auth",
1178 "Basic/realm12/", "", FALSE, "1", SOUP_STATUS_OK },
1180 { "Different auth provided via URL for the same realm, should succeed",
1181 "Basic/realm12/", "2", TRUE, "2", SOUP_STATUS_OK },
1183 { "Subdir should also automatically reuse auth",
1184 "Basic/realm12/subdir/", "", FALSE, "2", SOUP_STATUS_OK },
1186 { "Should fail with no auth",
1187 "Basic/realm12/", "4", TRUE, "4", SOUP_STATUS_UNAUTHORIZED },
1189 { "Make sure we've forgotten it",
1190 "Basic/realm12/", "", FALSE, "0", SOUP_STATUS_UNAUTHORIZED },
1192 { "Should fail with no auth, fail again with bad password, and give up",
1193 "Basic/realm12/", "3", FALSE, "03", SOUP_STATUS_UNAUTHORIZED },
1198 /* https://bugzilla.gnome.org/show_bug.cgi?id=755617 */
1199 static SoupAuthTest basic_root_pspace_test[] = {
1200 { "Auth provided via URL, should succeed",
1201 "BasicRoot", "1", TRUE, "01", SOUP_STATUS_OK },
1203 { "Parent dir should automatically reuse auth",
1204 "/", "1", FALSE, "1", SOUP_STATUS_OK },
1210 do_batch_tests (gconstpointer data)
1212 const SoupAuthTest *current_tests = data;
1213 SoupSession *session;
1215 char *expected, *uristr;
1220 SOUP_TEST_SKIP_IF_NO_APACHE;
1222 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
1223 base = soup_uri_new (base_uri);
1225 for (i = 0; current_tests[i].url; i++) {
1226 SoupURI *soup_uri = soup_uri_new_with_base (base, current_tests[i].url);
1228 debug_printf (1, "Test %d: %s\n", i + 1, current_tests[i].explanation);
1230 if (current_tests[i].url_auth) {
1231 gchar *username = g_strdup_printf ("user%c", current_tests[i].provided[0]);
1232 gchar *password = g_strdup_printf ("realm%c", current_tests[i].provided[0]);
1233 soup_uri_set_user (soup_uri, username);
1234 soup_uri_set_password (soup_uri, password);
1239 msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
1240 soup_uri_free (soup_uri);
1242 g_printerr ("auth-test: Could not parse URI\n");
1246 uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
1247 debug_printf (1, " GET %s\n", uristr);
1250 expected = g_strdup (current_tests[i].expected);
1251 soup_message_add_status_code_handler (
1252 msg, "got_headers", SOUP_STATUS_UNAUTHORIZED,
1253 G_CALLBACK (handler), expected);
1254 soup_message_add_status_code_handler (
1255 msg, "got_headers", SOUP_STATUS_OK,
1256 G_CALLBACK (handler), expected);
1258 signal = g_signal_connect (session, "authenticate",
1259 G_CALLBACK (authenticate),
1260 (gpointer)¤t_tests[i]);
1261 soup_session_send_message (session, msg);
1262 g_signal_handler_disconnect (session, signal);
1264 soup_test_assert_message_status (msg, current_tests[i].final_status);
1265 soup_test_assert (!*expected,
1266 "expected %d more round(s)\n",
1267 (int)strlen (expected));
1270 debug_printf (1, "\n");
1272 g_object_unref (msg);
1274 soup_uri_free (base);
1276 soup_test_session_abort_unref (session);
1280 do_clear_credentials_test (void)
1282 SoupSession *session;
1283 SoupAuthManager *manager;
1286 SOUP_TEST_SKIP_IF_NO_APACHE;
1288 session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
1290 uri = g_strconcat (base_uri, "Digest/realm1/", NULL);
1291 do_digest_nonce_test (session, "First", uri, TRUE, TRUE, TRUE);
1293 manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
1294 soup_auth_manager_clear_cached_credentials (manager);
1296 do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, TRUE);
1299 soup_test_session_abort_unref (session);
1303 do_message_do_not_use_auth_cache_test (void)
1305 SoupSession *session;
1306 SoupAuthManager *manager;
1308 SoupMessageFlags flags;
1312 SOUP_TEST_SKIP_IF_NO_APACHE;
1314 session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
1316 uri = g_strconcat (base_uri, "Digest/realm1/", NULL);
1318 /* First check that cached credentials are not used */
1319 do_digest_nonce_test (session, "First", uri, TRUE, TRUE, TRUE);
1320 do_digest_nonce_test (session, "Second", uri, TRUE, FALSE, FALSE);
1321 do_digest_nonce_test (session, "Third", uri, FALSE, TRUE, TRUE);
1323 /* Passing credentials in the URI should always authenticate
1324 * no matter whether the cache is used or not
1326 soup_uri = soup_uri_new (uri);
1327 soup_uri_set_user (soup_uri, "user1");
1328 soup_uri_set_password (soup_uri, "realm1");
1329 msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
1330 flags = soup_message_get_flags (msg);
1331 soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
1332 soup_session_send_message (session, msg);
1333 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
1334 g_object_unref (msg);
1335 soup_uri_free (soup_uri);
1337 manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
1339 soup_auth_manager_clear_cached_credentials (manager);
1341 /* Now check that credentials are not stored */
1342 do_digest_nonce_test (session, "First", uri, FALSE, TRUE, TRUE);
1343 do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, TRUE);
1344 do_digest_nonce_test (session, "Third", uri, TRUE, FALSE, FALSE);
1346 /* Credentials were stored for uri, but if we set SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE flag,
1347 * and we don't have the authenticate signal, it should respond with 401
1349 msg = soup_message_new (SOUP_METHOD_GET, uri);
1350 flags = soup_message_get_flags (msg);
1351 soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
1352 soup_session_send_message (session, msg);
1353 soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
1354 g_object_unref (msg);
1357 soup_test_session_abort_unref (session);
1361 async_no_auth_cache_authenticate (SoupSession *session, SoupMessage *msg,
1362 SoupAuth *auth, gboolean retrying, SoupAuth **auth_out)
1364 debug_printf (1, " async_no_auth_cache_authenticate\n");
1366 soup_session_pause_message (session, msg);
1367 *auth_out = g_object_ref (auth);
1368 g_main_loop_quit (loop);
1372 async_no_auth_cache_finished (SoupSession *session, SoupMessage *msg, gpointer user_data)
1374 debug_printf (1, " async_no_auth_cache_finished\n");
1376 g_main_loop_quit (loop);
1380 do_async_message_do_not_use_auth_cache_test (void)
1382 SoupSession *session;
1385 SoupAuth *auth = NULL;
1386 SoupMessageFlags flags;
1388 SOUP_TEST_SKIP_IF_NO_APACHE;
1390 loop = g_main_loop_new (NULL, TRUE);
1391 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
1392 uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
1394 msg = soup_message_new ("GET", uri);
1396 g_signal_connect (session, "authenticate",
1397 G_CALLBACK (async_no_auth_cache_authenticate), &auth);
1398 flags = soup_message_get_flags (msg);
1399 soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
1401 soup_session_queue_message (session, msg, async_no_auth_cache_finished, NULL);
1402 g_main_loop_run (loop);
1404 soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
1406 soup_test_assert (auth, "msg didn't get authenticate signal");
1407 soup_auth_authenticate (auth, "user1", "realm1");
1408 g_object_unref (auth);
1410 soup_session_unpause_message (session, msg);
1411 g_main_loop_run (loop);
1413 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
1415 soup_test_session_abort_unref (session);
1416 g_object_unref (msg);
1417 g_main_loop_unref (loop);
1421 has_authorization_header_authenticate (SoupSession *session, SoupMessage *msg,
1422 SoupAuth *auth, gboolean retrying, gpointer data)
1424 SoupAuth **saved_auth = data;
1426 soup_auth_authenticate (auth, "user1", "realm1");
1427 *saved_auth = g_object_ref (auth);
1431 has_authorization_header_authenticate_assert (SoupSession *session, SoupMessage *msg,
1432 SoupAuth *auth, gboolean retrying, gpointer data)
1434 soup_test_assert (FALSE, "authenticate emitted unexpectedly");
1438 do_message_has_authorization_header_test (void)
1440 SoupSession *session;
1442 SoupAuthManager *manager;
1443 SoupAuth *auth = NULL;
1448 g_test_bug ("775882");
1450 SOUP_TEST_SKIP_IF_NO_APACHE;
1452 session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
1453 uri = g_strconcat (base_uri, "Digest/realm1/", NULL);
1455 msg = soup_message_new ("GET", uri);
1456 auth_id = g_signal_connect (session, "authenticate",
1457 G_CALLBACK (has_authorization_header_authenticate), &auth);
1458 soup_session_send_message (session, msg);
1459 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
1460 soup_test_assert (SOUP_IS_AUTH (auth), "Expected a SoupAuth");
1461 token = soup_auth_get_authorization (auth, msg);
1462 g_object_unref (auth);
1463 g_object_unref (msg);
1464 g_signal_handler_disconnect (session, auth_id);
1466 manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
1467 soup_auth_manager_clear_cached_credentials (manager);
1469 msg = soup_message_new ("GET", uri);
1470 soup_message_headers_replace (msg->request_headers, "Authorization", token);
1471 auth_id = g_signal_connect (session, "authenticate",
1472 G_CALLBACK (has_authorization_header_authenticate_assert),
1474 soup_session_send_message (session, msg);
1475 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
1476 g_object_unref (msg);
1478 /* Check that we can also provide our own Authorization header when not using credentials cache. */
1479 soup_auth_manager_clear_cached_credentials (manager);
1480 msg = soup_message_new ("GET", uri);
1481 soup_message_headers_replace (msg->request_headers, "Authorization", token);
1482 soup_message_set_flags (msg, soup_message_get_flags (msg) | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
1483 soup_session_send_message (session, msg);
1484 soup_test_assert_message_status (msg, SOUP_STATUS_OK);
1485 g_object_unref (msg);
1487 g_signal_handler_disconnect (session, auth_id);
1490 soup_test_session_abort_unref (session);
1494 cancel_after_retry_authenticate (SoupSession *session,
1498 GCancellable *cancellable)
1501 soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED);
1502 g_cancellable_cancel (cancellable);
1504 soup_auth_authenticate (auth, "user1", "wrong");
1508 request_send_cb (SoupSession *session,
1509 GAsyncResult *result,
1512 GInputStream *stream;
1513 GError *error = NULL;
1515 stream = soup_session_send_finish (session, result, &error);
1516 g_assert_null (stream);
1517 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1519 g_main_loop_quit (loop);
1523 do_cancel_after_retry_test (void)
1525 SoupSession *session;
1528 GCancellable *cancellable;
1531 SOUP_TEST_SKIP_IF_NO_APACHE;
1533 session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
1534 cancellable = g_cancellable_new ();
1535 g_signal_connect (session, "authenticate",
1536 G_CALLBACK (cancel_after_retry_authenticate),
1539 loop = g_main_loop_new (NULL, FALSE);
1541 uri = g_strconcat (base_uri, "Digest/realm1/", NULL);
1542 msg = soup_message_new ("GET", uri);
1543 soup_session_send_async (session, msg, cancellable, (GAsyncReadyCallback)request_send_cb, loop);
1544 g_main_loop_run (loop);
1546 g_object_unref (msg);
1547 g_object_unref (cancellable);
1549 soup_test_session_abort_unref (session);
1553 main (int argc, char **argv)
1557 test_init (argc, argv, NULL);
1560 base_uri = "http://127.0.0.1:47524/";
1562 g_test_add_data_func ("/auth/main-tests", main_tests, do_batch_tests);
1563 g_test_add_data_func ("/auth/relogin-tests", relogin_tests, do_batch_tests);
1564 g_test_add_data_func ("/auth/basic-root-pspec-test", basic_root_pspace_test, do_batch_tests);
1565 g_test_add_func ("/auth/pipelined-auth", do_pipelined_auth_test);
1566 g_test_add_func ("/auth/digest-expiration", do_digest_expiration_test);
1567 g_test_add_func ("/auth/async-auth/good-password", do_async_auth_good_password_test);
1568 g_test_add_func ("/auth/async-auth/bad-password", do_async_auth_bad_password_test);
1569 g_test_add_func ("/auth/async-auth/no-password", do_async_auth_no_password_test);
1570 g_test_add_func ("/auth/select-auth", do_select_auth_test);
1571 g_test_add_func ("/auth/auth-close", do_auth_close_test);
1572 g_test_add_func ("/auth/infinite-auth", do_infinite_auth_test);
1573 g_test_add_func ("/auth/disappearing-auth", do_disappearing_auth_test);
1574 g_test_add_func ("/auth/clear-credentials", do_clear_credentials_test);
1575 g_test_add_func ("/auth/message-do-not-use-auth-cache", do_message_do_not_use_auth_cache_test);
1576 g_test_add_func ("/auth/async-message-do-not-use-auth-cache", do_async_message_do_not_use_auth_cache_test);
1577 g_test_add_func ("/auth/authorization-header-request", do_message_has_authorization_header_test);
1578 g_test_add_func ("/auth/cancel-after-retry", do_cancel_after_retry_test);
1580 ret = g_test_run ();