SoupMessageBody

SoupMessageBody — HTTP message body

Synopsis

#include <libsoup/soup.h>

                    SoupBuffer;
enum                SoupMemoryUse;
SoupBuffer *        soup_buffer_new                     (SoupMemoryUse use,
                                                         gconstpointer data,
                                                         gsize length);
SoupBuffer *        soup_buffer_new_subbuffer           (SoupBuffer *parent,
                                                         gsize offset,
                                                         gsize length);
SoupBuffer *        soup_buffer_new_with_owner          (gconstpointer data,
                                                         gsize length,
                                                         gpointer owner,
                                                         GDestroyNotify owner_dnotify);
SoupBuffer *        soup_buffer_new_take                (guchar *data,
                                                         gsize length);
gpointer            soup_buffer_get_owner               (SoupBuffer *buffer);
void                soup_buffer_get_data                (SoupBuffer *buffer,
                                                         const guint8 **data,
                                                         gsize *length);
SoupBuffer *        soup_buffer_copy                    (SoupBuffer *buffer);
void                soup_buffer_free                    (SoupBuffer *buffer);
GBytes *            soup_buffer_get_as_bytes            (SoupBuffer *buffer);

                    SoupMessageBody;
SoupMessageBody *   soup_message_body_new               (void);
void                soup_message_body_free              (SoupMessageBody *body);

void                soup_message_body_set_accumulate    (SoupMessageBody *body,
                                                         gboolean accumulate);
gboolean            soup_message_body_get_accumulate    (SoupMessageBody *body);

void                soup_message_body_append            (SoupMessageBody *body,
                                                         SoupMemoryUse use,
                                                         gconstpointer data,
                                                         gsize length);
void                soup_message_body_append_buffer     (SoupMessageBody *body,
                                                         SoupBuffer *buffer);
void                soup_message_body_append_take       (SoupMessageBody *body,
                                                         guchar *data,
                                                         gsize length);
void                soup_message_body_truncate          (SoupMessageBody *body);
void                soup_message_body_complete          (SoupMessageBody *body);
SoupBuffer *        soup_message_body_flatten           (SoupMessageBody *body);
SoupBuffer *        soup_message_body_get_chunk         (SoupMessageBody *body,
                                                         goffset offset);

void                soup_message_body_got_chunk         (SoupMessageBody *body,
                                                         SoupBuffer *chunk);
void                soup_message_body_wrote_chunk       (SoupMessageBody *body,
                                                         SoupBuffer *chunk);

Object Hierarchy

  GBoxed
   +----SoupBuffer
  GBoxed
   +----SoupMessageBody

Description

SoupMessageBody represents the request or response body of a SoupMessage.

In addition to SoupMessageBody, libsoup also defines a "smaller" data buffer type, SoupBuffer, which is primarily used as a component of SoupMessageBody. In particular, when using chunked encoding to transmit or receive a message, each chunk is represented as a SoupBuffer.

Details

SoupBuffer

typedef struct {
	const char *data;
	gsize       length;
} SoupBuffer;

A data buffer, generally used to represent a chunk of a SoupMessageBody.

data is a char because that's generally convenient; in some situations you may need to cast it to guchar or another type.

const char *data;

the data. [type gpointer]

gsize length;

length of data

enum SoupMemoryUse

typedef enum {
	SOUP_MEMORY_STATIC,
	SOUP_MEMORY_TAKE,
	SOUP_MEMORY_COPY,
	SOUP_MEMORY_TEMPORARY
} SoupMemoryUse;

Describes how SoupBuffer should use the data passed in by the caller.

See also soup_buffer_new_with_owner(), which allows to you create a buffer containing data which is owned by another object.

SOUP_MEMORY_STATIC

The memory is statically allocated and constant; libsoup can use the passed-in buffer directly and not need to worry about it being modified or freed.

SOUP_MEMORY_TAKE

