Blame src/microhttpd/internal.h

Packit 875988
/*
Packit 875988
  This file is part of libmicrohttpd
Packit 875988
  Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
Packit 875988
Packit 875988
  This library is free software; you can redistribute it and/or
Packit 875988
  modify it under the terms of the GNU Lesser General Public
Packit 875988
  License as published by the Free Software Foundation; either
Packit 875988
  version 2.1 of the License, or (at your option) any later version.
Packit 875988
Packit 875988
  This library is distributed in the hope that it will be useful,
Packit 875988
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 875988
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 875988
  Lesser General Public License for more details.
Packit 875988
Packit 875988
  You should have received a copy of the GNU Lesser General Public
Packit 875988
  License along with this library; if not, write to the Free Software
Packit 875988
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 875988
*/
Packit 875988
Packit 875988
/**
Packit 875988
 * @file microhttpd/internal.h
Packit 875988
 * @brief  internal shared structures
Packit 875988
 * @author Daniel Pittman
Packit 875988
 * @author Christian Grothoff
Packit 875988
 */
Packit 875988
Packit 875988
#ifndef INTERNAL_H
Packit 875988
#define INTERNAL_H
Packit 875988
Packit 875988
#include "mhd_options.h"
Packit 875988
#include "platform.h"
Packit 875988
#include "microhttpd.h"
Packit 875988
#include "mhd_assert.h"
Packit 875988
Packit 875988
#ifdef HTTPS_SUPPORT
Packit 875988
#include <gnutls/gnutls.h>
Packit 875988
#if GNUTLS_VERSION_MAJOR >= 3
Packit 875988
#include <gnutls/abstract.h>
Packit 875988
#endif
Packit 875988
#endif /* HTTPS_SUPPORT */
Packit 875988
Packit 875988
#ifdef HAVE_STDBOOL_H
Packit 875988
#include <stdbool.h>
Packit 875988
#endif
Packit 875988
Packit 875988
Packit 875988
#ifdef MHD_PANIC
Packit 875988
/* Override any defined MHD_PANIC macro with proper one */
Packit 875988
#undef MHD_PANIC
Packit 875988
#endif /* MHD_PANIC */
Packit 875988
Packit 875988
#ifdef HAVE_MESSAGES
Packit 875988
/**
Packit 875988
 * Trigger 'panic' action based on fatal errors.
Packit 875988
 *
Packit 875988
 * @param msg error message (const char *)
Packit 875988
 */
Packit 875988
#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); BUILTIN_NOT_REACHED; } while (0)
Packit 875988
#else
Packit 875988
/**
Packit 875988
 * Trigger 'panic' action based on fatal errors.
Packit 875988
 *
Packit 875988
 * @param msg error message (const char *)
Packit 875988
 */
Packit 875988
#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0)
Packit 875988
#endif
Packit 875988
Packit 875988
#include "mhd_threads.h"
Packit 875988
#include "mhd_locks.h"
Packit 875988
#include "mhd_sockets.h"
Packit 875988
#include "mhd_itc_types.h"
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Close FD and abort execution if error is detected.
Packit 875988
 * @param fd the FD to close
Packit 875988
 */
Packit 875988
#define MHD_fd_close_chk_(fd) do {             \
Packit 875988
    if (0 == close ((fd)) && (EBADF == errno)) \
Packit 875988
      MHD_PANIC(_("Failed to close FD.\n"));   \
Packit 875988
  } while(0)
Packit 875988
Packit 875988
/**
Packit 875988
 * Should we perform additional sanity checks at runtime (on our internal
Packit 875988
 * invariants)?  This may lead to aborts, but can be useful for debugging.
Packit 875988
 */
Packit 875988
#define EXTRA_CHECKS MHD_NO
Packit 875988
Packit 875988
#define MHD_MAX(a,b) (((a)<(b)) ? (b) : (a))
Packit 875988
#define MHD_MIN(a,b) (((a)<(b)) ? (a) : (b))
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Minimum size by which MHD tries to increment read/write buffers.
Packit 875988
 * We usually begin with half the available pool space for the
Packit 875988
 * IO-buffer, but if absolutely needed we additively grow by the
Packit 875988
 * number of bytes given here (up to -- theoretically -- the full pool
Packit 875988
 * space).
Packit 875988
 */
Packit 875988
#define MHD_BUF_INC_SIZE 1024
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Handler for fatal errors.
Packit 875988
 */
Packit 875988
extern MHD_PanicCallback mhd_panic;
Packit 875988
Packit 875988
/**
Packit 875988
 * Closure argument for "mhd_panic".
Packit 875988
 */
Packit 875988
extern void *mhd_panic_cls;
Packit 875988
Packit 875988
/* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */
Packit 875988
#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
Packit 875988
#define BUILTIN_NOT_REACHED __builtin_unreachable()
Packit 875988
#elif defined(_MSC_FULL_VER)
Packit 875988
#define BUILTIN_NOT_REACHED __assume(0)
Packit 875988
#else
Packit 875988
#define BUILTIN_NOT_REACHED
Packit 875988
#endif
Packit 875988
Packit 875988
#ifndef MHD_STATICSTR_LEN_
Packit 875988
/**
Packit 875988
 * Determine length of static string / macro strings at compile time.
Packit 875988
 */
Packit 875988
#define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1)
Packit 875988
#endif /* ! MHD_STATICSTR_LEN_ */
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * State of the socket with respect to epoll (bitmask).
Packit 875988
 */
