gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] 245/335: WIP-4


From: gnunet
Subject: [libmicrohttpd] 245/335: WIP-4
Date: Sat, 27 Jul 2024 22:02:21 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to tag stf-m2
in repository libmicrohttpd.

commit 706092798a9fa6210048052de6171f0f5660e793
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Sat Jul 20 18:46:46 2024 +0200

    WIP-4
---
 src/include/microhttpd2.h         |  73 +++++++++----
 src/mhd2/events_process.c         |   2 +-
 src/mhd2/mhd_mempool.c            |   2 +
 src/mhd2/mhd_request.h            |   9 +-
 src/mhd2/mhd_response.h           |   5 +
 src/mhd2/mhd_sockets_funcs.c      |  32 ++++++
 src/mhd2/mhd_sockets_funcs.h      |  17 +++
 src/mhd2/stream_funcs.c           | 224 ++++++++++++++++++++++++++++++++++++--
 src/mhd2/stream_funcs.h           | 146 ++++++++++++++++++-------
 src/mhd2/stream_process_reply.c   |  10 +-
 src/mhd2/stream_process_request.c |  36 +++---
 11 files changed, 462 insertions(+), 94 deletions(-)

diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
index 029a40b1..61c56e6a 100644
--- a/src/include/microhttpd2.h
+++ b/src/include/microhttpd2.h
@@ -492,6 +492,16 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
    */
   MHD_SC_CONNECTION_POOL_NO_MEM_COOKIE = 30132
   ,
+  /**
+   * Detected jump back of system clock
+   */
+  MHD_SC_SYS_CLOCK_JUMP_BACK_LARGE = 30140
+  ,
+  /**
+   * Detected correctable jump back of system clock
+   */
+  MHD_SC_SYS_CLOCK_JUMP_BACK_CORRECTED = 30141
+  ,
 
   /* 40000-level errors are caused by the HTTP client
      (or the network) */
@@ -600,27 +610,32 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
    */
   MHD_SC_REQ_FOOTER_LINE_NO_COLON = 40141
   ,
+  /**
+   * The request is malformed.
+   */
+  MHD_SC_REQ_MALFORMED = 40155
+  ,
   /**
    * The cookie string has been parsed, but it is not fully compliant with
    * specifications
    */
-  MHD_SC_REQ_COOKIE_PARSED_NOT_COMPLIANT = 40142
+  MHD_SC_REQ_COOKIE_PARSED_NOT_COMPLIANT = 40160
   ,
   /**
    * The cookie string has been parsed only partially
    */
-  MHD_SC_REQ_COOKIE_PARSED_PARTIALLY = 40142
+  MHD_SC_REQ_COOKIE_PARSED_PARTIALLY = 40161
   ,
   /**
    * The cookie string is ignored, as it is not fully compliant with
    * specifications
    */
-  MHD_SC_REQ_COOKIE_IGNORED_NOT_COMPLIANT = 40143
+  MHD_SC_REQ_COOKIE_IGNORED_NOT_COMPLIANT = 40162
   ,
   /**
    * The cookie string has been ignored as it is invalid
    */
-  MHD_SC_REQ_COOKIE_INVALID = 40143
+  MHD_SC_REQ_COOKIE_INVALID = 40163
   ,
 
   /* 50000-level errors are because of an error internal
@@ -1050,7 +1065,12 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
   /**
    * MHD failed to build the response header.
    */
-  MHD_SC_FAILED_RESPONSE_HEADER_GENERATION = 50230
+  MHD_SC_REPLY_FAILED_HEADER_GENERATION = 50230
+  ,
+  /**
+   * Failed to allocate memory in connection's pool for the reply.
+   */
+  MHD_SC_REPLY_POOL_ALLOCATION_FAILURE = 50231
   ,
   /**
    * The feature is not supported by this MHD build (either
@@ -1168,7 +1188,7 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
    * MHD is closing a connection because the application
    * callback told it to do so.
    */