The caller has allocated the memory for the SoupBuffer's use; libsoup will assume ownership of it and free it (with g_free()) when it is done with it.

SOUP_MEMORY_COPY

The passed-in data belongs to the caller; the SoupBuffer will copy it into new memory, leaving the caller free to reuse the original memory.

SOUP_MEMORY_TEMPORARY

The passed-in data belongs to the caller, but will remain valid for the lifetime of the SoupBuffer. The difference between this and SOUP_MEMORY_STATIC is that if you copy a SOUP_MEMORY_TEMPORARY buffer, it will make a copy of the memory as well, rather than reusing the original memory.

soup_buffer_new ()

SoupBuffer *        soup_buffer_new                     (SoupMemoryUse use,
                                                         gconstpointer data,
                                                         gsize length);

Creates a new SoupBuffer containing length bytes from data.

use :

how data is to be used by the buffer

data :

data

length :

length of data

Returns :

the new SoupBuffer.

soup_buffer_new_subbuffer ()

SoupBuffer *        soup_buffer_new_subbuffer           (SoupBuffer *parent,
                                                         gsize offset,
                                                         gsize length);

Creates a new SoupBuffer containing length bytes "copied" from parent starting at offset. (Normally this will not actually copy any data, but will instead simply reference the same data as parent does.)

parent :

the parent SoupBuffer

offset :

offset within parent to start at

length :

number of bytes to copy from parent

Returns :

the new SoupBuffer.

soup_buffer_new_with_owner ()

SoupBuffer *        soup_buffer_new_with_owner          (gconstpointer data,
                                                         gsize length,
                                                         gpointer owner,
                                                         GDestroyNotify owner_dnotify);

Creates a new SoupBuffer containing length bytes from data. When the SoupBuffer is freed, it will call owner_dnotify, passing owner to it. You must ensure that data will remain valid until owner_dnotify is called.

For example, you could use this to create a buffer containing data returned from libxml without needing to do an extra copy:

1
2
3
xmlDocDumpMemory (doc, &xmlbody, &len);
return soup_buffer_new_with_owner (xmlbody, len, xmlbody,
                                   (GDestroyNotify)xmlFree);

