diff options
author | Dan Winship <danw@src.gnome.org> | 2009-01-12 22:36:48 +0000 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2009-01-12 22:36:48 +0000 |
commit | 7546746140fe24d04c292c85d27ac41ef872ca5e (patch) | |
tree | 6dbab10cd4d9119bb3507cf7008b459f23295124 | |
parent | c84b49d9558b02b2ce61dbe992b5f223812b8dee (diff) | |
download | libsoup-7546746140fe24d04c292c85d27ac41ef872ca5e.tar.gz |
pull-ups from trunk
svn path=/branches/gnome-2-24/; revision=1228
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | docs/reference/client-howto.xml | 2 | ||||
-rw-r--r-- | gtk-doc.make | 47 | ||||
-rw-r--r-- | libsoup/soup-auth-manager.c | 2 | ||||
-rw-r--r-- | libsoup/soup-cookie-jar.c | 9 | ||||
-rw-r--r-- | libsoup/soup-form.c | 8 | ||||
-rw-r--r-- | libsoup/soup-message-headers.c | 7 | ||||
-rw-r--r-- | libsoup/soup-server.c | 2 | ||||
-rw-r--r-- | tests/auth-test.c | 212 |
9 files changed, 299 insertions, 22 deletions
@@ -1,3 +1,35 @@ +2009-01-12 Dan Winship <danw@gnome.org> + + * libsoup/soup-cookie-jar.c (request_started): Don't pass NULL to + soup_message_headers_replace(), call soup_message_headers_remove() + if there are no cookies. Likely fix for webkit bug #23240. + + * libsoup/soup-message-headers.c (soup_message_headers_append): + g_return_if_fail (value != NULL) + +2008-12-04 Dan Winship <danw@gnome.org> + + * libsoup/soup-form.c (soup_form_decode): Correctly handle forms + that have URI-encoded parameter names. #563302, Evan Nemerson. + +2008-11-28 Dan Winship <danw@gnome.org> + + * libsoup/soup-auth-manager.c (auth_type_compare_func): Fix this + so we choose the *strongest* auth type first, rather than the + weakest. Doh. #562339, Pontus Oldberg. + + * libsoup/soup-server.c (soup_server_add_auth_domain): use + g_slist_append() rather than prepend(), so auth headers get added + in the same order as the SoupAuthDomains were. + + * tests/auth-test.c (do_select_auth_test): add a test of selecting + between Basic and Digest auth + +2008-11-28 Dan Winship <danw@gnome.org> + + * docs/reference/client-howto.xml: fix method name in example. + #562411, Andreas Bruse. + 2008-11-25 Dan Winship <danw@gnome.org> * configure.in: 2.24.2.1 (sigh) diff --git a/docs/reference/client-howto.xml b/docs/reference/client-howto.xml index 23aa675b..24ee0461 100644 --- a/docs/reference/client-howto.xml +++ b/docs/reference/client-howto.xml @@ -178,7 +178,7 @@ linkend="soup-session-send-message"><function>soup_session_send_message</functio <informalexample><programlisting> guint status; - status = soup_session_send (session, msg); + status = soup_session_send_message (session, msg); </programlisting></informalexample> <para> diff --git a/gtk-doc.make b/gtk-doc.make index 354ffb7c..0f87cc79 100644 --- a/gtk-doc.make +++ b/gtk-doc.make @@ -7,9 +7,11 @@ if GTK_DOC_USE_LIBTOOL GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +GTKDOC_RUN = $(LIBTOOL) --mode=execute else GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +GTKDOC_RUN = sh -c endif # We set GPATH here; this gives us semantics for GNU make @@ -53,6 +55,8 @@ endif docs: html-build.stamp +$(REPORT_FILES): sgml-build.stamp + #### scan #### scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) @@ -61,7 +65,7 @@ scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) cd $(srcdir) && \ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \ - CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ else \ cd $(srcdir) ; \ for i in $(SCANOBJ_FILES) ; do \ @@ -107,7 +111,12 @@ html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) @-chmod -R u+w $(srcdir) rm -rf $(srcdir)/html mkdir $(srcdir)/html - cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) + mkhtml_options=""; \ + gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ + if test "$(?)" = "0"; then \ + mkhtml_options=--path="$(srcdir)"; \ + fi + cd $(srcdir)/html && gtkdoc-mkhtml $(mkhtml_options) $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) @echo 'gtk-doc: Fixing cross-references' cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) @@ -128,24 +137,37 @@ maintainer-clean-local: clean cd $(srcdir) && rm -rf xml html install-data-local: - -installfiles=`echo $(srcdir)/html/*`; \ + installfiles=`echo $(srcdir)/html/*`; \ if test "$$installfiles" = '$(srcdir)/html/*'; \ then echo '-- Nothing to install' ; \ else \ - $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR); \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + $(mkinstalldirs) $${installdir} ; \ for i in $$installfiles; do \ echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + $(INSTALL_DATA) $$i $${installdir}; \ done; \ - echo '-- Installing $(srcdir)/html/index.sgml' ; \ - $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR) || :; \ - which gtkdoc-rebase >/dev/null && \ - gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$(DESTDIR)$(TARGET_DIR) ; \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ + $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ + mv -f $${installdir}/$(DOC_MODULE).devhelp \ + $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp; \ + fi; \ + ! which gtkdoc-rebase >/dev/null 2>&1 || \ + gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir} ; \ fi - uninstall-local: - rm -f $(DESTDIR)$(TARGET_DIR)/* + if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + rm -rf $${installdir} # # Require gtk-doc when making dist @@ -168,6 +190,7 @@ dist-hook: dist-check-gtkdoc dist-hook-local -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/ -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/ cd $(distdir) && rm -f $(DISTCLEANFILES) - -gtkdoc-rebase --online --relative --html-dir=$(distdir)/html + ! which gtkdoc-rebase >/dev/null 2>&1 || \ + gtkdoc-rebase --online --relative --html-dir=$(distdir)/html .PHONY : dist-hook-local docs diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c index df8dddf5..c0adae83 100644 --- a/libsoup/soup-auth-manager.c +++ b/libsoup/soup-auth-manager.c @@ -150,7 +150,7 @@ auth_type_compare_func (gconstpointer a, gconstpointer b) SoupAuthClass **auth1 = (SoupAuthClass **)a; SoupAuthClass **auth2 = (SoupAuthClass **)b; - return (*auth2)->strength - (*auth1)->strength; + return (*auth1)->strength - (*auth2)->strength; } void diff --git a/libsoup/soup-cookie-jar.c b/libsoup/soup-cookie-jar.c index 9b717c5a..03516445 100644 --- a/libsoup/soup-cookie-jar.c +++ b/libsoup/soup-cookie-jar.c @@ -299,9 +299,12 @@ request_started (SoupSessionFeature *feature, SoupSession *session, char *cookies; cookies = soup_cookie_jar_get_cookies (jar, soup_message_get_uri (msg), TRUE); - soup_message_headers_replace (msg->request_headers, - "Cookie", cookies); - g_free (cookies); + if (cookies) { + soup_message_headers_replace (msg->request_headers, + "Cookie", cookies); + g_free (cookies); + } else + soup_message_headers_remove (msg->request_headers, "Cookie"); } static void diff --git a/libsoup/soup-form.c b/libsoup/soup-form.c index 0984ad85..dfc79d8a 100644 --- a/libsoup/soup-form.c +++ b/libsoup/soup-form.c @@ -63,15 +63,15 @@ soup_form_decode (const char *encoded_form) for (i = 0; pairs[i]; i++) { name = pairs[i]; eq = strchr (name, '='); - if (!form_decode (name)) { - g_free (name); - continue; - } if (eq) { *eq = '\0'; value = eq + 1; } else value = NULL; + if (!form_decode (name) || (value && !form_decode (value))) { + g_free (name); + continue; + } g_hash_table_insert (form_data_set, name, value); } diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c index b2d88506..edaae1e6 100644 --- a/libsoup/soup-message-headers.c +++ b/libsoup/soup-message-headers.c @@ -150,6 +150,9 @@ soup_message_headers_append (SoupMessageHeaders *hdrs, SoupHeader header; SoupHeaderSetter setter; + g_return_if_fail (name != NULL); + g_return_if_fail (value != NULL); + header.name = intern_header_name (name, &setter); header.value = g_strdup (value); g_array_append_val (hdrs->array, header); @@ -204,6 +207,8 @@ soup_message_headers_remove (SoupMessageHeaders *hdrs, const char *name) SoupHeaderSetter setter; int index; + g_return_if_fail (name != NULL); + name = intern_header_name (name, &setter); while ((index = find_header (hdr_array, name, 0)) != -1) { g_free (hdr_array[index].value); @@ -238,6 +243,8 @@ soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name) char *value; int index, i; + g_return_val_if_fail (name != NULL, NULL); + name = intern_header_name (name, NULL); if (hdrs->concat) { value = g_hash_table_lookup (hdrs->concat, name); diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c index b8e7dd94..2eb030e5 100644 --- a/libsoup/soup-server.c +++ b/libsoup/soup-server.c @@ -1251,7 +1251,7 @@ soup_server_add_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain) g_return_if_fail (SOUP_IS_SERVER (server)); priv = SOUP_SERVER_GET_PRIVATE (server); - priv->auth_domains = g_slist_prepend (priv->auth_domains, auth_domain); + priv->auth_domains = g_slist_append (priv->auth_domains, auth_domain); g_object_ref (auth_domain); } diff --git a/tests/auth-test.c b/tests/auth-test.c index 96a4979d..23bf513f 100644 --- a/tests/auth-test.c +++ b/tests/auth-test.c @@ -543,6 +543,215 @@ do_async_auth_test (const char *base_uri) g_free (uri); } +typedef struct { + const char *password; + struct { + const char *headers; + const char *response; + } round[2]; +} SelectAuthData; + +static void +select_auth_authenticate (SoupSession *session, SoupMessage *msg, + SoupAuth *auth, gboolean retrying, gpointer data) +{ + SelectAuthData *sad = data; + const char *header, *basic, *digest; + int round = retrying ? 1 : 0; + + header = soup_message_headers_get (msg->response_headers, "WWW-Authenticate"); + basic = strstr (header, "Basic"); + digest = strstr (header, "Digest"); + if (basic && digest) { + if (basic < digest) + sad->round[round].headers = "Basic, Digest"; + else + sad->round[round].headers = "Digest, Basic"; + } else if (basic) + sad->round[round].headers = "Basic"; + else if (digest) + sad->round[round].headers = "Digest"; + + sad->round[round].response = soup_auth_get_scheme_name (auth); + if (sad->password && !retrying) + soup_auth_authenticate (auth, "user", sad->password); +} + +static void +select_auth_test_one (SoupURI *uri, const char *password, + const char *first_headers, const char *first_response, + const char *second_headers, const char *second_response, + guint final_status) +{ + SelectAuthData sad; + SoupMessage *msg; + SoupSession *session; + + session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); + g_signal_connect (session, "authenticate", + G_CALLBACK (select_auth_authenticate), &sad); + memset (&sad, 0, sizeof (sad)); + sad.password = password; + + msg = soup_message_new_from_uri ("GET", uri); + soup_session_send_message (session, msg); + + if (strcmp (sad.round[0].headers, first_headers) != 0) { + debug_printf (1, " Header order wrong: expected %s, got %s\n", + first_headers, sad.round[0].headers); + errors++; + } + if (strcmp (sad.round[0].response, first_response) != 0) { + debug_printf (1, " Selected auth type wrong: expected %s, got %s\n", + first_response, sad.round[0].response); + errors++; + } + + if (second_headers && !sad.round[1].headers) { + debug_printf (1, " Expected a second round!\n"); + errors++; + } else if (!second_headers && sad.round[1].headers) { + debug_printf (1, " Didn't expect a second round!\n"); + errors++; + } else if (second_headers) { + if (strcmp (sad.round[1].headers, second_headers) != 0) { + debug_printf (1, " Second round header order wrong: expected %s, got %s\n", + second_headers, sad.round[1].headers); + errors++; + } + if (strcmp (sad.round[1].response, second_response) != 0) { + debug_printf (1, " Second round selected auth type wrong: expected %s, got %s\n", + second_response, sad.round[1].response); + errors++; + } + } + + if (msg->status_code != final_status) { + debug_printf (1, " Final status wrong: expected %u, got %u\n", + final_status, msg->status_code); + errors++; + } + + g_object_unref (msg); + soup_test_session_abort_unref (session); +} + +static void +server_callback (SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, + SoupClientContext *context, gpointer data) +{ + soup_message_set_response (msg, "text/plain", + SOUP_MEMORY_STATIC, + "OK\r\n", 4); + soup_message_set_status (msg, SOUP_STATUS_OK); +} + +static gboolean +server_basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg, + const char *username, const char *password, gpointer data) +{ + return FALSE; +} + +static char * +server_digest_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg, + const char *username, gpointer data) +{ + if (strcmp (username, "user") != 0) + return NULL; + return soup_auth_domain_digest_encode_password ("user", + "auth-test", + "good"); +} + +static void +do_select_auth_test (void) +{ + SoupServer *server; + SoupAuthDomain *basic_auth_domain, *digest_auth_domain; + SoupURI *uri; + + debug_printf (1, "\nTesting selection among multiple auths:\n"); + + /* It doesn't seem to be possible to configure Apache to serve + * multiple auth types for a single URL. So we have to use + * SoupServer here. We know that SoupServer handles the server + * side of this scenario correctly, because we test it against + * curl in server-auth-test. + */ + server = soup_test_server_new (FALSE); + soup_server_add_handler (server, NULL, + server_callback, NULL, NULL); + + uri = soup_uri_new ("http://localhost/"); + soup_uri_set_port (uri, soup_server_get_port (server)); + + basic_auth_domain = soup_auth_domain_basic_new ( + SOUP_AUTH_DOMAIN_REALM, "auth-test", + SOUP_AUTH_DOMAIN_ADD_PATH, "/", + SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, server_basic_auth_callback, + NULL); + soup_server_add_auth_domain (server, basic_auth_domain); + + digest_auth_domain = soup_auth_domain_digest_new ( + SOUP_AUTH_DOMAIN_REALM, "auth-test", + SOUP_AUTH_DOMAIN_ADD_PATH, "/", + SOUP_AUTH_DOMAIN_DIGEST_AUTH_CALLBACK, server_digest_auth_callback, + NULL); + soup_server_add_auth_domain (server, digest_auth_domain); + + /* FIXME: when we support disabling auth types in the session, + * test that too. + */ + + debug_printf (1, " Testing with no auth\n"); + select_auth_test_one (uri, NULL, + "Basic, Digest", "Digest", + NULL, NULL, + SOUP_STATUS_UNAUTHORIZED); + + debug_printf (1, " Testing with bad password\n"); + select_auth_test_one (uri, "bad", + "Basic, Digest", "Digest", + "Basic, Digest", "Digest", + SOUP_STATUS_UNAUTHORIZED); + + debug_printf (1, " Testing with good password\n"); + select_auth_test_one (uri, "good", + "Basic, Digest", "Digest", + NULL, NULL, + SOUP_STATUS_OK); + + /* Now flip the order of the domains, verify that this flips + * the order of the headers, and make sure that digest auth + * *still* gets used. + */ + + soup_server_remove_auth_domain (server, basic_auth_domain); + soup_server_remove_auth_domain (server, digest_auth_domain); + soup_server_add_auth_domain (server, digest_auth_domain); + soup_server_add_auth_domain (server, basic_auth_domain); + + debug_printf (1, " Testing flipped with no auth\n"); + select_auth_test_one (uri, NULL, + "Digest, Basic", "Digest", + NULL, NULL, + SOUP_STATUS_UNAUTHORIZED); + + debug_printf (1, " Testing flipped with bad password\n"); + select_auth_test_one (uri, "bad", + "Digest, Basic", "Digest", + "Digest, Basic", "Digest", + SOUP_STATUS_UNAUTHORIZED); + + debug_printf (1, " Testing flipped with good password\n"); + select_auth_test_one (uri, "good", + "Digest, Basic", "Digest", + NULL, NULL, + SOUP_STATUS_OK); +} + int main (int argc, char **argv) { @@ -727,6 +936,9 @@ main (int argc, char **argv) /* Async auth */ do_async_auth_test (base_uri); + /* Selecting correct auth when multiple auth types are available */ + do_select_auth_test (); + g_main_loop_unref (loop); test_cleanup (); |