-  MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED = 60006
+  MHD_SC_APPLICATION_CALLBACK_ABORT_ACTION = 60006
   ,
   /**
    * Application only partially processed upload and did
@@ -3446,49 +3466,56 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestTerminationCode
   MHD_REQUEST_TERMINATED_COMPLETED_OK = 0
   ,
   /**
-   * The application terminated request without response.
+   * No activity on the connection for the number of seconds specified using
+   * #MHD_C_OPTION_TIMEOUT().
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_BY_APP = 1
+  MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 10
   ,
   /**
-   * The request is not valid according to
-   * HTTP specifications.
+   * The connection was broken or TLS protocol error.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_HTTP_PROTOCOL_ERROR = 2
+  MHD_REQUEST_TERMINATED_CONNECTION_ERROR = 20
   ,
   /**
-   * The client terminated the connection by closing the socket
-   * for writing (TCP half-closed) before sending complete request;
+   * The client terminated the connection by closing the socket either
+   * completely or for writing (TCP half-closed) before sending complete
+   * request.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_CLIENT_ABORT = 3
+  MHD_REQUEST_TERMINATED_CLIENT_ABORT = 30
   ,
   /**
-   * Error handling the connection due to resources exhausted.
+   * The request is not valid according to
+   * HTTP specifications.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_NO_RESOURCES = 4
+  MHD_REQUEST_TERMINATED_HTTP_PROTOCOL_ERROR = 31
   ,
   /**
-   * Closing the session since MHD is being shut down.
+   * The application aborted request without response.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 5
+  MHD_REQUEST_TERMINATED_BY_APP_ABORT = 40
   ,
   /**
-   * No activity on the connection for the number of seconds specified using
-   * #MHD_C_OPTION_TIMEOUT().
+   * The application aborted request without response.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 6
+  MHD_REQUEST_TERMINATED_BY_APP_ERROR = 41
   ,
   /**
-   * The connection was broken or TLS protocol error.
+   * Error handling the connection due to resources exhausted.
+   * @ingroup request
+   */
+  MHD_REQUEST_TERMINATED_NO_RESOURCES = 50
+  ,
+  /**
+   * Closing the session since MHD is being shut down.
    * @ingroup request
    */
-  MHD_REQUEST_TERMINATED_CONNECTION_ERROR = 7
+  MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 60
 };
 
 /**
diff --git a/src/mhd2/events_process.c b/src/mhd2/events_process.c
index 43f36c18..b54cd0dc 100644
--- a/src/mhd2/events_process.c
+++ b/src/mhd2/events_process.c
@@ -416,7 +416,7 @@ get_all_net_updates_by_poll (struct MHD_Daemon *restrict d,
 
   // TODO: handle empty list situation
 
-  num_events = mhd_poll (d->events.data.poll.fds, num_fds, -1);
+  num_events = mhd_poll (d->events.data.poll.fds, num_fds, -1); // TODO: use 
correct timeout value
   if (0 > num_events)
   {
     int err;
diff --git a/src/mhd2/mhd_mempool.c b/src/mhd2/mhd_mempool.c
index 97d1f07d..a4bb9028 100644
--- a/src/mhd2/mhd_mempool.c
+++ b/src/mhd2/mhd_mempool.c
@@ -265,6 +265,8 @@ struct mhd_MemoryPool
    * 'false' if pool was malloc'ed, 'true' if mmapped (VirtualAlloc'ed for 
W32).
    */
   bool is_mmap;
+
+  // TODO: implement *optional* zeroing on reset on reallocs
 };
 
 
diff --git a/src/mhd2/mhd_request.h b/src/mhd2/mhd_request.h
index 445e32b2..cb608941 100644
--- a/src/mhd2/mhd_request.h
+++ b/src/mhd2/mhd_request.h
@@ -252,6 +252,11 @@ struct MHD_Request
    */
   struct mhd_ReqContentData cntn;
 
+  /**
+   * Set to true if request is too large to be handled
+   */
+  bool too_large;
+
   /**
    * HTTP version string (i.e. http/1.1).  Allocated
    * in pool.
@@ -357,14 +362,14 @@ struct MHD_Request
    * and some other API calls.  Here is where we store it.  (MHD does
    * not know or care what it is).
    */
-  void *client_context;
+  void *app_context;
 
   /**
    * Did we ever call the "default_handler" on this request?
    * This flag determines if we have called the #MHD_OPTION_NOTIFY_COMPLETED
    * handler when the request finishes.
    */
-  bool client_aware;
+  bool app_aware;
 
   /**
    * Number of bare CR characters that were replaced with space characters
diff --git a/src/mhd2/mhd_response.h b/src/mhd2/mhd_response.h
index 4153af4c..78b27aca 100644
--- a/src/mhd2/mhd_response.h
+++ b/src/mhd2/mhd_response.h
@@ -259,6 +259,11 @@ struct mhd_ResponseConfiguration
    * Response has "Connection:" header
    */
   bool has_hdr_conn; // TODO: set the member
+
+  /**
+   * Response is internal-only error response
+   */
+  bool int_err_resp;
 };
 
 #ifndef NDEBUG
diff --git a/src/mhd2/mhd_sockets_funcs.c b/src/mhd2/mhd_sockets_funcs.c
index 477cabbc..a24e2633 100644
--- a/src/mhd2/mhd_sockets_funcs.c
+++ b/src/mhd2/mhd_sockets_funcs.c
@@ -126,6 +126,38 @@ mhd_socket_set_nodelay (MHD_Socket sckt,
 }
 
 
