## 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);

                        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

### 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.4.1

### 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.4.1

### 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.4.1

### 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.4.1

## See Also

SoupMessage