mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
more work on mhd2 api implementation
This commit is contained in:
+24
-11
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2006-2017 Christian Grothoff, Karlson2k (Evgeny Grin)
|
||||
Copyright (C) 2006-2018 Christian Grothoff, Karlson2k (Evgeny Grin)
|
||||
(and other contributing authors)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
@@ -23,8 +23,9 @@
|
||||
* Note that we do not indicate which of the OLD APIs
|
||||
* simply need to be kept vs. deprecated.
|
||||
*
|
||||
*
|
||||
* The goal is to provide a basis for discussion!
|
||||
* None of this is implemented yet.
|
||||
* Little of this is implemented yet.
|
||||
*
|
||||
* Main goals:
|
||||
* - simplify application callbacks by splitting header/upload/post
|
||||
@@ -64,7 +65,13 @@
|
||||
* supported (include the descriptive string) by using an enum;
|
||||
* - simplify API for common-case of one-shot responses by
|
||||
* eliminating need for destroy response in most cases;
|
||||
*
|
||||
* TODO:
|
||||
* - varargs in upgrade is still there and ugly (and not even used!)
|
||||
* - migrate event loop apis (get fdset, timeout, MHD_run(), etc.)
|
||||
*/
|
||||
#ifndef MICROHTTPD2_H
|
||||
#define MICROHTTPD2_H
|
||||
|
||||
|
||||
/**
|
||||
@@ -1018,8 +1025,8 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
|
||||
* @return #MHD_SC_OK upon success; TODO: define failure modes
|
||||
*/
|
||||
_MHD_EXTERN enum MHD_StatusCode
|
||||
MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
||||
const char *dh);
|
||||
MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
||||
const char *dh);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1356,17 +1363,16 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
|
||||
|
||||
|
||||
/**
|
||||
* Generate option to set a custom timeout for the given connection.
|
||||
* Specified as the number of seconds. Use zero for no timeout. If
|
||||
* timeout was set to zero (or unset) before, setting of a new value
|
||||
* by MHD_connection_set_option() will reset timeout timer.
|
||||
* Set custom timeout for the given connection.
|
||||
* Specified as the number of seconds. Use zero for no timeout.
|
||||
* Calling this function will reset timeout timer.
|
||||
*
|
||||
* @param connection connection to configure timeout for
|
||||
* @param timeout_s new timeout in seconds
|
||||
*/
|
||||
_MHD_EXTERN struct MHD_ConnectionOption
|
||||
MHD_connection_timeout (struct MHD_Connection *connection,
|
||||
unsigned int timeout_s);
|
||||
_MHD_EXTERN void
|
||||
MHD_connection_set_timeout (struct MHD_Connection *connection,
|
||||
unsigned int timeout_s);
|
||||
|
||||
|
||||
/* **************** Request handling functions ***************** */
|
||||
@@ -1792,6 +1798,9 @@ struct MHD_UpgradeResponseHandle;
|
||||
* It allows applications to perform 'special' actions on
|
||||
* the underlying socket from the upgrade.
|
||||
*
|
||||
* FIXME: this API still uses the untyped, ugly varargs.
|
||||
* Should we not modernize this one as well?
|
||||
*
|
||||
* @param urh the handle identifying the connection to perform
|
||||
* the upgrade @a action on.
|
||||
* @param operation which operation should be performed
|
||||
@@ -1987,6 +1996,7 @@ MHD_response_get_header (struct MHD_Response *response,
|
||||
|
||||
/* ************Upload and PostProcessor functions ********************** */
|
||||
|
||||
|
||||
/**
|
||||
* Action telling MHD to continue processing the upload.
|
||||
*
|
||||
@@ -2493,3 +2503,6 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
|
||||
info_type, \
|
||||
return_value) \
|
||||
MHD_daemon_get_information_sz((daemon), (info_type), (return_value), sizeof(union MHD_DaemonInformation));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/action_continue.c
|
||||
* @brief implementation of MHD_action_continue()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* The continue action is being run. Continue
|
||||
* handling the upload.
|
||||
*
|
||||
* @param cls NULL
|
||||
* @param request the request to apply the action to
|
||||
*/
|
||||
static void
|
||||
cont_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
/* not sure yet, but this function body may
|
||||
just legitimately stay empty... */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action telling MHD to continue processing the upload.
|
||||
*
|
||||
* @return action operation, never NULL
|
||||
*/
|
||||
struct MHD_Action *
|
||||
MHD_action_continue (void)
|
||||
{
|
||||
static MHD_Action acont = {
|
||||
.action = &cont_action,
|
||||
.action_cls = NULL
|
||||
};
|
||||
|
||||
return &acont;
|
||||
}
|
||||
|
||||
/* end of action_continue.c */
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/action_from_response.c
|
||||
* @brief implementation of #MHD_action_from_response()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* A response was given as the desired action for a @a request.
|
||||
* Queue the response for the request.
|
||||
*
|
||||
* @param cls the `struct MHD_Response`
|
||||
* @param request the request we are processing
|
||||
*/
|
||||
static void
|
||||
response_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
struct MHD_Response *response = cls;
|
||||
struct MHD_Daemon *daemon = response->daemon;
|
||||
|
||||
if (daemon->shutdown)
|
||||
return MHD_YES; /* If daemon was shut down in parallel,
|
||||
* response will be aborted now or on later stage. */
|
||||
|
||||
#ifdef UPGRADE_SUPPORT
|
||||
if ( (NULL != response->upgrade_handler) &&
|
||||
(0 == (daemon->options & MHD_ALLOW_UPGRADE)) )
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
_("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
|
||||
#endif
|
||||
return MHD_NO;
|
||||
}
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
request->response = response;
|
||||
#if defined(_MHD_HAVE_SENDFILE)
|
||||
if ( (-1 == response->fd)
|
||||
#if HTTPS_SUPPORT
|
||||
|| (NULL != daemon->tls_api)
|
||||
#endif
|
||||
)
|
||||
request->resp_sender = MHD_resp_sender_std;
|
||||
else
|
||||
request->resp_sender = MHD_resp_sender_sendfile;
|
||||
#endif /* _MHD_HAVE_SENDFILE */
|
||||
|
||||
if ( ( (NULL != request->method) &&
|
||||
(MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_HEAD)) ) ||
|
||||
(MHD_HTTP_OK > response->status_code) ||
|
||||
(MHD_HTTP_NO_CONTENT == response->status_code) ||
|
||||
(MHD_HTTP_NOT_MODIFIED == response->status_code) )
|
||||
{
|
||||
/* if this is a "HEAD" request, or a status code for
|
||||
which a body is not allowed, pretend that we
|
||||
have already sent the full message body. */
|
||||
request->response_write_position = response->total_size;
|
||||
}
|
||||
if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
|
||||
(NULL != connection->method) &&
|
||||
( (MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_POST)) ||
|
||||
(MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_PUT))) )
|
||||
{
|
||||
/* response was queued "early", refuse to read body / footers or
|
||||
further requests! */
|
||||
connection->read_closed = true;
|
||||
request->state = MHD_CONNECTION_FOOTERS_RECEIVED;
|
||||
}
|
||||
if (! request->in_idle)
|
||||
(void) MHD_connection_handle_idle (connection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a @a response to an action. If @a consume
|
||||
* is set, the reference to the @a response is consumed
|
||||
* by the conversion. If @a consume is #MHD_NO, then
|
||||
* the response can be converted to actions in the future.
|
||||
* However, the @a response is frozen by this step and
|
||||
* must no longer be modified (i.e. by setting headers).
|
||||
*
|
||||
* @param response response to convert, not NULL
|
||||
* @param destroy_after_use should the response object be consumed?
|
||||
* @return corresponding action, never returns NULL
|
||||
*
|
||||
* Implementation note: internally, this is largely just
|
||||
* a cast (and possibly an RC increment operation),
|
||||
* as a response *is* an action. As no memory is
|
||||
* allocated, this operation cannot fail.
|
||||
*/
|
||||
_MHD_EXTERN struct MHD_Action *
|
||||
MHD_action_from_response (struct MHD_Response *response,
|
||||
enum MHD_bool destroy_after_use)
|
||||
{
|
||||
response->action.action = &response_action;
|
||||
response->action.action_cls = response;
|
||||
if (! destroy_after_use)
|
||||
{
|
||||
MHD_mutex_lock_chk_ (&response->mutex);
|
||||
response->reference_count++;
|
||||
MHD_mutex_unlock_chk_ (&response->mutex);
|
||||
}
|
||||
return &response->action;
|
||||
}
|
||||
|
||||
/* end of action_from_response */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/action_parse_post.c
|
||||
* @brief implementation of MHD_action_parse_post()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create an action that parses a POST request.
|
||||
*
|
||||
* This action can be used to (incrementally) parse the data portion
|
||||
* of a POST request. Note that some buggy browsers fail to set the
|
||||
* encoding type. If you want to support those, you may have to call
|
||||
* #MHD_set_connection_value with the proper encoding type before
|
||||
* returning this action (if no supported encoding type is detected,
|
||||
* returning this action will cause a bad request to be returned to
|
||||
* the client).
|
||||
*
|
||||
* @param buffer_size maximum number of bytes to use for
|
||||
* internal buffering (used only for the parsing,
|
||||
* specifically the parsing of the keys). A
|
||||
* tiny value (256-1024) should be sufficient.
|
||||
* Do NOT use a value smaller than 256. For good
|
||||
* performance, use 32 or 64k (i.e. 65536).
|
||||
* @param iter iterator to be called with the parsed data,
|
||||
* Must NOT be NULL.
|
||||
* @param iter_cls first argument to @a iter
|
||||
* @return NULL on error (out of memory, unsupported encoding),
|
||||
* otherwise a PP handle
|
||||
* @ingroup request
|
||||
*/
|
||||
struct MHD_Action *
|
||||
MHD_action_parse_post (size_t buffer_size,
|
||||
MHD_PostDataIterator iter,
|
||||
void *iter_cls)
|
||||
{
|
||||
return NULL; /* not yet implemented */
|
||||
}
|
||||
|
||||
/* end of action_parse_post.c */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/action_process_upload.c
|
||||
* @brief implementation of MHD_action_process_upload()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Internal details about an upload action.
|
||||
*/
|
||||
struct UploadAction
|
||||
{
|
||||
/**
|
||||
* An upload action is an action. This field
|
||||
* must come first!
|
||||
*/
|
||||
struct MHD_Action action;
|
||||
|
||||
MHD_UploadCallback uc;
|
||||
|
||||
void *uc_cls;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The application wants to process uploaded data for
|
||||
* the given request. Do it!
|
||||
*
|
||||
* @param cls the `struct UploadAction` with the
|
||||
* function we are to call for upload data
|
||||
* @param request the request for which we are to process
|
||||
* upload data
|
||||
*/
|
||||
static void
|
||||
upload_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
struct UploadAction *ua = cls;
|
||||
|
||||
(void) ua;
|
||||
// FIXME: implement!
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an action that handles an upload.
|
||||
*
|
||||
* @param uc function to call with uploaded data
|
||||
* @param uc_cls closure for @a uc
|
||||
* @return NULL on error (out of memory)
|
||||
* @ingroup action
|
||||
*/
|
||||
struct MHD_Action *
|
||||
MHD_action_process_upload (MHD_UploadCallback uc,
|
||||
void *uc_cls)
|
||||
{
|
||||
struct UploadAction *ua;
|
||||
|
||||
if (NULL == (ua = malloc (sizeof (struct UploadAction))))
|
||||
return NULL;
|
||||
ua->action = &upload_action;
|
||||
ua->action_cls = ua;
|
||||
ua->uc = uc;
|
||||
ua->uc_cls = uc_cls;
|
||||
return ua;
|
||||
}
|
||||
|
||||
|
||||
/* end of action_process_upload.c */
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/action_suspend.c
|
||||
* @brief implementation of MHD_action_suspend()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* The suspend action is being run. Suspend handling
|
||||
* of the given request.
|
||||
*
|
||||
* @param cls NULL
|
||||
* @param request the request to apply the action to
|
||||
*/
|
||||
static void
|
||||
suspend_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
struct MHD_Daemon *daemon = connection->daemon;
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
if (connection->resuming)
|
||||
{
|
||||
/* suspending again while we didn't even complete resuming yet */
|
||||
connection->resuming = false;
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
return;
|
||||
}
|
||||
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
|
||||
{
|
||||
if (connection->connection_timeout == daemon->connection_timeout)
|
||||
XDLL_remove (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
else
|
||||
XDLL_remove (daemon->manual_timeout_head,
|
||||
daemon->manual_timeout_tail,
|
||||
connection);
|
||||
}
|
||||
DLL_remove (daemon->connections_head,
|
||||
daemon->connections_tail,
|
||||
connection);
|
||||
mhd_assert (! connection->suspended);
|
||||
DLL_insert (daemon->suspended_connections_head,
|
||||
daemon->suspended_connections_tail,
|
||||
connection);
|
||||
connection->suspended = true;
|
||||
#ifdef EPOLL_SUPPORT
|
||||
if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
|
||||
{
|
||||
if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
|
||||
{
|
||||
EDLL_remove (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
}
|
||||
if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
|
||||
{
|
||||
if (0 != epoll_ctl (daemon->epoll_fd,
|
||||
EPOLL_CTL_DEL,
|
||||
connection->socket_fd,
|
||||
NULL))
|
||||
MHD_PANIC (_("Failed to remove FD from epoll set\n"));
|
||||
connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
|
||||
}
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
|
||||
}
|
||||
#endif
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Suspend handling of network data for a given request. This can
|
||||
* be used to dequeue a request from MHD's event loop for a while.
|
||||
*
|
||||
* If you use this API in conjunction with a internal select or a
|
||||
* thread pool, you must set the option #MHD_USE_ITC to
|
||||
* ensure that a resumed request is immediately processed by MHD.
|
||||
*
|
||||
* Suspended requests continue to count against the total number of
|
||||
* requests allowed (per daemon, as well as per IP, if such limits
|
||||
* are set). Suspended requests will NOT time out; timeouts will
|
||||
* restart when the request handling is resumed. While a
|
||||
* request is suspended, MHD will not detect disconnects by the
|
||||
* client.
|
||||
*
|
||||
* The only safe time to suspend a request is from either a
|
||||
* #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a
|
||||
* #MHD_RequestfetchResponseCallback. Suspending a request
|
||||
* at any other time will cause an assertion failure.
|
||||
*
|
||||
* Finally, it is an API violation to call #MHD_daemon_stop() while
|
||||
* having suspended requests (this will at least create memory and
|
||||
* socket leaks or lead to undefined behavior). You must explicitly
|
||||
* resume all requests before stopping the daemon.
|
||||
*
|
||||
* @return action to cause a request to be suspended.
|
||||
*/
|
||||
struct MHD_Action *
|
||||
MHD_action_suspend (void)
|
||||
{
|
||||
static MHD_Action suspend = {
|
||||
.action = &suspend_action,
|
||||
.action_cls = NULL
|
||||
};
|
||||
|
||||
return &suspend;
|
||||
}
|
||||
|
||||
/* end of action_suspend.c */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/connection_info.c
|
||||
* @brief implementation of MHD_connection_get_information_sz()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Obtain information about the given connection.
|
||||
* Use wrapper macro #MHD_connection_get_information() instead of direct use
|
||||
* of this function.
|
||||
*
|
||||
* @param connection what connection to get information about
|
||||
* @param info_type what information is desired?
|
||||
* @param[out] return_value pointer to union where requested information will
|
||||
* be stored
|
||||
* @param return_value_size size of union MHD_ConnectionInformation at compile
|
||||
* time
|
||||
* @return #MHD_YES on success, #MHD_NO on error
|
||||
* (@a info_type is unknown, NULL pointer etc.)
|
||||
* @ingroup specialized
|
||||
*/
|
||||
enum MHD_Bool
|
||||
MHD_connection_get_information_sz (struct MHD_Connection *connection,
|
||||
enum MHD_ConnectionInformationType info_type,
|
||||
union MHD_ConnectionInformation *return_value,
|
||||
size_t return_value_size)
|
||||
{
|
||||
return MHD_NO; /* FIXME: not yet implemented */
|
||||
}
|
||||
|
||||
/* end of connection_info.c */
|
||||
@@ -1,16 +1,113 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate option to set a custom timeout for the given connection.
|
||||
* Specified as the number of seconds. Use zero for no timeout. If
|
||||
* timeout was set to zero (or unset) before, setting of a new value
|
||||
* by MHD_connection_set_option() will reset timeout timer.
|
||||
* @file lib/connection_options.c
|
||||
* @brief functions to set per-connection options
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Set custom timeout for the given connection. Specified as the
|
||||
* number of seconds. Use zero for no timeout. Calling this function
|
||||
* will reset timeout timer.
|
||||
*
|
||||
* @param connection connection to configure timeout for
|
||||
* @param timeout_s new timeout in seconds
|
||||
*/
|
||||
struct MHD_ConnectionOption
|
||||
MHD_connection_timeout (struct MHD_Connection *connection,
|
||||
unsigned int timeout_s);
|
||||
void
|
||||
MHD_connection_set_timeout (struct MHD_Connection *connection,
|
||||
unsigned int timeout_s)
|
||||
{
|
||||
struct MHD_Daemon *daemon = connection->daemon;
|
||||
|
||||
connection->last_activity = MHD_monotonic_sec_counter();
|
||||
if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
|
||||
{
|
||||
/* Simple case, no need to lock to update DLLs */
|
||||
connection->connection_timeout = (time_t) timeout_s;
|
||||
return;
|
||||
}
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
if (! connection->suspended)
|
||||
{
|
||||
if (connection->connection_timeout == daemon->connection_timeout)
|
||||
XDLL_remove (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
else
|
||||
XDLL_remove (daemon->manual_timeout_head,
|
||||
daemon->manual_timeout_tail,
|
||||
connection);
|
||||
}
|
||||
connection->connection_timeout = (time_t) timeout_s;
|
||||
if (! connection->suspended)
|
||||
{
|
||||
if (connection->connection_timeout == daemon->connection_timeout)
|
||||
XDLL_insert (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
else
|
||||
XDLL_insert (daemon->manual_timeout_head,
|
||||
daemon->manual_timeout_tail,
|
||||
connection);
|
||||
}
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the 'last_activity' field of the connection to the current
|
||||
* time and move the connection to the head of the 'normal_timeout'
|
||||
* list if the timeout for the connection uses the default value.
|
||||
*
|
||||
* @param connection the connection that saw some activity
|
||||
*/
|
||||
void
|
||||
MHD_update_last_activity_ (struct MHD_Connection *connection)
|
||||
{
|
||||
struct MHD_Daemon *daemon = connection->daemon;
|
||||
|
||||
if (0 == connection->connection_timeout)
|
||||
return; /* Skip update of activity for connections
|
||||
without timeout timer. */
|
||||
if (connection->suspended)
|
||||
return; /* no activity on suspended connections */
|
||||
|
||||
connection->last_activity = MHD_monotonic_sec_counter();
|
||||
if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
|
||||
return; /* each connection has personal timeout */
|
||||
|
||||
if (connection->connection_timeout != daemon->connection_timeout)
|
||||
return; /* custom timeout, no need to move it in "normal" DLL */
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
/* move connection to head of timeout list (by remove + add operation) */
|
||||
XDLL_remove (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
XDLL_insert (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
}
|
||||
|
||||
/* end of connection_options.c */
|
||||
|
||||
+45
-10
@@ -1,20 +1,52 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain information about the given daemon
|
||||
* (not fully implemented!).
|
||||
* @file lib/daemon_info.c
|
||||
* @brief implementation of MHD_daemon_get_information_sz()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Obtain information about the given daemon.
|
||||
* Use wrapper macro #MHD_daemon_get_information() instead of direct use
|
||||
* of this function.
|
||||
*
|
||||
* @param daemon what daemon to get information about
|
||||
* @param info_type what information is desired?
|
||||
* @param ... depends on @a info_type
|
||||
* @return NULL if this information is not available
|
||||
* (or if the @a info_type is unknown)
|
||||
* @param[out] return_value pointer to union where requested information will
|
||||
* be stored
|
||||
* @param return_value_size size of union MHD_DaemonInformation at compile
|
||||
* time
|
||||
* @return #MHD_YES on success, #MHD_NO on error
|
||||
* (@a info_type is unknown, NULL pointer etc.)
|
||||
* @ingroup specialized
|
||||
*/
|
||||
const union MHD_DaemonInfo *
|
||||
MHD_get_daemon_info (struct MHD_Daemon *daemon,
|
||||
enum MHD_DaemonInfoType info_type,
|
||||
...)
|
||||
enum MHD_Bool
|
||||
MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
|
||||
enum MHD_DaemonInformationType info_type,
|
||||
union MHD_DaemonInformation *return_value,
|
||||
size_t return_value_size)
|
||||
{
|
||||
#if OLD
|
||||
if (NULL == daemon)
|
||||
return NULL;
|
||||
switch (info_type)
|
||||
@@ -55,6 +87,9 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
return MHD_NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* end of daemon_info.c */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/**
|
||||
* @file lib/daemon.c
|
||||
* @brief main functions to start a daemon
|
||||
* @brief functions to start a daemon
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
@@ -642,8 +642,8 @@ setup_thread_pool (struct MHD_Daemon *daemon)
|
||||
enum MHD_StatusCode sc;
|
||||
|
||||
/* Allocate memory for pooled objects */
|
||||
daemon->worker_pool = calloc (daemon->threading_model,
|
||||
sizeof (struct MHD_Daemon));
|
||||
daemon->worker_pool = MHD_calloc_ (daemon->threading_model,
|
||||
sizeof (struct MHD_Daemon));
|
||||
if (NULL == daemon->worker_pool)
|
||||
return MHD_SC_THREAD_POOL_MALLOC_FAILURE;
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/init.c
|
||||
* @brief initialization routines
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "init.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/init.h
|
||||
* @brief functions to initialize library
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#ifndef INIT_H
|
||||
|
||||
+167
-21
@@ -561,12 +561,6 @@ struct MHD_Request
|
||||
*/
|
||||
enum MHD_RequestEventLoopInfo event_loop_info;
|
||||
|
||||
/**
|
||||
* HTTP response code. Only valid if response object
|
||||
* is already set.
|
||||
*/
|
||||
unsigned int responseCode;
|
||||
|
||||
/**
|
||||
* Did we ever call the "default_handler" on this request? (this
|
||||
* flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED
|
||||
@@ -594,16 +588,6 @@ struct MHD_Request
|
||||
* be set to #MHD_NO again (before the final call to the handler).
|
||||
*/
|
||||
bool have_chunked_upload;
|
||||
|
||||
/**
|
||||
* Is the request suspended?
|
||||
*/
|
||||
bool suspended;
|
||||
|
||||
/**
|
||||
* Is the request wanting to resume?
|
||||
*/
|
||||
bool resuming;
|
||||
};
|
||||
|
||||
|
||||
@@ -660,6 +644,15 @@ struct MHD_Connection
|
||||
*/
|
||||
struct MHD_Request request;
|
||||
|
||||
/**
|
||||
* Is the connection suspended?
|
||||
*/
|
||||
bool suspended;
|
||||
|
||||
/**
|
||||
* Is the connection wanting to resume?
|
||||
*/
|
||||
bool resuming;
|
||||
|
||||
/**
|
||||
* Set to `true` if the thread has been joined.
|
||||
@@ -679,8 +672,7 @@ struct MHD_Connection
|
||||
*/
|
||||
bool read_closed;
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Length of the foreign address.
|
||||
*/
|
||||
socklen_t addr_len;
|
||||
@@ -998,13 +990,167 @@ struct MHD_Daemon
|
||||
*/
|
||||
bool allow_address_reuse;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Action function implementing some action to be
|
||||
* performed on a request.
|
||||
*
|
||||
* @param cls action-specfic closure
|
||||
* @param request the request on which the action is to be performed
|
||||
*/
|
||||
typedef void
|
||||
(*ActionCallback) (void *cls,
|
||||
const struct MHD_Request *request);
|
||||
|
||||
|
||||
/**
|
||||
* Actions are returned by the application to drive the request
|
||||
* handling of MHD.
|
||||
*/
|
||||
struct MHD_Action
|
||||
{
|
||||
|
||||
/**
|
||||
* Function to call for the action.
|
||||
*/
|
||||
ActionCallback action;
|
||||
|
||||
/**
|
||||
* Closure for @a action
|
||||
*/
|
||||
void *action_cls;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Representation of an HTTP response.
|
||||
*/
|
||||
struct MHD_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* A response *is* an action. See also
|
||||
* #MHD_action_from_response(). Hence this field
|
||||
* must be the first field in a response!
|
||||
*/
|
||||
struct MHD_Action action;
|
||||
|
||||
/**
|
||||
* Headers to send for the response. Initially
|
||||
* the linked list is created in inverse order;
|
||||
* the order should be inverted before sending!
|
||||
*/
|
||||
struct MHD_HTTP_Header *first_header;
|
||||
|
||||
/**
|
||||
* Buffer pointing to data that we are supposed
|
||||
* to send as a response.
|
||||
*/
|
||||
char *data;
|
||||
|
||||
/**
|
||||
* Closure to give to the content reader @e crc
|
||||
* and content reader free callback @e crfc.
|
||||
*/
|
||||
void *crc_cls;
|
||||
|
||||
/**
|
||||
* How do we get more data? NULL if we are
|
||||
* given all of the data up front.
|
||||
*/
|
||||
MHD_ContentReaderCallback crc;
|
||||
|
||||
/**
|
||||
* NULL if data must not be freed, otherwise
|
||||
* either user-specified callback or "&free".
|
||||
*/
|
||||
MHD_ContentReaderFreeCallback crfc;
|
||||
|
||||
/**
|
||||
* Function to call once MHD is finished with
|
||||
* the request, may be NULL.
|
||||
*/
|
||||
MHD_RequestTerminationCallback termination_cb;
|
||||
|
||||
/**
|
||||
* Closure for @e termination_cb.
|
||||
*/
|
||||
void *termination_cb_cls;
|
||||
|
||||
#ifdef UPGRADE_SUPPORT
|
||||
/**
|
||||
* Application function to call once we are done sending the headers
|
||||
* of the response; NULL unless this is a response created with
|
||||
* #MHD_create_response_for_upgrade().
|
||||
*/
|
||||
MHD_UpgradeHandler upgrade_handler;
|
||||
|
||||
/**
|
||||
* Closure for @e uh.
|
||||
*/
|
||||
void *upgrade_handler_cls;
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
|
||||
/**
|
||||
* Mutex to synchronize access to @e data, @e size and
|
||||
* @e reference_count.
|
||||
*/
|
||||
MHD_mutex_ mutex;
|
||||
|
||||
/**
|
||||
* Set to #MHD_SIZE_UNKNOWN if size is not known.
|
||||
*/
|
||||
uint64_t total_size;
|
||||
|
||||
/**
|
||||
* At what offset in the stream is the
|
||||
* beginning of @e data located?
|
||||
*/
|
||||
uint64_t data_start;
|
||||
|
||||
/**
|
||||
* Offset to start reading from when using @e fd.
|
||||
*/
|
||||
uint64_t fd_off;
|
||||
|
||||
/**
|
||||
* Number of bytes ready in @e data (buffer may be larger
|
||||
* than what is filled with payload).
|
||||
*/
|
||||
size_t data_size;
|
||||
|
||||
/**
|
||||
* Size of the data buffer @e data.
|
||||
*/
|
||||
size_t data_buffer_size;
|
||||
|
||||
/**
|
||||
* HTTP status code of the response.
|
||||
*/
|
||||
enum MHD_HTTP_StatusCode status_code;
|
||||
|
||||
/**
|
||||
* Reference count for this response. Free once the counter hits
|
||||
* zero.
|
||||
*/
|
||||
unsigned int reference_count;
|
||||
|
||||
/**
|
||||
* File-descriptor if this response is FD-backed.
|
||||
*/
|
||||
int fd;
|
||||
|
||||
/**
|
||||
* Only respond in HTTP 1.0 mode.
|
||||
*/
|
||||
bool v10_only;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/panic.c
|
||||
* @brief functions to panic (abort)
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/request_info.c
|
||||
* @brief implementation of MHD_request_get_information_sz()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Obtain information about the given request.
|
||||
* Use wrapper macro #MHD_request_get_information() instead of direct use
|
||||
* of this function.
|
||||
*
|
||||
* @param request what request to get information about
|
||||
* @param info_type what information is desired?
|
||||
* @param[out] return_value pointer to union where requested information will
|
||||
* be stored
|
||||
* @param return_value_size size of union MHD_RequestInformation at compile
|
||||
* time
|
||||
* @return #MHD_YES on success, #MHD_NO on error
|
||||
* (@a info_type is unknown, NULL pointer etc.)
|
||||
* @ingroup specialized
|
||||
*/
|
||||
enum MHD_Bool
|
||||
MHD_request_get_information_sz (struct MHD_Request *request,
|
||||
enum MHD_RequestInformationType info_type,
|
||||
union MHD_RequestInformation *return_value,
|
||||
size_t return_value_size)
|
||||
{
|
||||
return MHD_NO; /* not implemented */
|
||||
}
|
||||
|
||||
|
||||
/* end of request_info.c */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/request_resume.c
|
||||
* @brief implementation of MHD_request_resume()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Resume handling of network data for suspended request. It is
|
||||
* safe to resume a suspended request at any time. Calling this
|
||||
* function on a request that was not previously suspended will
|
||||
* result in undefined behavior.
|
||||
*
|
||||
* If you are using this function in ``external'' select mode, you must
|
||||
* make sure to run #MHD_run() afterwards (before again calling
|
||||
* #MHD_get_fdset(), as otherwise the change may not be reflected in
|
||||
* the set returned by #MHD_get_fdset() and you may end up with a
|
||||
* request that is stuck until the next network activity.
|
||||
*
|
||||
* @param request the request to resume
|
||||
*/
|
||||
void
|
||||
MHD_request_resume (struct MHD_Request *request)
|
||||
{
|
||||
abort (); // not implemented...
|
||||
}
|
||||
|
||||
/* end of request_resume.c */
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response.c
|
||||
* @brief implementation of general response functions
|
||||
* @author Daniel Pittman
|
||||
* @author Christian Grothoff
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Add a header or footer line to the response.
|
||||
*
|
||||
* @param response response to add a header to
|
||||
* @param kind header or footer
|
||||
* @param header the header to add
|
||||
* @param content value to add
|
||||
* @return false on error (i.e. invalid header or content format).
|
||||
*/
|
||||
static bool
|
||||
add_response_entry (struct MHD_Response *response,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *header,
|
||||
const char *content)
|
||||
{
|
||||
struct MHD_HTTP_Header *hdr;
|
||||
|
||||
if ( (NULL == header) ||
|
||||
(NULL == content) ||
|
||||
(0 == header[0]) ||
|
||||
(0 == content[0]) ||
|
||||
(NULL != strchr (header, '\t')) ||
|
||||
(NULL != strchr (header, '\r')) ||
|
||||
(NULL != strchr (header, '\n')) ||
|
||||
(NULL != strchr (content, '\t')) ||
|
||||
(NULL != strchr (content, '\r')) ||
|
||||
(NULL != strchr (content, '\n')) )
|
||||
return false;
|
||||
if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
|
||||
return false;
|
||||
if (NULL == (hdr->header = strdup (header)))
|
||||
{
|
||||
free (hdr);
|
||||
return false;
|
||||
}
|
||||
if (NULL == (hdr->value = strdup (content)))
|
||||
{
|
||||
free (hdr->header);
|
||||
free (hdr);
|
||||
return false;
|
||||
}
|
||||
hdr->kind = kind;
|
||||
hdr->next = response->first_header;
|
||||
response->first_header = hdr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Explicitly decrease reference counter of a response object. If the
|
||||
* counter hits zero, destroys a response object and associated
|
||||
* resources. Usually, this is implicitly done by converting a
|
||||
* response to an action and returning the action to MHD.
|
||||
*
|
||||
* @param response response to decrement RC of
|
||||
* @ingroup response
|
||||
*/
|
||||
void
|
||||
MHD_response_queue_for_destroy (struct MHD_Response *response)
|
||||
{
|
||||
struct MHD_HTTP_Header *pos;
|
||||
|
||||
MHD_mutex_lock_chk_ (&response->mutex);
|
||||
if (0 != --(response->reference_count))
|
||||
{
|
||||
MHD_mutex_unlock_chk_ (&response->mutex);
|
||||
return;
|
||||
}
|
||||
MHD_mutex_unlock_chk_ (&response->mutex);
|
||||
MHD_mutex_destroy_chk_ (&response->mutex);
|
||||
if (NULL != response->crfc)
|
||||
response->crfc (response->crc_cls);
|
||||
while (NULL != response->first_header)
|
||||
{
|
||||
pos = response->first_header;
|
||||
response->first_header = pos->next;
|
||||
free (pos->header);
|
||||
free (pos->value);
|
||||
free (pos);
|
||||
}
|
||||
free (response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a header line to the response.
|
||||
*
|
||||
* @param response response to add a header to
|
||||
* @param header the header to add
|
||||
* @param content value to add
|
||||
* @return #MHD_NO on error (i.e. invalid header or content format),
|
||||
* or out of memory
|
||||
* @ingroup response
|
||||
*/
|
||||
enum MHD_Bool
|
||||
MHD_response_add_header (struct MHD_Response *response,
|
||||
const char *header,
|
||||
const char *content)
|
||||
{
|
||||
return add_response_entry (response,
|
||||
MHD_HEADER_KIND,
|
||||
header,
|
||||
content) ? MHD_TRUE : MHD_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a tailer line to the response.
|
||||
*
|
||||
* @param response response to add a footer to
|
||||
* @param footer the footer to add
|
||||
* @param content value to add
|
||||
* @return #MHD_NO on error (i.e. invalid footer or content format),
|
||||
* or out of memory
|
||||
* @ingroup response
|
||||
*/
|
||||
enum MHD_Bool
|
||||
MHD_response_add_trailer (struct MHD_Response *response,
|
||||
const char *footer,
|
||||
const char *content)
|
||||
{
|
||||
return add_response_entry (response,
|
||||
MHD_FOOTER_KIND,
|
||||
footer,
|
||||
content) ? MHD_TRUE : MHD_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a header (or footer) line from the response.
|
||||
*
|
||||
* @param response response to remove a header from
|
||||
* @param header the header to delete
|
||||
* @param content value to delete
|
||||
* @return #MHD_NO on error (no such header known)
|
||||
* @ingroup response
|
||||
*/
|
||||
enum MHD_Bool
|
||||
MHD_response_del_header (struct MHD_Response *response,
|
||||
const char *header,
|
||||
const char *content)
|
||||
{
|
||||
struct MHD_HTTP_Header *pos;
|
||||
struct MHD_HTTP_Header *prev;
|
||||
|
||||
if ( (NULL == header) ||
|
||||
(NULL == content) )
|
||||
return MHD_NO;
|
||||
prev = NULL;
|
||||
pos = response->first_header;
|
||||
while (NULL != pos)
|
||||
{
|
||||
if ((0 == strcmp (header,
|
||||
pos->header)) &&
|
||||
(0 == strcmp (content,
|
||||
pos->value)))
|
||||
{
|
||||
free (pos->header);
|
||||
free (pos->value);
|
||||
if (NULL == prev)
|
||||
response->first_header = pos->next;
|
||||
else
|
||||
prev->next = pos->next;
|
||||
free (pos);
|
||||
return MHD_YES;
|
||||
}
|
||||
prev = pos;
|
||||
pos = pos->next;
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all of the headers (and footers) added to a response.
|
||||
*
|
||||
* @param response response to query
|
||||
* @param iterator callback to call on each header;
|
||||
* maybe NULL (then just count headers)
|
||||
* @param iterator_cls extra argument to @a iterator
|
||||
* @return number of entries iterated over
|
||||
* @ingroup response
|
||||
*/
|
||||
unsigned int
|
||||
MHD_response_get_headers (struct MHD_Response *response,
|
||||
MHD_KeyValueIterator iterator,
|
||||
void *iterator_cls)
|
||||
{
|
||||
unsigned int numHeaders = 0;
|
||||
struct MHD_HTTP_Header *pos;
|
||||
|
||||
for (pos = response->first_header;
|
||||
NULL != pos;
|
||||
pos = pos->next)
|
||||
{
|
||||
numHeaders++;
|
||||
if ( (NULL != iterator) &&
|
||||
(MHD_YES != iterator (iterator_cls,
|
||||
pos->kind,
|
||||
pos->header,
|
||||
pos->value)) )
|
||||
break;
|
||||
}
|
||||
return numHeaders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a particular header (or footer) from the response.
|
||||
*
|
||||
* @param response response to query
|
||||
* @param key which header to get
|
||||
* @return NULL if header does not exist
|
||||
* @ingroup response
|
||||
*/
|
||||
const char *
|
||||
MHD_response_get_header (struct MHD_Response *response,
|
||||
const char *key)
|
||||
{
|
||||
struct MHD_HTTP_Header *pos;
|
||||
|
||||
if (NULL == key)
|
||||
return NULL;
|
||||
for (pos = response->first_header;
|
||||
NULL != pos;
|
||||
pos = pos->next)
|
||||
{
|
||||
if (MHD_str_equal_caseless_ (pos->header,
|
||||
key))
|
||||
return pos->value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* end of response.c */
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response_for_upgrade.c
|
||||
* @brief implementation of MHD_response_for_upgrade()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Create a response object that can be used for 101 UPGRADE
|
||||
* responses, for example to implement WebSockets. After sending the
|
||||
* response, control over the data stream is given to the callback (which
|
||||
* can then, for example, start some bi-directional communication).
|
||||
* If the response is queued for multiple connections, the callback
|
||||
* will be called for each connection. The callback
|
||||
* will ONLY be called after the response header was successfully passed
|
||||
* to the OS; if there are communication errors before, the usual MHD
|
||||
* connection error handling code will be performed.
|
||||
*
|
||||
* MHD will automatically set the correct HTTP status
|
||||
* code (#MHD_HTTP_SWITCHING_PROTOCOLS).
|
||||
* Setting correct HTTP headers for the upgrade must be done
|
||||
* manually (this way, it is possible to implement most existing
|
||||
* WebSocket versions using this API; in fact, this API might be useful
|
||||
* for any protocol switch, not just WebSockets). Note that
|
||||
* draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
|
||||
* way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
|
||||
* cannot be generated; instead, MHD will always produce "HTTP/1.1 101
|
||||
* Switching Protocols" (if the response code 101 is used).
|
||||
*
|
||||
* As usual, the response object can be extended with header
|
||||
* information and then be used any number of times (as long as the
|
||||
* header information is not connection-specific).
|
||||
*
|
||||
* @param upgrade_handler function to call with the "upgraded" socket
|
||||
* @param upgrade_handler_cls closure for @a upgrade_handler
|
||||
* @return NULL on error (i.e. invalid arguments, out of memory)
|
||||
*/
|
||||
struct MHD_Response *
|
||||
MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
|
||||
void *upgrade_handler_cls)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
|
||||
mhd_assert (NULL != upgrade_handler);
|
||||
response = MHD_calloc_ (1,
|
||||
sizeof (struct MHD_Response));
|
||||
if (NULL == response)
|
||||
return NULL;
|
||||
if (! MHD_mutex_init_ (&response->mutex))
|
||||
{
|
||||
free (response);
|
||||
return NULL;
|
||||
}
|
||||
response->upgrade_handler = upgrade_handler;
|
||||
response->upgrade_handler_cls = upgrade_handler_cls;
|
||||
response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS;
|
||||
response->total_size = MHD_SIZE_UNKNOWN;
|
||||
response->reference_count = 1;
|
||||
if (MHD_NO ==
|
||||
MHD_add_response_header (response,
|
||||
MHD_HTTP_HEADER_CONNECTION,
|
||||
"Upgrade"))
|
||||
{
|
||||
MHD_destroy_response (response);
|
||||
return NULL;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/* end of response_for_upgrade.c */
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response_from_buffer.c
|
||||
* @brief implementation of MHD_response_from_buffer()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Create a response object. The response object can be extended with
|
||||
* header information and then be used any number of times.
|
||||
*
|
||||
* @param sc status code to use for the response;
|
||||
* #MHD_HTTP_NO_CONTENT is only valid if @a size is 0;
|
||||
* @param size size of the data portion of the response
|
||||
* @param buffer size bytes containing the response's data portion
|
||||
* @param mode flags for buffer management
|
||||
* @return NULL on error (i.e. invalid arguments, out of memory)
|
||||
* @ingroup response
|
||||
*/
|
||||
struct MHD_Response *
|
||||
MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
|
||||
size_t size,
|
||||
void *buffer,
|
||||
enum MHD_ResponseMemoryMode mode)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
void *tmp;
|
||||
|
||||
mhd_assert ( (NULL != data) ||
|
||||
(0 == size) );
|
||||
if (NULL ==
|
||||
(response = MHD_calloc_ (1,
|
||||
sizeof (struct MHD_Response))))
|
||||
return NULL;
|
||||
response->fd = -1;
|
||||
if (! MHD_mutex_init_ (&response->mutex))
|
||||
{
|
||||
free (response);
|
||||
return NULL;
|
||||
}
|
||||
if ( (MHD_RESPMEM_MUST_COPY == mode) &&
|
||||
(size > 0) )
|
||||
{
|
||||
if (NULL == (tmp = malloc (size)))
|
||||
{
|
||||
MHD_mutex_destroy_chk_ (&response->mutex);
|
||||
free (response);
|
||||
return NULL;
|
||||
}
|
||||
memcpy (tmp,
|
||||
data,
|
||||
size);
|
||||
data = tmp;
|
||||
}
|
||||
if (MHD_RESPMEM_PERSISTENT != mode)
|
||||
{
|
||||
response->crfc = &free;
|
||||
response->crc_cls = data;
|
||||
}
|
||||
response->status_code = sc;
|
||||
response->reference_count = 1;
|
||||
response->total_size = size;
|
||||
response->data = data;
|
||||
response->data_size = size;
|
||||
return response;
|
||||
}
|
||||
|
||||
/* end of response_from_buffer.c */
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response_from_callback.c
|
||||
* @brief implementation of MHD_response_from_callback()
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Create a response action. The response object can be extended with
|
||||
* header information and then be used any number of times.
|
||||
*
|
||||
* @param sc status code to return
|
||||
* @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
|
||||
* @param block_size preferred block size for querying crc (advisory only,
|
||||
* MHD may still call @a crc using smaller chunks); this
|
||||
* is essentially the buffer size used for IO, clients
|
||||
* should pick a value that is appropriate for IO and
|
||||
* memory performance requirements
|
||||
* @param crc callback to use to obtain response data
|
||||
* @param crc_cls extra argument to @a crc
|
||||
* @param crfc callback to call to free @a crc_cls resources
|
||||
* @return NULL on error (i.e. invalid arguments, out of memory)
|
||||
* @ingroup response
|
||||
*/
|
||||
struct MHD_Response *
|
||||
MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
|
||||
uint64_t size,
|
||||
size_t block_size,
|
||||
MHD_ContentReaderCallback crc,
|
||||
void *crc_cls,
|
||||
MHD_ContentReaderFreeCallback crfc)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
|
||||
mhd_assert (NULL != crc);
|
||||
mhd_assert (0 != block_size);
|
||||
if (NULL ==
|
||||
(response = MHD_calloc_ (1,
|
||||
sizeof (struct MHD_Response) +
|
||||
block_size)))
|
||||
return NULL;
|
||||
response->fd = -1;
|
||||
response->status_code = sc;
|
||||
response->data = (void *) &response[1];
|
||||
response->data_buffer_size = block_size;
|
||||
if (! MHD_mutex_init_ (&response->mutex))
|
||||
{
|
||||
free (response);
|
||||
return NULL;
|
||||
}
|
||||
response->crc = crc;
|
||||
response->crfc = crfc;
|
||||
response->crc_cls = crc_cls;
|
||||
response->reference_count = 1;
|
||||
response->total_size = size;
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
/* end of response_from_callback.c */
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response_from_fd.c
|
||||
* @brief implementation of MHD_response_from_fd()
|
||||
* @author Daniel Pittman
|
||||
* @author Christian Grothoff
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Given a file descriptor, read data from the file
|
||||
* to generate the response.
|
||||
*
|
||||
* @param cls pointer to the response
|
||||
* @param pos offset in the file to access
|
||||
* @param buf where to write the data
|
||||
* @param max number of bytes to write at most
|
||||
* @return number of bytes written
|
||||
*/
|
||||
static ssize_t
|
||||
file_reader (void *cls,
|
||||
uint64_t pos,
|
||||
char *buf,
|
||||
size_t max)
|
||||
{
|
||||
struct MHD_Response *response = cls;
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
ssize_t n;
|
||||
#else /* _WIN32 && !__CYGWIN__ */
|
||||
const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
|
||||
#endif /* _WIN32 && !__CYGWIN__ */
|
||||
const int64_t offset64 = (int64_t)(pos + response->fd_off);
|
||||
|
||||
if (offset64 < 0)
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
if (max > SSIZE_MAX)
|
||||
max = SSIZE_MAX; /* Clamp to maximum return value. */
|
||||
|
||||
#if defined(HAVE_PREAD64)
|
||||
n = pread64 (response->fd,
|
||||
buf,
|
||||
max,
|
||||
offset64);
|
||||
#elif defined(HAVE_PREAD)
|
||||
if ( (sizeof(off_t) < sizeof (uint64_t)) &&
|
||||
(offset64 > (uint64_t)INT32_MAX) )
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
|
||||
|
||||
n = pread (response->fd,
|
||||
buf,
|
||||
max,
|
||||
(off_t) offset64);
|
||||
#else /* ! HAVE_PREAD */
|
||||
#if defined(HAVE_LSEEK64)
|
||||
if (lseek64 (response->fd,
|
||||
offset64,
|
||||
SEEK_SET) != offset64)
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
|
||||
#else /* ! HAVE_LSEEK64 */
|
||||
if ( (sizeof(off_t) < sizeof (uint64_t)) &&
|
||||
(offset64 > (uint64_t)INT32_MAX) )
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
|
||||
|
||||
if (lseek (response->fd,
|
||||
(off_t) offset64,
|
||||
SEEK_SET) != (off_t) offset64)
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
|
||||
#endif /* ! HAVE_LSEEK64 */
|
||||
n = read (response->fd,
|
||||
buf,
|
||||
max);
|
||||
|
||||
#endif /* ! HAVE_PREAD */
|
||||
if (0 == n)
|
||||
return MHD_CONTENT_READER_END_OF_STREAM;
|
||||
if (n < 0)
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR;
|
||||
return n;
|
||||
#else /* _WIN32 && !__CYGWIN__ */
|
||||
if (INVALID_HANDLE_VALUE == fh)
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
|
||||
else
|
||||
{
|
||||
OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
|
||||
ULARGE_INTEGER pos_uli;
|
||||
DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
|
||||
DWORD resRead;
|
||||
|
||||
pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
|
||||
f_ol.Offset = pos_uli.LowPart;
|
||||
f_ol.OffsetHigh = pos_uli.HighPart;
|
||||
if (! ReadFile (fh,
|
||||
(void*)buf,
|
||||
toRead,
|
||||
&resRead,
|
||||
&f_ol))
|
||||
return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
|
||||
if (0 == resRead)
|
||||
return MHD_CONTENT_READER_END_OF_STREAM;
|
||||
return (ssize_t) resRead;
|
||||
}
|
||||
#endif /* _WIN32 && !__CYGWIN__ */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy file reader context. Closes the file
|
||||
* descriptor.
|
||||
*
|
||||
* @param cls pointer to file descriptor
|
||||
*/
|
||||
static void
|
||||
free_callback (void *cls)
|
||||
{
|
||||
struct MHD_Response *response = cls;
|
||||
|
||||
(void) close (response->fd);
|
||||
response->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a response object based on an @a fd from which
|
||||
* data is read. The response object can be extended with
|
||||
* header information and then be used any number of times.
|
||||
*
|
||||
* @param sc status code to return
|
||||
* @param fd file descriptor referring to a file on disk with the
|
||||
* data; will be closed when response is destroyed;
|
||||
* fd should be in 'blocking' mode
|
||||
* @param offset offset to start reading from in the file;
|
||||
* reading file beyond 2 GiB may be not supported by OS or
|
||||
* MHD build; see ::MHD_FEATURE_LARGE_FILE
|
||||
* @param size size of the data portion of the response;
|
||||
* sizes larger than 2 GiB may be not supported by OS or
|
||||
* MHD build; see ::MHD_FEATURE_LARGE_FILE
|
||||
* @return NULL on error (i.e. invalid arguments, out of memory)
|
||||
* @ingroup response
|
||||
*/
|
||||
struct MHD_Response *
|
||||
MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
|
||||
int fd,
|
||||
uint64_t offset,
|
||||
uint64_t size)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
|
||||
mhd_assert (-1 != fd);
|
||||
#if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64)
|
||||
if ( (sizeof (uint64_t) > sizeof (off_t)) &&
|
||||
( (size > (uint64_t)INT32_MAX) ||
|
||||
(offset > (uint64_t)INT32_MAX) ||
|
||||
((size + offset) >= (uint64_t)INT32_MAX) ) )
|
||||
return NULL;
|
||||
#endif
|
||||
if ( ((int64_t) size < 0) ||
|
||||
((int64_t) offset < 0) ||
|
||||
((int64_t) (size + offset) < 0) )
|
||||
return NULL;
|
||||
|
||||
response = MHD_response_from_callback (size,
|
||||
4 * 1024,
|
||||
&file_reader,
|
||||
NULL,
|
||||
&free_callback);
|
||||
if (NULL == response)
|
||||
return NULL;
|
||||
response->fd = fd;
|
||||
response->status_code = sc;
|
||||
response->fd_off = offset;
|
||||
response->crc_cls = response;
|
||||
return response;
|
||||
}
|
||||
|
||||
/* end of response_from_fd.c */
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/response_option.c
|
||||
* @brief implementation of response options
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
* Only respond in conservative HTTP 1.0-mode. In
|
||||
* particular, do not (automatically) sent "Connection" headers and
|
||||
* always close the connection after generating the response.
|
||||
*
|
||||
* @param request the request for which we force HTTP 1.0 to be used
|
||||
*/
|
||||
void
|
||||
MHD_response_option_v10_only (struct MHD_Response *response)
|
||||
{
|
||||
response->v10_only = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a function to be called once MHD is finished with the
|
||||
* request.
|
||||
*
|
||||
* @param response which response to set the callback for
|
||||
* @param termination_cb function to call
|
||||
* @param termination_cb_cls closure for @e termination_cb
|
||||
*/
|
||||
void
|
||||
MHD_response_option_termination_callback (struct MHD_Response *response,
|
||||
MHD_RequestTerminationCallback termination_cb,
|
||||
void *termination_cb_cls)
|
||||
{
|
||||
/* Q: should we assert termination_cb non-NULL? */
|
||||
response->termination_cb = termination_cb;
|
||||
response->termination_cb_cls = termination_cb_cls;
|
||||
}
|
||||
|
||||
|
||||
/* end of response_option.c */
|
||||
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lib/version.c
|
||||
* @brief versioning and optional feature tests
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -246,12 +246,13 @@ MHD_get_response_header (struct MHD_Response *response,
|
||||
NULL != pos;
|
||||
pos = pos->next)
|
||||
{
|
||||
if ( MHD_str_equal_caseless_ (pos->header, key) )
|
||||
if (MHD_str_equal_caseless_ (pos->header, key))
|
||||
return pos->value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether response header contains particular token.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user