+MHD_INTERNAL bool
+mhd_socket_set_hard_close (MHD_Socket sckt)
+{
+  // TODO: detect constants in configure
+#if defined(SOL_SOCKET) && defined(SO_LINGER)
+  struct linger par;
+
+  par.l_onoff = 1;
+  par.l_linger = 0;
+
+  return 0 == setsockopt (sckt, SOL_SOCKET, SO_LINGER,
+                          (const void *) &par, sizeof (par));
+#else  /* ! TCP_NODELAY */
+  (void) sock;
+  return false;
+#endif /* ! TCP_NODELAY */
+}
+
+
+MHD_INTERNAL bool
+mhd_socket_shut_wr (MHD_Socket sckt)
+{
+#if defined(SHUT_WR) // TODO: detect constants in configure
+  return 0 == shutdown (sckt, SHUT_WR);
+#elif defined(SD_SEND) // TODO: detect constants in configure
+  return 0 == shutdown (sckt, SD_SEND);
+#else
+  return false;
+#endif
+}
+
+
 #ifndef HAVE_SOCKETPAIR
 
 static bool
diff --git a/src/mhd2/mhd_sockets_funcs.h b/src/mhd2/mhd_sockets_funcs.h
index d8b52daa..64e78579 100644
--- a/src/mhd2/mhd_sockets_funcs.h
+++ b/src/mhd2/mhd_sockets_funcs.h
@@ -51,6 +51,23 @@ mhd_socket_nonblocking (MHD_Socket sckt);
 MHD_INTERNAL bool
 mhd_socket_noninheritable (MHD_Socket sckt);
 
+/**
+ * Change socket options to be closed "hard".
+ *
+ * @param sock the socket to manipulate
+ * @return true on success, false otherwise
+ */
+MHD_INTERNAL bool
+mhd_socket_set_hard_close (MHD_Socket sckt);
+
+/**
+ * Shutdown sending on socket
+ *
+ * @param sock the socket to manipulate
+ * @return true on success, false otherwise
+ */
+MHD_INTERNAL bool
+mhd_socket_shut_wr (MHD_Socket sckt);
 
 /**
  * Control Nagle's algorithm on @a sock.
diff --git a/src/mhd2/stream_funcs.c b/src/mhd2/stream_funcs.c
index 931be594..87a08111 100644
--- a/src/mhd2/stream_funcs.c
+++ b/src/mhd2/stream_funcs.c
@@ -37,9 +37,12 @@
 #include "mhd_str.h"
 #include "mhd_str_macros.h"
 
+#include "mhd_sockets_funcs.h"
+
 #include "request_get_value.h"
 #include "response_destroy.h"
 #include "mhd_mono_clock.h"
+#include "daemon_logger.h"
 
 #include "mhd_public_api.h"
 
@@ -501,13 +504,13 @@ mhd_stream_finish_req_serving (struct MHD_Connection 
*restrict c,
 
 #if 0 // TODO: notification callback
     if ( (NULL != d->notify_completed) &&
-         (c->rq.client_aware) )
+         (c->rq.app_aware) )
       d->notify_completed (d->notify_completed_cls,
                            c,
-                           &c->rq.client_context,
+                           &c->rq.app_context,
                            MHD_REQUEST_TERMINATED_COMPLETED_OK);
+    c->rq.app_aware = false;
 #endif
-    c->rq.client_aware = false;
 
     if (NULL != c->rp.response)
       mhd_response_dec_use_count (c->rp.response);
@@ -524,6 +527,8 @@ mhd_stream_finish_req_serving (struct MHD_Connection 
*restrict c,
     /* iov (if any) will be deallocated by mhd_pool_reset */
     memset (&c->rp, 0, sizeof(c->rp));
 
+    // TODO: set all rq and tp pointers to NULL manually. Do the same in other 
places.
+
     c->write_buffer = NULL;
     c->write_buffer_size = 0;
     c->write_buffer_send_offset = 0;
@@ -543,15 +548,51 @@ mhd_stream_finish_req_serving (struct MHD_Connection 
*restrict c,
                         new_read_buf_size);
     c->read_buffer_size = new_read_buf_size;
   }
