libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

mhd_connection.h (21189B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2014-2025 Evgeny Grin (Karlson2k)
      5   Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
      6 
      7   GNU libmicrohttpd is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   GNU libmicrohttpd is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   Alternatively, you can redistribute GNU libmicrohttpd and/or
     18   modify it under the terms of the GNU General Public License as
     19   published by the Free Software Foundation; either version 2 of
     20   the License, or (at your option) any later version, together
     21   with the eCos exception, as follows:
     22 
     23     As a special exception, if other files instantiate templates or
     24     use macros or inline functions from this file, or you compile this
     25     file and link it with other works to produce a work based on this
     26     file, this file does not by itself cause the resulting work to be
     27     covered by the GNU General Public License. However the source code
     28     for this file must still be made available in accordance with
     29     section (3) of the GNU General Public License v2.
     30 
     31     This exception does not invalidate any other reasons why a work
     32     based on this file might be covered by the GNU General Public
     33     License.
     34 
     35   You should have received copies of the GNU Lesser General Public
     36   License and the GNU General Public License along with this library;
     37   if not, see <https://www.gnu.org/licenses/>.
     38 */
     39 
     40 /**
     41  * @file src/mhd2/mhd_connection.h
     42  * @brief  Definition of struct MHD_connection
     43  * @author Karlson2k (Evgeny Grin)
     44  * @author Daniel Pittman
     45  * @author Christian Grothoff
     46  *
     47  * @warning Imported from MHD1 with minimal changes
     48  * TODO: Rewrite
     49  */
     50 
     51 #ifndef MHD_CONNECTION_H
     52 #define MHD_CONNECTION_H 1
     53 
     54 #include "mhd_sys_options.h"
     55 
     56 #include "sys_bool_type.h"
     57 #include "sys_base_types.h"
     58 
     59 #include "mhd_conn_socket.h"
     60 
     61 #ifdef MHD_SUPPORT_THREADS
     62 #  include "mhd_threads.h"
     63 #endif
     64 
     65 #include "mhd_tristate.h"
     66 #include "mhd_dlinked_list.h"
     67 
     68 #include "mhd_request.h"
     69 #include "mhd_reply.h"
     70 #include "mhd_stream.h"
     71 
     72 #ifdef MHD_SUPPORT_UPGRADE
     73 #  include "mhd_upgrade.h"
     74 #endif /* MHD_SUPPORT_UPGRADE */
     75 
     76 #ifdef MHD_SUPPORT_HTTP2
     77 #  include "mhd_http_layer_state.h"
     78 #endif
     79 
     80 #include "mhd_socket_error.h"
     81 
     82 #include "mhd_public_api.h"
     83 
     84 #ifdef MHD_SUPPORT_HTTPS
     85 #  include "mhd_tls_choice.h" /* For the TLS struct forward declaration */
     86 #endif
     87 
     88 #ifdef MHD_SUPPORT_HTTP2
     89 #  include "h2/h2_conn_data.h"
     90 #endif
     91 
     92 /**
     93  * Minimum reasonable size by which MHD tries to increment read/write buffers.
     94  * We usually begin with half the available pool space for the
     95  * IO-buffer, but if absolutely needed we additively grow by the
     96  * number of bytes given here (up to -- theoretically -- the full pool
     97  * space).
     98  *
     99  * Currently set to reasonable maximum MSS size.
    100  */
    101 #define mhd_BUF_INC_SIZE 1500
    102 
    103 /**
    104  * Message to transmit when http 1.1 request is received
    105  */
    106 #define mdh_HTTP_1_1_100_CONTINUE_REPLY "HTTP/1.1 100 Continue\r\n\r\n"
    107 
    108 
    109 struct MHD_Connection; /* forward declaration */
    110 
    111 #define mhd_CONN_FLAG_RECV      (1u << 0)
    112 #define mhd_CONN_FLAG_SEND      (1u << 1)
    113 #define mhd_CONN_FLAG_TLS       (1u << 2)
    114 #define mhd_CONN_FLAG_HANDSHAKE (1u << 3)
    115 #define mhd_CONN_FLAG_CLOSING   (1u << 4)
    116 #define mhd_CONN_FLAG_ERROR     (1u << 6)
    117 #define mhd_CONN_FLAG_CLOSED    (1u << 7)
    118 
    119 /**
    120  * The states of connection TLS layer
    121  * The bits (1 << 0) | (1 << 1) in enum values match the same bits in
    122  * enum MHD_ConnectionEventLoopInfo and in enum mhd_SocketNetState values
    123  */
    124 enum MHD_FIXED_ENUM_ mhd_ConnState
    125 {
    126   /**
    127    * TLS not started / plain TCP communication
    128    */
    129   mhd_CONN_STATE_TCP_CONNECTED = 0
    130   ,
    131   /**
    132    * TLS handshake in progress, need to receive the data
    133    */
    134   mhd_CONN_STATE_TLS_HANDSHAKE_RECV =
    135     mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_HANDSHAKE | mhd_CONN_FLAG_RECV
    136   ,
    137   /**
    138    * TLS handshake in progress, need to send the data
    139    */
    140   mhd_CONN_STATE_TLS_HANDSHAKE_SEND =
    141     mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_HANDSHAKE | mhd_CONN_FLAG_SEND
    142   ,
    143   /**
    144    * TLS connection established, HTTP communication is performing
    145    */
    146   mhd_CONN_STATE_TLS_CONNECTED = mhd_CONN_FLAG_TLS
    147   ,
    148   /**
    149    * Sending TLS message for shutting down TLS communication on the MHD side
    150    */
    151   mhd_CONN_STATE_TLS_SHUT_WR_SENDING =
    152     mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_CLOSING | mhd_CONN_FLAG_SEND
    153   ,
    154   /**
    155    * Waiting to receive message from remote for shutting down TLS communication
    156    */
    157   mhd_CONN_STATE_TLS_LINGERING =
    158     mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_CLOSING | mhd_CONN_FLAG_RECV
    159   ,
    160   /**
    161    * TLS communication gracefully closed.
    162    * This state should be avoided. Use #mhd_CONN_STATE_TCP_CONNECTED or
    163    * #mhd_CONN_STATE_CLOSED.
    164    */
    165   mhd_CONN_STATE_TLS_CLOSED = mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_CLOSED
    166   ,
    167   /**
    168    * TLS communication broken
    169    */
    170   mhd_CONN_STATE_TLS_FAILED = mhd_CONN_FLAG_TLS | mhd_CONN_FLAG_ERROR
    171 #if 0 // TODO: Extend to TCP states
    172   ,
    173   /**
    174    * Setting TCP shutdown WR
    175    */
    176   mhd_CONN_STATE_TCP_SHUT_WR_SENDING =
    177     mhd_CONN_FLAG_CLOSING | mhd_CONN_FLAG_SEND
    178   ,
    179   /**
    180    * Waiting for EOF from the remote side
    181    */
    182   mhd_CONN_STATE_TCP_LINGERING =
    183     mhd_CONN_FLAG_CLOSING | mhd_CONN_FLAG_RECV
    184 #endif
    185   ,
    186   /**
    187    * TCP communication closed
    188    */
    189   mhd_CONN_STATE_CLOSED = mhd_CONN_FLAG_CLOSED
    190 };
    191 
    192 #ifdef MHD_SUPPORT_HTTPS
    193 /**
    194  * The status of TLS buffer for incoming (receive) data
    195  */
    196 enum mhd_TlsBufDataIn
    197 {
    198   /**
    199    * No data in pending in the TLS buffer
    200    */
    201   mhd_TLS_BUF_NO_DATA = 0
    202   ,
    203   /**
    204    * The incoming data in already pending in the TLS buffer
    205    */
    206   mhd_TLS_BUF_HAS_DATA_IN = mhd_SOCKET_NET_STATE_RECV_READY
    207 };
    208 #endif /* MHD_SUPPORT_HTTPS */
    209 
    210 
    211 #ifdef MHD_SUPPORT_HTTP2
    212 /**
    213  * The HTTP protocol version family
    214  */
    215 enum MHD_FIXED_ENUM_ mhd_HttpVerFamily
    216 {
    217   /**
    218    * Not yet detected
    219    */
    220   mhd_HTTP_VER_FAM_NOT_SET = 0
    221   ,
    222   /**
    223    * Not HTTP/2 (assuming HTTP/1.1 or HTTP/1.0)
    224    */
    225   mhd_HTTP_VER_FAM_NOT_2
    226   ,
    227   /***
    228    * HTTP/2 (also called HTTP/2.0)
    229    */
    230   mhd_HTTP_VER_FAM_2
    231   ,
    232   /**
    233    * Unsupported (but detected) protocol family
    234    */
    235   mhd_HTTP_VER_FAM_UNSUPPORTED = 99
    236   ,
    237   /**
    238    * Invalid protocol family
    239    */
    240   mhd_HTTP_VER_FAM_INVALID = 100
    241 };
    242 
    243 
    244 struct mhd_HttpCommLayer
    245 {
    246   enum mhd_HttpLayerState state;
    247   enum mhd_HttpVerFamily fam;
    248 };
    249 #endif /* MHD_SUPPORT_HTTP2 */
    250 
    251 /**
    252  * What is this connection waiting for?
    253  */
    254 enum MHD_FIXED_FLAGS_ENUM_ MHD_ConnectionEventLoopInfo
    255 {
    256   /**
    257    * We are waiting to be able to read.
    258    * The same value as #mhd_SOCKET_NET_STATE_RECV_READY
    259    */
    260   MHD_EVENT_LOOP_INFO_RECV = 1 << 0
    261   ,
    262   /**
    263    * We are waiting to be able to write.
    264    * The same value as #mhd_SOCKET_NET_STATE_SEND_READY
    265    */
    266   MHD_EVENT_LOOP_INFO_SEND = 1 << 1
    267   ,
    268   /**
    269    * We are waiting for the application to provide data.
    270    */
    271   MHD_EVENT_LOOP_INFO_PROCESS = 1 << 4
    272   ,
    273   /**
    274    * We are finished and are awaiting cleanup.
    275    */
    276   MHD_EVENT_LOOP_INFO_CLEANUP = 1 << 5
    277 #ifdef MHD_SUPPORT_UPGRADE
    278   ,
    279   /**
    280    * We are finished and are awaiting cleanup.
    281    */
    282   MHD_EVENT_LOOP_INFO_UPGRADED = 1 << 6
    283 #endif /* MHD_SUPPORT_UPGRADE */
    284 };
    285 
    286 #define MHD_EVENT_LOOP_INFO_PROCESS_READ \
    287         (MHD_EVENT_LOOP_INFO_RECV | MHD_EVENT_LOOP_INFO_PROCESS)
    288 
    289 
    290 /**
    291  * The reason for the connection closure
    292  */
    293 enum mhd_ConnClosureReason
    294 {
    295   /**
    296    * The socket is not closed / closing.
    297    */
    298   mhd_CONN_CLOSURE_REASON_NO_CLOSURE = 0
    299   ,
    300   /**
    301    * Socket has to be closed because HTTP protocol successfully finished data
    302    * exchange.
    303    */
    304   mhd_CONN_CLOSURE_REASON_PROTOCOL_SUCCESS
    305   ,
    306   /**
    307    * Socket has to be closed because remote side violated some HTTP
    308    * specification requirements or request processed with an error.
    309    * The HTTP error response should be sent.
    310    */
    311   mhd_CONN_CLOSURE_REASON_PROTOCOL_FAILURE_SOFT
    312   ,
    313   /**
    314    * Timeout expired
    315    */
    316   mhd_CONN_CLOSURE_REASON_TIMEOUT
    317   ,
    318   /**
    319    * Socket has to be closed because received data cannot be interpreted as
    320    * valid HTTP data.
    321    */
    322   mhd_CONN_CLOSURE_REASON_PROTOCOL_FAILURE_HARD
    323   ,
    324   /**
    325    * Unrecoverable TLS error
    326    */
    327   mhd_CONN_CLOSURE_REASON_TLS_ERROR
    328   ,
    329   /**
    330    * The remote side closed connection in abortive way
    331    */
    332   mhd_CONN_CLOSURE_REASON_REMOTE_HARD_DISCONN
    333   ,
    334   /**
    335    * The connection has been broken for some reason
    336    */
    337   mhd_CONN_CLOSURE_REASON_CONN_BROKEN
    338 };
    339 
    340 /**
    341  * States in a state machine for a connection.
    342  *
    343  * The main transitions are any-state to #mhd_HTTP_STAGE_CLOSED, any
    344  * state to state+1, #mhd_HTTP_STAGE_FOOTERS_SENT to
    345  * #mhd_HTTP_STAGE_INIT.  #mhd_HTTP_STAGE_CLOSED is the terminal state
    346  * and #mhd_HTTP_STAGE_INIT the initial state.
    347  *
    348  * Note that transitions for *reading* happen only after the input has
    349  * been processed; transitions for *writing* happen after the
    350  * respective data has been put into the write buffer (the write does
    351  * not have to be completed yet).  A transition to
    352  * #mhd_HTTP_STAGE_CLOSED or #mhd_HTTP_STAGE_INIT requires the write
    353  * to be complete.
    354  */
    355 enum MHD_FIXED_ENUM_ mhd_HttpStage
    356 {
    357   /**
    358    * Connection just started (no headers received).
    359    * Waiting for the line with the request type, URL and version.
    360    */
    361   mhd_HTTP_STAGE_INIT = 0
    362   ,
    363   /**
    364    * Part of the request line was received.
    365    * Wait for complete line.
    366    */
    367   mhd_HTTP_STAGE_REQ_LINE_RECEIVING
    368   ,
    369   /**
    370    * We got the URL (and request type and version).  Wait for a header line.
    371    *
    372    * A milestone state. No received data is processed in this state.
    373    */
    374   mhd_HTTP_STAGE_REQ_LINE_RECEIVED
    375   ,
    376   /**
    377    * Receiving request headers.  Wait for the rest of the headers.
    378    */
    379   mhd_HTTP_STAGE_REQ_HEADERS_RECEIVING
    380   ,
    381   /**
    382    * We got the request headers.  Process them.
    383    */
    384   mhd_HTTP_STAGE_HEADERS_RECEIVED
    385   ,
    386   /**
    387    * We have processed the request headers.  Call application callback.
    388    */
    389   mhd_HTTP_STAGE_HEADERS_PROCESSED
    390   ,
    391   /**
    392    * We have processed the headers and need to send 100 CONTINUE.
    393    */
    394   mhd_HTTP_STAGE_CONTINUE_SENDING
    395   ,
    396   /**
    397    * We have sent 100 CONTINUE (or do not need to).  Read the message body.
    398    */
    399   mhd_HTTP_STAGE_BODY_RECEIVING
    400   ,
    401   /**
    402    * We got the request body.
    403    *
    404    * A milestone state. No received data is processed in this state.
    405    */
    406   mhd_HTTP_STAGE_BODY_RECEIVED
    407   ,
    408   /**
    409    * We are reading the request footers.
    410    */
    411   mhd_HTTP_STAGE_FOOTERS_RECEIVING
    412   ,
    413   /**
    414    * We received the entire footer.
    415    *
    416    * A milestone state. No data is receiving in this state.
    417    */
    418   mhd_HTTP_STAGE_FOOTERS_RECEIVED
    419   ,
    420   /**
    421    * We received the entire request.
    422    *
    423    * A milestone state. No data is receiving in this state.
    424    */
    425   mhd_HTTP_STAGE_FULL_REQ_RECEIVED
    426   ,
    427   /**
    428    * Finished receiving request data: either complete request received or
    429    * MHD is going to send reply early, without getting full request.
    430    */
    431   mhd_HTTP_STAGE_REQ_RECV_FINISHED
    432   ,
    433   /**
    434    * Finished reading of the request and the response is ready.
    435    * Switch internal logic from receiving to sending, prepare connection
    436    * sending the reply and build the reply header.
    437    */
    438   mhd_HTTP_STAGE_START_REPLY
    439   ,
    440   /**
    441    * We have prepared the response headers in the write buffer.
    442    * Send the response headers.
    443    */
    444   mhd_HTTP_STAGE_HEADERS_SENDING
    445   ,
    446   /**
    447    * We have sent the response headers.  Get ready to send the body.
    448    */
    449   mhd_HTTP_STAGE_HEADERS_SENT
    450 #ifdef MHD_SUPPORT_UPGRADE
    451   ,
    452   /**
    453    * Sending special HTTP "Upgrade" headers
    454    */
    455   mhd_HTTP_STAGE_UPGRADE_HEADERS_SENDING
    456 #endif /* MHD_SUPPORT_UPGRADE */
    457   ,
    458   /**
    459    * We are waiting for the client to provide more
    460    * data of a non-chunked body.
    461    */
    462   mhd_HTTP_STAGE_UNCHUNKED_BODY_UNREADY
    463   ,
    464   /**
    465    * We are ready to send a part of a non-chunked body.  Send it.
    466    */
    467   mhd_HTTP_STAGE_UNCHUNKED_BODY_READY
    468   ,
    469   /**
    470    * We are waiting for the client to provide a chunk of the body.
    471    */
    472   mhd_HTTP_STAGE_CHUNKED_BODY_UNREADY
    473   ,
    474   /**
    475    * We are ready to send a chunk.
    476    */
    477   mhd_HTTP_STAGE_CHUNKED_BODY_READY
    478   ,
    479   /**
    480    * We have sent the chunked response body. Prepare the footers.
    481    */
    482   mhd_HTTP_STAGE_CHUNKED_BODY_SENT
    483   ,
    484   /**
    485    * We have prepared the response footer.  Send it.
    486    */
    487   mhd_HTTP_STAGE_FOOTERS_SENDING
    488   ,
    489   /**
    490    * We have sent the entire reply.
    491    * Shutdown connection or restart processing to get a new request.
    492    */
    493   mhd_HTTP_STAGE_FULL_REPLY_SENT
    494 #ifdef MHD_SUPPORT_UPGRADE
    495   ,
    496   /**
    497    * Transition to "Upgraded" state
    498    */
    499   mhd_HTTP_STAGE_UPGRADING
    500   ,
    501   /**
    502    * Sending and receiving data on HTTP-Upgraded connection channel.
    503    * Normal data processing and connection handling is not performed
    504    * by MHD anymore.
    505    */
    506   mhd_HTTP_STAGE_UPGRADED
    507   ,
    508   /**
    509    * Closing HTTP-Upgraded connection
    510    */
    511   mhd_HTTP_STAGE_UPGRADED_CLEANING
    512 #endif /* MHD_SUPPORT_UPGRADE */
    513   ,
    514   /**
    515    * Finished regular connection processing.
    516    * Initial buffers cleanup and freeing.
    517    */
    518   mhd_HTTP_STAGE_PRE_CLOSING
    519   ,
    520   /**
    521    * This connection is to be closed.
    522    */
    523   mhd_HTTP_STAGE_CLOSED
    524 
    525 };
    526 
    527 
    528 /**
    529  * The connection's external event data
    530  */
    531 struct mhd_ConnExtrEvents
    532 {
    533   /**
    534    * Connection's application context for the external events monitoring
    535    */
    536   void *app_cntx;
    537 
    538   /**
    539    * The last targets for which the connection FD has been registration for
    540    */
    541   enum MHD_FdState reg_for;
    542 };
    543 
    544 
    545 struct mhd_ConnDebugData
    546 {
    547   bool closing_started;
    548   bool pre_cleaned;
    549   bool removed_from_daemon;
    550   bool tls_inited;
    551   bool avoid_accept4;
    552 };
    553 
    554 /**
    555  * Ability to use same connection for next request
    556  */
    557 enum MHD_FIXED_ENUM_ mhd_ConnReuse
    558 {
    559   /**
    560    * Connection must be closed after sending response.
    561    */
    562   mhd_CONN_MUST_CLOSE = -1
    563   ,
    564   /**
    565    * KeepAlive state is possible
    566    */
    567   mhd_CONN_KEEPALIVE_POSSIBLE = 0
    568   ,
    569   /**
    570    * Connection will be upgraded
    571    */
    572   mhd_CONN_MUST_UPGRADE = 1
    573 };
    574 
    575 /**
    576  * The helper struct for the connections list
    577  */
    578 mhd_DLINKEDL_LINKS_DEF (MHD_Connection);
    579 
    580 /**
    581  * State kept for HTTP network connection.
    582  */
    583 struct MHD_Connection
    584 {
    585 
    586   /**
    587    * The list with all daemon's connections
    588    */
    589   mhd_DLNKDL_LINKS (MHD_Connection,all_conn);
    590 
    591   /**
    592    * The connection socket data
    593    */
    594   struct mhd_ConnSocket sk;
    595 
    596   /**
    597    * The connection's external event data
    598    */
    599   struct mhd_ConnExtrEvents extr_event;
    600 
    601 #ifdef MHD_SUPPORT_HTTPS
    602   /**
    603    * Connection-specific TLS data.
    604    * NULL if TLS is not used (plain HTTP connection).
    605    * Allocated (and freed) together with struct MHD_Connection, cannot be
    606    * deallocated separately.
    607    */
    608   struct mhd_TlsConnData *tls;
    609 
    610   /**
    611    * The state of the communication layer
    612    */
    613   enum mhd_ConnState conn_state;
    614 
    615   /**
    616    * Status of TLS buffer for the incoming data
    617    */
    618   enum mhd_TlsBufDataIn tls_has_data_in;
    619 #endif /* MHD_SUPPORT_HTTPS */
    620 
    621 #ifdef MHD_SUPPORT_HTTP2
    622   /**
    623    * HTTP communication layer
    624    */
    625   struct mhd_HttpCommLayer h_layer;
    626 
    627   /**
    628    * HTTP/2 data
    629    * Used only if @ h_layer.fam is #mhd_HTTP_VER_FAM_2
    630    */
    631   struct mhd_H2ConnData h2;
    632 #endif
    633   /**
    634    * 'true' if connection is in 'process ready' list,
    635    * 'false' otherwise
    636    */
    637   bool in_proc_ready;
    638 
    639   /**
    640    * The list with all daemon's connections that ready to processing
    641    */
    642   mhd_DLNKDL_LINKS (MHD_Connection,proc_ready);
    643 
    644   /**
    645    * The list of connections sorted by timeout
    646    */
    647   mhd_DLNKDL_LINKS (MHD_Connection,by_timeout);
    648 
    649 #ifdef MHD_SUPPORT_UPGRADE
    650   /**
    651    * The data for handling HTTP-Upgraded connection
    652    */
    653   struct MHD_UpgradedHandle upgr;
    654 
    655   /**
    656    * Double-linked list of HTTP-Upgraded connections waiting for clean-up
    657    */
    658   mhd_DLNKDL_LINKS (MHD_Connection,upgr_cleanup);
    659 #endif /* MHD_SUPPORT_UPGRADE */
    660 
    661   /**
    662    * Reference to the MHD_Daemon struct.
    663    */
    664   struct MHD_Daemon *daemon;
    665 
    666   /**
    667    * HTTP/1.x stream data.
    668    * Currently not used for the actual data.
    669    */
    670   struct MHD_Stream h1_stream;
    671 
    672   /**
    673    * True if connection is suspended
    674    */
    675   volatile bool suspended;
    676 
    677   /**
    678    * True if connection is resuming
    679    */
    680   volatile bool resuming;
    681 
    682   /**
    683    * Request-specific data
    684    */
    685   struct MHD_Request rq;
    686 
    687   /**
    688    * Reply-specific data
    689    */
    690   struct MHD_Reply rp;
    691 
    692   /**
    693    * The memory pool is created whenever we first read from the TCP
    694    * stream and destroyed at the end of each request (and re-created
    695    * for the next request).  In the meantime, this pointer is NULL.
    696    * The pool is used for all connection-related data except for the
    697    * response (which maybe shared between connections) and the IP
    698    * address (which persists across individual requests).
    699    */
    700   struct mhd_MemoryPool *pool;
    701 
    702   /**
    703    * We allow the main application to associate some pointer with the
    704    * TCP connection (which may span multiple HTTP requests).  Here is
    705    * where we store it.  (MHD does not know or care what it is).
    706    * The location is given to the #MHD_NotifyConnectionCallback and
    707    * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
    708    */
    709   void *socket_context;
    710 
    711   /**
    712    * Close connection after sending response?
    713    * Functions may change value from "KeepAlive" to "Must close",
    714    * but no functions reset value "Must Close" to any other value.
    715    */
    716   enum mhd_ConnReuse conn_reuse;
    717 
    718   /**
    719    * Buffer for reading requests.  Allocated in pool.  Actually one
    720    * byte larger than @e read_buffer_size (if non-NULL) to allow for
    721    * 0-termination.
    722    */
    723   char *read_buffer;
    724 
    725   /**
    726    * Buffer for writing response (headers only).  Allocated
    727    * in pool.
    728    */
    729   char *write_buffer;
    730 
    731 #if defined(MHD_SUPPORT_THREADS)
    732   /**
    733    * Thread handle for this connection (if we are using
    734    * one thread per connection).
    735    */
    736   mhd_thread_handle_ID tid;
    737 #endif
    738 
    739   /**
    740    * Size of @e read_buffer (in bytes).
    741    * This value indicates how many bytes we're willing to read
    742    * into the buffer.
    743    */
    744   size_t read_buffer_size;
    745 
    746   /**
    747    * Position where we currently append data in @e read_buffer (the
    748    * next char after the last valid position).
    749    */
    750   size_t read_buffer_offset;
    751 
    752   /**
    753    * Size of @e write_buffer (in bytes).
    754    */
    755   size_t write_buffer_size;
    756 
    757   /**
    758    * Offset where we are with sending from @e write_buffer.
    759    */
    760   size_t write_buffer_send_offset;
    761 
    762   /**
    763    * Last valid location in write_buffer (where do we
    764    * append and up to where is it safe to send?)
    765    */
    766   size_t write_buffer_append_offset;
    767 
    768   /**
    769    * Position in the 100 CONTINUE message that
    770    * we need to send when receiving http 1.1 requests.
    771    */
    772   size_t continue_message_write_offset;
    773 
    774   /**
    775    * Last time this connection had any activity
    776    * (reading or writing).
    777    */
    778   uint_fast64_t last_activity;
    779 
    780   /**
    781    * After how many milliseconds of inactivity should
    782    * this connection time out?
    783    * Zero for no timeout.
    784    */
    785   uint_fast64_t connection_timeout_ms;
    786 
    787   /**
    788    * Some error happens during processing the connection therefore this
    789    * connection must be closed.
    790    * The error may come from the client side (like wrong request format),
    791    * from the application side (like data callback returned error), or from
    792    * the OS side (like out-of-memory).
    793    */
    794   bool stop_with_error;
    795 
    796   /**
    797    * Response queued early, before the request is fully processed,
    798    * the client upload is rejected.
    799    * The connection cannot be reused for additional requests as the current
    800    * request is incompletely read and it is unclear where is the initial
    801    * byte of the next request.
    802    */
    803   bool discard_request;
    804 
    805 #if defined(MHD_SUPPORT_THREADS)
    806   /**
    807    * Set to `true` if the thread has been joined.
    808    */
    809   bool thread_joined;
    810 #endif
    811 
    812   /**
    813    * Connection is in the cleanup DL-linked list.
    814    */
    815   bool in_cleanup;
    816 
    817   /**
    818    * State in the FSM for this connection.
    819    */
    820   enum mhd_HttpStage stage;
    821 
    822   /**
    823    * What is this connection waiting for?
    824    */
    825   enum MHD_ConnectionEventLoopInfo event_loop_info;
    826 
    827 #ifndef NDEBUG
    828   /**
    829    * Debugging data
    830    */
    831   struct mhd_ConnDebugData dbg;
    832 #endif
    833 };
    834 
    835 #ifdef MHD_SUPPORT_HTTPS
    836 /**
    837  * Returns non-zero if connection has TLS enabled or zero otherwise
    838  */
    839 #  define mhd_C_HAS_TLS(c) (((c)->tls) ? (! 0) : (0))
    840 #else  /* ! MHD_SUPPORT_HTTPS */
    841 /**
    842  * Returns non-zero if connection has TLS enabled or zero otherwise
    843  */
    844 #  define mhd_C_HAS_TLS(c) (0)
    845 #endif /* ! MHD_SUPPORT_HTTPS */
    846 
    847 
    848 #ifdef MHD_SUPPORT_HTTPS
    849 /**
    850  * Returns #mhd_SOCKET_NET_STATE_RECV_READY if connection has incoming data
    851  * pending in TLS buffers
    852  */
    853 #  define mhd_C_HAS_TLS_DATA_IN(c) \
    854         (((c)->tls) ? ((unsigned int) ((c)->tls_has_data_in)) : (0u))
    855 #else  /* ! MHD_SUPPORT_HTTPS */
    856 /**
    857  * Returns #mhd_SOCKET_NET_STATE_RECV_READY if connection has incoming data
    858  * pending in TLS buffers
    859  */
    860 #  define mhd_C_HAS_TLS_DATA_IN(c) (0)
    861 #endif /* ! MHD_SUPPORT_HTTPS */
    862 
    863 #ifdef MHD_SUPPORT_HTTP2
    864 #  define mhd_C_IS_HTTP2(c) \
    865         (mhd_HTTP_VER_FAM_2 == c->h_layer.fam)
    866 #else  /* ! MHD_SUPPORT_HTTP2 */
    867 #  define mhd_C_IS_HTTP2(c)     (! ! 0)
    868 #endif /* ! MHD_SUPPORT_HTTP2 */
    869 
    870 #endif /* ! MHD_CONNECTION_H */