|
Packit Service |
ca3877 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
Packit Service |
ca3877 |
/*
|
|
Packit Service |
ca3877 |
* soup-message-headers.c: HTTP message header arrays
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Copyright (C) 2007, 2008 Red Hat, Inc.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
ca3877 |
#include <config.h>
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include <string.h>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include "soup-message-headers.h"
|
|
Packit Service |
ca3877 |
#include "soup.h"
|
|
Packit Service |
ca3877 |
#include "soup-misc-private.h"
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SECTION:soup-message-headers
|
|
Packit Service |
ca3877 |
* @short_description: HTTP message headers
|
|
Packit Service |
ca3877 |
* @see_also: #SoupMessage
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* #SoupMessageHeaders represents the HTTP message headers associated
|
|
Packit Service |
ca3877 |
* with a request or response.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMessageHeaders:
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* The HTTP message headers associated with a request or response.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMessageHeadersType:
|
|
Packit Service |
ca3877 |
* @SOUP_MESSAGE_HEADERS_REQUEST: request headers
|
|
Packit Service |
ca3877 |
* @SOUP_MESSAGE_HEADERS_RESPONSE: response headers
|
|
Packit Service |
ca3877 |
* @SOUP_MESSAGE_HEADERS_MULTIPART: multipart body part headers
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Value passed to soup_message_headers_new() to set certain default
|
|
Packit Service |
ca3877 |
* behaviors.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef void (*SoupHeaderSetter) (SoupMessageHeaders *, const char *);
|
|
Packit Service |
ca3877 |
static const char *intern_header_name (const char *name, SoupHeaderSetter *setter);
|
|
Packit Service |
ca3877 |
static void clear_special_headers (SoupMessageHeaders *hdrs);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
const char *name;
|
|
Packit Service |
ca3877 |
char *value;
|
|
Packit Service |
ca3877 |
} SoupHeader;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
struct SoupMessageHeaders {
|
|
Packit Service |
ca3877 |
GArray *array;
|
|
Packit Service |
ca3877 |
GHashTable *concat;
|
|
Packit Service |
ca3877 |
SoupMessageHeadersType type;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
SoupEncoding encoding;
|
|
Packit Service |
ca3877 |
goffset content_length;
|
|
Packit Service |
ca3877 |
SoupExpectation expectations;
|
|
Packit Service |
ca3877 |
char *content_type;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
int ref_count;
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_new:
|
|
Packit Service |
ca3877 |
* @type: the type of headers
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a #SoupMessageHeaders. (#SoupMessage does this
|
|
Packit Service |
ca3877 |
* automatically for its own headers. You would only need to use this
|
|
Packit Service |
ca3877 |
* method if you are manually parsing or generating message headers.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a new #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupMessageHeaders *
|
|
Packit Service |
ca3877 |
soup_message_headers_new (SoupMessageHeadersType type)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageHeaders *hdrs;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
hdrs = g_slice_new0 (SoupMessageHeaders);
|
|
Packit Service |
ca3877 |
/* FIXME: is "5" a good default? */
|
|
Packit Service |
ca3877 |
hdrs->array = g_array_sized_new (TRUE, FALSE, sizeof (SoupHeader), 5);
|
|
Packit Service |
ca3877 |
hdrs->type = type;
|
|
Packit Service |
ca3877 |
hdrs->encoding = -1;
|
|
Packit Service |
ca3877 |
hdrs->ref_count = 1;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return hdrs;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static SoupMessageHeaders *
|
|
Packit Service |
ca3877 |
soup_message_headers_copy (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_atomic_int_inc (&hdrs->ref_count);
|
|
Packit Service |
ca3877 |
return hdrs;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_free:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Frees @hdrs.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_free (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (!g_atomic_int_dec_and_test (&hdrs->ref_count))
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_message_headers_clear (hdrs);
|
|
Packit Service |
ca3877 |
g_array_free (hdrs->array, TRUE);
|
|
Packit Service |
ca3877 |
g_clear_pointer (&hdrs->concat, g_hash_table_destroy);
|
|
Packit Service |
ca3877 |
g_slice_free (SoupMessageHeaders, hdrs);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_BOXED_TYPE (SoupMessageHeaders, soup_message_headers, soup_message_headers_copy, soup_message_headers_free)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_headers_type:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the type of headers.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the header's type.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.50
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupMessageHeadersType
|
|
Packit Service |
ca3877 |
soup_message_headers_get_headers_type (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return hdrs->type;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_clear:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Clears @hdrs.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_clear (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)hdrs->array->data;
|
|
Packit Service |
ca3877 |
guint i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
for (i = 0; i < hdrs->array->len; i++)
|
|
Packit Service |
ca3877 |
g_free (hdr_array[i].value);
|
|
Packit Service |
ca3877 |
g_array_set_size (hdrs->array, 0);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (hdrs->concat)
|
|
Packit Service |
ca3877 |
g_hash_table_remove_all (hdrs->concat);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
clear_special_headers (hdrs);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_clean_connection_headers:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Removes all the headers listed in the Connection header.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.36
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_clean_connection_headers (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* RFC 2616 14.10 */
|
|
Packit Service |
ca3877 |
const char *connection;
|
|
Packit Service |
ca3877 |
GSList *tokens, *t;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
connection = soup_message_headers_get_list (hdrs, "Connection");
|
|
Packit Service |
ca3877 |
if (!connection)
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
tokens = soup_header_parse_list (connection);
|
|
Packit Service |
ca3877 |
for (t = tokens; t; t = t->next)
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, t->data);
|
|
Packit Service |
ca3877 |
soup_header_free_list (tokens);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_append:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: the header name to add
|
|
Packit Service |
ca3877 |
* @value: the new value of @name
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Appends a new header with name @name and value @value to @hdrs. (If
|
|
Packit Service |
ca3877 |
* there is an existing header with name @name, then this creates a
|
|
Packit Service |
ca3877 |
* second one, which is only allowed for list-valued headers; see also
|
|
Packit Service |
ca3877 |
* soup_message_headers_replace().)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* The caller is expected to make sure that @name and @value are
|
|
Packit Service |
ca3877 |
* syntactically correct.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_append (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
const char *name, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader header;
|
|
Packit Service |
ca3877 |
SoupHeaderSetter setter;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_if_fail (name != NULL);
|
|
Packit Service |
ca3877 |
g_return_if_fail (value != NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Setting a syntactically invalid header name or value is
|
|
Packit Service |
ca3877 |
* considered to be a programming error. However, it can also
|
|
Packit Service |
ca3877 |
* be a security hole, so we want to fail here even if
|
|
Packit Service |
ca3877 |
* compiled with G_DISABLE_CHECKS.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
#ifndef G_DISABLE_CHECKS
|
|
Packit Service |
ca3877 |
g_return_if_fail (*name && strpbrk (name, " \t\r\n:") == NULL);
|
|
Packit Service |
ca3877 |
g_return_if_fail (strpbrk (value, "\r\n") == NULL);
|
|
Packit Service |
ca3877 |
#else
|
|
Packit Service |
ca3877 |
if (*name && strpbrk (name, " \t\r\n:")) {
|
|
Packit Service |
ca3877 |
g_warning ("soup_message_headers_append: Ignoring bad name '%s'", name);
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
if (strpbrk (value, "\r\n")) {
|
|
Packit Service |
ca3877 |
g_warning ("soup_message_headers_append: Ignoring bad value '%s'", value);
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
header.name = intern_header_name (name, &setter);
|
|
Packit Service |
ca3877 |
header.value = g_strdup (value);
|
|
Packit Service |
ca3877 |
g_array_append_val (hdrs->array, header);
|
|
Packit Service |
ca3877 |
if (hdrs->concat)
|
|
Packit Service |
ca3877 |
g_hash_table_remove (hdrs->concat, header.name);
|
|
Packit Service |
ca3877 |
if (setter)
|
|
Packit Service |
ca3877 |
setter (hdrs, header.value);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_replace:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: the header name to replace
|
|
Packit Service |
ca3877 |
* @value: the new value of @name
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Replaces the value of the header @name in @hdrs with @value. (See
|
|
Packit Service |
ca3877 |
* also soup_message_headers_append().)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* The caller is expected to make sure that @name and @value are
|
|
Packit Service |
ca3877 |
* syntactically correct.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
const char *name, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, name);
|
|
Packit Service |
ca3877 |
soup_message_headers_append (hdrs, name, value);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static int
|
|
Packit Service |
ca3877 |
find_header (SoupHeader *hdr_array, const char *interned_name, int nth)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
int i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
for (i = 0; hdr_array[i].name; i++) {
|
|
Packit Service |
ca3877 |
if (hdr_array[i].name == interned_name) {
|
|
Packit Service |
ca3877 |
if (nth-- == 0)
|
|
Packit Service |
ca3877 |
return i;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static int
|
|
Packit Service |
ca3877 |
find_last_header (SoupHeader *hdr_array, guint length, const char *interned_name, int nth)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
int i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
for (i = length; i >= 0; i--) {
|
|
Packit Service |
ca3877 |
if (hdr_array[i].name == interned_name) {
|
|
Packit Service |
ca3877 |
if (nth-- == 0)
|
|
Packit Service |
ca3877 |
return i;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_remove:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: the header name to remove
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Removes @name from @hdrs. If there are multiple values for @name,
|
|
Packit Service |
ca3877 |
* they are all removed.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (SoupMessageHeaders *hdrs, const char *name)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)(hdrs->array->data);
|
|
Packit Service |
ca3877 |
SoupHeaderSetter setter;
|
|
Packit Service |
ca3877 |
int index;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_if_fail (name != NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
name = intern_header_name (name, &setter);
|
|
Packit Service |
ca3877 |
while ((index = find_header (hdr_array, name, 0)) != -1) {
|
|
Packit Service |
ca3877 |
g_free (hdr_array[index].value);
|
|
Packit Service |
ca3877 |
g_array_remove_index (hdrs->array, index);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
if (hdrs->concat)
|
|
Packit Service |
ca3877 |
g_hash_table_remove (hdrs->concat, name);
|
|
Packit Service |
ca3877 |
if (setter)
|
|
Packit Service |
ca3877 |
setter (hdrs, NULL);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_one:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: header name
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the value of header @name in @hdrs. Use this for headers whose
|
|
Packit Service |
ca3877 |
* values are <emphasis>not</emphasis> comma-delimited lists, and
|
|
Packit Service |
ca3877 |
* which therefore can only appear at most once in the headers. For
|
|
Packit Service |
ca3877 |
* list-valued headers, use soup_message_headers_get_list().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @hdrs does erroneously contain multiple copies of the header, it
|
|
Packit Service |
ca3877 |
* is not defined which one will be returned. (Ideally, it will return
|
|
Packit Service |
ca3877 |
* whichever one makes libsoup most compatible with other HTTP
|
|
Packit Service |
ca3877 |
* implementations.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): the header's value or %NULL if not found.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.28
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
const char *
|
|
Packit Service |
ca3877 |
soup_message_headers_get_one (SoupMessageHeaders *hdrs, const char *name)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)(hdrs->array->data);
|
|
Packit Service |
ca3877 |
guint hdr_length = hdrs->array->len;
|
|
Packit Service |
ca3877 |
int index;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (name != NULL, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
name = intern_header_name (name, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
index = find_last_header (hdr_array, hdr_length, name, 0);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return (index == -1) ? NULL : hdr_array[index].value;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_header_contains:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: header name
|
|
Packit Service |
ca3877 |
* @token: token to look for
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Checks whether the list-valued header @name is present in @hdrs,
|
|
Packit Service |
ca3877 |
* and contains a case-insensitive match for @token.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* (If @name is present in @hdrs, then this is equivalent to calling
|
|
Packit Service |
ca3877 |
* soup_header_contains() on its value.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if the header is present and contains @token,
|
|
Packit Service |
ca3877 |
* %FALSE otherwise.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.50
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_header_contains (SoupMessageHeaders *hdrs, const char *name, const char *token)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
value = soup_message_headers_get_list (hdrs, name);
|
|
Packit Service |
ca3877 |
if (!value)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
return soup_header_contains (value, token);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_header_equals:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: header name
|
|
Packit Service |
ca3877 |
* @value: expected value
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Checks whether the header @name is present in @hdrs and is
|
|
Packit Service |
ca3877 |
* (case-insensitively) equal to @value.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if the header is present and its value is
|
|
Packit Service |
ca3877 |
* @value, %FALSE otherwise.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.50
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_header_equals (SoupMessageHeaders *hdrs, const char *name, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *internal_value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
internal_value = soup_message_headers_get_list (hdrs, name);
|
|
Packit Service |
ca3877 |
if (!internal_value)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
return !g_ascii_strcasecmp (internal_value, value);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_list:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: header name
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the value of header @name in @hdrs. Use this for headers whose
|
|
Packit Service |
ca3877 |
* values are comma-delimited lists, and which are therefore allowed
|
|
Packit Service |
ca3877 |
* to appear multiple times in the headers. For non-list-valued
|
|
Packit Service |
ca3877 |
* headers, use soup_message_headers_get_one().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @name appears multiple times in @hdrs,
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_list() will concatenate all of the values
|
|
Packit Service |
ca3877 |
* together, separated by commas. This is sometimes awkward to parse
|
|
Packit Service |
ca3877 |
* (eg, WWW-Authenticate, Set-Cookie), but you have to be able to deal
|
|
Packit Service |
ca3877 |
* with it anyway, because the HTTP spec explicitly states that this
|
|
Packit Service |
ca3877 |
* transformation is allowed, and so an upstream proxy could do the
|
|
Packit Service |
ca3877 |
* same thing.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): the header's value or %NULL if not found.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.28
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
const char *
|
|
Packit Service |
ca3877 |
soup_message_headers_get_list (SoupMessageHeaders *hdrs, const char *name)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)(hdrs->array->data);
|
|
Packit Service |
ca3877 |
GString *concat;
|
|
Packit Service |
ca3877 |
char *value;
|
|
Packit Service |
ca3877 |
int index, i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (name != NULL, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
name = intern_header_name (name, NULL);
|
|
Packit Service |
ca3877 |
if (hdrs->concat) {
|
|
Packit Service |
ca3877 |
value = g_hash_table_lookup (hdrs->concat, name);
|
|
Packit Service |
ca3877 |
if (value)
|
|
Packit Service |
ca3877 |
return value;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
index = find_header (hdr_array, name, 0);
|
|
Packit Service |
ca3877 |
if (index == -1)
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
else if (find_header (hdr_array, name, 1) == -1)
|
|
Packit Service |
ca3877 |
return hdr_array[index].value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
concat = g_string_new (NULL);
|
|
Packit Service |
ca3877 |
for (i = 0; (index = find_header (hdr_array, name, i)) != -1; i++) {
|
|
Packit Service |
ca3877 |
if (i != 0)
|
|
Packit Service |
ca3877 |
g_string_append (concat, ", ");
|
|
Packit Service |
ca3877 |
g_string_append (concat, hdr_array[index].value);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
value = g_string_free (concat, FALSE);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!hdrs->concat)
|
|
Packit Service |
ca3877 |
hdrs->concat = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (hdrs->concat, (gpointer)name, value);
|
|
Packit Service |
ca3877 |
return value;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @name: header name
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the value of header @name in @hdrs.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This method was supposed to work correctly for both single-valued
|
|
Packit Service |
ca3877 |
* and list-valued headers, but because some HTTP clients/servers
|
|
Packit Service |
ca3877 |
* mistakenly send multiple copies of headers that are supposed to be
|
|
Packit Service |
ca3877 |
* single-valued, it sometimes returns incorrect results. To fix this,
|
|
Packit Service |
ca3877 |
* the methods soup_message_headers_get_one() and
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_list() were introduced, so callers can
|
|
Packit Service |
ca3877 |
* explicitly state which behavior they are expecting.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): as with soup_message_headers_get_list().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Deprecated: Use soup_message_headers_get_one() or
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_list() instead.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
const char *
|
|
Packit Service |
ca3877 |
soup_message_headers_get (SoupMessageHeaders *hdrs, const char *name)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return soup_message_headers_get_list (hdrs, name);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMessageHeadersIter:
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* An opaque type used to iterate over a %SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* structure.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* After intializing the iterator with
|
|
Packit Service |
ca3877 |
* soup_message_headers_iter_init(), call
|
|
Packit Service |
ca3877 |
* soup_message_headers_iter_next() to fetch data from it.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* You may not modify the headers while iterating over them.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
SoupMessageHeaders *hdrs;
|
|
Packit Service |
ca3877 |
int index;
|
|
Packit Service |
ca3877 |
} SoupMessageHeadersIterReal;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_iter_init:
|
|
Packit Service |
ca3877 |
* @iter: (out) (transfer none): a pointer to a %SoupMessageHeadersIter
|
|
Packit Service |
ca3877 |
* structure
|
|
Packit Service |
ca3877 |
* @hdrs: a %SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Initializes @iter for iterating @hdrs.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_iter_init (SoupMessageHeadersIter *iter,
|
|
Packit Service |
ca3877 |
SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageHeadersIterReal *real = (SoupMessageHeadersIterReal *)iter;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
real->hdrs = hdrs;
|
|
Packit Service |
ca3877 |
real->index = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_iter_next:
|
|
Packit Service |
ca3877 |
* @iter: (inout) (transfer none): a %SoupMessageHeadersIter
|
|
Packit Service |
ca3877 |
* @name: (out) (transfer none): pointer to a variable to return
|
|
Packit Service |
ca3877 |
* the header name in
|
|
Packit Service |
ca3877 |
* @value: (out) (transfer none): pointer to a variable to return
|
|
Packit Service |
ca3877 |
* the header value in
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Yields the next name/value pair in the %SoupMessageHeaders being
|
|
Packit Service |
ca3877 |
* iterated by @iter. If @iter has already yielded the last header,
|
|
Packit Service |
ca3877 |
* then soup_message_headers_iter_next() will return %FALSE and @name
|
|
Packit Service |
ca3877 |
* and @value will be unchanged.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if another name and value were returned, %FALSE
|
|
Packit Service |
ca3877 |
* if the end of the headers has been reached.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_iter_next (SoupMessageHeadersIter *iter,
|
|
Packit Service |
ca3877 |
const char **name, const char **value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupMessageHeadersIterReal *real = (SoupMessageHeadersIterReal *)iter;
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)real->hdrs->array->data;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (real->index >= real->hdrs->array->len)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
*name = hdr_array[real->index].name;
|
|
Packit Service |
ca3877 |
*value = hdr_array[real->index].value;
|
|
Packit Service |
ca3877 |
real->index++;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupMessageHeadersForeachFunc:
|
|
Packit Service |
ca3877 |
* @name: the header name
|
|
Packit Service |
ca3877 |
* @value: the header value
|
|
Packit Service |
ca3877 |
* @user_data: the data passed to soup_message_headers_foreach()
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* The callback passed to soup_message_headers_foreach().
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_foreach:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @func: (scope call): callback function to run for each header
|
|
Packit Service |
ca3877 |
* @user_data: data to pass to @func
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Calls @func once for each header value in @hdrs.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Beware that unlike soup_message_headers_get(), this processes the
|
|
Packit Service |
ca3877 |
* headers in exactly the way they were added, rather than
|
|
Packit Service |
ca3877 |
* concatenating multiple same-named headers into a single value.
|
|
Packit Service |
ca3877 |
* (This is intentional; it ensures that if you call
|
|
Packit Service |
ca3877 |
* soup_message_headers_append() multiple times with the same name,
|
|
Packit Service |
ca3877 |
* then the I/O code will output multiple copies of the header when
|
|
Packit Service |
ca3877 |
* sending the message to the remote implementation, which may be
|
|
Packit Service |
ca3877 |
* required for interoperability in some cases.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* You may not modify the headers from @func.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_foreach (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
SoupMessageHeadersForeachFunc func,
|
|
Packit Service |
ca3877 |
gpointer user_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeader *hdr_array = (SoupHeader *)hdrs->array->data;
|
|
Packit Service |
ca3877 |
guint i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
for (i = 0; i < hdrs->array->len; i++)
|
|
Packit Service |
ca3877 |
func (hdr_array[i].name, hdr_array[i].value, user_data);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_LOCK_DEFINE_STATIC (header_pool);
|
|
Packit Service |
ca3877 |
static GHashTable *header_pool, *header_setters;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void transfer_encoding_setter (SoupMessageHeaders *, const char *);
|
|
Packit Service |
ca3877 |
static void content_length_setter (SoupMessageHeaders *, const char *);
|
|
Packit Service |
ca3877 |
static void expectation_setter (SoupMessageHeaders *, const char *);
|
|
Packit Service |
ca3877 |
static void content_type_setter (SoupMessageHeaders *, const char *);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static char *
|
|
Packit Service |
ca3877 |
intern_header_locked (const char *name)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char *interned;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
interned = g_hash_table_lookup (header_pool, name);
|
|
Packit Service |
ca3877 |
if (!interned) {
|
|
Packit Service |
ca3877 |
char *dup = g_strdup (name);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (header_pool, dup, dup);
|
|
Packit Service |
ca3877 |
interned = dup;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return interned;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static const char *
|
|
Packit Service |
ca3877 |
intern_header_name (const char *name, SoupHeaderSetter *setter)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *interned;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_LOCK (header_pool);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!header_pool) {
|
|
Packit Service |
ca3877 |
header_pool = g_hash_table_new (soup_str_case_hash, soup_str_case_equal);
|
|
Packit Service |
ca3877 |
header_setters = g_hash_table_new (NULL, NULL);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (header_setters,
|
|
Packit Service |
ca3877 |
intern_header_locked ("Transfer-Encoding"),
|
|
Packit Service |
ca3877 |
transfer_encoding_setter);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (header_setters,
|
|
Packit Service |
ca3877 |
intern_header_locked ("Content-Length"),
|
|
Packit Service |
ca3877 |
content_length_setter);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (header_setters,
|
|
Packit Service |
ca3877 |
intern_header_locked ("Expect"),
|
|
Packit Service |
ca3877 |
expectation_setter);
|
|
Packit Service |
ca3877 |
g_hash_table_insert (header_setters,
|
|
Packit Service |
ca3877 |
intern_header_locked ("Content-Type"),
|
|
Packit Service |
ca3877 |
content_type_setter);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
interned = intern_header_locked (name);
|
|
Packit Service |
ca3877 |
if (setter)
|
|
Packit Service |
ca3877 |
*setter = g_hash_table_lookup (header_setters, interned);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_UNLOCK (header_pool);
|
|
Packit Service |
ca3877 |
return interned;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
clear_special_headers (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupHeaderSetter setter;
|
|
Packit Service |
ca3877 |
GHashTableIter iter;
|
|
Packit Service |
ca3877 |
gpointer key, value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Make sure header_setters has been initialized */
|
|
Packit Service |
ca3877 |
intern_header_name ("", NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_hash_table_iter_init (&iter, header_setters);
|
|
Packit Service |
ca3877 |
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
Packit Service |
ca3877 |
setter = value;
|
|
Packit Service |
ca3877 |
setter (hdrs, NULL);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Specific headers */
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
transfer_encoding_setter (SoupMessageHeaders *hdrs, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (value) {
|
|
Packit Service |
ca3877 |
if (g_ascii_strcasecmp (value, "chunked") == 0)
|
|
Packit Service |
ca3877 |
hdrs->encoding = SOUP_ENCODING_CHUNKED;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
hdrs->encoding = -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
content_length_setter (SoupMessageHeaders *hdrs, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* Transfer-Encoding trumps Content-Length */
|
|
Packit Service |
ca3877 |
if (hdrs->encoding == SOUP_ENCODING_CHUNKED)
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (value) {
|
|
Packit Service |
ca3877 |
char *end;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
hdrs->content_length = g_ascii_strtoull (value, &end, 10);
|
|
Packit Service |
ca3877 |
if (*end)
|
|
Packit Service |
ca3877 |
hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
hdrs->encoding = -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupEncoding:
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_UNRECOGNIZED: unknown / error
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_NONE: no body is present (which is not the same as a
|
|
Packit Service |
ca3877 |
* 0-length body, and only occurs in certain places)
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_CONTENT_LENGTH: Content-Length encoding
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_EOF: Response body ends when the connection is closed
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_CHUNKED: chunked encoding (currently only supported
|
|
Packit Service |
ca3877 |
* for response)
|
|
Packit Service |
ca3877 |
* @SOUP_ENCODING_BYTERANGES: multipart/byteranges (Reserved for future
|
|
Packit Service |
ca3877 |
* use: NOT CURRENTLY IMPLEMENTED)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* How a message body is encoded for transport
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_encoding:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the message body encoding that @hdrs declare. This may not
|
|
Packit Service |
ca3877 |
* always correspond to the encoding used on the wire; eg, a HEAD
|
|
Packit Service |
ca3877 |
* response may declare a Content-Length or Transfer-Encoding, but
|
|
Packit Service |
ca3877 |
* it will never actually include a body.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the encoding declared by @hdrs.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupEncoding
|
|
Packit Service |
ca3877 |
soup_message_headers_get_encoding (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *header;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (hdrs->encoding != -1)
|
|
Packit Service |
ca3877 |
return hdrs->encoding;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* If Transfer-Encoding was set, hdrs->encoding would already
|
|
Packit Service |
ca3877 |
* be set. So we don't need to check that possibility.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
header = soup_message_headers_get_one (hdrs, "Content-Length");
|
|
Packit Service |
ca3877 |
if (header) {
|
|
Packit Service |
ca3877 |
content_length_setter (hdrs, header);
|
|
Packit Service |
ca3877 |
if (hdrs->encoding != -1)
|
|
Packit Service |
ca3877 |
return hdrs->encoding;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Per RFC 2616 4.4, a response body that doesn't indicate its
|
|
Packit Service |
ca3877 |
* encoding otherwise is terminated by connection close, and a
|
|
Packit Service |
ca3877 |
* request that doesn't indicate otherwise has no body. Note
|
|
Packit Service |
ca3877 |
* that SoupMessage calls soup_message_headers_set_encoding()
|
|
Packit Service |
ca3877 |
* to override the response body default for our own
|
|
Packit Service |
ca3877 |
* server-side messages.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ?
|
|
Packit Service |
ca3877 |
SOUP_ENCODING_EOF : SOUP_ENCODING_NONE;
|
|
Packit Service |
ca3877 |
return hdrs->encoding;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_encoding:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @encoding: a #SoupEncoding
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets the message body encoding that @hdrs will declare. In particular,
|
|
Packit Service |
ca3877 |
* you should use this if you are going to send a request or response in
|
|
Packit Service |
ca3877 |
* chunked encoding.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_encoding (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
SoupEncoding encoding)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (encoding == hdrs->encoding)
|
|
Packit Service |
ca3877 |
return;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
switch (encoding) {
|
|
Packit Service |
ca3877 |
case SOUP_ENCODING_NONE:
|
|
Packit Service |
ca3877 |
case SOUP_ENCODING_EOF:
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Transfer-Encoding");
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Content-Length");
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
case SOUP_ENCODING_CONTENT_LENGTH:
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Transfer-Encoding");
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
case SOUP_ENCODING_CHUNKED:
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Content-Length");
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, "Transfer-Encoding", "chunked");
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
default:
|
|
Packit Service |
ca3877 |
g_return_if_reached ();
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
hdrs->encoding = encoding;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_content_length:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the message body length that @hdrs declare. This will only
|
|
Packit Service |
ca3877 |
* be non-0 if soup_message_headers_get_encoding() returns
|
|
Packit Service |
ca3877 |
* %SOUP_ENCODING_CONTENT_LENGTH.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the message body length declared by @hdrs.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
goffset
|
|
Packit Service |
ca3877 |
soup_message_headers_get_content_length (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupEncoding encoding;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
encoding = soup_message_headers_get_encoding (hdrs);
|
|
Packit Service |
ca3877 |
if (encoding == SOUP_ENCODING_CONTENT_LENGTH)
|
|
Packit Service |
ca3877 |
return hdrs->content_length;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
return 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_content_length:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @content_length: the message body length
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets the message body length that @hdrs will declare, and sets
|
|
Packit Service |
ca3877 |
* @hdrs's encoding to %SOUP_ENCODING_CONTENT_LENGTH.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* You do not normally need to call this; if @hdrs is set to use
|
|
Packit Service |
ca3877 |
* Content-Length encoding, libsoup will automatically set its
|
|
Packit Service |
ca3877 |
* Content-Length header for you immediately before sending the
|
|
Packit Service |
ca3877 |
* headers. One situation in which this method is useful is when
|
|
Packit Service |
ca3877 |
* generating the response to a HEAD request; Calling
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_content_length() allows you to put the
|
|
Packit Service |
ca3877 |
* correct content length into the response without needing to waste
|
|
Packit Service |
ca3877 |
* memory by filling in a response body which won't actually be sent.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_content_length (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset content_length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char length[128];
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_snprintf (length, sizeof (length), "%" G_GUINT64_FORMAT,
|
|
Packit Service |
ca3877 |
content_length);
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Transfer-Encoding");
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, "Content-Length", length);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
expectation_setter (SoupMessageHeaders *hdrs, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (value) {
|
|
Packit Service |
ca3877 |
if (!g_ascii_strcasecmp (value, "100-continue"))
|
|
Packit Service |
ca3877 |
hdrs->expectations = SOUP_EXPECTATION_CONTINUE;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
hdrs->expectations = SOUP_EXPECTATION_UNRECOGNIZED;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
hdrs->expectations = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupExpectation:
|
|
Packit Service |
ca3877 |
* @SOUP_EXPECTATION_CONTINUE: "100-continue"
|
|
Packit Service |
ca3877 |
* @SOUP_EXPECTATION_UNRECOGNIZED: any unrecognized expectation
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Represents the parsed value of the "Expect" header.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_expectations:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets the expectations declared by @hdrs's "Expect" header.
|
|
Packit Service |
ca3877 |
* Currently this will either be %SOUP_EXPECTATION_CONTINUE or
|
|
Packit Service |
ca3877 |
* %SOUP_EXPECTATION_UNRECOGNIZED.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: the contents of @hdrs's "Expect" header
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupExpectation
|
|
Packit Service |
ca3877 |
soup_message_headers_get_expectations (SoupMessageHeaders *hdrs)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return hdrs->expectations;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_expectations:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @expectations: the expectations to set
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets @hdrs's "Expect" header according to @expectations.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Currently %SOUP_EXPECTATION_CONTINUE is the only known expectation
|
|
Packit Service |
ca3877 |
* value. You should set this value on a request if you are sending a
|
|
Packit Service |
ca3877 |
* large message body (eg, via POST or PUT), and want to give the
|
|
Packit Service |
ca3877 |
* server a chance to reject the request after seeing just the headers
|
|
Packit Service |
ca3877 |
* (eg, because it will require authentication before allowing you to
|
|
Packit Service |
ca3877 |
* post, or because you're POSTing to a URL that doesn't exist). This
|
|
Packit Service |
ca3877 |
* saves you from having to transmit the large request body when the
|
|
Packit Service |
ca3877 |
* server is just going to ignore it anyway.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_expectations (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
SoupExpectation expectations)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_if_fail ((expectations & ~SOUP_EXPECTATION_CONTINUE) == 0);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (expectations & SOUP_EXPECTATION_CONTINUE)
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, "Expect", "100-continue");
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
soup_message_headers_remove (hdrs, "Expect");
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupRange:
|
|
Packit Service |
ca3877 |
* @start: the start of the range
|
|
Packit Service |
ca3877 |
* @end: the end of the range
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Represents a byte range as used in the Range header.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @end is non-negative, then @start and @end represent the bounds
|
|
Packit Service |
ca3877 |
* of of the range, counting from 0. (Eg, the first 500 bytes would be
|
|
Packit Service |
ca3877 |
* represented as @start = 0 and @end = 499.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @end is -1 and @start is non-negative, then this represents a
|
|
Packit Service |
ca3877 |
* range starting at @start and ending with the last byte of the
|
|
Packit Service |
ca3877 |
* requested resource body. (Eg, all but the first 500 bytes would be
|
|
Packit Service |
ca3877 |
* @start = 500, and @end = -1.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @end is -1 and @start is negative, then it represents a "suffix
|
|
Packit Service |
ca3877 |
* range", referring to the last -@start bytes of the resource body.
|
|
Packit Service |
ca3877 |
* (Eg, the last 500 bytes would be @start = -500 and @end = -1.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static int
|
|
Packit Service |
ca3877 |
sort_ranges (gconstpointer a, gconstpointer b)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupRange *ra = (SoupRange *)a;
|
|
Packit Service |
ca3877 |
SoupRange *rb = (SoupRange *)b;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return ra->start - rb->start;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* like soup_message_headers_get_ranges(), except it returns:
|
|
Packit Service |
ca3877 |
* SOUP_STATUS_OK if there is no Range or it should be ignored.
|
|
Packit Service |
ca3877 |
* SOUP_STATUS_PARTIAL_CONTENT if there is at least one satisfiable range.
|
|
Packit Service |
ca3877 |
* SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE if @check_satisfiable
|
|
Packit Service |
ca3877 |
* is %TRUE and the request is not satisfiable given @total_length.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
guint
|
|
Packit Service |
ca3877 |
soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset total_length,
|
|
Packit Service |
ca3877 |
gboolean check_satisfiable,
|
|
Packit Service |
ca3877 |
SoupRange **ranges,
|
|
Packit Service |
ca3877 |
int *length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *range = soup_message_headers_get_one (hdrs, "Range");
|
|
Packit Service |
ca3877 |
GSList *range_list, *r;
|
|
Packit Service |
ca3877 |
GArray *array;
|
|
Packit Service |
ca3877 |
char *spec, *end;
|
|
Packit Service |
ca3877 |
guint status = SOUP_STATUS_OK;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!range || strncmp (range, "bytes", 5) != 0)
|
|
Packit Service |
ca3877 |
return status;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
range += 5;
|
|
Packit Service |
ca3877 |
while (g_ascii_isspace (*range))
|
|
Packit Service |
ca3877 |
range++;
|
|
Packit Service |
ca3877 |
if (*range++ != '=')
|
|
Packit Service |
ca3877 |
return status;
|
|
Packit Service |
ca3877 |
while (g_ascii_isspace (*range))
|
|
Packit Service |
ca3877 |
range++;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
range_list = soup_header_parse_list (range);
|
|
Packit Service |
ca3877 |
if (!range_list)
|
|
Packit Service |
ca3877 |
return status;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
array = g_array_new (FALSE, FALSE, sizeof (SoupRange));
|
|
Packit Service |
ca3877 |
for (r = range_list; r; r = r->next) {
|
|
Packit Service |
ca3877 |
SoupRange cur;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
spec = r->data;
|
|
Packit Service |
ca3877 |
if (*spec == '-') {
|
|
Packit Service |
ca3877 |
cur.start = g_ascii_strtoll (spec, &end, 10) + total_length;
|
|
Packit Service |
ca3877 |
cur.end = total_length - 1;
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
cur.start = g_ascii_strtoull (spec, &end, 10);
|
|
Packit Service |
ca3877 |
if (*end == '-')
|
|
Packit Service |
ca3877 |
end++;
|
|
Packit Service |
ca3877 |
if (*end) {
|
|
Packit Service |
ca3877 |
cur.end = g_ascii_strtoull (end, &end, 10);
|
|
Packit Service |
ca3877 |
if (cur.end < cur.start) {
|
|
Packit Service |
ca3877 |
status = SOUP_STATUS_OK;
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
cur.end = total_length - 1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
if (*end) {
|
|
Packit Service |
ca3877 |
status = SOUP_STATUS_OK;
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
} else if (check_satisfiable && cur.start >= total_length) {
|
|
Packit Service |
ca3877 |
if (status == SOUP_STATUS_OK)
|
|
Packit Service |
ca3877 |
status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE;
|
|
Packit Service |
ca3877 |
continue;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_array_append_val (array, cur);
|
|
Packit Service |
ca3877 |
status = SOUP_STATUS_PARTIAL_CONTENT;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
soup_header_free_list (range_list);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (status != SOUP_STATUS_PARTIAL_CONTENT) {
|
|
Packit Service |
ca3877 |
g_array_free (array, TRUE);
|
|
Packit Service |
ca3877 |
return status;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (total_length) {
|
|
Packit Service |
ca3877 |
guint i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_array_sort (array, sort_ranges);
|
|
Packit Service |
ca3877 |
for (i = 1; i < array->len; i++) {
|
|
Packit Service |
ca3877 |
SoupRange *cur = &((SoupRange *)array->data)[i];
|
|
Packit Service |
ca3877 |
SoupRange *prev = &((SoupRange *)array->data)[i - 1];
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (cur->start <= prev->end) {
|
|
Packit Service |
ca3877 |
prev->end = MAX (prev->end, cur->end);
|
|
Packit Service |
ca3877 |
g_array_remove_index (array, i);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
*ranges = (SoupRange *)array->data;
|
|
Packit Service |
ca3877 |
*length = array->len;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_array_free (array, FALSE);
|
|
Packit Service |
ca3877 |
return SOUP_STATUS_PARTIAL_CONTENT;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_ranges:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @total_length: the total_length of the response body
|
|
Packit Service |
ca3877 |
* @ranges: (out) (array length=length): return location for an array
|
|
Packit Service |
ca3877 |
* of #SoupRange
|
|
Packit Service |
ca3877 |
* @length: the length of the returned array
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Parses @hdrs's Range header and returns an array of the requested
|
|
Packit Service |
ca3877 |
* byte ranges. The returned array must be freed with
|
|
Packit Service |
ca3877 |
* soup_message_headers_free_ranges().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @total_length is non-0, its value will be used to adjust the
|
|
Packit Service |
ca3877 |
* returned ranges to have explicit start and end values, and the
|
|
Packit Service |
ca3877 |
* returned ranges will be sorted and non-overlapping. If
|
|
Packit Service |
ca3877 |
* @total_length is 0, then some ranges may have an end value of -1,
|
|
Packit Service |
ca3877 |
* as described under #SoupRange, and some of the ranges may be
|
|
Packit Service |
ca3877 |
* redundant.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Beware that even if given a @total_length, this function does not
|
|
Packit Service |
ca3877 |
* check that the ranges are satisfiable.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* <note><para>
|
|
Packit Service |
ca3877 |
* #SoupServer has built-in handling for range requests. If your
|
|
Packit Service |
ca3877 |
* server handler returns a %SOUP_STATUS_OK response containing the
|
|
Packit Service |
ca3877 |
* complete response body (rather than pausing the message and
|
|
Packit Service |
ca3877 |
* returning some of the response body later), and there is a Range
|
|
Packit Service |
ca3877 |
* header in the request, then libsoup will automatically convert the
|
|
Packit Service |
ca3877 |
* response to a %SOUP_STATUS_PARTIAL_CONTENT response containing only
|
|
Packit Service |
ca3877 |
* the range(s) requested by the client.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* The only time you need to process the Range header yourself is if
|
|
Packit Service |
ca3877 |
* either you need to stream the response body rather than returning
|
|
Packit Service |
ca3877 |
* it all at once, or you do not already have the complete response
|
|
Packit Service |
ca3877 |
* body available, and only want to generate the parts that were
|
|
Packit Service |
ca3877 |
* actually requested by the client.
|
|
Packit Service |
ca3877 |
* </para></note>
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if @hdrs contained a syntactically-valid
|
|
Packit Service |
ca3877 |
* "Range" header, %FALSE otherwise (in which case @range and @length
|
|
Packit Service |
ca3877 |
* will not be set).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_get_ranges (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset total_length,
|
|
Packit Service |
ca3877 |
SoupRange **ranges,
|
|
Packit Service |
ca3877 |
int *length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
guint status;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
status = soup_message_headers_get_ranges_internal (hdrs, total_length, FALSE, ranges, length);
|
|
Packit Service |
ca3877 |
return status == SOUP_STATUS_PARTIAL_CONTENT;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_free_ranges:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @ranges: an array of #SoupRange
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Frees the array of ranges returned from soup_message_headers_get_ranges().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_free_ranges (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
SoupRange *ranges)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_free (ranges);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_ranges:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @ranges: an array of #SoupRange
|
|
Packit Service |
ca3877 |
* @length: the length of @range
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets @hdrs's Range header to request the indicated ranges. (If you
|
|
Packit Service |
ca3877 |
* only want to request a single range, you can use
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_range().)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_ranges (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
SoupRange *ranges,
|
|
Packit Service |
ca3877 |
int length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GString *header;
|
|
Packit Service |
ca3877 |
int i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
header = g_string_new ("bytes=");
|
|
Packit Service |
ca3877 |
for (i = 0; i < length; i++) {
|
|
Packit Service |
ca3877 |
if (i > 0)
|
|
Packit Service |
ca3877 |
g_string_append_c (header, ',');
|
|
Packit Service |
ca3877 |
if (ranges[i].end >= 0) {
|
|
Packit Service |
ca3877 |
g_string_append_printf (header, "%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT,
|
|
Packit Service |
ca3877 |
ranges[i].start, ranges[i].end);
|
|
Packit Service |
ca3877 |
} else if (ranges[i].start >= 0) {
|
|
Packit Service |
ca3877 |
g_string_append_printf (header,"%" G_GINT64_FORMAT "-",
|
|
Packit Service |
ca3877 |
ranges[i].start);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
g_string_append_printf (header, "%" G_GINT64_FORMAT,
|
|
Packit Service |
ca3877 |
ranges[i].start);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, "Range", header->str);
|
|
Packit Service |
ca3877 |
g_string_free (header, TRUE);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_range:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @start: the start of the range to request
|
|
Packit Service |
ca3877 |
* @end: the end of the range to request
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets @hdrs's Range header to request the indicated range.
|
|
Packit Service |
ca3877 |
* @start and @end are interpreted as in a #SoupRange.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If you need to request multiple ranges, use
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_ranges().
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_range (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset start,
|
|
Packit Service |
ca3877 |
goffset end)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupRange range;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
range.start = start;
|
|
Packit Service |
ca3877 |
range.end = end;
|
|
Packit Service |
ca3877 |
soup_message_headers_set_ranges (hdrs, &range, 1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_content_range:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @start: (out): return value for the start of the range
|
|
Packit Service |
ca3877 |
* @end: (out): return value for the end of the range
|
|
Packit Service |
ca3877 |
* @total_length: (out) (optional): return value for the total length of the
|
|
Packit Service |
ca3877 |
* resource, or %NULL if you don't care.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Parses @hdrs's Content-Range header and returns it in @start,
|
|
Packit Service |
ca3877 |
* @end, and @total_length. If the total length field in the header
|
|
Packit Service |
ca3877 |
* was specified as "*", then @total_length will be set to -1.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if @hdrs contained a "Content-Range" header
|
|
Packit Service |
ca3877 |
* containing a byte range which could be parsed, %FALSE otherwise.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_get_content_range (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset *start,
|
|
Packit Service |
ca3877 |
goffset *end,
|
|
Packit Service |
ca3877 |
goffset *total_length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *header = soup_message_headers_get_one (hdrs, "Content-Range");
|
|
Packit Service |
ca3877 |
goffset length;
|
|
Packit Service |
ca3877 |
char *p;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!header || strncmp (header, "bytes ", 6) != 0)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
header += 6;
|
|
Packit Service |
ca3877 |
while (g_ascii_isspace (*header))
|
|
Packit Service |
ca3877 |
header++;
|
|
Packit Service |
ca3877 |
if (!g_ascii_isdigit (*header))
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
*start = g_ascii_strtoull (header, &p, 10);
|
|
Packit Service |
ca3877 |
if (*p != '-')
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
*end = g_ascii_strtoull (p + 1, &p, 10);
|
|
Packit Service |
ca3877 |
if (*p != '/')
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
p++;
|
|
Packit Service |
ca3877 |
if (*p == '*') {
|
|
Packit Service |
ca3877 |
length = -1;
|
|
Packit Service |
ca3877 |
p++;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
length = g_ascii_strtoull (p, &p, 10);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (total_length)
|
|
Packit Service |
ca3877 |
*total_length = length;
|
|
Packit Service |
ca3877 |
return *p == '\0';
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_content_range:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @start: the start of the range
|
|
Packit Service |
ca3877 |
* @end: the end of the range
|
|
Packit Service |
ca3877 |
* @total_length: the total length of the resource, or -1 if unknown
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets @hdrs's Content-Range header according to the given values.
|
|
Packit Service |
ca3877 |
* (Note that @total_length is the total length of the entire resource
|
|
Packit Service |
ca3877 |
* that this is a range of, not simply @end - @start + 1.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* <note><para>
|
|
Packit Service |
ca3877 |
* #SoupServer has built-in handling for range requests, and you do
|
|
Packit Service |
ca3877 |
* not normally need to call this function youself. See
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_ranges() for more details.
|
|
Packit Service |
ca3877 |
* </para></note>
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_content_range (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
goffset start,
|
|
Packit Service |
ca3877 |
goffset end,
|
|
Packit Service |
ca3877 |
goffset total_length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char *header;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (total_length >= 0) {
|
|
Packit Service |
ca3877 |
header = g_strdup_printf ("bytes %" G_GINT64_FORMAT "-%"
|
|
Packit Service |
ca3877 |
G_GINT64_FORMAT "/%" G_GINT64_FORMAT,
|
|
Packit Service |
ca3877 |
start, end, total_length);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
header = g_strdup_printf ("bytes %" G_GINT64_FORMAT "-%"
|
|
Packit Service |
ca3877 |
G_GINT64_FORMAT "/*", start, end);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, "Content-Range", header);
|
|
Packit Service |
ca3877 |
g_free (header);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
parse_content_foo (SoupMessageHeaders *hdrs, const char *header_name,
|
|
Packit Service |
ca3877 |
char **foo, GHashTable **params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *header;
|
|
Packit Service |
ca3877 |
char *semi;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
header = soup_message_headers_get_one (hdrs, header_name);
|
|
Packit Service |
ca3877 |
if (!header)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (foo) {
|
|
Packit Service |
ca3877 |
*foo = g_strdup (header);
|
|
Packit Service |
ca3877 |
semi = strchr (*foo, ';');
|
|
Packit Service |
ca3877 |
if (semi) {
|
|
Packit Service |
ca3877 |
char *p = semi;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
*semi++ = '\0';
|
|
Packit Service |
ca3877 |
while (p - 1 > *foo && g_ascii_isspace(p[-1]))
|
|
Packit Service |
ca3877 |
*(--p) = '\0';
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
semi = strchr (header, ';');
|
|
Packit Service |
ca3877 |
if (semi)
|
|
Packit Service |
ca3877 |
semi++;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!params)
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!semi) {
|
|
Packit Service |
ca3877 |
*params = soup_header_parse_semi_param_list ("");
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
*params = soup_header_parse_semi_param_list (semi);
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
set_content_foo (SoupMessageHeaders *hdrs, const char *header_name,
|
|
Packit Service |
ca3877 |
const char *foo, GHashTable *params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GString *str;
|
|
Packit Service |
ca3877 |
GHashTableIter iter;
|
|
Packit Service |
ca3877 |
gpointer key, value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
str = g_string_new (foo);
|
|
Packit Service |
ca3877 |
if (params) {
|
|
Packit Service |
ca3877 |
g_hash_table_iter_init (&iter, params);
|
|
Packit Service |
ca3877 |
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
Packit Service |
ca3877 |
g_string_append (str, "; ");
|
|
Packit Service |
ca3877 |
soup_header_g_string_append_param (str, key, value);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_message_headers_replace (hdrs, header_name, str->str);
|
|
Packit Service |
ca3877 |
g_string_free (str, TRUE);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
content_type_setter (SoupMessageHeaders *hdrs, const char *value)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_free (hdrs->content_type);
|
|
Packit Service |
ca3877 |
if (value) {
|
|
Packit Service |
ca3877 |
char *content_type, *p;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
parse_content_foo (hdrs, "Content-Type", &content_type, NULL);
|
|
Packit Service |
ca3877 |
p = strpbrk (content_type, " /");
|
|
Packit Service |
ca3877 |
if (!p || *p != '/' || strpbrk (p + 1, " /")) {
|
|
Packit Service |
ca3877 |
g_free (content_type);
|
|
Packit Service |
ca3877 |
hdrs->content_type = NULL;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
hdrs->content_type = content_type;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
hdrs->content_type = NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_content_type:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @params: (out) (element-type utf8 utf8) (allow-none) (transfer full):
|
|
Packit Service |
ca3877 |
* return location for the Content-Type parameters (eg, "charset"), or
|
|
Packit Service |
ca3877 |
* %NULL
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Looks up the "Content-Type" header in @hdrs, parses it, and returns
|
|
Packit Service |
ca3877 |
* its value in *@content_type and *@params. @params can be %NULL if you
|
|
Packit Service |
ca3877 |
* are only interested in the content type itself.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): a string with the value of the
|
|
Packit Service |
ca3877 |
* "Content-Type" header or %NULL if @hdrs does not contain that
|
|
Packit Service |
ca3877 |
* header or it cannot be parsed (in which case *@params will be
|
|
Packit Service |
ca3877 |
* unchanged).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
const char *
|
|
Packit Service |
ca3877 |
soup_message_headers_get_content_type (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
GHashTable **params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (!hdrs->content_type)
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (params)
|
|
Packit Service |
ca3877 |
parse_content_foo (hdrs, "Content-Type", NULL, params);
|
|
Packit Service |
ca3877 |
return hdrs->content_type;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_content_type:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @content_type: the MIME type
|
|
Packit Service |
ca3877 |
* @params: (allow-none) (element-type utf8 utf8): additional
|
|
Packit Service |
ca3877 |
* parameters, or %NULL
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets the "Content-Type" header in @hdrs to @content_type,
|
|
Packit Service |
ca3877 |
* optionally with additional parameters specified in @params.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_content_type (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
const char *content_type,
|
|
Packit Service |
ca3877 |
GHashTable *params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
set_content_foo (hdrs, "Content-Type", content_type, params);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_get_content_disposition:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @disposition: (out) (transfer full): return location for the
|
|
Packit Service |
ca3877 |
* disposition-type, or %NULL
|
|
Packit Service |
ca3877 |
* @params: (out) (transfer full) (element-type utf8 utf8): return
|
|
Packit Service |
ca3877 |
* location for the Content-Disposition parameters, or %NULL
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Looks up the "Content-Disposition" header in @hdrs, parses it, and
|
|
Packit Service |
ca3877 |
* returns its value in *@disposition and *@params. @params can be
|
|
Packit Service |
ca3877 |
* %NULL if you are only interested in the disposition-type.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* In HTTP, the most common use of this header is to set a
|
|
Packit Service |
ca3877 |
* disposition-type of "attachment", to suggest to the browser that a
|
|
Packit Service |
ca3877 |
* response should be saved to disk rather than displayed in the
|
|
Packit Service |
ca3877 |
* browser. If @params contains a "filename" parameter, this is a
|
|
Packit Service |
ca3877 |
* suggestion of a filename to use. (If the parameter value in the
|
|
Packit Service |
ca3877 |
* header contains an absolute or relative path, libsoup will truncate
|
|
Packit Service |
ca3877 |
* it down to just the final path component, so you do not need to
|
|
Packit Service |
ca3877 |
* test this yourself.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Content-Disposition is also used in "multipart/form-data", however
|
|
Packit Service |
ca3877 |
* this is handled automatically by #SoupMultipart and the associated
|
|
Packit Service |
ca3877 |
* form methods.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if @hdrs contains a "Content-Disposition"
|
|
Packit Service |
ca3877 |
* header, %FALSE if not (in which case *@disposition and *@params
|
|
Packit Service |
ca3877 |
* will be unchanged).
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_message_headers_get_content_disposition (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
char **disposition,
|
|
Packit Service |
ca3877 |
GHashTable **params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
gpointer orig_key, orig_value;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!parse_content_foo (hdrs, "Content-Disposition",
|
|
Packit Service |
ca3877 |
disposition, params))
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* If there is a filename parameter, make sure it contains
|
|
Packit Service |
ca3877 |
* only a single path component
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (params && g_hash_table_lookup_extended (*params, "filename",
|
|
Packit Service |
ca3877 |
&orig_key, &orig_value)) {
|
|
Packit Service |
ca3877 |
char *filename = strrchr (orig_value, '/');
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (filename)
|
|
Packit Service |
ca3877 |
g_hash_table_insert (*params, g_strdup (orig_key), filename + 1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_message_headers_set_content_disposition:
|
|
Packit Service |
ca3877 |
* @hdrs: a #SoupMessageHeaders
|
|
Packit Service |
ca3877 |
* @disposition: the disposition-type
|
|
Packit Service |
ca3877 |
* @params: (allow-none) (element-type utf8 utf8): additional
|
|
Packit Service |
ca3877 |
* parameters, or %NULL
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Sets the "Content-Disposition" header in @hdrs to @disposition,
|
|
Packit Service |
ca3877 |
* optionally with additional parameters specified in @params.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* See soup_message_headers_get_content_disposition() for a discussion
|
|
Packit Service |
ca3877 |
* of how Content-Disposition is used in HTTP.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.26
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_message_headers_set_content_disposition (SoupMessageHeaders *hdrs,
|
|
Packit Service |
ca3877 |
const char *disposition,
|
|
Packit Service |
ca3877 |
GHashTable *params)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
set_content_foo (hdrs, "Content-Disposition", disposition, params);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|