-  c->rq.client_context = NULL;
+  c->rq.app_context = NULL;
 }
 
 
 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool
 mhd_stream_check_timedout (struct MHD_Connection *restrict c)
 {
-  (void) c;
-  // TODO: implement
+  const uint_fast64_t timeout = c->connection_timeout_ms;
+  uint_fast64_t now;
+  uint_fast64_t since_actv;
+
+  mhd_assert (! c->suspended);
+
+  if (0 == timeout)
+    return false;
+
+  now = MHD_monotonic_msec_counter (); // TODO: Get and use timer value one 
time only per round
+  since_actv = now - c->last_activity;
+  /* Keep the next lines in sync with #connection_get_wait() to avoid
+   * undesired side-effects like busy-waiting. */
+  if (timeout < since_actv)
+  {
+    const uint_fast64_t jump_back = c->last_activity - now;
+    if (jump_back < since_actv)
+    {
+      /* Very unlikely that it is more than quarter-million years pause.
+       * More likely that system clock jumps back. */
+      if (4000 >= jump_back)
+      {
+        c->last_activity = now; /* Avoid repetitive messages.
+                                   Warn: the order of connections sorted
+                                   by timeout is not updated. */
+        mhd_LOG_PRINT (c->daemon, MHD_SC_SYS_CLOCK_JUMP_BACK_CORRECTED, \
+                       mhd_LOG_FMT ("Detected system clock %u " \
+                                    "milliseconds jump back."),
+                       (unsigned int) jump_back);
+        return false;
+      }
+      mhd_LOG_PRINT (c->daemon, MHD_SC_SYS_CLOCK_JUMP_BACK_LARGE, \
+                     mhd_LOG_FMT ("Detected too large system clock %" \
+                                  PRIuFAST64 " milliseconds jump back"),
+                     jump_back);
+    }
+    return true;
+  }
   return false;
 }
 
@@ -574,7 +615,7 @@ mhd_stream_update_activity_mark (struct MHD_Connection 
*restrict c)
     return;  /* Skip update of activity for connections
                without timeout timer. */
 
-  c->last_activity = MHD_monotonic_msec_counter ();
+  c->last_activity = MHD_monotonic_msec_counter (); // TODO: Get and use time 
value one time per round
   if (mhd_D_HAS_THR_PER_CONN (d))
     return; /* each connection has personal timeout */
 
@@ -585,3 +626,172 @@ mhd_stream_update_activity_mark (struct MHD_Connection 
*restrict c)
   mhd_DLINKEDL_DEL_D (&(d->conns.def_timeout), c, by_timeout);
   mhd_DLINKEDL_INS_FIRST_D (&(d->conns.def_timeout), c, by_timeout);
 }