In this example, data and owner are the same, but in other cases they would be different (eg, owner would be a object, and data would be a pointer to one of the object's fields).

data :

data

length :

length of data

owner :

pointer to an object that owns data

owner_dnotify :

a function to free/unref owner when the buffer is freed. [allow-none]

Returns :

the new SoupBuffer.

soup_buffer_new_take ()

SoupBuffer *        soup_buffer_new_take                (guchar *data,
                                                         gsize length);

Creates a new SoupBuffer containing length bytes from data.

This function is exactly equivalent to soup_buffer_new() with SOUP_MEMORY_TAKE as first argument; it exists mainly for convenience and simplifying language bindings.

data :

data. [array length=length][transfer full]

length :

length of data

Returns :

the new SoupBuffer. Rename to: soup_buffer_new

Since 2.32


soup_buffer_get_owner ()

gpointer            soup_buffer_get_owner               (SoupBuffer *buffer);

Gets the "owner" object for a buffer created with soup_buffer_new_with_owner().

buffer :

a SoupBuffer created with soup_buffer_new_with_owner()

Returns :

the owner pointer. [transfer none]

soup_buffer_get_data ()

void                soup_buffer_get_data                (SoupBuffer *buffer,
                                                         const guint8 **data,
                                                         gsize *length);

This function exists for use by language bindings, because it's not currently possible to get the right effect by annotating the fields of SoupBuffer.

buffer :

a SoupBuffer

data :

the pointer to the buffer data is stored here. [out][array length=length][transfer none]

length :

the length of the buffer data is stored here. [out]

Since 2.32


soup_buffer_copy ()

SoupBuffer *        soup_buffer_copy                    (SoupBuffer *buffer);

Makes a copy of buffer. In reality, SoupBuffer is a refcounted type, and calling soup_buffer_copy() will normally just increment the refcount on buffer and return it. However, if buffer was created with SOUP_MEMORY_TEMPORARY memory, then soup_buffer_copy() will actually return a copy of it, so that the data in the copy will remain valid after the temporary buffer is freed.

buffer :

a SoupBuffer

Returns :

the new (or newly-reffed) buffer

soup_buffer_free ()

void                soup_buffer_free                    (SoupBuffer *buffer);

Frees buffer. (In reality, as described in the documentation for soup_buffer_copy(), this is actually an "unref" operation, and may or may not actually free buffer.)

buffer :

a SoupBuffer

soup_buffer_get_as_bytes ()

GBytes *            soup_buffer_get_as_bytes            (SoupBuffer *buffer);

Creates a GBytes pointing to the same memory as buffer. The GBytes will hold a reference on buffer to ensure that it is not freed while the GBytes is still valid.

buffer :

a SoupBuffer

Returns :

a new GBytes which has the same content as the SoupBuffer. [transfer full]

Since 2.40


SoupMessageBody

typedef struct {
	const char *data;
	goffset     length;
} SoupMessageBody;

A SoupMessage request or response body.

Note that while length always reflects the full length of the message body, data is normally NULL, and will only be filled in after soup_message_body_flatten() is called. For client-side messages, this automatically happens for the response body after it has been fully read, unless you set the SOUP_MESSAGE_OVERWRITE_CHUNKS flags. Likewise, for server-side messages, the request body is automatically filled in after being read.

As an added bonus, when data is filled in, it is always terminated with a '\0' byte (which is not reflected in length).

const char *data;

the data

goffset length;

length of data

soup_message_body_new ()

SoupMessageBody *   soup_message_body_new               (void);

Creates a new SoupMessageBody. SoupMessage uses this internally; you will not normally need to call it yourself.

Returns :

a new SoupMessageBody.

soup_message_body_free ()

void                soup_message_body_free              (SoupMessageBody *body);

Frees body. You will not normally need to use this, as SoupMessage frees its associated message bodies automatically.

body :

a SoupMessageBody

soup_message_body_set_accumulate ()

void                soup_message_body_set_accumulate    (SoupMessageBody *body,
                                                         gboolean accumulate);

Sets or clears the accumulate flag on body. (The default value is TRUE.) If set to FALSE, body's data field will not be filled in after the body is fully sent/received, and the chunks that make up body may be discarded when they are no longer needed.

In particular, if you set this flag to FALSE on an "incoming" message body (that is, the "response_body" of a client-side message, or "request_body" of a server-side message), this will cause each chunk of the body to be discarded after its corresponding "got_chunk" signal is emitted. (This is equivalent to setting the deprecated SOUP_MESSAGE_OVERWRITE_CHUNKS flag on the message.)

If you set this flag to FALSE on the "response_body" of a server-side message, it will cause each chunk of the body to be discarded after its corresponding "wrote_chunk" signal is emitted.

If you set the flag to FALSE on the "request_body" of a client-side message, it will block the accumulation of chunks into body's data field, but it will not normally cause the chunks to be discarded after being written like in the server-side "response_body" case, because the request body needs to be kept around in case the request needs to be sent a second time due to redirection or authentication. However, if you set the SOUP_MESSAGE_CAN_REBUILD flag on the message, then the chunks will be discarded, and you will be responsible for recreating the request body after the "restarted" signal is emitted.

body :

a SoupMessageBody

accumulate :

whether or not to accumulate body chunks in body

Since 2.24


soup_message_body_get_accumulate ()

gboolean            soup_message_body_get_accumulate    (SoupMessageBody *body);

Gets the accumulate flag on body; see soup_message_body_set_accumulate() for details.

body :

a SoupMessageBody

Returns :

the accumulate flag for body.

Since 2.24


soup_message_body_append ()

void                soup_message_body_append            (SoupMessageBody *body,
                                                         SoupMemoryUse use,
                                                         gconstpointer data,
                                                         gsize length);

Appends length bytes from data to body according to use.

body :

a SoupMessageBody

use :

how to use data

data :

data to append. [array length=length][element-type guint8]

length :

length of data

soup_message_body_append_buffer ()

void                soup_message_body_append_buffer     (SoupMessageBody *body,
                                                         SoupBuffer *buffer);

Appends the data from buffer to body. (SoupMessageBody uses SoupBuffers internally, so this is normally a constant-time operation that doesn't actually require copying the data in buffer.)

body :

a SoupMessageBody

buffer :

a SoupBuffer

soup_message_body_append_take ()

void                soup_message_body_append_take       (SoupMessageBody *body,
                                                         guchar *data,
                                                         gsize length);

Appends length bytes from data to body.

This function is exactly equivalent to soup_message_body_append() with SOUP_MEMORY_TAKE as second argument; it exists mainly for convenience and simplifying language bindings.

Rename to: soup_message_body_append

body :

a SoupMessageBody

data :

data to append. [array length=length][transfer full]

length :

length of data

Since 2.32


soup_message_body_truncate ()

void                soup_message_body_truncate          (SoupMessageBody *body);

Deletes all of the data in body.

body :

a SoupMessageBody

soup_message_body_complete ()

void                soup_message_body_complete          (SoupMessageBody *body);

Tags body as being complete; Call this when using chunked encoding after you have appended the last chunk.

body :

a SoupMessageBody

soup_message_body_flatten ()

SoupBuffer *        soup_message_body_flatten           (SoupMessageBody *body);

Fills in body's data field with a buffer containing all of the data in body (plus an additional '\0' byte not counted by body's length field).

body :

a SoupMessageBody

Returns :

a SoupBuffer containing the same data as body. (You must free this buffer if you do not want it.)

soup_message_body_get_chunk ()

SoupBuffer *        soup_message_body_get_chunk         (SoupMessageBody *body,
                                                         goffset offset);

Gets a SoupBuffer containing data from body starting at offset. The size of the returned chunk is unspecified. You can iterate through the entire body by first calling soup_message_body_get_chunk() with an offset of 0, and then on each successive call, increment the offset by the length of the previously-returned chunk.

If offset is greater than or equal to the total length of body, then the return value depends on whether or not soup_message_body_complete() has been called or not; if it has, then soup_message_body_get_chunk() will return a 0-length chunk (indicating the end of body). If it has not, then soup_message_body_get_chunk() will return NULL (indicating that body may still potentially have more data, but that data is not currently available).

body :

a SoupMessageBody

offset :

an offset

Returns :

a SoupBuffer, or NULL.

soup_message_body_got_chunk ()

void                soup_message_body_got_chunk         (SoupMessageBody *body,
                                                         SoupBuffer *chunk);

Handles the SoupMessageBody part of receiving a chunk of data from the network. Normally this means appending chunk to body, exactly as with soup_message_body_append_buffer(), but if you have set body's accumulate flag to FALSE, then that will not happen.

This is a low-level method which you should not normally need to use.

body :

a SoupMessageBody

chunk :

a SoupBuffer received from the network

Since 2.24


soup_message_body_wrote_chunk ()

void                soup_message_body_wrote_chunk       (SoupMessageBody *body,
                                                         SoupBuffer *chunk);

Handles the SoupMessageBody part of writing a chunk of data to the network. Normally this is a no-op, but if you have set body's accumulate flag to FALSE, then this will cause chunk to be discarded to free up memory.

This is a low-level method which you should not need to use, and there are further restrictions on its proper use which are not documented here.

body :

a SoupMessageBody

chunk :

a SoupBuffer returned from soup_message_body_get_chunk()

Since 2.24

See Also

SoupMessage