mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
expand tests
This commit is contained in:
@@ -1129,16 +1129,19 @@ struct MHD_DynContentZCIoVec
|
||||
* The number of elements in @a iov
|
||||
*/
|
||||
unsigned int iov_count;
|
||||
|
||||
/**
|
||||
* The pointer to the array with @a iov_count elements.
|
||||
*/
|
||||
const struct MHD_IoVec *iov;
|
||||
|
||||
/**
|
||||
* The callback to free resources.
|
||||
* It is called once the full array of iov elements is sent.
|
||||
* No callback is called if NULL.
|
||||
*/
|
||||
MHD_FreeCallback iov_fcb;
|
||||
|
||||
/**
|
||||
* The parameter for @a iov_fcb
|
||||
*/
|
||||
@@ -1149,6 +1152,7 @@ struct MHD_DynContentZCIoVec
|
||||
* The action type returned by Dynamic Content Creator callback
|
||||
*/
|
||||
struct MHD_DynamicContentCreatorAction;
|
||||
|
||||
/**
|
||||
* The context used for Dynamic Content Creator callback
|
||||
*/
|
||||
@@ -1163,7 +1167,7 @@ struct MHD_DynamicContentCreatorContext;
|
||||
* The total size of the data in the buffer and in @a iov_data must
|
||||
* be non-zero.
|
||||
* @param[in,out] ctx the pointer the context as provided to the callback
|
||||
* @param data_size the amount of the data placed to the provided buffer,
|
||||
* @param data_size the amount of the data placed to the provided buffer (not @a iov_data),
|
||||
* cannot be larger than provided buffer size,
|
||||
* must be non-zero if @a iov_data is NULL or has no data,
|
||||
* @param iov_data the optional pointer to the iov data,
|
||||
@@ -1184,13 +1188,52 @@ MHD_DCC_action_continue_zc (
|
||||
MHD_FN_PAR_NONNULL_ (1)
|
||||
MHD_FN_PAR_CSTR_ (4);
|
||||
|
||||
#define MHD_DCC_action_continue(ctx,data_size,chunk_ext) \
|
||||
|
||||
/**
|
||||
* Set action to "continue processing", the data is provided in the
|
||||
* buffer and/or in the zero-copy @a iov_data.
|
||||
* If data is provided both in the buffer and @a ivo_data then
|
||||
* data in the buffer sent first, following the iov data.
|
||||
* The total size of the data in the buffer and in @a iov_data must
|
||||
* be non-zero.
|
||||
* @param[in,out] ctx the pointer the context as provided to the callback
|
||||
* @param data_size the amount of the data placed to the provided buffer (not @a iov_data),
|
||||
* cannot be larger than provided buffer size,
|
||||
* must be non-zero.
|
||||
* @param chunk_ext the optional pointer to chunk extension string,
|
||||
* can be NULL to not use chunk extension,
|
||||
* ignored if chunked encoding is not used
|
||||
* @return the pointer to the action if succeed,
|
||||
* NULL (equivalent of MHD_DCC_action_abort())in case of any error
|
||||
*/
|
||||
#define MHD_DCC_action_continue_ce(ctx,data_size,chunk_ext) \
|
||||
MHD_DCC_action_continue_zc (ctx, data_size, NULL, chunk_ext)
|
||||
|
||||
|
||||
/**
|
||||
* Set action to "continue processing", the data is provided in the
|
||||
* buffer and/or in the zero-copy @a iov_data.
|
||||
* If data is provided both in the buffer and @a ivo_data then
|
||||
* data in the buffer sent first, following the iov data.
|
||||
* The total size of the data in the buffer and in @a iov_data must
|
||||
* be non-zero.
|
||||
* @param[in,out] ctx the pointer the context as provided to the callback
|
||||
* @param data_size the amount of the data placed to the provided buffer;
|
||||
* cannot be larger than provided buffer size,
|
||||
* must be non-zero.
|
||||
*
|
||||
* @return the pointer to the action if succeed,
|
||||
* NULL (equivalent of MHD_DCC_action_abort())in case of any error
|
||||
*/
|
||||
#define MHD_DCC_action_continue(ctx,data_size) \
|
||||
MHD_DCC_action_continue_ce (ctx, data_size, NULL)
|
||||
|
||||
|
||||
/**
|
||||
* Set action to "finished".
|
||||
* If function failed for any reason, the action is automatically
|
||||
* set to "stop with error".
|
||||
*
|
||||
* @param[in,out] ctx the pointer the context as provided to the callback
|
||||
* @param num_footers number of elements in the @a footers array,
|
||||
* must be zero if @a footers is NULL
|
||||
@@ -1209,8 +1252,17 @@ MHD_DCC_action_finished_with_footer (
|
||||
MHD_FN_PAR_NONNULL_ (1);
|
||||
|
||||
|
||||
#define MHD_DCC_action_finished(action) \
|
||||
MHD_DCC_set_action_finished_with_footer (action, 0, NULL)
|
||||
/**
|
||||
* Set action to "finished".
|
||||
* If function failed for any reason, the action is automatically
|
||||
* set to "stop with error".
|
||||
*
|
||||
* @param[in,out] ctx the pointer the context as provided to the callback
|
||||
* @return the pointer to the action if succeed,
|
||||
* NULL (equivalent of MHD_DCC_action_abort())in case of any error
|
||||
*/
|
||||
#define MHD_DCC_action_finished(ctx) \
|
||||
MHD_DCC_set_action_finished_with_footer (ctx, 0, NULL)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -218,6 +218,35 @@ MHDT_server_reply_text (
|
||||
uint_fast64_t upload_size);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the text from @a cls as the response to any
|
||||
* request, but using chunks by returning @a cls
|
||||
* word-wise (breaking into chunks at spaces).
|
||||
*
|
||||
* @param cls argument given together with the function
|
||||
* pointer when the handler was registered with MHD
|
||||
* @param request the request object
|
||||
* @param path the requested uri (without arguments after "?")
|
||||
* @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
|
||||
* #MHD_HTTP_METHOD_PUT, etc.)
|
||||
* @param upload_size the size of the message upload content payload,
|
||||
* #MHD_SIZE_UNKNOWN for chunked uploads (if the
|
||||
* final chunk has not been processed yet)
|
||||
* @return action how to proceed, NULL
|
||||
* if the request must be aborted due to a serious
|
||||
* error while handling the request (implies closure
|
||||
* of underling data stream, for HTTP/1.1 it means
|
||||
* socket closure).
|
||||
*/
|
||||
const struct MHD_Action *
|
||||
MHDT_server_reply_chunked_text (
|
||||
void *cls,
|
||||
struct MHD_Request *MHD_RESTRICT request,
|
||||
const struct MHD_String *MHD_RESTRICT path,
|
||||
enum MHD_HTTP_Method method,
|
||||
uint_fast64_t upload_size);
|
||||
|
||||
|
||||
/**
|
||||
* Returns writes text from @a cls to a temporary file
|
||||
* and then uses the file descriptor to serve the
|
||||
|
||||
@@ -366,3 +366,85 @@ MHDT_server_reply_check_upload (
|
||||
&check_upload_cb,
|
||||
(void *) want);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #chunk_return.
|
||||
*/
|
||||
struct ChunkContext
|
||||
{
|
||||
/**
|
||||
* Where we are in the buffer.
|
||||
*/
|
||||
const char *pos;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function that returns a string in chunks.
|
||||
*
|
||||
* @param dyn_cont_cls must be a `struct ChunkContext`
|
||||
* @param ctx the context to produce the action to return,
|
||||
* the pointer is only valid until the callback returns
|
||||
* @param pos position in the datastream to access;
|
||||
* note that if a `struct MHD_Response` object is re-used,
|
||||
* it is possible for the same content reader to
|
||||
* be queried multiple times for the same data;
|
||||
* however, if a `struct MHD_Response` is not re-used,
|
||||
* libmicrohttpd guarantees that "pos" will be
|
||||
* the sum of all data sizes provided by this callback
|
||||
* @param[out] buf where to copy the data
|
||||
* @param max maximum number of bytes to copy to @a buf (size of @a buf)
|
||||
* @return action to use,
|
||||
* NULL in case of any error (the response will be aborted)
|
||||
*/
|
||||
static const struct MHD_DynamicContentCreatorAction *
|
||||
chunk_return (void *cls,
|
||||
struct MHD_DynamicContentCreatorContext *ctx,
|
||||
uint_fast64_t pos,
|
||||
void *buf,
|
||||
size_t max)
|
||||
{
|
||||
struct ChunkContext *cc = cls;
|
||||
size_t imax = strlen (cc->pos);
|
||||
const char *space = strchr (cc->pos, ' ');
|
||||
|
||||
if (0 == imax)
|
||||
return MHD_DCC_action_finished (ctx);
|
||||
if (imax > space - cc->pos + 1)
|
||||
imax = space - cc->pos;
|
||||
if (imax > max)
|
||||
imax = max;
|
||||
memcpy (buf,
|
||||
cc->pos,
|
||||
imax);
|
||||
cc->pos += imax;
|
||||
return MHD_DCC_action_continue (ctx,
|
||||
imax);
|
||||
}
|
||||
|
||||
|
||||
const struct MHD_Action *
|
||||
MHDT_server_reply_chunked_text (
|
||||
void *cls,
|
||||
struct MHD_Request *MHD_RESTRICT request,
|
||||
const struct MHD_String *MHD_RESTRICT path,
|
||||
enum MHD_HTTP_Method method,
|
||||
uint_fast64_t upload_size)
|
||||
{
|
||||
const char *text = cls;
|
||||
struct ChunkContext *cc;
|
||||
|
||||
cc = malloc (sizeof (struct ChunkContext));
|
||||
if (NULL == cc)
|
||||
return NULL;
|
||||
cc->pos = text;
|
||||
|
||||
return MHD_action_from_response (
|
||||
request,
|
||||
MHD_response_from_callback (MHD_HTTP_STATUS_OK,
|
||||
MHD_SIZE_UNKNOWN,
|
||||
&chunk_return,
|
||||
cc,
|
||||
&free));
|
||||
}
|
||||
|
||||
@@ -238,6 +238,14 @@ main (int argc, char *argv[])
|
||||
.timeout_ms = 5000,
|
||||
.num_clients = 1
|
||||
},
|
||||
{
|
||||
.label = "chunked response get",
|
||||
.server_cb = &MHDT_server_reply_chunked_text,
|
||||
.server_cb_cls = "Hello world",
|
||||
.client_cb = &MHDT_client_get_root,
|
||||
.client_cb_cls = "Hello world",
|
||||
.timeout_ms = 2500,
|
||||
},
|
||||
// TODO: chunked download
|
||||
{
|
||||
.label = NULL,
|
||||
|
||||
Reference in New Issue
Block a user