+
+
+MHD_INTERNAL
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (3) void
+mhd_conn_pre_close (struct MHD_Connection *restrict c,
+                    enum mhd_ConnCloseReason reason,
+                    const char *log_msg)
+{
+  bool close_hard;
+  enum MHD_RequestTerminationCode term_code;
+  enum MHD_StatusCode sc;
+
+  sc = MHD_SC_INTERNAL_ERROR;
+  switch (reason)
+  {
+  case mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_HTTP_PROTOCOL_ERROR;
+    sc = MHD_SC_REQ_MALFORMED;
+    break;
+  case mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REQUEST:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_NO_RESOURCES;
+    break;
+  case mhd_CONN_CLOSE_CLIENT_SHUTDOWN_EARLY:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_CLIENT_ABORT;
+    sc = MHD_SC_REPLY_POOL_ALLOCATION_FAILURE;
+    break;
+  case mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_NO_RESOURCES;
+    break;
+  case mhd_CONN_CLOSE_APP_ERROR:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_BY_APP_ERROR;
+    sc = MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED;
+    break;
+  case mhd_CONN_CLOSE_APP_ABORTED:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_BY_APP_ABORT;
+    sc = MHD_SC_APPLICATION_CALLBACK_ABORT_ACTION;
+    break;
+  case mhd_CONN_CLOSE_INT_ERROR:
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_NO_RESOURCES;
+    break;
+  case mhd_CONN_CLOSE_SOCKET_ERR:
+    close_hard = true;
+    switch (c->sk_discnt_err)
+    {
+    case mhd_SOCKET_ERR_NOMEM:
+      term_code = MHD_REQUEST_TERMINATED_NO_RESOURCES;
+      break;
+    case mhd_SOCKET_ERR_CONNRESET:
+      term_code = MHD_REQUEST_TERMINATED_CLIENT_ABORT;
+      break;
+    case mhd_SOCKET_ERR_CONN_BROKEN:
+    case mhd_SOCKET_ERR_NOTCONN:
+    case mhd_SOCKET_ERR_TLS:
+    case mhd_SOCKET_ERR_PIPE:
+    case mhd_SOCKET_ERR_NOT_CHECKED:
+    case mhd_SOCKET_ERR_BADF:
+    case mhd_SOCKET_ERR_INVAL:
+    case mhd_SOCKET_ERR_OPNOTSUPP:
+    case mhd_SOCKET_ERR_NOTSOCK:
+    case mhd_SOCKET_ERR_OTHER:
+    case mhd_SOCKET_ERR_INTERNAL:
+      term_code = MHD_REQUEST_TERMINATED_CONNECTION_ERROR;
+      break;
+    case mhd_SOCKET_ERR_NO_ERROR:
+    case mhd_SOCKET_ERR_AGAIN:
+    case mhd_SOCKET_ERR_INTR:
+    default:
+      mhd_assert (0 && "Impossible value");
+      MHD_UNREACHABLE_;
+    }
+    break;
+
+  case mhd_CONN_CLOSE_TIMEDOUT:
+    if (MHD_CONNECTION_INIT == c->state)
+    {
+      close_hard = false;
+      term_code = MHD_REQUEST_TERMINATED_COMPLETED_OK; /* Not used */
+      break;
+    }
+    close_hard = true;
+    term_code = MHD_REQUEST_TERMINATED_TIMEOUT_REACHED;
+    break;
+
+  case mhd_CONN_CLOSE_CLIENT_HTTP_ERR_SENT_ERR:
+    close_hard = false;
+    term_code = c->rq.too_large ?
+                MHD_REQUEST_TERMINATED_NO_RESOURCES :
+                MHD_REQUEST_TERMINATED_HTTP_PROTOCOL_ERROR;
+    break;
+  case mhd_CONN_CLOSE_HTTP_COMPLETED:
+    close_hard = false;
+    term_code = MHD_REQUEST_TERMINATED_COMPLETED_OK;
+    break;
+
+  default:
+    mhd_assert (0 && "Unreachable code");
+    MHD_UNREACHABLE_;
+    term_code = MHD_REQUEST_TERMINATED_COMPLETED_OK;
+    close_hard = false;
+  }
+
+  mhd_assert ((NULL == log_msg) || (MHD_SC_INTERNAL_ERROR != sc));
+
+  /* Make changes on the socket early to let the kernel and the remote
+   * to process the changes in parallel. */
+  if (close_hard)
+  {
+    /* Use abortive closing, send RST to remote to indicate a problem */
+    (void) mhd_socket_set_hard_close (c->socket_fd);
+    c->state = MHD_CONNECTION_CLOSED;
+    c->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+  }
+  else
+  {
+    if (mhd_socket_shut_wr (c->socket_fd) && (! c->sk_rmt_shut_wr))
+    {
+      (void) 0; // TODO: start local lingering phase
+      c->state = MHD_CONNECTION_CLOSED; // TODO: start local lingering phase
+      c->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; // TODO: start local 
lingering phase
+    }
+    else
+    {  /* No need / not possible to linger */
+      c->state = MHD_CONNECTION_CLOSED;
+      c->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+    }
+  }
+
+#ifdef HAVE_LOG_FUNCTIONALITY
+  if (NULL != log_msg)
+  {
+    mhd_LOG_MSG (c->daemon, sc, log_msg);
+  }
+#else  /* ! HAVE_LOG_FUNCTIONALITY */
+  (void) log_msg;
+#endif /* ! HAVE_LOG_FUNCTIONALITY */
+
+#if 0 // TODO: notification callback
+  if ( (NULL != d->notify_completed) &&
+       (c->rq.app_aware) )
+    d->notify_completed (d->notify_completed_cls,
+                         c,
+                         &c->rq.app_context,
+                         MHD_REQUEST_TERMINATED_COMPLETED_OK);
+#else
+  (void) term_code;
+#endif
+
+  if (NULL != c->rp.response)
+    mhd_response_dec_use_count (c->rp.response);
+  c->rp.response = NULL;
+
+  mhd_assert (NULL != c->pool);
+  c->read_buffer_offset = 0;
+  c->read_buffer_size = 0;
+  c->read_buffer = NULL;
+  c->write_buffer_send_offset = 0;
+  c->write_buffer_append_offset = 0;
+  c->write_buffer_size = 0;
+  c->write_buffer = NULL;
+  mhd_pool_destroy (c->pool);
+  c->pool = NULL;
+}
diff --git a/src/mhd2/stream_funcs.h b/src/mhd2/stream_funcs.h
index 1c105c0c..cc36670b 100644
--- a/src/mhd2/stream_funcs.h
+++ b/src/mhd2/stream_funcs.h
@@ -134,80 +134,146 @@ MHD_INTERNAL void
 mhd_stream_update_activity_mark (struct MHD_Connection *restrict c)
 MHD_FN_PAR_NONNULL_ALL_;
 
+/**
+ * Update last activity mark to the current time..
+ * @param c the connection to update
+ * @return 'true' if connection has not been timed out,
+ *         'false' otherwise
+ */
+MHD_INTERNAL bool
+mhd_stream_check_timedout (struct MHD_Connection *restrict c)
+MHD_FN_PAR_NONNULL_ALL_;
 
