mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-29 04:09:31 +03:00
adding MHD_OPTION_ARRAY
This commit is contained in:
@@ -384,10 +384,49 @@ Note that MHD will not generate any log messages
|
||||
if it was compiled without the "--enable-messages"
|
||||
flag being set and the MHD_USE_DEBUG flag being set,
|
||||
even if this argument is used.
|
||||
|
||||
@item MHD_OPTION_ARRAY
|
||||
@cindex options
|
||||
This option can be used for initializing MHD using options from an
|
||||
array. A common use for this is writing an FFI for MHD. The actual
|
||||
options given are in an array of 'struct MHD_OptionItem', so this
|
||||
option requires a single argument of type 'struct MHD_OptionItem'.
|
||||
The array must be terminated with an entry @code{MHD_OPTION_END}.
|
||||
|
||||
An example for code using MHD_OPTION_ARRAY is:
|
||||
@example
|
||||
struct MHD_OptionItem ops[] = @{
|
||||
@{ MHD_OPTION_CONNECTION_LIMIT, 100, NULL @},
|
||||
@{ MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL @},
|
||||
@{ MHD_OPTION_END, 0, NULL @}
|
||||
@};
|
||||
d = MHD_start_daemon(0, 8080, NULL, NULL, dh, NULL,
|
||||
MHD_OPTION_ARRAY, ops,
|
||||
MHD_OPTION_END);
|
||||
@end example
|
||||
For options that expect a single pointer argument, the
|
||||
second member of the @code{struct MHD_OptionItem} is ignored.
|
||||
For options that expect two pointer arguments, the first
|
||||
argument must be cast to @code{intptr_t}.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
|
||||
@deftp {C Struct} MHD_OptionItem
|
||||
Entry in an MHD_OPTION_ARRAY. See the @code{MHD_OPTION_ARRAY} option
|
||||
argument for its use.
|
||||
|
||||
The @code{option} member is used to specify which option is specified
|
||||
in the array. The other members specify the respective argument.
|
||||
|
||||
Note that for options taking only a single pointer, the
|
||||
@code{ptr_value} member should be set. For options taking two pointer
|
||||
arguments, the first pointer must be cast to @code{intptr_t} and both
|
||||
the @code{value} and the @code{ptr_value} members should be used to
|
||||
pass the two pointers.
|
||||
@end deftp
|
||||
|
||||
|
||||
@deftp {Enumeration} MHD_ValueKind
|
||||
The @code{MHD_ValueKind} specifies the source of the key-value pairs in
|
||||
the @http{} protocol.
|
||||
|
||||
+209
-77
@@ -1141,6 +1141,212 @@ MHD_start_daemon (unsigned int options,
|
||||
|
||||
typedef void (*VfprintfFunctionPointerType)(void *, const char *, va_list);
|
||||
|
||||
|
||||
/**
|
||||
* Parse a list of options given as varargs.
|
||||
*
|
||||
* @param daemon the daemon to initialize
|
||||
* @param ap the options
|
||||
* @return MHD_YES on success, MHD_NO on error
|
||||
*/
|
||||
static int
|
||||
parse_options_va (struct MHD_Daemon *daemon,
|
||||
const struct sockaddr **servaddr,
|
||||
va_list ap);
|
||||
|
||||
|
||||
/**
|
||||
* Parse a list of options given as varargs.
|
||||
*
|
||||
* @param daemon the daemon to initialize
|
||||
* @param ... the options
|
||||
* @return MHD_YES on success, MHD_NO on error
|
||||
*/
|
||||
static int
|
||||
parse_options (struct MHD_Daemon *daemon,
|
||||
const struct sockaddr **servaddr,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start (ap, servaddr);
|
||||
ret = parse_options_va (daemon, servaddr, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a list of options given as varargs.
|
||||
*
|
||||
* @param daemon the daemon to initialize
|
||||
* @param ap the options
|
||||
* @return MHD_YES on success, MHD_NO on error
|
||||
*/
|
||||
static int
|
||||
parse_options_va (struct MHD_Daemon *daemon,
|
||||
const struct sockaddr **servaddr,
|
||||
va_list ap)
|
||||
{
|
||||
enum MHD_OPTION opt;
|
||||
struct MHD_OptionItem *oa;
|
||||
unsigned int i;
|
||||
|
||||
while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
|
||||
daemon->pool_size = va_arg (ap, size_t);
|
||||
break;
|
||||
case MHD_OPTION_CONNECTION_LIMIT:
|
||||
daemon->max_connections = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_CONNECTION_TIMEOUT:
|
||||
daemon->connection_timeout = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_NOTIFY_COMPLETED:
|
||||
daemon->notify_completed =
|
||||
va_arg (ap, MHD_RequestCompletedCallback);
|
||||
daemon->notify_completed_cls = va_arg (ap, void *);
|
||||
break;
|
||||
case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
|
||||
daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_SOCK_ADDR:
|
||||
*servaddr = va_arg (ap, const struct sockaddr *);
|
||||
break;
|
||||
case MHD_OPTION_URI_LOG_CALLBACK:
|
||||
daemon->uri_log_callback =
|
||||
va_arg (ap, LogCallback);
|
||||
daemon->uri_log_callback_cls = va_arg (ap, void *);
|
||||
break;
|
||||
case MHD_OPTION_THREAD_POOL_SIZE:
|
||||
daemon->worker_pool_size = va_arg (ap, unsigned int);
|
||||
break;
|
||||
#if HTTPS_SUPPORT
|
||||
case MHD_OPTION_PROTOCOL_VERSION:
|
||||
_set_priority (&daemon->priority_cache->protocol,
|
||||
va_arg (ap, const int *));
|
||||
break;
|
||||
case MHD_OPTION_HTTPS_MEM_KEY:
|
||||
daemon->https_mem_key = va_arg (ap, const char *);
|
||||
break;
|
||||
case MHD_OPTION_HTTPS_MEM_CERT:
|
||||
daemon->https_mem_cert = va_arg (ap, const char *);
|
||||
break;
|
||||
case MHD_OPTION_CIPHER_ALGORITHM:
|
||||
_set_priority (&daemon->priority_cache->cipher,
|
||||
va_arg (ap, const int *));
|
||||
break;
|
||||
#endif
|
||||
case MHD_OPTION_EXTERNAL_LOGGER:
|
||||
#if HAVE_MESSAGES
|
||||
daemon->custom_error_log =
|
||||
va_arg (ap, VfprintfFunctionPointerType);
|
||||
daemon->custom_error_log_cls = va_arg (ap, void *);
|
||||
#else
|
||||
va_arg (ap, VfprintfFunctionPointerType);
|
||||
va_arg (ap, void *);
|
||||
#endif
|
||||
break;
|
||||
case MHD_OPTION_ARRAY:
|
||||
oa = va_arg (ap, struct MHD_OptionItem*);
|
||||
i = 0;
|
||||
while (MHD_OPTION_END != (opt = oa[i].option))
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case MHD_OPTION_END:
|
||||
abort ();
|
||||
break;
|
||||
/* all options taking 'size_t' */
|
||||
case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
|
||||
if (MHD_YES != parse_options (daemon,
|
||||
servaddr,
|
||||
opt,
|
||||
(size_t) oa[i].value,
|
||||
MHD_OPTION_END))
|
||||
return MHD_NO;
|
||||
break;
|
||||
/* all options taking 'unsigned int' */
|
||||
case MHD_OPTION_CONNECTION_LIMIT:
|
||||
case MHD_OPTION_CONNECTION_TIMEOUT:
|
||||
case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
|
||||
case MHD_OPTION_THREAD_POOL_SIZE:
|
||||
if (MHD_YES != parse_options (daemon,
|
||||
servaddr,
|
||||
opt,
|
||||
(unsigned int) oa[i].value,
|
||||
MHD_OPTION_END))
|
||||
return MHD_NO;
|
||||
break;
|
||||
/* all options taking 'int' or 'enum' */
|
||||
case MHD_OPTION_CRED_TYPE:
|
||||
if (MHD_YES != parse_options (daemon,
|
||||
servaddr,
|
||||
opt,
|
||||
(int) oa[i].value,
|
||||
MHD_OPTION_END))
|
||||
return MHD_NO;
|
||||
break;
|
||||
/* all options taking one pointer */
|
||||
case MHD_OPTION_SOCK_ADDR:
|
||||
case MHD_OPTION_HTTPS_MEM_KEY:
|
||||
case MHD_OPTION_HTTPS_MEM_CERT:
|
||||
case MHD_OPTION_PROTOCOL_VERSION:
|
||||
case MHD_OPTION_CIPHER_ALGORITHM:
|
||||
case MHD_OPTION_ARRAY:
|
||||
if (MHD_YES != parse_options (daemon,
|
||||
servaddr,
|
||||
opt,
|
||||
oa[i].ptr_value,
|
||||
MHD_OPTION_END))
|
||||
return MHD_NO;
|
||||
break;
|
||||
/* all options taking two pointers */
|
||||
case MHD_OPTION_NOTIFY_COMPLETED:
|
||||
case MHD_OPTION_URI_LOG_CALLBACK:
|
||||
case MHD_OPTION_EXTERNAL_LOGGER:
|
||||
if (MHD_YES != parse_options (daemon,
|
||||
servaddr,
|
||||
opt,
|
||||
(void *) oa[i].value,
|
||||
oa[i].ptr_value,
|
||||
MHD_OPTION_END))
|
||||
return MHD_NO;
|
||||
break;
|
||||
|
||||
default:
|
||||
return MHD_NO;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if HAVE_MESSAGES
|
||||
if ((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
|
||||
(opt <= MHD_OPTION_CIPHER_ALGORITHM))
|
||||
{
|
||||
FPRINTF (stderr,
|
||||
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
|
||||
opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
FPRINTF (stderr,
|
||||
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
|
||||
opt);
|
||||
}
|
||||
#endif
|
||||
return MHD_NO;
|
||||
}
|
||||
}
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start a webserver on the given port.
|
||||
*
|
||||
@@ -1168,7 +1374,6 @@ MHD_start_daemon_va (unsigned int options,
|
||||
#endif
|
||||
const struct sockaddr *servaddr = NULL;
|
||||
socklen_t addrlen;
|
||||
enum MHD_OPTION opt;
|
||||
unsigned int i;
|
||||
|
||||
if ((port == 0) || (dh == NULL))
|
||||
@@ -1215,83 +1420,10 @@ MHD_start_daemon_va (unsigned int options,
|
||||
}
|
||||
#endif
|
||||
|
||||
while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
|
||||
if (MHD_YES != parse_options_va (retVal, &servaddr, ap))
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
|
||||
retVal->pool_size = va_arg (ap, size_t);
|
||||
break;
|
||||
case MHD_OPTION_CONNECTION_LIMIT:
|
||||
retVal->max_connections = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_CONNECTION_TIMEOUT:
|
||||
retVal->connection_timeout = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_NOTIFY_COMPLETED:
|
||||
retVal->notify_completed =
|
||||
va_arg (ap, MHD_RequestCompletedCallback);
|
||||
retVal->notify_completed_cls = va_arg (ap, void *);
|
||||
break;
|
||||
case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
|
||||
retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
|
||||
break;
|
||||
case MHD_OPTION_SOCK_ADDR:
|
||||
servaddr = va_arg (ap, struct sockaddr *);
|
||||
break;
|
||||
case MHD_OPTION_URI_LOG_CALLBACK:
|
||||
retVal->uri_log_callback =
|
||||
va_arg (ap, LogCallback);
|
||||
retVal->uri_log_callback_cls = va_arg (ap, void *);
|
||||
break;
|
||||
case MHD_OPTION_THREAD_POOL_SIZE:
|
||||
retVal->worker_pool_size = va_arg (ap, unsigned int);
|
||||
break;
|
||||
#if HTTPS_SUPPORT
|
||||
case MHD_OPTION_PROTOCOL_VERSION:
|
||||
_set_priority (&retVal->priority_cache->protocol,
|
||||
va_arg (ap, const int *));
|
||||
break;
|
||||
case MHD_OPTION_HTTPS_MEM_KEY:
|
||||
retVal->https_mem_key = va_arg (ap, const char *);
|
||||
break;
|
||||
case MHD_OPTION_HTTPS_MEM_CERT:
|
||||
retVal->https_mem_cert = va_arg (ap, const char *);
|
||||
break;
|
||||
case MHD_OPTION_CIPHER_ALGORITHM:
|
||||
_set_priority (&retVal->priority_cache->cipher,
|
||||
va_arg (ap, const int *));
|
||||
break;
|
||||
#endif
|
||||
case MHD_OPTION_EXTERNAL_LOGGER:
|
||||
#if HAVE_MESSAGES
|
||||
retVal->custom_error_log =
|
||||
va_arg (ap, VfprintfFunctionPointerType);
|
||||
retVal->custom_error_log_cls = va_arg (ap, void *);
|
||||
#else
|
||||
va_arg (ap, VfprintfFunctionPointerType);
|
||||
va_arg (ap, void *);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
#if HAVE_MESSAGES
|
||||
if ((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
|
||||
(opt <= MHD_OPTION_CIPHER_ALGORITHM))
|
||||
{
|
||||
FPRINTF (stderr,
|
||||
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
|
||||
opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
FPRINTF (stderr,
|
||||
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
|
||||
opt);
|
||||
}
|
||||
#endif
|
||||
free (retVal);
|
||||
return NULL;
|
||||
}
|
||||
free (retVal);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* poll support currently only works with MHD_USE_THREAD_PER_CONNECTION */
|
||||
|
||||
@@ -453,9 +453,58 @@ enum MHD_OPTION
|
||||
* (MHD_start_daemon returns NULL for an unsupported thread
|
||||
* model).
|
||||
*/
|
||||
MHD_OPTION_THREAD_POOL_SIZE = 14
|
||||
MHD_OPTION_THREAD_POOL_SIZE = 14,
|
||||
|
||||
/**
|
||||
* Additional options given in an array of "struct MHD_OptionItem".
|
||||
* The array must be terminated with an entry '{MHD_OPTION_END, 0, NULL}'.
|
||||
* An example for code using MHD_OPTION_ARRAY is:
|
||||
* <code>
|
||||
* struct MHD_OptionItem ops[] = {
|
||||
* { MHD_OPTION_CONNECTION_LIMIT, 100, NULL },
|
||||
* { MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL },
|
||||
* { MHD_OPTION_END, 0, NULL }
|
||||
* };
|
||||
* d = MHD_start_daemon(0, 8080, NULL, NULL, dh, NULL,
|
||||
* MHD_OPTION_ARRAY, ops,
|
||||
* MHD_OPTION_END);
|
||||
* </code>
|
||||
* For options that expect a single pointer argument, the
|
||||
* second member of the struct MHD_OptionItem is ignored.
|
||||
* For options that expect two pointer arguments, the first
|
||||
* argument must be cast to 'intptr_t'.
|
||||
*/
|
||||
MHD_OPTION_ARRAY = 15
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Entry in an MHD_OPTION_ARRAY.
|
||||
*/
|
||||
struct MHD_OptionItem
|
||||
{
|
||||
/**
|
||||
* Which option is being given. Use MHD_OPTION_END
|
||||
* to terminate the array.
|
||||
*/
|
||||
enum MHD_OPTION option;
|
||||
|
||||
/**
|
||||
* Option value (for integer arguments, and for options requiring
|
||||
* two pointer arguments); should be 0 for options that take no
|
||||
* arguments or only a single pointer argument.
|
||||
*/
|
||||
intptr_t value;
|
||||
|
||||
/**
|
||||
* Pointer option value (use NULL for options taking no arguments
|
||||
* or only an integer option).
|
||||
*/
|
||||
void *ptr_value;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The MHD_ValueKind specifies the source of
|
||||
* the key-value pairs in the HTTP protocol.
|
||||
|
||||
Reference in New Issue
Block a user