diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | docs/reference/libsoup-2.4-sections.txt | 2 | ||||
-rw-r--r-- | libsoup/soup-auth-digest.c | 8 | ||||
-rw-r--r-- | libsoup/soup-auth-domain-basic.c | 3 | ||||
-rw-r--r-- | libsoup/soup-auth-domain-digest.c | 3 | ||||
-rw-r--r-- | libsoup/soup-auth-domain.c | 8 | ||||
-rw-r--r-- | libsoup/soup-auth-manager-ntlm.c | 4 | ||||
-rw-r--r-- | libsoup/soup-auth-manager.c | 8 | ||||
-rw-r--r-- | libsoup/soup-cookie.c | 11 | ||||
-rw-r--r-- | libsoup/soup-headers.c | 2 | ||||
-rw-r--r-- | libsoup/soup-logger.c | 2 | ||||
-rw-r--r-- | libsoup/soup-message-client-io.c | 2 | ||||
-rw-r--r-- | libsoup/soup-message-headers.c | 89 | ||||
-rw-r--r-- | libsoup/soup-message-headers.h | 4 | ||||
-rw-r--r-- | libsoup/soup-message-server-io.c | 8 | ||||
-rw-r--r-- | libsoup/soup-message.c | 8 | ||||
-rw-r--r-- | libsoup/soup-session.c | 3 | ||||
-rw-r--r-- | tests/auth-test.c | 7 | ||||
-rw-r--r-- | tests/chunk-test.c | 9 | ||||
-rw-r--r-- | tests/continue-test.c | 4 | ||||
-rw-r--r-- | tests/get.c | 3 | ||||
-rw-r--r-- | tests/header-parsing.c | 67 | ||||
-rw-r--r-- | tests/ntlm-test.c | 19 | ||||
-rw-r--r-- | tests/range-test.c | 6 | ||||
-rw-r--r-- | tests/redirect-test.c | 3 | ||||
-rw-r--r-- | tests/server-auth-test.c | 8 | ||||
-rw-r--r-- | tests/simple-httpd.c | 2 |
27 files changed, 244 insertions, 71 deletions
@@ -1,3 +1,25 @@ +2009-04-02 Dan Winship <danw@gnome.org> + + Bug 576760 – soup_message_headers_get_content_type returns bad headers + + * libsoup/soup-message-headers.c (soup_message_headers_get_one) + (soup_message_headers_get_list): New replacements for + soup_message_headers_get(), indicating explicitly whether the + caller expects the header to be a list or not; for non-list-type + headers, if there's more than one, the second one should be + ignored rather than concatenated to the first. + (soup_message_headers_get): deprecate this. + + * libsoup/*.c: + * tests/*.c: Update to use soup_message_headers_get_one() or + _get_list() as appropriate. + + * tests/header-parsing.c (do_content_type_tests): Add some tests + of Content-Type parsing/setting, including making sure that + duplicate Content-Type headers are ignored. + + * docs/reference/libsoup-2.4-sections.txt: update + 2009-03-27 Dan Winship <danw@gnome.org> Bug 576583 – Tests fail if "localhost" resolves to ::1 diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt index 05611d8a..66b16440 100644 --- a/docs/reference/libsoup-2.4-sections.txt +++ b/docs/reference/libsoup-2.4-sections.txt @@ -90,6 +90,8 @@ soup_message_headers_append soup_message_headers_replace soup_message_headers_remove soup_message_headers_clear +soup_message_headers_get_one +soup_message_headers_get_list soup_message_headers_get <SUBSECTION> SoupMessageHeadersForeachFunc diff --git a/libsoup/soup-auth-digest.c b/libsoup/soup-auth-digest.c index 6ebbcdcf..665bac76 100644 --- a/libsoup/soup-auth-digest.c +++ b/libsoup/soup-auth-digest.c @@ -397,10 +397,10 @@ authentication_info_cb (SoupMessage *msg, gpointer data) if (auth != soup_message_get_auth (msg)) return; - header = soup_message_headers_get (msg->response_headers, - soup_auth_is_for_proxy (auth) ? - "Proxy-Authentication-Info" : - "Authentication-Info"); + header = soup_message_headers_get_one (msg->response_headers, + soup_auth_is_for_proxy (auth) ? + "Proxy-Authentication-Info" : + "Authentication-Info"); g_return_if_fail (header != NULL); auth_params = soup_header_parse_param_list (header); diff --git a/libsoup/soup-auth-domain-basic.c b/libsoup/soup-auth-domain-basic.c index 6d515914..49f82443 100644 --- a/libsoup/soup-auth-domain-basic.c +++ b/libsoup/soup-auth-domain-basic.c @@ -338,7 +338,8 @@ check_password (SoupAuthDomain *domain, char *msg_username, *msg_password; gboolean ok; - header = soup_message_headers_get (msg->request_headers, "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (!parse_basic (msg, header, &msg_username, &msg_password)) return FALSE; diff --git a/libsoup/soup-auth-domain-digest.c b/libsoup/soup-auth-domain-digest.c index f3345a94..509995ec 100644 --- a/libsoup/soup-auth-domain-digest.c +++ b/libsoup/soup-auth-domain-digest.c @@ -429,7 +429,8 @@ check_password (SoupAuthDomain *domain, char hex_urp[33]; gboolean accept; - header = soup_message_headers_get (msg->request_headers, "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (strncmp (header, "Digest ", 7) != 0) return FALSE; diff --git a/libsoup/soup-auth-domain.c b/libsoup/soup-auth-domain.c index c34447c2..d3949d15 100644 --- a/libsoup/soup-auth-domain.c +++ b/libsoup/soup-auth-domain.c @@ -574,10 +574,10 @@ soup_auth_domain_accepts (SoupAuthDomain *domain, SoupMessage *msg) SoupAuthDomainPrivate *priv = SOUP_AUTH_DOMAIN_GET_PRIVATE (domain); const char *header; - header = soup_message_headers_get (msg->request_headers, - priv->proxy ? - "Proxy-Authorization" : - "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + priv->proxy ? + "Proxy-Authorization" : + "Authorization"); if (!header) return NULL; return SOUP_AUTH_DOMAIN_GET_CLASS (domain)->accepts (domain, msg, header); diff --git a/libsoup/soup-auth-manager-ntlm.c b/libsoup/soup-auth-manager-ntlm.c index 35487d97..6e6956c9 100644 --- a/libsoup/soup-auth-manager-ntlm.c +++ b/libsoup/soup-auth-manager-ntlm.c @@ -280,8 +280,8 @@ ntlm_authorize_pre (SoupMessage *msg, gpointer ntlm) if (!conn) return; - val = soup_message_headers_get (msg->response_headers, - "WWW-Authenticate"); + val = soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); if (val) val = strstr (val, "NTLM "); if (!val) diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c index 6fad72c2..92ffae88 100644 --- a/libsoup/soup-auth-manager.c +++ b/libsoup/soup-auth-manager.c @@ -202,11 +202,11 @@ static inline const char * auth_header_for_message (SoupMessage *msg) { if (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED) { - return soup_message_headers_get (msg->response_headers, - "Proxy-Authenticate"); + return soup_message_headers_get_list (msg->response_headers, + "Proxy-Authenticate"); } else { - return soup_message_headers_get (msg->response_headers, - "WWW-Authenticate"); + return soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); } } diff --git a/libsoup/soup-cookie.c b/libsoup/soup-cookie.c index ac4644b5..5e18bd01 100644 --- a/libsoup/soup-cookie.c +++ b/libsoup/soup-cookie.c @@ -841,8 +841,13 @@ soup_cookies_from_request (SoupMessage *msg) GHashTable *params; GHashTableIter iter; gpointer name, value; + const char *header; - params = soup_header_parse_semi_param_list (soup_message_headers_get (msg->request_headers, "Cookie")); + header = soup_message_headers_get_one (msg->request_headers, "Cookie"); + if (!header) + return NULL; + + params = soup_header_parse_semi_param_list (header); g_hash_table_iter_init (&iter, params); while (g_hash_table_iter_next (&iter, &name, &value)) { cookie = soup_cookie_new (name, value, NULL, NULL, 0); @@ -898,8 +903,8 @@ soup_cookies_to_request (GSList *cookies, SoupMessage *msg) { GString *header; - header = g_string_new (soup_message_headers_get (msg->request_headers, - "Cookie")); + header = g_string_new (soup_message_headers_get_one (msg->request_headers, + "Cookie")); while (cookies) { serialize_cookie (cookies->data, header, FALSE); cookies = cookies->next; diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c index 697163b4..a46f2352 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c @@ -131,7 +131,7 @@ soup_headers_clean_for_10 (SoupMessageHeaders *hdrs) const char *connection; GSList *tokens, *t; - connection = soup_message_headers_get (hdrs, "Connection"); + connection = soup_message_headers_get_list (hdrs, "Connection"); if (!connection) return; diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c index bb984411..b38cb87b 100644 --- a/libsoup/soup-logger.c +++ b/libsoup/soup-logger.c @@ -487,7 +487,7 @@ print_request (SoupLogger *logger, SoupMessage *msg, if (log_level == SOUP_LOGGER_LOG_MINIMAL) return; - if (!soup_message_headers_get (msg->request_headers, "Host")) { + if (!soup_message_headers_get_one (msg->request_headers, "Host")) { soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>', "Host: %s%c%u", uri->host, soup_uri_uses_default_port (uri) ? '\0' : ':', diff --git a/libsoup/soup-message-client-io.c b/libsoup/soup-message-client-io.c index 42ad94e0..ebf144c7 100644 --- a/libsoup/soup-message-client-io.c +++ b/libsoup/soup-message-client-io.c @@ -92,7 +92,7 @@ get_request_headers (SoupMessage *req, GString *header, } else { g_string_append_printf (header, "%s %s HTTP/1.1\r\n", req->method, uri_string); - if (!soup_message_headers_get (req->request_headers, "Host")) { + if (!soup_message_headers_get_one (req->request_headers, "Host")) { if (soup_uri_uses_default_port (uri)) { g_string_append_printf (header, "Host: %s\r\n", uri_host); diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c index c1570c5f..b47a1f0e 100644 --- a/libsoup/soup-message-headers.c +++ b/libsoup/soup-message-headers.c @@ -226,22 +226,61 @@ soup_message_headers_remove (SoupMessageHeaders *hdrs, const char *name) } /** - * soup_message_headers_get: + * soup_message_headers_get_one: * @hdrs: a #SoupMessageHeaders * @name: header name * - * Gets the value of header @name in @hdrs. + * Gets the value of header @name in @hdrs. Use this for headers whose + * values are <emphasis>not</emphasis> comma-delimited lists, and + * which therefore can only appear at most once in the headers. For + * list-valued headers, use soup_message_headers_get_list(). + * + * If @hdrs does erroneously contain multiple copies of the header, it + * is not defined which one will be returned. (Ideally, it will return + * whichever one makes libsoup most compatible with other HTTP + * implementations.) + * + * Return value: the header's value or %NULL if not found. * - * If @name has multiple values in @hdrs, soup_message_headers_get() - * will concatenate all of the values together, separated by commas. - * This is sometimes awkward to parse (eg, WWW-Authenticate, - * Set-Cookie), but you have to be able to deal with it anyway, - * because an upstream proxy could do the same thing. + * Since: 2.26.1 + **/ +const char * +soup_message_headers_get_one (SoupMessageHeaders *hdrs, const char *name) +{ + SoupHeader *hdr_array = (SoupHeader *)(hdrs->array->data); + int index; + + g_return_val_if_fail (name != NULL, NULL); + + name = intern_header_name (name, NULL); + index = find_header (hdr_array, name, 0); + return (index == -1) ? NULL : hdr_array[index].value; +} + +/** + * soup_message_headers_get_list: + * @hdrs: a #SoupMessageHeaders + * @name: header name + * + * Gets the value of header @name in @hdrs. Use this for headers whose + * values are comma-delimited lists, and which are therefore allowed + * to appear multiple times in the headers. For non-list-valued + * headers, use soup_message_headers_get_one(). + * + * If @name appears multiple times in @hdrs, + * soup_message_headers_get_list() will concatenate all of the values + * together, separated by commas. This is sometimes awkward to parse + * (eg, WWW-Authenticate, Set-Cookie), but you have to be able to deal + * with it anyway, because the HTTP spec explicitly states that this + * transformation is allowed, and so an upstream proxy could do the + * same thing. * * Return value: the header's value or %NULL if not found. + * + * Since: 2.26.1 **/ const char * -soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name) +soup_message_headers_get_list (SoupMessageHeaders *hdrs, const char *name) { SoupHeader *hdr_array = (SoupHeader *)(hdrs->array->data); GString *concat; @@ -278,6 +317,32 @@ soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name) } /** + * soup_message_headers_get: + * @hdrs: a #SoupMessageHeaders + * @name: header name + * + * Gets the value of header @name in @hdrs. + * + * This method was supposed to work correctly for both single-valued + * and list-valued headers, but because some HTTP clients/servers + * mistakenly send multiple copies of headers that are supposed to be + * single-valued, it sometimes returns incorrect results. To fix this, + * the methods soup_message_headers_get_one() and + * soup_message_headers_get_list() were introduced, so callers can + * explicitly state which behavior they are expecting. + * + * Return value: as with soup_message_headers_get_list(). + * + * Deprecated: Use soup_message_headers_get_one() or + * soup_message_headers_get_list() instead. + **/ +const char * +soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name) +{ + return soup_message_headers_get_list (hdrs, name); +} + +/** * SoupMessageHeadersIter: * * An opaque type used to iterate over a %SoupMessageHeaders @@ -508,7 +573,7 @@ soup_message_headers_get_encoding (SoupMessageHeaders *hdrs) /* If Transfer-Encoding was set, hdrs->encoding would already * be set. So we don't need to check that possibility. */ - header = soup_message_headers_get (hdrs, "Content-Length"); + header = soup_message_headers_get_one (hdrs, "Content-Length"); if (header) { content_length_setter (hdrs, header); if (hdrs->encoding != -1) @@ -738,7 +803,7 @@ soup_message_headers_get_ranges (SoupMessageHeaders *hdrs, SoupRange **ranges, int *length) { - const char *range = soup_message_headers_get (hdrs, "Range"); + const char *range = soup_message_headers_get_one (hdrs, "Range"); GSList *range_list, *r; GArray *array; char *spec, *end; @@ -912,7 +977,7 @@ soup_message_headers_get_content_range (SoupMessageHeaders *hdrs, goffset *end, goffset *total_length) { - const char *header = soup_message_headers_get (hdrs, "Content-Range"); + const char *header = soup_message_headers_get_one (hdrs, "Content-Range"); goffset length; char *p; @@ -983,7 +1048,7 @@ parse_content_foo (SoupMessageHeaders *hdrs, const char *header_name, const char *header; char *semi; - header = soup_message_headers_get (hdrs, header_name); + header = soup_message_headers_get_one (hdrs, header_name); if (!header) return FALSE; diff --git a/libsoup/soup-message-headers.h b/libsoup/soup-message-headers.h index 6572f396..f80d1235 100644 --- a/libsoup/soup-message-headers.h +++ b/libsoup/soup-message-headers.h @@ -35,6 +35,10 @@ void soup_message_headers_clear (SoupMessageHeaders *hdrs); const char *soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name); +const char *soup_message_headers_get_one (SoupMessageHeaders *hdrs, + const char *name); +const char *soup_message_headers_get_list (SoupMessageHeaders *hdrs, + const char *name); typedef void (*SoupMessageHeadersForeachFunc)(const char *name, const char *value, diff --git a/libsoup/soup-message-server-io.c b/libsoup/soup-message-server-io.c index 06225f20..2e769f43 100644 --- a/libsoup/soup-message-server-io.c +++ b/libsoup/soup-message-server-io.c @@ -48,14 +48,14 @@ parse_request_headers (SoupMessage *msg, char *headers, guint headers_len, /* Handle request body encoding */ *encoding = soup_message_headers_get_encoding (msg->request_headers); if (*encoding == SOUP_ENCODING_UNRECOGNIZED) { - if (soup_message_headers_get (msg->request_headers, "Transfer-Encoding")) + if (soup_message_headers_get_list (msg->request_headers, "Transfer-Encoding")) return SOUP_STATUS_NOT_IMPLEMENTED; else return SOUP_STATUS_BAD_REQUEST; } /* Generate correct context for request */ - req_host = soup_message_headers_get (msg->request_headers, "Host"); + req_host = soup_message_headers_get_one (msg->request_headers, "Host"); if (*req_path != '/') { /* Check for absolute URI */ @@ -154,8 +154,8 @@ handle_partial_get (SoupMessage *msg) */ multipart = soup_multipart_new ("multipart/byteranges"); - content_type = soup_message_headers_get (msg->response_headers, - "Content-Type"); + content_type = soup_message_headers_get_one (msg->response_headers, + "Content-Type"); for (i = 0; i < nranges; i++) { part_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); if (content_type) { diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index a600f0f0..68a21c1e 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -919,7 +919,7 @@ header_handler_metamarshal (GClosure *closure, GValue *return_value, return; hdrs = priv->server_side ? msg->request_headers : msg->response_headers; - if (soup_message_headers_get (hdrs, header_name)) { + if (soup_message_headers_get_one (hdrs, header_name)) { closure->marshal (closure, return_value, n_param_values, param_values, invocation_hint, ((GCClosure *)closure)->callback); @@ -1293,8 +1293,10 @@ soup_message_is_keepalive (SoupMessage *msg) { const char *c_conn, *s_conn; - c_conn = soup_message_headers_get (msg->request_headers, "Connection"); - s_conn = soup_message_headers_get (msg->response_headers, "Connection"); + c_conn = soup_message_headers_get_list (msg->request_headers, + "Connection"); + s_conn = soup_message_headers_get_list (msg->response_headers, + "Connection"); if (msg->status_code == SOUP_STATUS_OK && msg->method == SOUP_METHOD_CONNECT) diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index fa66fd73..5e4151b8 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -860,7 +860,8 @@ redirect_handler (SoupMessage *msg, gpointer user_data) const char *new_loc; SoupURI *new_uri; - new_loc = soup_message_headers_get (msg->response_headers, "Location"); + new_loc = soup_message_headers_get_one (msg->response_headers, + "Location"); g_return_if_fail (new_loc != NULL); if (msg->status_code == SOUP_STATUS_SEE_OTHER || diff --git a/tests/auth-test.c b/tests/auth-test.c index c035f650..cc992b1c 100644 --- a/tests/auth-test.c +++ b/tests/auth-test.c @@ -166,8 +166,8 @@ identify_auth (SoupMessage *msg) const char *header; int num; - header = soup_message_headers_get (msg->request_headers, - "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (!header) return 0; @@ -559,7 +559,8 @@ select_auth_authenticate (SoupSession *session, SoupMessage *msg, const char *header, *basic, *digest; int round = retrying ? 1 : 0; - header = soup_message_headers_get (msg->response_headers, "WWW-Authenticate"); + header = soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); basic = strstr (header, "Basic"); digest = strstr (header, "Digest"); if (basic && digest) { diff --git a/tests/chunk-test.c b/tests/chunk-test.c index e6bc1e82..97c3ed5d 100644 --- a/tests/chunk-test.c +++ b/tests/chunk-test.c @@ -142,7 +142,8 @@ do_request_test (SoupSession *session, SoupURI *base_uri) errors++; } - server_md5 = soup_message_headers_get (msg->response_headers, "Content-MD5"); + server_md5 = soup_message_headers_get_one (msg->response_headers, + "Content-MD5"); if (!server_md5 || strcmp (client_md5, server_md5) != 0) { debug_printf (1, " client/server data mismatch: %s vs %s\n", client_md5, server_md5 ? server_md5 : "(null)"); @@ -229,7 +230,8 @@ do_response_test (SoupSession *session, SoupURI *base_uri) } client_md5 = g_checksum_get_string (gtd.check); - server_md5 = soup_message_headers_get (msg->response_headers, "Content-MD5"); + server_md5 = soup_message_headers_get_one (msg->response_headers, + "Content-MD5"); if (!server_md5 || strcmp (client_md5, server_md5) != 0) { debug_printf (1, " client/server data mismatch: %s vs %s\n", client_md5, server_md5 ? server_md5 : "(null)"); @@ -290,7 +292,8 @@ do_temporary_test (SoupSession *session, SoupURI *base_uri) errors++; } - server_md5 = soup_message_headers_get (msg->response_headers, "Content-MD5"); + server_md5 = soup_message_headers_get_one (msg->response_headers, + "Content-MD5"); if (!server_md5 || strcmp (client_md5, server_md5) != 0) { debug_printf (1, " client/server data mismatch: %s vs %s\n", client_md5, server_md5 ? server_md5 : "(null)"); diff --git a/tests/continue-test.c b/tests/continue-test.c index 1bca9173..d9a94a29 100644 --- a/tests/continue-test.c +++ b/tests/continue-test.c @@ -359,8 +359,8 @@ server_got_headers (SoupMessage *msg, gpointer server) SOUP_EXPECTATION_CONTINUE) { const char *length; - length = soup_message_headers_get (msg->request_headers, - "Content-Length"); + length = soup_message_headers_get_one (msg->request_headers, + "Content-Length"); if (length && atoi (length) > MAX_POST_LENGTH) { soup_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE); soup_message_headers_append (msg->response_headers, "Connection", "close"); diff --git a/tests/get.c b/tests/get.c index a489b06e..714d6bd8 100644 --- a/tests/get.c +++ b/tests/get.c @@ -183,7 +183,8 @@ get_url (const char *url) if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { if (recurse) unlink (name); - header = soup_message_headers_get (msg->response_headers, "Location"); + header = soup_message_headers_get_one (msg->response_headers, + "Location"); if (header) { if (!debug) printf (" -> %s\n", header); diff --git a/tests/header-parsing.c b/tests/header-parsing.c index 671ff861..9fd788c2 100644 --- a/tests/header-parsing.c +++ b/tests/header-parsing.c @@ -599,7 +599,7 @@ check_headers (Header *headers, SoupMessageHeaders *hdrs) ok = FALSE; break; } - value = soup_message_headers_get (hdrs, headers[i].name); + value = soup_message_headers_get_list (hdrs, headers[i].name); if (strcmp (value, headers[i].value) != 0) { ok = FALSE; break; @@ -839,7 +839,7 @@ do_rfc2231_tests (void) soup_message_headers_set_content_disposition (hdrs, "attachment", params); g_hash_table_destroy (params); - header = soup_message_headers_get (hdrs, "Content-Disposition"); + header = soup_message_headers_get_one (hdrs, "Content-Disposition"); if (!strcmp (header, RFC2231_TEST_HEADER)) debug_printf (1, " encoded OK\n"); else { @@ -873,6 +873,68 @@ do_rfc2231_tests (void) g_hash_table_destroy (params); soup_message_headers_free (hdrs); + + debug_printf (1, "\n"); +} + +#define CONTENT_TYPE_TEST_MIME_TYPE "text/plain" +#define CONTENT_TYPE_TEST_ATTRIBUTE "charset" +#define CONTENT_TYPE_TEST_VALUE "US-ASCII" +#define CONTENT_TYPE_TEST_HEADER "text/plain; charset=\"US-ASCII\"" + +static void +do_content_type_tests (void) +{ + SoupMessageHeaders *hdrs; + GHashTable *params; + const char *header, *mime_type; + + debug_printf (1, "Content-Type tests\n"); + + hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); + params = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (params, CONTENT_TYPE_TEST_ATTRIBUTE, + CONTENT_TYPE_TEST_VALUE); + soup_message_headers_set_content_type (hdrs, CONTENT_TYPE_TEST_MIME_TYPE, params); + g_hash_table_destroy (params); + + header = soup_message_headers_get_one (hdrs, "Content-Type"); + if (!strcmp (header, CONTENT_TYPE_TEST_HEADER)) + debug_printf (1, " encoded OK\n"); + else { + debug_printf (1, " encoding FAILED!\n expected: %s\n got: %s\n", + CONTENT_TYPE_TEST_HEADER, header); + errors++; + } + + soup_message_headers_clear (hdrs); + soup_message_headers_append (hdrs, "Content-Type", + CONTENT_TYPE_TEST_MIME_TYPE); + /* Add a second Content-Type header: should be ignored */ + soup_message_headers_append (hdrs, "Content-Type", + CONTENT_TYPE_TEST_MIME_TYPE); + + mime_type = soup_message_headers_get_content_type (hdrs, ¶ms); + if (!mime_type) { + debug_printf (1, " decoding FAILED!\n could not parse\n"); + errors++; + return; + } + + if (strcmp (mime_type, CONTENT_TYPE_TEST_MIME_TYPE) != 0) { + debug_printf (1, " decoding FAILED!\n bad returned MIME type: %s\n", + mime_type); + errors++; + } else if (params && g_hash_table_size (params) != 0) { + debug_printf (1, " decoding FAILED!\n params contained %d params (should be 0)\n", + g_hash_table_size (params)); + errors++; + } else + debug_printf (1, " decoded OK\n"); + + if (params) + g_hash_table_destroy (params); + soup_message_headers_free (hdrs); } int @@ -884,6 +946,7 @@ main (int argc, char **argv) do_response_tests (); do_qvalue_tests (); do_rfc2231_tests (); + do_content_type_tests (); test_cleanup (); return errors != 0; diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c index 4e8ace9a..bbec0373 100644 --- a/tests/ntlm-test.c +++ b/tests/ntlm-test.c @@ -87,7 +87,8 @@ server_callback (SoupServer *server, SoupMessage *msg, socket = soup_client_context_get_socket (client); state = GPOINTER_TO_INT (g_hash_table_lookup (connections, socket)); - auth = soup_message_headers_get (msg->request_headers, "Authorization"); + auth = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (auth) { if (!strncmp (auth, "NTLM ", 5)) { @@ -175,8 +176,8 @@ prompt_check (SoupMessage *msg, gpointer user_data) NTLMState *state = user_data; const char *header; - header = soup_message_headers_get (msg->response_headers, - "WWW-Authenticate"); + header = soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); if (header && strstr (header, "Basic ")) state->got_basic_prompt = TRUE; if (!state->sent_ntlm_request) { @@ -192,8 +193,8 @@ challenge_check (SoupMessage *msg, gpointer user_data) NTLMState *state = user_data; const char *header; - header = soup_message_headers_get (msg->response_headers, - "WWW-Authenticate"); + header = soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); if (header && !strncmp (header, "NTLM ", 5)) state->got_ntlm_challenge = TRUE; } @@ -204,8 +205,8 @@ request_check (SoupMessage *msg, gpointer user_data) NTLMState *state = user_data; const char *header; - header = soup_message_headers_get (msg->request_headers, - "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (header && !strncmp (header, "NTLM " NTLM_REQUEST_START, strlen ("NTLM " NTLM_REQUEST_START))) state->sent_ntlm_request = TRUE; @@ -217,8 +218,8 @@ response_check (SoupMessage *msg, gpointer user_data) NTLMState *state = user_data; const char *header; - header = soup_message_headers_get (msg->request_headers, - "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (header && !strncmp (header, "NTLM " NTLM_RESPONSE_START, strlen ("NTLM " NTLM_RESPONSE_START))) state->sent_ntlm_response = TRUE; diff --git a/tests/range-test.c b/tests/range-test.c index c673f83f..b4f27f98 100644 --- a/tests/range-test.c +++ b/tests/range-test.c @@ -40,7 +40,7 @@ check_part (SoupMessageHeaders *headers, const char *body, gsize body_len, goffset start, end, total_length; debug_printf (1, " Content-Range: %s\n", - soup_message_headers_get (headers, "Content-Range")); + soup_message_headers_get_one (headers, "Content-Range")); if (!soup_message_headers_get_content_range (headers, &start, &end, &total_length)) { debug_printf (1, " Could not find/parse Content-Range\n"); @@ -91,7 +91,7 @@ do_single_range (SoupSession *session, SoupMessage *msg, const char *content_type; debug_printf (1, " Range: %s\n", - soup_message_headers_get (msg->request_headers, "Range")); + soup_message_headers_get_one (msg->request_headers, "Range")); soup_session_send_message (session, msg); @@ -137,7 +137,7 @@ do_multi_range (SoupSession *session, SoupMessage *msg, int i, length; debug_printf (1, " Range: %s\n", - soup_message_headers_get (msg->request_headers, "Range")); + soup_message_headers_get_one (msg->request_headers, "Range")); soup_session_send_message (session, msg); diff --git a/tests/redirect-test.c b/tests/redirect-test.c index 7cada959..9d5d9b86 100644 --- a/tests/redirect-test.c +++ b/tests/redirect-test.c @@ -111,7 +111,8 @@ got_headers (SoupMessage *msg, gpointer user_data) debug_printf (2, " -> %d %s\n", msg->status_code, msg->reason_phrase); - location = soup_message_headers_get (msg->response_headers, "Location"); + location = soup_message_headers_get_one (msg->response_headers, + "Location"); if (location) debug_printf (2, " Location: %s\n", location); diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c index 72f6f7cb..e4c84bdc 100644 --- a/tests/server-auth-test.c +++ b/tests/server-auth-test.c @@ -282,8 +282,8 @@ got_headers_callback (SoupMessage *msg, gpointer data) { const char *header; - header = soup_message_headers_get (msg->request_headers, - "Authorization"); + header = soup_message_headers_get_one (msg->request_headers, + "Authorization"); if (header) { if (strstr (header, "Basic ")) test_data.client_sent_basic = TRUE; @@ -297,8 +297,8 @@ wrote_headers_callback (SoupMessage *msg, gpointer data) { const char *header; - header = soup_message_headers_get (msg->response_headers, - "WWW-Authenticate"); + header = soup_message_headers_get_list (msg->response_headers, + "WWW-Authenticate"); if (header) { if (strstr (header, "Basic ")) test_data.server_requested_basic = TRUE; diff --git a/tests/simple-httpd.c b/tests/simple-httpd.c index 7425f7a5..b63ad04a 100644 --- a/tests/simple-httpd.c +++ b/tests/simple-httpd.c @@ -191,7 +191,7 @@ do_put (SoupServer *server, SoupMessage *msg, const char *path) gboolean created = TRUE; if (stat (path, &st) != -1) { - const char *match = soup_message_headers_get (msg->request_headers, "If-None-Match"); + const char *match = soup_message_headers_get_one (msg->request_headers, "If-None-Match"); if (match && !strcmp (match, "*")) { soup_message_set_status (msg, SOUP_STATUS_CONFLICT); return; |