-enum mhd_StreamAbortReason
+/**
+ * The reason to close the connection
+ */
+enum mhd_ConnCloseReason
 {
-  mhd_STREAM_ABORT_CLIENT_HTTP_ERR
+  /* Hard problem while receiving */
+  /**
+   * Client sent data that cannot be interpreted as HTTP data
+   */
+  mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN
+  ,
+  /**
+   * No space in the connection pool memory for receiving or processing
+   * the request
+   */
+  mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REQUEST
+  ,
+  /**
+   * The client shut down send before complete request sent
+   */
+  mhd_CONN_CLOSE_CLIENT_SHUTDOWN_EARLY
   ,
-  mhd_STREAM_ABORT_NO_POOL_MEM_FOR_REPLY
+
+  /* Hard problem while sending */
+
+  /**
+   * No space in the connection pool memory for the reply
+   */
+  mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY
+  ,
+  /**
+   * Application behaves incorrectly
+   */
+  mhd_CONN_CLOSE_APP_ERROR
+  ,
+  /**
+   * Application requested about of the stream
+   */
+  mhd_CONN_CLOSE_APP_ABORTED
+  ,
+
+  /* Hard problem while receiving or sending */
+  /**
+   * MHD internal error.
+   * Should never appear.
+   */
+  mhd_CONN_CLOSE_INT_ERROR
+  ,
+  /**
+   * The TCP or TLS connection is broken or aborted due to error on socket
+   * or TLS
+   */
+  mhd_CONN_CLOSE_SOCKET_ERR
   ,
-  mhd_STREAM_ABORT_APP_ERROR
+
+  /* Could be hard or soft error depending on connection state */
+  /**
+   * Timeout detected when receiving request
+   */
+  mhd_CONN_CLOSE_TIMEDOUT
+  ,
+
+  /* Soft problem */
+  /**
+   * The connection must be closed after error response as the client
+   * violates HTTP specification
+   */
+  mhd_CONN_CLOSE_CLIENT_HTTP_ERR_SENT_ERR
+  ,
+
+  /* Graceful closing */
+  /**
+   * Close connection after graceful completion of HTTP communication
+   */
+  mhd_CONN_CLOSE_HTTP_COMPLETED
+
 };
 
+
 /**
- * Close stream with error
- *
- * @param c the connection to close.
+ * Perform initial clean-up and mark for closing.
+ * Set the reason to "request finished"
+ * @param c the connection for pre-closing
  */
 MHD_INTERNAL void
-mhd_stream_abort (struct MHD_Connection *c,
-                  enum mhd_StreamAbortReason reason,
-                  const char *log_msg)
+mhd_conn_pre_close (struct MHD_Connection *restrict c,
+                    enum mhd_ConnCloseReason reason,
+                    const char *log_msg)
 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (3);
 
+/**
+ * Abort the stream and log message
+ */
 #ifdef HAVE_LOG_FUNCTIONALITY
-#  define mhd_STREAM_ABORT(c,r,m) (mhd_stream_abort ((c),(r),(m)))
+#  define mhd_STREAM_ABORT(c,r,m) (mhd_conn_pre_close ((c),(r),(m)))
 #else  /* ! HAVE_LOG_FUNCTIONALITY */
-#  define mhd_STREAM_ABORT(c,r,m) (mhd_stream_abort ((c),(r),NULL))
+#  define mhd_STREAM_ABORT(c,r,m) (mhd_conn_pre_close ((c),(r),NULL))
 #endif /* ! HAVE_LOG_FUNCTIONALITY */
 
-/**
- * Update last activity mark to the current time..
- * @param c the connection to update
- * @return 'true' if connection has not been timed out,
- *         'false' otherwise
- */
-MHD_INTERNAL bool
-mhd_stream_check_timedout (struct MHD_Connection *restrict c)
-MHD_FN_PAR_NONNULL_ALL_;
-
-
 /**
  * Perform initial clean-up and mark for closing.
  * Set the reason to "aborted by application"
- * @param c to make
+ * @param c the connection for pre-closing
  */
-MHD_INTERNAL void
-mhd_conn_pre_close_app_abort (struct MHD_Connection *restrict c)
-MHD_FN_PAR_NONNULL_ALL_;
-
+#define mhd_conn_pre_close_app_abort(c) \
+        mhd_conn_pre_close (c, mhd_CONN_CLOSE_APP_ABORTED, NULL)
 
 /**
  * Perform initial clean-up and mark for closing.
  * Set the reason to "socket error"
- * @param c to make
+ * @param c the connection for pre-closing
  */
