libmicrohttpd2

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

mhd_connection.h (21545B)


      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 /**
    546  * The helper struct for the connections list
    547  */
    548 mhd_DLINKEDL_LINKS_DEF (MHD_Connection);
    549 
    550 /**
    551  * Connection's activity timeout data
    552  */
    553 struct mhd_ConnTimeoutData
    554 {
    555   /**
    556    * Connection's maximum idle time before closing by timeout.
    557    * Zero for no timeout.
    558    */
    559   uint_fast32_t milsec;
    560 
    561   /**
    562    * The time of the the connection's last network activity
    563    */
    564   uint_fast64_t last_act;
    565 
    566   /**
    567    * The list of connections sorted by timeout
    568    */
    569   mhd_DLNKDL_LINKS (MHD_Connection,tmout_list);
    570 
    571   /**
    572    * Set to 'true' if this connection is in daemon's 'custom timeout list'.
    573    * 'false' if connection is not in this list, including situation when
    574    * connection is out of any daemon's timeouts lists.
    575    */
    576   bool in_cstm_tmout_list;
    577 };
    578 
    579 struct mhd_ConnDebugData
    580 {
    581   bool closing_started;
    582   bool pre_cleaned;
    583   bool removed_from_daemon;
    584   bool tls_inited;
    585   bool avoid_accept4;
    586 };
    587 
    588 /**
    589  * Ability to use same connection for next request
    590  */
    591 enum MHD_FIXED_ENUM_ mhd_ConnReuse
    592 {
    593   /**
    594    * Connection must be closed after sending response.
    595    */
    596   mhd_CONN_MUST_CLOSE = -1
    597   ,
    598   /**
    599    * KeepAlive state is possible
    600    */
    601   mhd_CONN_KEEPALIVE_POSSIBLE = 0
    602   ,
    603   /**
    604    * Connection will be upgraded
    605    */
    606   mhd_CONN_MUST_UPGRADE = 1
    607 };
    608 
    609 /**
    610  * State kept for HTTP network connection.
    611  */
    612 struct MHD_Connection
    613 {
    614 
    615   /**
    616    * The list with all daemon's connections
    617    */
    618   mhd_DLNKDL_LINKS (MHD_Connection,all_conn);
    619 
    620   /**
    621    * The connection socket data
    622    */
    623   struct mhd_ConnSocket sk;
    624 
    625   /**
    626    * The connection's external event data
    627    */
    628   struct mhd_ConnExtrEvents extr_event;
    629 
    630 #ifdef MHD_SUPPORT_HTTPS
    631   /**
    632    * Connection-specific TLS data.
    633    * NULL if TLS is not used (plain HTTP connection).
    634    * Allocated (and freed) together with struct MHD_Connection, cannot be
    635    * deallocated separately.
    636    */
    637   struct mhd_TlsConnData *tls;
    638 
    639   /**
    640    * The state of the communication layer
    641    */
    642   enum mhd_ConnState conn_state;
    643 
    644   /**
    645    * Status of TLS buffer for the incoming data
    646    */
    647   enum mhd_TlsBufDataIn tls_has_data_in;
    648 #endif /* MHD_SUPPORT_HTTPS */
    649 
    650 #ifdef MHD_SUPPORT_HTTP2
    651   /**
    652    * HTTP communication layer
    653    */
    654   struct mhd_HttpCommLayer h_layer;
    655 
    656   /**
    657    * HTTP/2 data
    658    * Used only if @ h_layer.fam is #mhd_HTTP_VER_FAM_2
    659    */
    660   struct mhd_H2ConnData h2;
    661 #endif
    662   /**
    663    * 'true' if connection is in 'process ready' list,
    664    * 'false' otherwise
    665    */
    666   bool in_proc_ready;
    667 
    668   /**
    669    * The list with all daemon's connections that ready to processing
    670    */
    671   mhd_DLNKDL_LINKS (MHD_Connection,proc_ready);
    672 
    673   /**
    674    * Connection's activity timeout data
    675    */
    676   struct mhd_ConnTimeoutData timeout;
    677 
    678 #ifdef MHD_SUPPORT_UPGRADE
    679   /**
    680    * The data for handling HTTP-Upgraded connection
    681    */
    682   struct MHD_UpgradedHandle upgr;
    683 
    684   /**
    685    * Double-linked list of HTTP-Upgraded connections waiting for clean-up
    686    */
    687   mhd_DLNKDL_LINKS (MHD_Connection,upgr_cleanup);
    688 #endif /* MHD_SUPPORT_UPGRADE */
    689 
    690   /**
    691    * Reference to the MHD_Daemon struct.
    692    */
    693   struct MHD_Daemon *daemon;
    694 
    695   /**
    696    * HTTP/1.x stream data.
    697    * Currently not used for the actual data.
    698    */
    699   struct MHD_Stream h1_stream;
    700 
    701   /**
    702    * True if connection is suspended
    703    */
    704   volatile bool suspended;
    705 
    706   /**
    707    * True if connection is resuming
    708    */
    709   volatile bool resuming;
    710 
    711   /**
    712    * Request-specific data
    713    */
    714   struct MHD_Request rq;
    715 
    716   /**
    717    * Reply-specific data
    718    */
    719   struct MHD_Reply rp;
    720 
    721   /**
    722    * The memory pool is created whenever we first read from the TCP
    723    * stream and destroyed at the end of each request (and re-created
    724    * for the next request).  In the meantime, this pointer is NULL.
    725    * The pool is used for all connection-related data except for the
    726    * response (which maybe shared between connections) and the IP
    727    * address (which persists across individual requests).
    728    */
    729   struct mhd_MemoryPool *pool;
    730 
    731   /**
    732    * We allow the main application to associate some pointer with the
    733    * TCP connection (which may span multiple HTTP requests).  Here is
    734    * where we store it.  (MHD does not know or care what it is).
    735    * The location is given to the #MHD_NotifyConnectionCallback and
    736    * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
    737    */
    738   void *socket_context;
    739 
    740   /**
    741    * Close connection after sending response?
    742    * Functions may change value from "KeepAlive" to "Must close",
    743    * but no functions reset value "Must Close" to any other value.
    744    */
    745   enum mhd_ConnReuse conn_reuse;
    746 
    747   /**
    748    * Buffer for reading requests.  Allocated in pool.  Actually one
    749    * byte larger than @e read_buffer_size (if non-NULL) to allow for
    750    * 0-termination.
    751    */
    752   char *read_buffer;
    753 
    754   /**
    755    * Buffer for writing response (headers only).  Allocated
    756    * in pool.
    757    */
    758   char *write_buffer;
    759 
    760 #if defined(MHD_SUPPORT_THREADS)
    761   /**
    762    * Thread handle for this connection (if we are using
    763    * one thread per connection).
    764    */
    765   mhd_thread_handle_ID tid;
    766 #endif
    767 
    768   /**
    769    * Size of @e read_buffer (in bytes).
    770    * This value indicates how many bytes we're willing to read
    771    * into the buffer.
    772    */
    773   size_t read_buffer_size;
    774 
    775   /**
    776    * Position where we currently append data in @e read_buffer (the
    777    * next char after the last valid position).
    778    */
    779   size_t read_buffer_offset;
    780 
    781   /**
    782    * Size of @e write_buffer (in bytes).
    783    */
    784   size_t write_buffer_size;
    785 
    786   /**
    787    * Offset where we are with sending from @e write_buffer.
    788    */
    789   size_t write_buffer_send_offset;
    790 
    791   /**
    792    * Last valid location in write_buffer (where do we
    793    * append and up to where is it safe to send?)
    794    */
    795   size_t write_buffer_append_offset;
    796 
    797   /**
    798    * Position in the 100 CONTINUE message that
    799    * we need to send when receiving http 1.1 requests.
    800    */
    801   size_t continue_message_write_offset;
    802 
    803   /**
    804    * Some error happens during processing the connection therefore this
    805    * connection must be closed.
    806    * The error may come from the client side (like wrong request format),
    807    * from the application side (like data callback returned error), or from
    808    * the OS side (like out-of-memory).
    809    */
    810   bool stop_with_error;
    811 
    812   /**
    813    * Response queued early, before the request is fully processed,
    814    * the client upload is rejected.
    815    * The connection cannot be reused for additional requests as the current
    816    * request is incompletely read and it is unclear where is the initial
    817    * byte of the next request.
    818    */
    819   bool discard_request;
    820 
    821 #if defined(MHD_SUPPORT_THREADS)
    822   /**
    823    * Set to `true` if the thread has been joined.
    824    */
    825   bool thread_joined;
    826 #endif
    827 
    828   /**
    829    * Connection is in the cleanup DL-linked list.
    830    */
    831   bool in_cleanup;
    832 
    833   /**
    834    * State in the FSM for this connection.
    835    */
    836   enum mhd_HttpStage stage;
    837 
    838   /**
    839    * What is this connection waiting for?
    840    */
    841   enum MHD_ConnectionEventLoopInfo event_loop_info;
    842 
    843 #ifndef NDEBUG
    844   /**
    845    * Debugging data
    846    */
    847   struct mhd_ConnDebugData dbg;
    848 #endif
    849 };
    850 
    851 #ifdef MHD_SUPPORT_HTTPS
    852 /**
    853  * Returns non-zero if connection has TLS enabled or zero otherwise
    854  */
    855 #  define mhd_C_HAS_TLS(c) (((c)->tls) ? (! 0) : (0))
    856 #else  /* ! MHD_SUPPORT_HTTPS */
    857 /**
    858  * Returns non-zero if connection has TLS enabled or zero otherwise
    859  */
    860 #  define mhd_C_HAS_TLS(c) (0)
    861 #endif /* ! MHD_SUPPORT_HTTPS */
    862 
    863 
    864 #ifdef MHD_SUPPORT_HTTPS
    865 /**
    866  * Returns #mhd_SOCKET_NET_STATE_RECV_READY if connection has incoming data
    867  * pending in TLS buffers
    868  */
    869 #  define mhd_C_HAS_TLS_DATA_IN(c) \
    870         (((c)->tls) ? ((unsigned int) ((c)->tls_has_data_in)) : (0u))
    871 #else  /* ! MHD_SUPPORT_HTTPS */
    872 /**
    873  * Returns #mhd_SOCKET_NET_STATE_RECV_READY if connection has incoming data
    874  * pending in TLS buffers
    875  */
    876 #  define mhd_C_HAS_TLS_DATA_IN(c) (0)
    877 #endif /* ! MHD_SUPPORT_HTTPS */
    878 
    879 #ifdef MHD_SUPPORT_HTTP2
    880 #  define mhd_C_IS_HTTP2(c) \
    881         (mhd_HTTP_VER_FAM_2 == c->h_layer.fam)
    882 #else  /* ! MHD_SUPPORT_HTTP2 */
    883 #  define mhd_C_IS_HTTP2(c)     (! ! 0)
    884 #endif /* ! MHD_SUPPORT_HTTP2 */
    885 
    886 #endif /* ! MHD_CONNECTION_H */