Packit 875988
enum MHD_EpollState
Packit 875988
{
Packit 875988
Packit 875988
  /**
Packit 875988
   * The socket is not involved with a defined state in epoll() right
Packit 875988
   * now.
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_UNREADY = 0,
Packit 875988
Packit 875988
  /**
Packit 875988
   * epoll() told us that data was ready for reading, and we did
Packit 875988
   * not consume all of it yet.
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_READ_READY = 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * epoll() told us that space was available for writing, and we did
Packit 875988
   * not consume all of it yet.
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_WRITE_READY = 2,
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is this connection currently in the 'eready' EDLL?
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_IN_EREADY_EDLL = 4,
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is this connection currently in the epoll() set?
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_IN_EPOLL_SET = 8,
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is this connection currently suspended?
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_SUSPENDED = 16,
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is this connection in some error state?
Packit 875988
   */
Packit 875988
  MHD_EPOLL_STATE_ERROR = 128
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * What is this connection waiting for?
Packit 875988
 */
Packit 875988
enum MHD_ConnectionEventLoopInfo
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * We are waiting to be able to read.
Packit 875988
   */
Packit 875988
  MHD_EVENT_LOOP_INFO_READ = 0,
Packit 875988
Packit 875988
  /**
Packit 875988
   * We are waiting to be able to write.
Packit 875988
   */
Packit 875988
  MHD_EVENT_LOOP_INFO_WRITE = 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * We are waiting for the application to provide data.
Packit 875988
   */
Packit 875988
  MHD_EVENT_LOOP_INFO_BLOCK = 2,
Packit 875988
Packit 875988
  /**
Packit 875988
   * We are finished and are awaiting cleanup.
Packit 875988
   */
Packit 875988
  MHD_EVENT_LOOP_INFO_CLEANUP = 3
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Additional test value for enum MHD_FLAG to check only for MHD_ALLOW_SUSPEND_RESUME and
Packit 875988
 * NOT for MHD_USE_ITC.
Packit 875988
 */
Packit 875988
#define MHD_TEST_ALLOW_SUSPEND_RESUME 8192
Packit 875988
Packit 875988
/**
Packit 875988
 * Maximum length of a nonce in digest authentication.  32(MD5 Hex) +
Packit 875988
 * 8(Timestamp Hex) + 1(NULL); hence 41 should suffice, but Opera
Packit 875988
 * (already) takes more (see Mantis #1633), so we've increased the
Packit 875988
 * value to support something longer...
Packit 875988
 */
Packit 875988
#define MAX_NONCE_LENGTH 129
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * A structure representing the internal holder of the
Packit 875988
 * nonce-nc map.
Packit 875988
 */
Packit 875988
struct MHD_NonceNc
Packit 875988
{
Packit 875988
Packit 875988
  /**
Packit 875988
   * Nonce counter, a value that increases for each subsequent
Packit 875988
   * request for the same nonce.
Packit 875988
   */
Packit 875988
  uint64_t nc;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Bitmask over the nc-64 previous nonce values.  Used to
Packit 875988
   * allow out-of-order nonces.
Packit 875988
   */
Packit 875988
  uint64_t nmask;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Nonce value:
Packit 875988
   */
Packit 875988
  char nonce[MAX_NONCE_LENGTH];
Packit 875988
Packit 875988
};
Packit 875988
Packit 875988
#ifdef HAVE_MESSAGES
Packit 875988
/**
Packit 875988
 * fprintf()-like helper function for logging debug
Packit 875988
 * messages.
Packit 875988
 */
Packit 875988
void
Packit 875988
MHD_DLOG (const struct MHD_Daemon *daemon,
Packit 875988
	  const char *format,
Packit 875988
          ...);
Packit 875988
#endif
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Header or cookie in HTTP request or response.
Packit 875988
 */
Packit 875988
struct MHD_HTTP_Header
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * Headers are kept in a linked list.
Packit 875988
   */
Packit 875988
  struct MHD_HTTP_Header *next;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The name of the header (key), without the colon.
Packit 875988
   */
Packit 875988
  char *header;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The value of the header.
Packit 875988
   */
Packit 875988
  char *value;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Type of the header (where in the HTTP protocol is this header
Packit 875988
   * from).
Packit 875988
   */
Packit 875988
  enum MHD_ValueKind kind;
Packit 875988
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Representation of a response.
Packit 875988
 */
Packit 875988
struct MHD_Response
Packit 875988
{
Packit 875988
Packit 875988
  /**
Packit 875988
   * Headers to send for the response.  Initially
Packit 875988
   * the linked list is created in inverse order;
Packit 875988
   * the order should be inverted before sending!
Packit 875988
   */
Packit 875988
  struct MHD_HTTP_Header *first_header;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Buffer pointing to data that we are supposed
Packit 875988
   * to send as a response.
Packit 875988
   */
Packit 875988
  char *data;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure to give to the content reader @e crc
Packit 875988
   * and content reader free callback @e crfc.
Packit 875988
   */
Packit 875988
  void *crc_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * How do we get more data?  NULL if we are
Packit 875988
   * given all of the data up front.
Packit 875988
   */
Packit 875988
  MHD_ContentReaderCallback crc;
Packit 875988
Packit 875988
  /**
Packit 875988
   * NULL if data must not be freed, otherwise
Packit 875988
   * either user-specified callback or "&free".
Packit 875988
   */
Packit 875988
  MHD_ContentReaderFreeCallback crfc;
Packit 875988
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
  /**
Packit 875988
   * Application function to call once we are done sending the headers
Packit 875988
   * of the response; NULL unless this is a response created with
Packit 875988
   * #MHD_create_response_for_upgrade().
Packit 875988
   */
Packit 875988
  MHD_UpgradeHandler upgrade_handler;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure for @e uh.
Packit 875988
   */
Packit 875988
  void *upgrade_handler_cls;
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Mutex to synchronize access to @e data, @e size and
Packit 875988
   * @e reference_count.
Packit 875988
   */
Packit 875988
  MHD_mutex_ mutex;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Set to #MHD_SIZE_UNKNOWN if size is not known.
Packit 875988
   */
Packit 875988
  uint64_t total_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * At what offset in the stream is the
Packit 875988
   * beginning of @e data located?
Packit 875988
   */
Packit 875988
  uint64_t data_start;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Offset to start reading from when using @e fd.
Packit 875988
   */
Packit 875988
  uint64_t fd_off;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of bytes ready in @e data (buffer may be larger
Packit 875988
   * than what is filled with payload).
Packit 875988
   */
Packit 875988
  size_t data_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of the data buffer @e data.
Packit 875988
   */
Packit 875988
  size_t data_buffer_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Reference count for this response.  Free once the counter hits
Packit 875988
   * zero.
Packit 875988
   */
Packit 875988
  unsigned int reference_count;
Packit 875988
Packit 875988
  /**
Packit 875988
   * File-descriptor if this response is FD-backed.
Packit 875988
   */
Packit 875988
  int fd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Flags set for the MHD response.
Packit 875988
   */
Packit 875988
  enum MHD_ResponseFlags flags;
Packit 875988
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * States in a state machine for a connection.
Packit 875988
 *
Packit 875988
 * The main transitions are any-state to #MHD_CONNECTION_CLOSED, any
Packit 875988
 * state to state+1, #MHD_CONNECTION_FOOTERS_SENT to
Packit 875988
 * #MHD_CONNECTION_INIT.  #MHD_CONNECTION_CLOSED is the terminal state
Packit 875988
 * and #MHD_CONNECTION_INIT the initial state.
Packit 875988
 *
Packit 875988
 * Note that transitions for *reading* happen only after the input has
Packit 875988
 * been processed; transitions for *writing* happen after the
Packit 875988
 * respective data has been put into the write buffer (the write does
Packit 875988
 * not have to be completed yet).  A transition to
Packit 875988
 * #MHD_CONNECTION_CLOSED or #MHD_CONNECTION_INIT requires the write
Packit 875988
 * to be complete.
Packit 875988
 */
Packit 875988
enum MHD_CONNECTION_STATE
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * Connection just started (no headers received).
Packit 875988
   * Waiting for the line with the request type, URL and version.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_INIT = 0,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 1: We got the URL (and request type and version).  Wait for a header line.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_URL_RECEIVED = MHD_CONNECTION_INIT + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 2: We got part of a multi-line request header.  Wait for the rest.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_HEADER_PART_RECEIVED = MHD_CONNECTION_URL_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 3: We got the request headers.  Process them.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_HEADERS_RECEIVED = MHD_CONNECTION_HEADER_PART_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 4: We have processed the request headers.  Send 100 continue.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_HEADERS_PROCESSED = MHD_CONNECTION_HEADERS_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 5: We have processed the headers and need to send 100 CONTINUE.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_CONTINUE_SENDING = MHD_CONNECTION_HEADERS_PROCESSED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 6: We have sent 100 CONTINUE (or do not need to).  Read the message body.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_CONTINUE_SENT = MHD_CONNECTION_CONTINUE_SENDING + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 7: We got the request body.  Wait for a line of the footer.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_BODY_RECEIVED = MHD_CONNECTION_CONTINUE_SENT + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 8: We got part of a line of the footer.  Wait for the
Packit 875988
   * rest.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_FOOTER_PART_RECEIVED = MHD_CONNECTION_BODY_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 9: We received the entire footer.  Wait for a response to be queued
Packit 875988
   * and prepare the response headers.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_FOOTERS_RECEIVED = MHD_CONNECTION_FOOTER_PART_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 10: We have prepared the response headers in the writ buffer.
Packit 875988
   * Send the response headers.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_HEADERS_SENDING = MHD_CONNECTION_FOOTERS_RECEIVED + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 11: We have sent the response headers.  Get ready to send the body.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_HEADERS_SENT = MHD_CONNECTION_HEADERS_SENDING + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 12: We are ready to send a part of a non-chunked body.  Send it.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_NORMAL_BODY_READY = MHD_CONNECTION_HEADERS_SENT + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 13: We are waiting for the client to provide more
Packit 875988
   * data of a non-chunked body.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_NORMAL_BODY_UNREADY = MHD_CONNECTION_NORMAL_BODY_READY + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 14: We are ready to send a chunk.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_CHUNKED_BODY_READY = MHD_CONNECTION_NORMAL_BODY_UNREADY + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 15: We are waiting for the client to provide a chunk of the body.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_CHUNKED_BODY_UNREADY = MHD_CONNECTION_CHUNKED_BODY_READY + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 16: We have sent the response body. Prepare the footers.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_BODY_SENT = MHD_CONNECTION_CHUNKED_BODY_UNREADY + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 17: We have prepared the response footer.  Send it.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_FOOTERS_SENDING = MHD_CONNECTION_BODY_SENT + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 18: We have sent the response footer.  Shutdown or restart.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_FOOTERS_SENT = MHD_CONNECTION_FOOTERS_SENDING + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 19: This connection is to be closed.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * 20: This connection is finished (only to be freed)
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_IN_CLEANUP = MHD_CONNECTION_CLOSED + 1,
Packit 875988
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
  /**
Packit 875988
   * Connection was "upgraded" and socket is now under the
Packit 875988
   * control of the application.
Packit 875988
   */
Packit 875988
  MHD_CONNECTION_UPGRADE
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * States of TLS transport layer.
Packit 875988
 */
Packit 875988
enum MHD_TLS_CONN_STATE
Packit 875988
{
Packit 875988
  MHD_TLS_CONN_NO_TLS = 0,  /**< Not a TLS connection (plain socket).   */
Packit 875988
  MHD_TLS_CONN_INIT,        /**< TLS connection is not established yet. */
Packit 875988
  MHD_TLS_CONN_HANDSHAKING, /**< TLS is in handshake process.           */
Packit 875988
  MHD_TLS_CONN_CONNECTED,   /**< TLS is established.                    */
Packit 875988
  MHD_TLS_CONN_WR_CLOSING,  /**< Closing WR side of TLS layer.          */
Packit 875988
  MHD_TLS_CONN_WR_CLOSED,   /**< WR side of TLS layer is closed.        */
Packit 875988
  MHD_TLS_CONN_TLS_CLOSING, /**< TLS session is terminating.            */
Packit 875988
  MHD_TLS_CONN_TLS_CLOSED,  /**< TLS session is terminated.             */
Packit 875988
  MHD_TLS_CONN_TLS_FAILED,  /**< TLS session failed.                    */
Packit 875988
  MHD_TLS_CONN_INVALID_STATE/**< Sentinel. Not a valid value.           */
Packit 875988
};
Packit 875988
Packit 875988
/**
Packit 875988
 * Should all state transitions be printed to stderr?
Packit 875988
 */
Packit 875988
#define DEBUG_STATES MHD_NO
Packit 875988
Packit 875988
Packit 875988
#ifdef HAVE_MESSAGES
Packit 875988
#if DEBUG_STATES
Packit 875988
const char *
Packit 875988
MHD_state_to_string (enum MHD_CONNECTION_STATE state);
Packit 875988
#endif
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * Function to receive plaintext data.
Packit 875988
 *
Packit 875988
 * @param conn the connection struct
Packit 875988
 * @param write_to where to write received data
Packit 875988
 * @param max_bytes maximum number of bytes to receive
Packit 875988
 * @return number of bytes written to @a write_to
Packit 875988
 */
Packit 875988
typedef ssize_t
Packit 875988
(*ReceiveCallback) (struct MHD_Connection *conn,
Packit 875988
                    void *write_to,
Packit 875988
                    size_t max_bytes);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Function to transmit plaintext data.
Packit 875988
 *
Packit 875988
 * @param conn the connection struct
Packit 875988
 * @param read_from where to read data to transmit
Packit 875988
 * @param max_bytes maximum number of bytes to transmit
Packit 875988
 * @return number of bytes transmitted
Packit 875988
 */
Packit 875988
typedef ssize_t
Packit 875988
(*TransmitCallback) (struct MHD_Connection *conn,
Packit 875988
                     const void *read_from,
Packit 875988
                     size_t max_bytes);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Ability to use same connection for next request
Packit 875988
 */
Packit 875988
enum MHD_ConnKeepAlive
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * Connection must be closed after sending response.
Packit 875988
   */
Packit 875988
  MHD_CONN_MUST_CLOSE = -1,
Packit 875988
Packit 875988
  /**
Packit 875988
   * KeelAlive state is not yet determined
Packit 875988
   */
Packit 875988
  MHD_CONN_KEEPALIVE_UNKOWN = 0,
Packit 875988
Packit 875988
  /**
Packit 875988
   * Connection can be used for serving next request
Packit 875988
   */
Packit 875988
  MHD_CONN_USE_KEEPALIVE = 1
Packit 875988
};
Packit 875988
Packit 875988
/**
Packit 875988
 * State kept for each HTTP request.
Packit 875988
 */
Packit 875988
struct MHD_Connection
Packit 875988
{
Packit 875988
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
  /**
Packit 875988
   * Next pointer for the EDLL listing connections that are epoll-ready.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *nextE;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Previous pointer for the EDLL listing connections that are epoll-ready.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *prevE;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * Next pointer for the DLL describing our IO state.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *next;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Previous pointer for the DLL describing our IO state.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *prev;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Next pointer for the XDLL organizing connections by timeout.
Packit 875988
   * This DLL can be either the
Packit 875988
   * 'manual_timeout_head/manual_timeout_tail' or the
Packit 875988
   * 'normal_timeout_head/normal_timeout_tail', depending on whether a
Packit 875988
   * custom timeout is set for the connection.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *nextX;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Previous pointer for the XDLL organizing connections by timeout.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *prevX;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Reference to the MHD_Daemon struct.
Packit 875988
   */
Packit 875988
  struct MHD_Daemon *daemon;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Linked list of parsed headers.
Packit 875988
   */
Packit 875988
  struct MHD_HTTP_Header *headers_received;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of linked list of parsed headers.
Packit 875988
   */
Packit 875988
  struct MHD_HTTP_Header *headers_received_tail;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Response to transmit (initially NULL).
Packit 875988
   */
Packit 875988
  struct MHD_Response *response;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The memory pool is created whenever we first read from the TCP
Packit 875988
   * stream and destroyed at the end of each request (and re-created
Packit 875988
   * for the next request).  In the meantime, this pointer is NULL.
Packit 875988
   * The pool is used for all connection-related data except for the
Packit 875988
   * response (which maybe shared between connections) and the IP
Packit 875988
   * address (which persists across individual requests).
Packit 875988
   */
Packit 875988
  struct MemoryPool *pool;
Packit 875988
Packit 875988
  /**
Packit 875988
   * We allow the main application to associate some pointer with the
Packit 875988
   * HTTP request, which is passed to each #MHD_AccessHandlerCallback
Packit 875988
   * and some other API calls.  Here is where we store it.  (MHD does
Packit 875988
   * not know or care what it is).
Packit 875988
   */
Packit 875988
  void *client_context;
Packit 875988
Packit 875988
  /**
Packit 875988
   * We allow the main application to associate some pointer with the
Packit 875988
   * TCP connection (which may span multiple HTTP requests).  Here is
Packit 875988
   * where we store it.  (MHD does not know or care what it is).
Packit 875988
   * The location is given to the #MHD_NotifyConnectionCallback and
Packit 875988
   * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
Packit 875988
   */
Packit 875988
  void *socket_context;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Request method.  Should be GET/POST/etc.  Allocated in pool.
Packit 875988
   */
Packit 875988
  char *method;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Requested URL (everything after "GET" only).  Allocated
Packit 875988
   * in pool.
Packit 875988
   */
Packit 875988
  const char *url;
Packit 875988
Packit 875988
  /**
Packit 875988
   * HTTP version string (i.e. http/1.1).  Allocated
Packit 875988
   * in pool.
Packit 875988
   */
Packit 875988
  char *version;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Close connection after sending response?
Packit 875988
   * Functions may change value from "Unknown" or "KeepAlive" to "Must close",
Packit 875988
   * but no functions reset value "Must Close" to any other value.
Packit 875988
   */
Packit 875988
  enum MHD_ConnKeepAlive keepalive;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Buffer for reading requests.  Allocated in pool.  Actually one
Packit 875988
   * byte larger than @e read_buffer_size (if non-NULL) to allow for
Packit 875988
   * 0-termination.
Packit 875988
   */
Packit 875988
  char *read_buffer;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Buffer for writing response (headers only).  Allocated
Packit 875988
   * in pool.
Packit 875988
   */
Packit 875988
  char *write_buffer;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Last incomplete header line during parsing of headers.
Packit 875988
   * Allocated in pool.  Only valid if state is
Packit 875988
   * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
Packit 875988
   * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
Packit 875988
   */
Packit 875988
  char *last;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Position after the colon on the last incomplete header
Packit 875988
   * line during parsing of headers.
Packit 875988
   * Allocated in pool.  Only valid if state is
Packit 875988
   * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
Packit 875988
   * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
Packit 875988
   */
Packit 875988
  char *colon;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Foreign address (of length @e addr_len).  MALLOCED (not
Packit 875988
   * in pool!).
Packit 875988
   */
Packit 875988
  struct sockaddr *addr;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Thread handle for this connection (if we are using
Packit 875988
   * one thread per connection).
Packit 875988
   */
Packit 875988
  MHD_thread_handle_ID_ pid;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of @e read_buffer (in bytes).  This value indicates
Packit 875988
   * how many bytes we're willing to read into the buffer;
Packit 875988
   * the real buffer is one byte longer to allow for
Packit 875988
   * adding zero-termination (when needed).
Packit 875988
   */
Packit 875988
  size_t read_buffer_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Position where we currently append data in
Packit 875988
   * @e read_buffer (last valid position).
Packit 875988
   */
Packit 875988
  size_t read_buffer_offset;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of @e write_buffer (in bytes).
Packit 875988
   */
Packit 875988
  size_t write_buffer_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Offset where we are with sending from @e write_buffer.
Packit 875988
   */
Packit 875988
  size_t write_buffer_send_offset;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Last valid location in write_buffer (where do we
Packit 875988
   * append and up to where is it safe to send?)
Packit 875988
   */
Packit 875988
  size_t write_buffer_append_offset;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of bytes we had in the HTTP header, set once we
Packit 875988
   * pass #MHD_CONNECTION_HEADERS_RECEIVED.
Packit 875988
   */
Packit 875988
  size_t header_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * How many more bytes of the body do we expect
Packit 875988
   * to read? #MHD_SIZE_UNKNOWN for unknown.
Packit 875988
   */
Packit 875988
  uint64_t remaining_upload_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Current write position in the actual response
Packit 875988
   * (excluding headers, content only; should be 0
Packit 875988
   * while sending headers).
Packit 875988
   */
Packit 875988
  uint64_t response_write_position;
Packit 875988
Packit 875988
#if defined(_MHD_HAVE_SENDFILE)
Packit 875988
  enum MHD_resp_sender_
Packit 875988
  {
Packit 875988
    MHD_resp_sender_std = 0,
Packit 875988
    MHD_resp_sender_sendfile
Packit 875988
  } resp_sender;
Packit 875988
#endif /* _MHD_HAVE_SENDFILE */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Position in the 100 CONTINUE message that
Packit 875988
   * we need to send when receiving http 1.1 requests.
Packit 875988
   */
Packit 875988
  size_t continue_message_write_offset;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Length of the foreign address.
Packit 875988
   */
Packit 875988
  socklen_t addr_len;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Last time this connection had any activity
Packit 875988
   * (reading or writing).
Packit 875988
   */
Packit 875988
  time_t last_activity;
Packit 875988
Packit 875988
  /**
Packit 875988
   * After how many seconds of inactivity should
Packit 875988
   * this connection time out?  Zero for no timeout.
Packit 875988
   */
Packit 875988
  time_t connection_timeout;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Special member to be returned by #MHD_get_connection_info()
Packit 875988
   */
Packit 875988
  unsigned int connection_timeout_dummy;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Did we ever call the "default_handler" on this connection?  (this
Packit 875988
   * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED
Packit 875988
   * handler when the connection closes down).
Packit 875988
   */
Packit 875988
  bool client_aware;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Socket for this connection.  Set to #MHD_INVALID_SOCKET if
Packit 875988
   * this connection has died (daemon should clean
Packit 875988
   * up in that case).
Packit 875988
   */
Packit 875988
  MHD_socket socket_fd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * true if #socket_fd is non-blocking, false otherwise.
Packit 875988
   */
Packit 875988
  bool sk_nonblck;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Has this socket been closed for reading (i.e.  other side closed
Packit 875988
   * the connection)?  If so, we must completely close the connection
Packit 875988
   * once we are done sending our response (and stop trying to read
Packit 875988
   * from this socket).
Packit 875988
   */
Packit 875988
  bool read_closed;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Set to `true` if the thread has been joined.
Packit 875988
   */
Packit 875988
  bool thread_joined;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Are we currently inside the "idle" handler (to avoid recursively
Packit 875988
   * invoking it).
Packit 875988
   */
Packit 875988
  bool in_idle;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Are we currently inside the "idle" handler (to avoid recursively
Packit 875988
   * invoking it).
Packit 875988
   */
Packit 875988
  bool in_cleanup;
Packit 875988
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
  /**
Packit 875988
   * What is the state of this socket in relation to epoll?
Packit 875988
   */
Packit 875988
  enum MHD_EpollState epoll_state;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * State in the FSM for this connection.
Packit 875988
   */
Packit 875988
  enum MHD_CONNECTION_STATE state;
Packit 875988
Packit 875988
  /**
Packit 875988
   * What is this connection waiting for?
Packit 875988
   */
Packit 875988
  enum MHD_ConnectionEventLoopInfo event_loop_info;
Packit 875988
Packit 875988
  /**
Packit 875988
   * HTTP response code.  Only valid if response object
Packit 875988
   * is already set.
Packit 875988
   */
Packit 875988
  unsigned int responseCode;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Are we receiving with chunked encoding?  This will be set to
Packit 875988
   * #MHD_YES after we parse the headers and are processing the body
Packit 875988
   * with chunks.  After we are done with the body and we are
Packit 875988
   * processing the footers; once the footers are also done, this will
Packit 875988
   * be set to #MHD_NO again (before the final call to the handler).
Packit 875988
   */
Packit 875988
  bool have_chunked_upload;
Packit 875988
Packit 875988
  /**
Packit 875988
   * If we are receiving with chunked encoding, where are we right
Packit 875988
   * now?  Set to 0 if we are waiting to receive the chunk size;
Packit 875988
   * otherwise, this is the size of the current chunk.  A value of
Packit 875988
   * zero is also used when we're at the end of the chunks.
Packit 875988
   */
Packit 875988
  uint64_t current_chunk_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * If we are receiving with chunked encoding, where are we currently
Packit 875988
   * with respect to the current chunk (at what offset / position)?
Packit 875988
   */
Packit 875988
  uint64_t current_chunk_offset;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function used for reading HTTP request stream.
Packit 875988
   */
Packit 875988
  ReceiveCallback recv_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function used for writing HTTP response stream.
Packit 875988
   */
Packit 875988
  TransmitCallback send_cls;
Packit 875988
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
  /**
Packit 875988
   * If this connection was upgraded, this points to
Packit 875988
   * the upgrade response details such that the
Packit 875988
   * #thread_main_connection_upgrade()-logic can perform the
Packit 875988
   * bi-directional forwarding.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *urh;
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
Packit 875988
#ifdef HTTPS_SUPPORT
Packit 875988
Packit 875988
  /**
Packit 875988
   * State required for HTTPS/SSL/TLS support.
Packit 875988
   */
Packit 875988
  gnutls_session_t tls_session;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Memory location to return for protocol session info.
Packit 875988
   */
Packit 875988
  int protocol;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Memory location to return for protocol session info.
Packit 875988
   */
Packit 875988
  int cipher;
Packit 875988
Packit 875988
  /**
Packit 875988
   * State of connection's TLS layer
Packit 875988
   */
Packit 875988
  enum MHD_TLS_CONN_STATE tls_state;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Could it be that we are ready to read due to TLS buffers
Packit 875988
   * even though the socket is not?
Packit 875988
   */
Packit 875988
  bool tls_read_ready;
Packit 875988
#endif /* HTTPS_SUPPORT */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is the connection suspended?
Packit 875988
   */
Packit 875988
  bool suspended;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Special member to be returned by #MHD_get_connection_info()
Packit 875988
   */
Packit 875988
  int suspended_dummy;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Is the connection wanting to resume?
Packit 875988
   */
Packit 875988
  bool resuming;
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
/**
Packit 875988
 * Buffer we use for upgrade response handling in the unlikely
Packit 875988
 * case where the memory pool was so small it had no buffer
Packit 875988
 * capacity left.  Note that we don't expect to _ever_ use this
Packit 875988
 * buffer, so it's mostly wasted memory (except that it allows
Packit 875988
 * us to handle a tricky error condition nicely). So no need to
Packit 875988
 * make this one big.  Applications that want to perform well
Packit 875988
 * should just pick an adequate size for the memory pools.
Packit 875988
 */
Packit 875988
#define RESERVE_EBUF_SIZE 8
Packit 875988
Packit 875988
/**
Packit 875988
 * Context we pass to epoll() for each of the two sockets
Packit 875988
 * of a `struct MHD_UpgradeResponseHandle`.  We need to do
Packit 875988
 * this so we can distinguish the two sockets when epoll()
Packit 875988
 * gives us event notifications.
Packit 875988
 */
Packit 875988
struct UpgradeEpollHandle
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * Reference to the overall response handle this struct is
Packit 875988
   * included within.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *urh;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The socket this event is kind-of about.  Note that this is NOT
Packit 875988
   * necessarily the socket we are polling on, as for when we read
Packit 875988
   * from TLS, we epoll() on the connection's socket
Packit 875988
   * (`urh->connection->socket_fd`), while this then the application's
Packit 875988
   * socket (where the application will read from).  Nevertheless, for
Packit 875988
   * the application to read, we need to first read from TLS, hence
Packit 875988
   * the two are related.
Packit 875988
   *
Packit 875988
   * Similarly, for writing to TLS, this epoll() will be on the
Packit 875988
   * connection's `socket_fd`, and this will merely be the FD which
Packit 875988
   * the applicatio would write to.  Hence this struct must always be
Packit 875988
   * interpreted based on which field in `struct
Packit 875988
   * MHD_UpgradeResponseHandle` it is (`app` or `mhd`).
Packit 875988
   */
Packit 875988
  MHD_socket socket;
Packit 875988
Packit 875988
  /**
Packit 875988
   * IO-state of the @e socket (or the connection's `socket_fd`).
Packit 875988
   */
Packit 875988
  enum MHD_EpollState celi;
Packit 875988
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Handle given to the application to manage special
Packit 875988
 * actions relating to MHD responses that "upgrade"
Packit 875988
 * the HTTP protocol (i.e. to WebSockets).
Packit 875988
 */
Packit 875988
struct MHD_UpgradeResponseHandle
Packit 875988
{
Packit 875988
  /**
Packit 875988
   * The connection for which this is an upgrade handle.  Note that
Packit 875988
   * because a response may be shared over many connections, this may
Packit 875988
   * not be the only upgrade handle for the response of this connection.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *connection;
Packit 875988
Packit 875988
#ifdef HTTPS_SUPPORT
Packit 875988
  /**
Packit 875988
   * Kept in a DLL per daemon.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *next;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Kept in a DLL per daemon.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *prev;
Packit 875988
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
  /**
Packit 875988
   * Next pointer for the EDLL listing urhs that are epoll-ready.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *nextE;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Previous pointer for the EDLL listing urhs that are epoll-ready.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *prevE;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Specifies whether urh already in EDLL list of ready connections.
Packit 875988
   */
Packit 875988
  bool in_eready_list;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * The buffer for receiving data from TLS to
Packit 875988
   * be passed to the application.  Contains @e in_buffer_size
Packit 875988
   * bytes (unless @e in_buffer_size is zero). Do not free!
Packit 875988
   */
Packit 875988
  char *in_buffer;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The buffer for receiving data from the application to
Packit 875988
   * be passed to TLS.  Contains @e out_buffer_size
Packit 875988
   * bytes (unless @e out_buffer_size is zero). Do not free!
Packit 875988
   */
Packit 875988
  char *out_buffer;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of the @e in_buffer.
Packit 875988
   * Set to 0 if the TLS connection went down for reading or socketpair
Packit 875988
   * went down for writing.
Packit 875988
   */
Packit 875988
  size_t in_buffer_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of the @e out_buffer.
Packit 875988
   * Set to 0 if the TLS connection went down for writing or socketpair
Packit 875988
   * went down for reading.
Packit 875988
   */
Packit 875988
  size_t out_buffer_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of bytes actually in use in the @e in_buffer.  Can be larger
Packit 875988
   * than @e in_buffer_size if and only if @a in_buffer_size is zero and
Packit 875988
   * we still have bytes that can be forwarded.
Packit 875988
   * Reset to zero if all data was forwarded to socketpair or
Packit 875988
   * if socketpair went down for writing.
Packit 875988
   */
Packit 875988
  size_t in_buffer_used;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of bytes actually in use in the @e out_buffer. Can be larger
Packit 875988
   * than @e out_buffer_size if and only if @a out_buffer_size is zero and
Packit 875988
   * we still have bytes that can be forwarded.
Packit 875988
   * Reset to zero if all data was forwarded to TLS connection or
Packit 875988
   * if TLS connection went down for writing.
Packit 875988
   */
Packit 875988
  size_t out_buffer_used;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The socket we gave to the application (r/w).
Packit 875988
   */
Packit 875988
  struct UpgradeEpollHandle app;
Packit 875988
Packit 875988
  /**
Packit 875988
   * If @a app_sock was a socketpair, our end of it, otherwise
Packit 875988
   * #MHD_INVALID_SOCKET; (r/w).
Packit 875988
   */
Packit 875988
  struct UpgradeEpollHandle mhd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Emergency IO buffer we use in case the memory pool has literally
Packit 875988
   * nothing left.
Packit 875988
   */
Packit 875988
  char e_buf[RESERVE_EBUF_SIZE];
Packit 875988
Packit 875988
#endif /* HTTPS_SUPPORT */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Set to true after the application finished with the socket
Packit 875988
   * by #MHD_UPGRADE_ACTION_CLOSE.
Packit 875988
   *
Packit 875988
   * When BOTH @e was_closed (changed by command from application)
Packit 875988
   * AND @e clean_ready (changed internally by MHD) are set to
Packit 875988
   * #MHD_YES, function #MHD_resume_connection() will move this
Packit 875988
   * connection to cleanup list.
Packit 875988
   * @remark This flag could be changed from any thread.
Packit 875988
   */
Packit 875988
  volatile bool was_closed;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Set to true if connection is ready for cleanup.
Packit 875988
   *
Packit 875988
   * In TLS mode functions #MHD_connection_finish_forward_() must
Packit 875988
   * be called before setting this flag to true.
Packit 875988
   *
Packit 875988
   * In thread-per-connection mode, true in this flag means
Packit 875988
   * that connection's thread exited or about to exit and will
Packit 875988
   * not use MHD_Connection::urh data anymore.
Packit 875988
   *
Packit 875988
   * In any mode true in this flag also means that
Packit 875988
   * MHD_Connection::urh data will not be used for socketpair
Packit 875988
   * forwarding and forwarding itself is finished.
Packit 875988
   *
Packit 875988
   * When BOTH @e was_closed (changed by command from application)
Packit 875988
   * AND @e clean_ready (changed internally by MHD) are set to
Packit 875988
   * true, function #MHD_resume_connection() will move this
Packit 875988
   * connection to cleanup list.
Packit 875988
   * @remark This flag could be changed from thread that process
Packit 875988
   * connection's recv(), send() and response.
Packit 875988
   */
Packit 875988
  bool clean_ready;
Packit 875988
};
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Signature of function called to log URI accesses.
Packit 875988
 *
Packit 875988
 * @param cls closure
Packit 875988
 * @param uri uri being accessed
Packit 875988
 * @param con connection handle
Packit 875988
 * @return new closure
Packit 875988
 */
Packit 875988
typedef void *
Packit 875988
(*LogCallback)(void *cls,
Packit 875988
               const char *uri,
Packit 875988
               struct MHD_Connection *con);
Packit 875988
Packit 875988
/**
Packit 875988
 * Signature of function called to unescape URIs.  See also
Packit 875988
 * #MHD_http_unescape().
Packit 875988
 *
Packit 875988
 * @param cls closure
Packit 875988
 * @param conn connection handle
Packit 875988
 * @param uri 0-terminated string to unescape (should be updated)
Packit 875988
 * @return length of the resulting string
Packit 875988
 */
Packit 875988
typedef size_t
Packit 875988
(*UnescapeCallback)(void *cls,
Packit 875988
                    struct MHD_Connection *conn,
Packit 875988
                    char *uri);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * State kept for each MHD daemon.  All connections are kept in two
Packit 875988
 * doubly-linked lists.  The first one reflects the state of the
Packit 875988
 * connection in terms of what operations we are waiting for (read,
Packit 875988
 * write, locally blocked, cleanup) whereas the second is about its
Packit 875988
 * timeout state (default or custom).
Packit 875988
 */
Packit 875988
struct MHD_Daemon
Packit 875988
{
Packit 875988
Packit 875988
  /**
Packit 875988
   * Callback function for all requests.
Packit 875988
   */
Packit 875988
  MHD_AccessHandlerCallback default_handler;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to default_handler.
Packit 875988
   */
Packit 875988
  void *default_handler_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Head of doubly-linked list of our current, active connections.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *connections_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of doubly-linked list of our current, active connections.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *connections_tail;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Head of doubly-linked list of our current but suspended connections.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *suspended_connections_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of doubly-linked list of our current but suspended connections.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *suspended_connections_tail;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Head of doubly-linked list of connections to clean up.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *cleanup_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of doubly-linked list of connections to clean up.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *cleanup_tail;
Packit 875988
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
  /**
Packit 875988
   * Head of EDLL of connections ready for processing (in epoll mode).
Packit 875988
   */
Packit 875988
  struct MHD_Connection *eready_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of EDLL of connections ready for processing (in epoll mode)
Packit 875988
   */
Packit 875988
  struct MHD_Connection *eready_tail;
Packit 875988
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
  /**
Packit 875988
   * Head of EDLL of upgraded connections ready for processing (in epoll mode).
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *eready_urh_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of EDLL of upgraded connections ready for processing (in epoll mode)
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *eready_urh_tail;
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
#endif /* EPOLL_SUPPORT */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Head of the XDLL of ALL connections with a default ('normal')
Packit 875988
   * timeout, sorted by timeout (earliest at the tail, most recently
Packit 875988
   * used connection at the head).  MHD can just look at the tail of
Packit 875988
   * this list to determine the timeout for all of its elements;
Packit 875988
   * whenever there is an event of a connection, the connection is
Packit 875988
   * moved back to the tail of the list.
Packit 875988
   *
Packit 875988
   * All connections by default start in this list; if a custom
Packit 875988
   * timeout that does not match @e connection_timeout is set, they
Packit 875988
   * are moved to the @e manual_timeout_head-XDLL.
Packit 875988
   * Not used in MHD_USE_THREAD_PER_CONNECTION mode as each thread
Packit 875988
   * needs only one connection-specific timeout.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *normal_timeout_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of the XDLL of ALL connections with a default timeout,
Packit 875988
   * sorted by timeout (earliest timeout at the tail).
Packit 875988
   * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *normal_timeout_tail;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Head of the XDLL of ALL connections with a non-default/custom
Packit 875988
   * timeout, unsorted.  MHD will do a O(n) scan over this list to
Packit 875988
   * determine the current timeout.
Packit 875988
   * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *manual_timeout_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of the XDLL of ALL connections with a non-default/custom
Packit 875988
   * timeout, unsorted.
Packit 875988
   * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
Packit 875988
   */
Packit 875988
  struct MHD_Connection *manual_timeout_tail;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function to call to check if we should accept or reject an
Packit 875988
   * incoming request.  May be NULL.
Packit 875988
   */
Packit 875988
  MHD_AcceptPolicyCallback apc;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to apc.
Packit 875988
   */
Packit 875988
  void *apc_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function to call when we are done processing
Packit 875988
   * a particular request.  May be NULL.
Packit 875988
   */
Packit 875988
  MHD_RequestCompletedCallback notify_completed;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to @e notify_completed.
Packit 875988
   */
Packit 875988
  void *notify_completed_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function to call when we are starting/stopping
Packit 875988
   * a connection.  May be NULL.
Packit 875988
   */
Packit 875988
  MHD_NotifyConnectionCallback notify_connection;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to @e notify_connection.
Packit 875988
   */
Packit 875988
  void *notify_connection_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function to call with the full URI at the
Packit 875988
   * beginning of request processing.  May be NULL.
Packit 875988
   * 

Packit 875988
   * Returns the initial pointer to internal state
Packit 875988
   * kept by the client for the request.
Packit 875988
   */
Packit 875988
  LogCallback uri_log_callback;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to @e uri_log_callback.
Packit 875988
   */
Packit 875988
  void *uri_log_callback_cls;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Function to call when we unescape escape sequences.
Packit 875988
   */
Packit 875988
  UnescapeCallback unescape_callback;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure for @e unescape_callback.
Packit 875988
   */
Packit 875988
  void *unescape_callback_cls;
Packit 875988
Packit 875988
#ifdef HAVE_MESSAGES
Packit 875988
  /**
Packit 875988
   * Function for logging error messages (if we
Packit 875988
   * support error reporting).
Packit 875988
   */
Packit 875988
  void (*custom_error_log) (void *cls, const char *fmt, va_list va);
Packit 875988
Packit 875988
  /**
Packit 875988
   * Closure argument to @e custom_error_log.
Packit 875988
   */
Packit 875988
  void *custom_error_log_cls;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * Pointer to master daemon (NULL if this is the master)
Packit 875988
   */
Packit 875988
  struct MHD_Daemon *master;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Worker daemons (one per thread)
Packit 875988
   */
Packit 875988
  struct MHD_Daemon *worker_pool;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Table storing number of connections per IP
Packit 875988
   */
Packit 875988
  void *per_ip_connection_count;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of the per-connection memory pools.
Packit 875988
   */
Packit 875988
  size_t pool_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Increment for growth of the per-connection memory pools.
Packit 875988
   */
Packit 875988
  size_t pool_increment;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of threads created by MHD.
Packit 875988
   */
Packit 875988
  size_t thread_stack_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of worker daemons
Packit 875988
   */
Packit 875988
  unsigned int worker_pool_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * The select thread handle (if we have internal select)
Packit 875988
   */
Packit 875988
  MHD_thread_handle_ID_ pid;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Mutex for per-IP connection counts.
Packit 875988
   */
Packit 875988
  MHD_mutex_ per_ip_connection_mutex;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Mutex for (modifying) access to the "cleanup", "normal_timeout" and
Packit 875988
   * "manual_timeout" DLLs.
Packit 875988
   */
Packit 875988
  MHD_mutex_ cleanup_connection_mutex;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Listen socket.
Packit 875988
   */
Packit 875988
  MHD_socket listen_fd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Whether to allow/disallow/ignore reuse of listening address.
Packit 875988
   * The semantics is the following:
Packit 875988
   * 0: ignore (user did not ask for neither allow/disallow, use SO_REUSEADDR
Packit 875988
   *    except W32)
Packit 875988
   * >0: allow (use SO_REUSEPORT on most platforms, SO_REUSEADDR on Windows)
Packit 875988
   * <0: disallow (mostly no action, SO_EXCLUSIVEADDRUSE on Windows or SO_EXCLBIND
Packit 875988
   *     on Solaris)
Packit 875988
   */
Packit 875988
  int listening_address_reuse;
Packit 875988
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
  /**
Packit 875988
   * File descriptor associated with our epoll loop.
Packit 875988
   */
Packit 875988
  int epoll_fd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * true if the listen socket is in the 'epoll' set,
Packit 875988
   * false if not.
Packit 875988
   */
Packit 875988
  bool listen_socket_in_epoll;
Packit 875988
Packit 875988
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
Packit 875988
  /**
Packit 875988
   * File descriptor associated with the #run_epoll_for_upgrade() loop.
Packit 875988
   * Only available if #MHD_USE_HTTPS_EPOLL_UPGRADE is set.
Packit 875988
   */
Packit 875988
  int epoll_upgrade_fd;
Packit 875988
Packit 875988
  /**
Packit 875988
   * true if @e epoll_upgrade_fd is in the 'epoll' set,
Packit 875988
   * false if not.
Packit 875988
   */
Packit 875988
  bool upgrade_fd_in_epoll;
Packit 875988
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
Packit 875988
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * Inter-thread communication channel.
Packit 875988
   */
Packit 875988
  struct MHD_itc_ itc;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Are we shutting down?
Packit 875988
   */
Packit 875988
  volatile bool shutdown;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Has this deamon been quiesced via #MHD_quiesce_daemon()?
Packit 875988
   * If so, we should no longer use the @e listen_fd (including
Packit 875988
   * removing it from the @e epoll_fd when possible).
Packit 875988
   */
Packit 875988
  volatile bool was_quiesced;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Did we hit some system or process-wide resource limit while
Packit 875988
   * trying to accept() the last time? If so, we don't accept new
Packit 875988
   * connections until we close an existing one.  This effectively
Packit 875988
   * temporarily lowers the "connection_limit" to the current
Packit 875988
   * number of connections.
Packit 875988
   */
Packit 875988
  bool at_limit;
Packit 875988
Packit 875988
  /*
Packit 875988
   * Do we need to process resuming connections?
Packit 875988
   */
Packit 875988
  bool resuming;
Packit 875988
Packit 875988
  /**
Packit 875988
   * 'True' if some data is already waiting to be processed.
Packit 875988
   * If set to 'true' - zero timeout for select()/poll*()
Packit 875988
   * is used.
Packit 875988
   * Should be reset each time before processing connections
Packit 875988
   * and raised by any connection which require additional
Packit 875988
   * immediately processing (application does not provide
Packit 875988
   * data for response, data waiting in TLS buffers etc.)
Packit 875988
   */
Packit 875988
  bool data_already_pending;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Number of active parallel connections.
Packit 875988
   */
Packit 875988
  unsigned int connections;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Limit on the number of parallel connections.
Packit 875988
   */
Packit 875988
  unsigned int connection_limit;
Packit 875988
Packit 875988
  /**
Packit 875988
   * After how many seconds of inactivity should
Packit 875988
   * connections time out?  Zero for no timeout.
Packit 875988
   */
Packit 875988
  time_t connection_timeout;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Maximum number of connections per IP, or 0 for
Packit 875988
   * unlimited.
Packit 875988
   */
Packit 875988
  unsigned int per_ip_connection_limit;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Daemon's flags (bitfield).
Packit 875988
   */
Packit 875988
  enum MHD_FLAG options;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Listen port.
Packit 875988
   */
Packit 875988
  uint16_t port;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Be neutral (zero), strict (1) or permissive (-1) to client.
Packit 875988
   */
Packit 875988
  int strict_for_client;
Packit 875988
Packit 875988
#ifdef HTTPS_SUPPORT
Packit 875988
#ifdef UPGRADE_SUPPORT
Packit 875988
  /**
Packit 875988
   * Head of DLL of upgrade response handles we are processing.
Packit 875988
   * Used for upgraded TLS connections when thread-per-connection
Packit 875988
   * is not used.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *urh_head;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Tail of DLL of upgrade response handles we are processing.
Packit 875988
   * Used for upgraded TLS connections when thread-per-connection
Packit 875988
   * is not used.
Packit 875988
   */
Packit 875988
  struct MHD_UpgradeResponseHandle *urh_tail;
Packit 875988
#endif /* UPGRADE_SUPPORT */
Packit 875988
Packit 875988
  /**
Packit 875988
   * Desired cipher algorithms.
Packit 875988
   */
Packit 875988
  gnutls_priority_t priority_cache;
Packit 875988
Packit 875988
  /**
Packit 875988
   * What kind of credentials are we offering
Packit 875988
   * for SSL/TLS?
Packit 875988
   */
Packit 875988
  gnutls_credentials_type_t cred_type;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Server x509 credentials
Packit 875988
   */
Packit 875988
  gnutls_certificate_credentials_t x509_cred;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Diffie-Hellman parameters
Packit 875988
   */
Packit 875988
  gnutls_dh_params_t dh_params;
Packit 875988
Packit 875988
#if GNUTLS_VERSION_MAJOR >= 3
Packit 875988
  /**
Packit 875988
   * Function that can be used to obtain the certificate.  Needed
Packit 875988
   * for SNI support.  See #MHD_OPTION_HTTPS_CERT_CALLBACK.
Packit 875988
   */
Packit 875988
  gnutls_certificate_retrieve_function2 *cert_callback;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * Pointer to our SSL/TLS key (in ASCII) in memory.
Packit 875988
   */
Packit 875988
  const char *https_mem_key;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Pointer to our SSL/TLS certificate (in ASCII) in memory.
Packit 875988
   */
Packit 875988
  const char *https_mem_cert;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Pointer to 0-terminated HTTPS passphrase in memory.
Packit 875988
   */
Packit 875988
  const char *https_key_password;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Pointer to our SSL/TLS certificate authority (in ASCII) in memory.
Packit 875988
   */
Packit 875988
  const char *https_mem_trust;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Our Diffie-Hellman parameters in memory.
Packit 875988
   */
Packit 875988
  gnutls_dh_params_t https_mem_dhparams;
Packit 875988
Packit 875988
  /**
Packit 875988
   * true if we have initialized @e https_mem_dhparams.
Packit 875988
   */
Packit 875988
  bool have_dhparams;
Packit 875988
Packit 875988
#endif /* HTTPS_SUPPORT */
Packit 875988
Packit 875988
#ifdef DAUTH_SUPPORT
Packit 875988
Packit 875988
  /**
Packit 875988
   * Character array of random values.
Packit 875988
   */
Packit 875988
  const char *digest_auth_random;
Packit 875988
Packit 875988
  /**
Packit 875988
   * An array that contains the map nonce-nc.
Packit 875988
   */
Packit 875988
  struct MHD_NonceNc *nnc;
Packit 875988
Packit 875988
  /**
Packit 875988
   * A rw-lock for synchronizing access to @e nnc.
Packit 875988
   */
Packit 875988
  MHD_mutex_ nnc_lock;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of `digest_auth_random.
Packit 875988
   */
Packit 875988
  size_t digest_auth_rand_size;
Packit 875988
Packit 875988
  /**
Packit 875988
   * Size of the nonce-nc array.
Packit 875988
   */
Packit 875988
  unsigned int nonce_nc_size;
Packit 875988
Packit 875988
#endif
Packit 875988
Packit 875988
#ifdef TCP_FASTOPEN
Packit 875988
  /**
Packit 875988
   * The queue size for incoming SYN + DATA packets.
Packit 875988
   */
Packit 875988
  unsigned int fastopen_queue_size;
Packit 875988
#endif
Packit 875988
Packit 875988
  /**
Packit 875988
   * The size of queue for listen socket.
Packit 875988
   */
Packit 875988
  unsigned int listen_backlog_size;
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Insert an element at the head of a DLL. Assumes that head, tail and
Packit 875988
 * element are structs with prev and next fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the DLL
Packit 875988
 * @param tail pointer to the tail of the DLL
Packit 875988
 * @param element element to insert
Packit 875988
 */
Packit 875988
#define DLL_insert(head,tail,element) do { \
Packit 875988
  mhd_assert (NULL == (element)->next); \
Packit 875988
  mhd_assert (NULL == (element)->prev); \
Packit 875988
  (element)->next = (head); \
Packit 875988
  (element)->prev = NULL; \
Packit 875988
  if ((tail) == NULL) \
Packit 875988
    (tail) = element; \
Packit 875988
  else \
Packit 875988
    (head)->prev = element; \
Packit 875988
  (head) = (element); } while (0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Remove an element from a DLL. Assumes
Packit 875988
 * that head, tail and element are structs
Packit 875988
 * with prev and next fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the DLL
Packit 875988
 * @param tail pointer to the tail of the DLL
Packit 875988
 * @param element element to remove
Packit 875988
 */
Packit 875988
#define DLL_remove(head,tail,element) do { \
Packit 875988
  mhd_assert ( (NULL != (element)->next) || ((element) == (tail)));  \
Packit 875988
  mhd_assert ( (NULL != (element)->prev) || ((element) == (head)));  \
Packit 875988
  if ((element)->prev == NULL) \
Packit 875988
    (head) = (element)->next;  \
Packit 875988
  else \
Packit 875988
    (element)->prev->next = (element)->next; \
Packit 875988
  if ((element)->next == NULL) \
Packit 875988
    (tail) = (element)->prev;  \
Packit 875988
  else \
Packit 875988
    (element)->next->prev = (element)->prev; \
Packit 875988
  (element)->next = NULL; \
Packit 875988
  (element)->prev = NULL; } while (0)
Packit 875988
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Insert an element at the head of a XDLL. Assumes that head, tail and
Packit 875988
 * element are structs with prevX and nextX fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the XDLL
Packit 875988
 * @param tail pointer to the tail of the XDLL
Packit 875988
 * @param element element to insert
Packit 875988
 */
Packit 875988
#define XDLL_insert(head,tail,element) do { \
Packit 875988
  mhd_assert (NULL == (element)->nextX); \
Packit 875988
  mhd_assert (NULL == (element)->prevX); \
Packit 875988
  (element)->nextX = (head); \
Packit 875988
  (element)->prevX = NULL; \
Packit 875988
  if (NULL == (tail)) \
Packit 875988
    (tail) = element; \
Packit 875988
  else \
Packit 875988
    (head)->prevX = element; \
Packit 875988
  (head) = (element); } while (0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Remove an element from a XDLL. Assumes
Packit 875988
 * that head, tail and element are structs
Packit 875988
 * with prevX and nextX fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the XDLL
Packit 875988
 * @param tail pointer to the tail of the XDLL
Packit 875988
 * @param element element to remove
Packit 875988
 */
Packit 875988
#define XDLL_remove(head,tail,element) do { \
Packit 875988
  mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail)));  \
Packit 875988
  mhd_assert ( (NULL != (element)->prevX) || ((element) == (head)));  \
Packit 875988
  if (NULL == (element)->prevX) \
Packit 875988
    (head) = (element)->nextX;  \
Packit 875988
  else \
Packit 875988
    (element)->prevX->nextX = (element)->nextX; \
Packit 875988
  if (NULL == (element)->nextX) \
Packit 875988
    (tail) = (element)->prevX;  \
Packit 875988
  else \
Packit 875988
    (element)->nextX->prevX = (element)->prevX; \
Packit 875988
  (element)->nextX = NULL; \
Packit 875988
  (element)->prevX = NULL; } while (0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Insert an element at the head of a EDLL. Assumes that head, tail and
Packit 875988
 * element are structs with prevE and nextE fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the EDLL
Packit 875988
 * @param tail pointer to the tail of the EDLL
Packit 875988
 * @param element element to insert
Packit 875988
 */
Packit 875988
#define EDLL_insert(head,tail,element) do { \
Packit 875988
  (element)->nextE = (head); \
Packit 875988
  (element)->prevE = NULL; \
Packit 875988
  if ((tail) == NULL) \
Packit 875988
    (tail) = element; \
Packit 875988
  else \
Packit 875988
    (head)->prevE = element; \
Packit 875988
  (head) = (element); } while (0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Remove an element from a EDLL. Assumes
Packit 875988
 * that head, tail and element are structs
Packit 875988
 * with prevE and nextE fields.
Packit 875988
 *
Packit 875988
 * @param head pointer to the head of the EDLL
Packit 875988
 * @param tail pointer to the tail of the EDLL
Packit 875988
 * @param element element to remove
Packit 875988
 */
Packit 875988
#define EDLL_remove(head,tail,element) do { \
Packit 875988
  if ((element)->prevE == NULL) \
Packit 875988
    (head) = (element)->nextE;  \
Packit 875988
  else \
Packit 875988
    (element)->prevE->nextE = (element)->nextE; \
Packit 875988
  if ((element)->nextE == NULL) \
Packit 875988
    (tail) = (element)->prevE;  \
Packit 875988
  else \
Packit 875988
    (element)->nextE->prevE = (element)->prevE; \
Packit 875988
  (element)->nextE = NULL; \
Packit 875988
  (element)->prevE = NULL; } while (0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Convert all occurrences of '+' to ' '.
Packit 875988
 *
Packit 875988
 * @param arg string that is modified (in place), must be 0-terminated
Packit 875988
 */
Packit 875988
void
Packit 875988
MHD_unescape_plus (char *arg);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Callback invoked when iterating over @a key / @a value
Packit 875988
 * argument pairs during parsing.
Packit 875988
 *
Packit 875988
 * @param connection context of the iteration
Packit 875988
 * @param key 0-terminated key string, never NULL
Packit 875988
 * @param value 0-terminated value string, may be NULL
Packit 875988
 * @param kind origin of the key-value pair
Packit 875988
 * @return #MHD_YES on success (continue to iterate)
Packit 875988
 *         #MHD_NO to signal failure (and abort iteration)
Packit 875988
 */
Packit 875988
typedef int
Packit 875988
(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
Packit 875988
			 const char *key,
Packit 875988
			 const char *value,
Packit 875988
			 enum MHD_ValueKind kind);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Parse and unescape the arguments given by the client
Packit 875988
 * as part of the HTTP request URI.
Packit 875988
 *
Packit 875988
 * @param kind header kind to pass to @a cb
Packit 875988
 * @param connection connection to add headers to
Packit 875988
 * @param[in,out] args argument URI string (after "?" in URI),
Packit 875988
 *        clobbered in the process!
Packit 875988
 * @param cb function to call on each key-value pair found
Packit 875988
 * @param[out] num_headers set to the number of headers found
Packit 875988
 * @return #MHD_NO on failure (@a cb returned #MHD_NO),
Packit 875988
 *         #MHD_YES for success (parsing succeeded, @a cb always
Packit 875988
 *                               returned #MHD_YES)
Packit 875988
 */
Packit 875988
int
Packit 875988
MHD_parse_arguments_ (struct MHD_Connection *connection,
Packit 875988
		      enum MHD_ValueKind kind,
Packit 875988
		      char *args,
Packit 875988
		      MHD_ArgumentIterator_ cb,
Packit 875988
		      unsigned int *num_headers);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether response header contains particular @a token.
Packit 875988
 *
Packit 875988
 * Token could be surrounded by spaces and tabs and delimited by comma.
Packit 875988
 * Case-insensitive match used for header names and tokens.
Packit 875988
 * @param response  the response to query
Packit 875988
 * @param key       header name
Packit 875988
 * @param token     the token to find
Packit 875988
 * @param token_len the length of token, not including optional
Packit 875988
 *                  terminating null-character.
Packit 875988
 * @return true if token is found in specified header,
Packit 875988
 *         false otherwise
Packit 875988
 */
Packit 875988
bool
Packit 875988
MHD_check_response_header_token_ci (const struct MHD_Response *response,
Packit 875988
                                    const char *key,
Packit 875988
                                    const char *token,
Packit 875988
                                    size_t token_len);
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether response header contains particular static @a tkn.
Packit 875988
 *
Packit 875988
 * Token could be surrounded by spaces and tabs and delimited by comma.
Packit 875988
 * Case-insensitive match used for header names and tokens.
Packit 875988
 * @param r   the response to query
Packit 875988
 * @param k   header name
Packit 875988
 * @param tkn the static string of token to find
Packit 875988
 * @return true if token is found in specified header,
Packit 875988
 *         false otherwise
Packit 875988
 */
Packit 875988
#define MHD_check_response_header_s_token_ci(r,k,tkn) \
Packit 875988
    MHD_check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn))
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Internal version of #MHD_suspend_connection().
Packit 875988
 *
Packit 875988
 * @remark In thread-per-connection mode: can be called from any thread,
Packit 875988
 * in any other mode: to be called only from thread that process
Packit 875988
 * daemon's select()/poll()/etc.
Packit 875988
 *
Packit 875988
 * @param connection the connection to suspend
Packit 875988
 */
Packit 875988
void
Packit 875988
internal_suspend_connection_ (struct MHD_Connection *connection);
Packit 875988
Packit 875988
#endif