-MHD_INTERNAL void
-mhd_conn_pre_close_skt_err (struct MHD_Connection *restrict c)
-MHD_FN_PAR_NONNULL_ALL_;
+#define mhd_conn_pre_close_skt_err(c) \
+        mhd_conn_pre_close (c, mhd_CONN_CLOSE_SOCKET_ERR, NULL)
 
 /**
  * Perform initial clean-up and mark for closing.
  * Set the reason to "request finished"
- * @param c to make
+ * @param c the connection for pre-closing
  */
-MHD_INTERNAL void
-mhd_conn_pre_close_req_finished (struct MHD_Connection *restrict c)
-MHD_FN_PAR_NONNULL_ALL_;
+#define mhd_conn_pre_close_req_finished(c) \
+        mhd_conn_pre_close (c, mhd_CONN_CLOSE_HTTP_COMPLETED, NULL)
 
 /**
  * Perform initial clean-up and mark for closing.
  * Set the reason to "timed out".
- * @param c to make
+ * @param c the connection for pre-closing
  */
-MHD_INTERNAL void
-mhd_conn_pre_close_timedout (struct MHD_Connection *restrict c)
-MHD_FN_PAR_NONNULL_ALL_;
+#define mhd_conn_pre_close_timedout(c) \
+        mhd_conn_pre_close (c, mhd_CONN_CLOSE_TIMEDOUT, NULL)
 
 
 #endif /* ! MHD_STREAM_FUNCS_H */
diff --git a/src/mhd2/stream_process_reply.c b/src/mhd2/stream_process_reply.c
index 68b06d8d..3a0dacb1 100644
--- a/src/mhd2/stream_process_reply.c
+++ b/src/mhd2/stream_process_reply.c
@@ -853,7 +853,7 @@ mhd_stream_build_header_response (struct MHD_Connection 
*restrict c)
   if (! build_header_response_inn (c))
   {
     mhd_STREAM_ABORT (c,
-                      mhd_STREAM_ABORT_NO_POOL_MEM_FOR_REPLY,
+                      mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY,
                       "No memory in the pool for the reply headers.");
     return false;
   }
@@ -928,7 +928,7 @@ mhd_stream_prep_unchunked_body (struct MHD_Connection 
*restrict c)
     {
       /* not enough memory */
       mhd_STREAM_ABORT (c,
-                        mhd_STREAM_ABORT_NO_POOL_MEM_FOR_REPLY,
+                        mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY,
                         "No memory in the pool for the response data.");
       return;
     }
@@ -978,7 +978,7 @@ mhd_stream_prep_chunked_body (struct MHD_Connection 
*restrict c)
   if (32 > c->write_buffer_size)
   {
     mhd_STREAM_ABORT (c,
-                      mhd_STREAM_ABORT_NO_POOL_MEM_FOR_REPLY,
+                      mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY,
                       "No memory in the pool for the reply chunked content.");
   }
   mhd_assert (max_chunk_overhead < \
@@ -1025,7 +1025,7 @@ mhd_stream_prep_chunked_body (struct MHD_Connection 
*restrict c)
   if (size_to_fill < filled)
   {
     mhd_STREAM_ABORT (c,
-                      mhd_STREAM_ABORT_APP_ERROR,
+                      mhd_CONN_CLOSE_APP_ERROR,
                       "Closing connection (application returned more data "
                       "than requested).");
     return;
@@ -1133,7 +1133,7 @@ mhd_stream_prep_chunked_footer (struct MHD_Connection 
*restrict c)
   if (! prep_chunked_footer_inn (c))
   {
     mhd_STREAM_ABORT (c,
-                      mhd_STREAM_ABORT_NO_POOL_MEM_FOR_REPLY,
+                      mhd_CONN_CLOSE_NO_POOL_MEM_FOR_REPLY,
                       "No memory in the pool for the reply chunked footer.");
     return;
   }
diff --git a/src/mhd2/stream_process_request.c 
b/src/mhd2/stream_process_request.c
index 1dc0672b..ee4d8734 100644
--- a/src/mhd2/stream_process_request.c
+++ b/src/mhd2/stream_process_request.c
@@ -630,7 +630,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
                               MHD_MAX_EMPTY_LINES_SKIP : 1)) <
              c->rq.hdrs.rq_line.skipped_empty_lines))
         {
-          mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+          mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                             "Too many meaningless extra empty lines " \
                             "received before the request.");
           return true; /* Process connection closure */
@@ -706,7 +706,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
                                            ERR_RSP_BARE_CR_IN_HEADER);
           }
           else
-            mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+            mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                               "Bare CR characters are not allowed " \
                               "in the request line.");
 
