summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2009-01-12 22:36:48 +0000
committerDan Winship <danw@src.gnome.org>2009-01-12 22:36:48 +0000
commit7546746140fe24d04c292c85d27ac41ef872ca5e (patch)
tree6dbab10cd4d9119bb3507cf7008b459f23295124
parentc84b49d9558b02b2ce61dbe992b5f223812b8dee (diff)
downloadlibsoup-7546746140fe24d04c292c85d27ac41ef872ca5e.tar.gz
pull-ups from trunk
svn path=/branches/gnome-2-24/; revision=1228
-rw-r--r--ChangeLog32
-rw-r--r--docs/reference/client-howto.xml2
-rw-r--r--gtk-doc.make47
-rw-r--r--libsoup/soup-auth-manager.c2
-rw-r--r--libsoup/soup-cookie-jar.c9
-rw-r--r--libsoup/soup-form.c8
-rw-r--r--libsoup/soup-message-headers.c7
-rw-r--r--libsoup/soup-server.c2
-rw-r--r--tests/auth-test.c212
9 files changed, 299 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 28a40ca6..d2f4e957 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 ();