@@ -734,7 +734,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
                                          ERR_RSP_BARE_LF_IN_HEADER);
         }
         else
-          mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+          mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                             "Bare LF characters are not allowed " \
                             "in the request line.");
         return true; /* Error in the request */
@@ -859,7 +859,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
                                        ERR_RSP_REQUEST_MALFORMED);
       }
       else
-        mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+        mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                           "The request line is malformed.");
 
       return true;
@@ -922,7 +922,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
           mhd_assert (NULL == c->rq.version);
           if (0 == p)
           {
-            mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+            mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                               "The request line starts with a whitespace.");
             return true; /* Error in the request */
           }
@@ -959,7 +959,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
                                                ERR_RSP_RQ_LINE_TOO_MANY_WSP);
               }
               else
-                mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+                mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                                   "The request line has more than "
                                   "two whitespaces.");
               return true; /* Error in the request */
@@ -1048,7 +1048,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
         }
         else
         {
-          mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+          mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                             "Invalid character is in the request line.");
           return true; /* Error in the request */
         }
@@ -1056,7 +1056,7 @@ get_request_line_inner (struct MHD_Connection *restrict c)
       else if (0 == chr)
       {
         /* NUL character */
-        mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+        mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                           "The NUL character is in the request line.");
         return true; /* Error in the request */
       }
@@ -1196,12 +1196,16 @@ process_request_target (struct MHD_Connection *c)
   if (NULL != c->daemon->req_cfg.uri_cb.cb)
   {
     struct MHD_String full_uri;
+    struct MHD_EarlyUriCbData req_data;
     full_uri.cstr = c->rq.hdrs.rq_line.rq_tgt;
     full_uri.len = c->rq.req_target_len;
-    c->rq.client_aware = true;
+    req_data.request = &(c->rq);
+    req_data.request_app_context = NULL;
+    c->rq.app_aware = true;
     c->daemon->req_cfg.uri_cb.cb (c->daemon->req_cfg.uri_cb.cls,
-                                  &(c->rq),
-                                  &full_uri);
+                                  &full_uri,
+                                  &req_data);
+    c->rq.app_context = req_data.request_app_context;
   }
 
   if (NULL != c->rq.hdrs.rq_line.rq_tgt_qmark)
@@ -1286,7 +1290,7 @@ send_redirect_fixed_rq_target (struct MHD_Connection 
*restrict c)
        (fixed_uri_len > MHD_MAX_FIXED_URI_LEN) ||
        (NULL == (b = malloc (fixed_uri_len + 1))) )
   {
-    mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR, \
+    mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN, \
                       "The request has whitespace character is " \
                       "in the URI and the URI is too large to " \
                       "send automatic redirect to fixed URI.");
@@ -1350,7 +1354,7 @@ send_redirect_fixed_rq_target (struct MHD_Connection 
*restrict c)
     return;
   }
   free (b);
-  mhd_STREAM_ABORT (c, mhd_STREAM_ABORT_CLIENT_HTTP_ERR,
+  mhd_STREAM_ABORT (c, mhd_CONN_CLOSE_CLIENT_HTTP_ERR_ABORT_CONN,
                     "The request has whitespace character is in the URI.");
   return;
 }
@@ -2867,7 +2871,7 @@ mhd_stream_call_app_request_cb (struct MHD_Connection 
*restrict c)
   path.cstr = c->rq.url;
   path.len = c->rq.url_len;
 
-  c->rq.client_aware = true;
+  c->rq.app_aware = true;
   a = d->req_cfg.cb (d->req_cfg.cb_cls,
                      &(c->rq),
                      &path,
@@ -3181,7 +3185,7 @@ process_request_chunked_body (struct MHD_Connection 
*restrict c)
                                        ERR_RSP_REQUEST_CHUNK_TOO_LARGE);
       return true;
     }
-    mhd_assert (c->rq.client_aware);
+    mhd_assert (c->rq.app_aware);
 
     if (mhd_ACTION_POST_PROCESS == c->rq.app_act.head_act.act)
     {
@@ -3288,7 +3292,7 @@ process_request_nonchunked_body (struct MHD_Connection 
*restrict c)
   mhd_assert (! c->rq.have_chunked_upload);
   mhd_assert (MHD_SIZE_UNKNOWN != c->rq.cntn.cntn_size);
   mhd_assert (c->rq.cntn.recv_size < c->rq.cntn.cntn_size);
-  mhd_assert (c->rq.client_aware);
+  mhd_assert (c->rq.app_aware);
 
   if ((c->rq.cntn.cntn_size - c->rq.cntn.recv_size) < c->read_buffer_offset)
     cntn_data_ready = (size_t) (c->rq.cntn.cntn_size - c->rq.cntn.recv_size);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]