GNU libmicrohttpd  0.9.59
connection.c File Reference

Methods for managing connections. More...

#include "internal.h"
#include "mhd_limits.h"
#include "connection.h"
#include "memorypool.h"
#include "response.h"
#include "mhd_mono_clock.h"
#include "mhd_str.h"
#include "mhd_locks.h"
#include "mhd_sockets.h"
#include "mhd_compat.h"
#include "mhd_itc.h"
Include dependency graph for connection.c:

Go to the source code of this file.

Macros

#define HTTP_100_CONTINUE   "HTTP/1.1 100 Continue\r\n\r\n"
 
#define REQUEST_TOO_BIG   ""
 
#define REQUEST_LACKS_HOST   ""
 
#define REQUEST_MALFORMED   ""
 
#define INTERNAL_ERROR   ""
 
#define DEBUG_CLOSE   MHD_NO
 
#define DEBUG_SEND_DATA   MHD_NO
 
#define MHD_SENFILE_CHUNK_   (0x20000)
 
#define MHD_SENFILE_CHUNK_THR_P_C_   (0x200000)
 
#define MHD_lookup_header_s_token_ci(c, h, tkn)   MHD_lookup_header_token_ci((c),(h),(tkn),MHD_STATICSTR_LEN_(tkn))
 
#define CONNECTION_CLOSE_ERROR(c, emsg)   connection_close_error (c, NULL)
 

Functions

static ssize_t recv_param_adapter (struct MHD_Connection *connection, void *other, size_t i)
 
static ssize_t send_param_adapter (struct MHD_Connection *connection, const void *other, size_t i)
 
static int socket_flush_possible (struct MHD_Connection *connection)
 
static int socket_start_extra_buffering (struct MHD_Connection *connection)
 
static int socket_start_no_buffering (struct MHD_Connection *connection)
 
static int socket_start_no_buffering_flush (struct MHD_Connection *connection)
 
static int socket_start_normal_buffering (struct MHD_Connection *connection)
 
_MHD_EXTERN int MHD_get_connection_values (struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
 
_MHD_EXTERN int MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
 
_MHD_EXTERN const char * MHD_lookup_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
 
static bool MHD_lookup_header_token_ci (const struct MHD_Connection *connection, const char *header, const char *token, size_t token_len)
 
static int need_100_continue (struct MHD_Connection *connection)
 
void MHD_connection_mark_closed_ (struct MHD_Connection *connection)
 
void MHD_connection_close_ (struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
 
static void connection_close_error (struct MHD_Connection *connection, const char *emsg)
 
static int try_ready_normal_body (struct MHD_Connection *connection)
 
static int try_ready_chunked_body (struct MHD_Connection *connection)
 
static int keepalive_possible (struct MHD_Connection *connection)
 
static void get_date_string (char *date, size_t date_len)
 
static int try_grow_read_buffer (struct MHD_Connection *connection)
 
static int build_header_response (struct MHD_Connection *connection)
 
static void transmit_error_response (struct MHD_Connection *connection, unsigned int status_code, const char *message)
 
static void MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
 
static char * get_next_header_line (struct MHD_Connection *connection, size_t *line_len)
 
static int connection_add_header (struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
 
static int parse_cookie_header (struct MHD_Connection *connection)
 
static int parse_initial_message_line (struct MHD_Connection *connection, char *line, size_t line_len)
 
static void call_connection_handler (struct MHD_Connection *connection)
 
static void process_request_body (struct MHD_Connection *connection)
 
static int check_write_done (struct MHD_Connection *connection, enum MHD_CONNECTION_STATE next_state)
 
static int process_header_line (struct MHD_Connection *connection, char *line)
 
static int process_broken_line (struct MHD_Connection *connection, char *line, enum MHD_ValueKind kind)
 
static void parse_connection_headers (struct MHD_Connection *connection)
 
void MHD_update_last_activity_ (struct MHD_Connection *connection)
 
void MHD_connection_handle_read (struct MHD_Connection *connection)
 
void MHD_connection_handle_write (struct MHD_Connection *connection)
 
static void cleanup_connection (struct MHD_Connection *connection)
 
int MHD_connection_handle_idle (struct MHD_Connection *connection)
 
void MHD_set_http_callbacks_ (struct MHD_Connection *connection)
 
_MHD_EXTERN const union MHD_ConnectionInfoMHD_get_connection_info (struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
 
_MHD_EXTERN int MHD_set_connection_option (struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
 
_MHD_EXTERN int MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
 

Detailed Description

Methods for managing connections.

Author
Daniel Pittman
Christian Grothoff
Karlson2k (Evgeny Grin)

Definition in file connection.c.

Macro Definition Documentation

◆ CONNECTION_CLOSE_ERROR

◆ DEBUG_CLOSE

#define DEBUG_CLOSE   MHD_NO

Add extra debug messages with reasons for closing connections (non-error reasons).

Definition at line 112 of file connection.c.

◆ DEBUG_SEND_DATA

#define DEBUG_SEND_DATA   MHD_NO

Should all data send be printed to stderr?

Definition at line 117 of file connection.c.

◆ HTTP_100_CONTINUE

#define HTTP_100_CONTINUE   "HTTP/1.1 100 Continue\r\n\r\n"

Message to transmit when http 1.1 request is received

Definition at line 55 of file connection.c.

Referenced by MHD_connection_handle_idle(), MHD_connection_handle_write(), and need_100_continue().

◆ INTERNAL_ERROR

#define INTERNAL_ERROR   ""

Response text used when there is an internal server error.

Intentionally empty here to keep our memory footprint minimal.

Definition at line 105 of file connection.c.

Referenced by MHD_connection_update_event_loop_info().

◆ MHD_lookup_header_s_token_ci

#define MHD_lookup_header_s_token_ci (   c,
  h,
  tkn 
)    MHD_lookup_header_token_ci((c),(h),(tkn),MHD_STATICSTR_LEN_(tkn))

Check whether request header contains particular static tkn.

Token could be surrounded by spaces and tabs and delimited by comma. Case-insensitive match used for header names and tokens.

Parameters
cthe connection to get values from
hthe header name
tknthe static string of token to find
Returns
true if token is found in specified header, false otherwise

Definition at line 861 of file connection.c.

Referenced by build_header_response(), and keepalive_possible().

◆ MHD_SENFILE_CHUNK_

#define MHD_SENFILE_CHUNK_   (0x20000)

sendfile() chuck size

Definition at line 123 of file connection.c.

◆ MHD_SENFILE_CHUNK_THR_P_C_

#define MHD_SENFILE_CHUNK_THR_P_C_   (0x200000)

sendfile() chuck size for thread-per-connection

Definition at line 128 of file connection.c.

◆ REQUEST_LACKS_HOST

#define REQUEST_LACKS_HOST   ""

Response text used when the request (http header) does not contain a "Host:" header and still claims to be HTTP 1.1.

Intentionally empty here to keep our memory footprint minimal.

Definition at line 80 of file connection.c.

Referenced by parse_connection_headers().

◆ REQUEST_MALFORMED

#define REQUEST_MALFORMED   ""

Response text used when the request (http header) is malformed.

Intentionally empty here to keep our memory footprint minimal.

Definition at line 93 of file connection.c.

Referenced by MHD_connection_handle_idle(), and process_broken_line().

◆ REQUEST_TOO_BIG

#define REQUEST_TOO_BIG   ""

Response text used when the request (http header) is too big to be processed.

Intentionally empty here to keep our memory footprint minimal.

Definition at line 67 of file connection.c.

Referenced by connection_add_header(), get_next_header_line(), MHD_connection_update_event_loop_info(), parse_cookie_header(), and process_broken_line().

Function Documentation

◆ build_header_response()

static int build_header_response ( struct MHD_Connection connection)
static

Allocate the connection's write buffer and fill it with all of the headers (or footers, if we have already sent the body) from the HTTPd's response. If headers are missing in the response supplied by the application, additional headers may be added here.

Parameters
connectionthe connection
Returns
MHD_YES on success, MHD_NO on failure (out of memory)

Definition at line 1403 of file connection.c.

References MHD_Connection::daemon, data, MHD_Response::first_header, MHD_Response::flags, get_date_string(), MHD_Connection::have_chunked_upload, MHD_HTTP_Header::header, MHD_Connection::keepalive, keepalive_possible(), MHD_HTTP_Header::kind, MHD_Connection::method, mhd_assert, MHD_check_response_header_s_token_ci, MHD_CONN_MUST_CLOSE, MHD_CONN_USE_KEEPALIVE, MHD_CONNECTION_BODY_SENT, MHD_CONNECTION_FOOTERS_RECEIVED, MHD_FOOTER_KIND, MHD_get_reason_phrase_for(), MHD_get_response_header(), MHD_HEADER_KIND, MHD_HTTP_HEADER_CONNECTION, MHD_HTTP_HEADER_CONTENT_LENGTH, MHD_HTTP_HEADER_DATE, MHD_HTTP_HEADER_TRANSFER_ENCODING, MHD_HTTP_METHOD_CONNECT, MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED, MHD_HTTP_OK, MHD_HTTP_VERSION_1_0, MHD_HTTP_VERSION_1_1, MHD_ICY_FLAG, MHD_lookup_header_s_token_ci, MHD_NO, mhd_panic, mhd_panic_cls, MHD_pool_allocate(), MHD_RF_HTTP_VERSION_1_0_ONLY, MHD_SIZE_UNKNOWN, MHD_STATICSTR_LEN_, MHD_str_equal_caseless_(), MHD_UNSIGNED_LONG_LONG, MHD_UNSIGNED_LONG_LONG_PRINTF, MHD_USE_SUPPRESS_DATE_NO_CLOCK, MHD_YES, MHD_HTTP_Header::next, NULL, MHD_Daemon::options, MHD_Connection::pool, MHD_Connection::read_closed, MHD_Connection::response, MHD_Connection::responseCode, MHD_Connection::state, MHD_Response::total_size, MHD_HTTP_Header::value, MHD_Connection::version, MHD_Connection::write_buffer, MHD_Connection::write_buffer_append_offset, MHD_Connection::write_buffer_send_offset, and MHD_Connection::write_buffer_size.

Referenced by MHD_connection_handle_idle(), and transmit_error_response().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ call_connection_handler()

static void call_connection_handler ( struct MHD_Connection connection)
static

Call the handler of the application for this connection. Handles chunking of the upload as well as normal uploads.

Parameters
connectionconnection we're processing

Definition at line 2275 of file connection.c.

References _, MHD_Connection::client_aware, MHD_Connection::client_context, CONNECTION_CLOSE_ERROR, MHD_Connection::daemon, MHD_Daemon::default_handler, MHD_Daemon::default_handler_cls, MHD_Connection::method, MHD_NO, NULL, MHD_Connection::response, MHD_Connection::url, and MHD_Connection::version.

Referenced by MHD_connection_handle_idle().

Here is the caller graph for this function:

◆ check_write_done()

static int check_write_done ( struct MHD_Connection connection,
enum MHD_CONNECTION_STATE  next_state 
)
static

Check if we are done sending the write-buffer. If so, transition into "next_state".

Parameters
connectionconnection to check write status for
next_statethe next state to transition to
Returns
MHD_NO if we are not done, MHD_YES if we are

Definition at line 2533 of file connection.c.

References MHD_NO, MHD_pool_reallocate(), MHD_YES, NULL, MHD_Connection::pool, MHD_Connection::state, MHD_Connection::write_buffer, MHD_Connection::write_buffer_append_offset, MHD_Connection::write_buffer_send_offset, and MHD_Connection::write_buffer_size.

Referenced by MHD_connection_handle_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_connection()

static void cleanup_connection ( struct MHD_Connection connection)
static

◆ connection_add_header()

static int connection_add_header ( struct MHD_Connection connection,
const char *  key,
const char *  value,
enum MHD_ValueKind  kind 
)
static

Add an entry to the HTTP headers of a connection. If this fails, transmit an error response (request too big).

Parameters
connectionthe connection for which a value should be set
kindkind of the value
keykey for the value
valuethe value itself
Returns
MHD_NO on failure (out of memory), MHD_YES for success

Definition at line 2035 of file connection.c.

References _, MHD_Connection::daemon, MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, MHD_NO, MHD_set_connection_value(), MHD_YES, REQUEST_TOO_BIG, and transmit_error_response().

Referenced by parse_cookie_header(), parse_initial_message_line(), and process_broken_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connection_close_error()

static void connection_close_error ( struct MHD_Connection connection,
const char *  emsg 
)
static

A serious error occured, close the connection (and notify the application).

Parameters
connectionconnection to close with error
emsgerror message (can be NULL)

Definition at line 1032 of file connection.c.

References MHD_Connection::daemon, MHD_connection_close_(), MHD_REQUEST_TERMINATED_WITH_ERROR, and NULL.

Here is the call graph for this function:

◆ get_date_string()

static void get_date_string ( char *  date,
size_t  date_len 
)
static

Produce HTTP time stamp.

Parameters
datewhere to write the header, with at least 128 bytes available space.
date_lennumber of bytes in date

Definition at line 1311 of file connection.c.

References NULL.

Referenced by build_header_response().

Here is the caller graph for this function:

◆ get_next_header_line()

static char* get_next_header_line ( struct MHD_Connection connection,
size_t *  line_len 
)
static

Parse a single line of the HTTP header. Advance read_buffer (!) appropriately. If the current line does not fit, consider growing the buffer. If the line is far too long, close the connection. If no line is found (incomplete, buffer too small, line too long), return NULL. Otherwise return a pointer to the line.

Parameters
connectionconnection we're processing
[out]line_lenpointer to variable that receive length of line or NULL
Returns
NULL if no full line is available; note that the returned string will not be 0-termianted

Definition at line 1976 of file connection.c.

References MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, MHD_HTTP_URI_TOO_LONG, MHD_NO, NULL, MHD_Connection::read_buffer, MHD_Connection::read_buffer_offset, MHD_Connection::read_buffer_size, REQUEST_TOO_BIG, transmit_error_response(), try_grow_read_buffer(), and MHD_Connection::url.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ keepalive_possible()

static int keepalive_possible ( struct MHD_Connection connection)
static

Are we allowed to keep the given connection alive? We can use the TCP stream for a second request if the connection is HTTP 1.1 and the "Connection" header either does not exist or is not set to "close", or if the connection is HTTP 1.0 and the "Connection" header is explicitly set to "keep-alive". If no HTTP version is specified (or if it is not 1.0 or 1.1), we definitively close the connection. If the "Connection" header is not exactly "close" or "keep-alive", we proceed to use the default for the respective HTTP version (which is conservative for HTTP 1.0, but might be a bit optimistic for HTTP 1.1).

Parameters
connectionthe connection to check for keepalive
Returns
MHD_YES if (based on the request), a keepalive is legal

Definition at line 1264 of file connection.c.

References MHD_Response::flags, MHD_Connection::keepalive, MHD_CONN_MUST_CLOSE, MHD_HTTP_HEADER_CONNECTION, MHD_HTTP_VERSION_1_0, MHD_HTTP_VERSION_1_1, MHD_lookup_header_s_token_ci, MHD_NO, MHD_RF_HTTP_VERSION_1_0_ONLY, MHD_str_equal_caseless_(), MHD_YES, NULL, MHD_Connection::response, and MHD_Connection::version.

Referenced by build_header_response().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_connection_close_()

void MHD_connection_close_ ( struct MHD_Connection connection,
enum MHD_RequestTerminationCode  termination_code 
)

Close the given connection and give the specified termination code to the user.

Remarks
To be called only from thread that process connection's recv(), send() and response.
Parameters
connectionconnection to close
termination_codetermination reason to give

Definition at line 936 of file connection.c.

References MHD_Connection::client_aware, MHD_Connection::client_context, MHD_Connection::daemon, MHD_connection_mark_closed_(), MHD_destroy_response(), MHD_Daemon::notify_completed, MHD_Daemon::notify_completed_cls, NULL, and MHD_Connection::response.

Referenced by call_handlers(), close_connection(), connection_close_error(), MHD_connection_handle_idle(), MHD_connection_handle_read(), MHD_run_tls_handshake_(), thread_main_handle_connection(), and try_ready_normal_body().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_connection_handle_idle()

int MHD_connection_handle_idle ( struct MHD_Connection connection)

This function was created to handle per-connection processing that has to happen even if the socket cannot be read or written to.

Remarks
To be called only from thread that process connection's recv(), send() and response.
Parameters
connectionconnection to handle
Returns
MHD_YES if we should continue to process the connection (not dead yet), MHD_NO if it died

Definition at line 3240 of file connection.c.

References _, build_header_response(), call_connection_handler(), cleanup_connection(), MHD_Connection::client_aware, MHD_Connection::client_context, MHD_Connection::colon, CONNECTION_CLOSE_ERROR, MHD_Connection::connection_timeout, MHD_Connection::continue_message_write_offset, MHD_Response::crc, MHD_Connection::current_chunk_offset, MHD_Connection::current_chunk_size, MHD_Connection::daemon, get_next_header_line(), MHD_Connection::have_chunked_upload, MHD_Connection::header_size, MHD_Connection::headers_received, MHD_Connection::headers_received_tail, HTTP_100_CONTINUE, MHD_Connection::in_idle, MHD_Connection::keepalive, MHD_Connection::last, MHD_Connection::last_activity, MHD_Connection::method, mhd_assert, MHD_CONN_KEEPALIVE_UNKOWN, MHD_CONN_USE_KEEPALIVE, MHD_CONNECTION_BODY_RECEIVED, MHD_CONNECTION_BODY_SENT, MHD_CONNECTION_CHUNKED_BODY_READY, MHD_CONNECTION_CHUNKED_BODY_UNREADY, MHD_connection_close_(), MHD_CONNECTION_CLOSED, MHD_CONNECTION_CONTINUE_SENDING, MHD_CONNECTION_CONTINUE_SENT, MHD_CONNECTION_FOOTER_PART_RECEIVED, MHD_CONNECTION_FOOTERS_RECEIVED, MHD_CONNECTION_FOOTERS_SENDING, MHD_CONNECTION_FOOTERS_SENT, MHD_CONNECTION_HEADER_PART_RECEIVED, MHD_CONNECTION_HEADERS_PROCESSED, MHD_CONNECTION_HEADERS_RECEIVED, MHD_CONNECTION_HEADERS_SENDING, MHD_CONNECTION_HEADERS_SENT, MHD_CONNECTION_INIT, MHD_CONNECTION_NORMAL_BODY_READY, MHD_CONNECTION_NORMAL_BODY_UNREADY, MHD_connection_update_event_loop_info(), MHD_CONNECTION_URL_RECEIVED, MHD_destroy_response(), MHD_FOOTER_KIND, MHD_HEADER_KIND, MHD_HTTP_BAD_REQUEST, MHD_HTTP_METHOD_POST, MHD_HTTP_METHOD_PUT, MHD_HTTP_PROCESSING, MHD_monotonic_sec_counter(), MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_pool_destroy(), MHD_pool_reset(), MHD_REQUEST_TERMINATED_COMPLETED_OK, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED, MHD_response_execute_upgrade_(), MHD_SIZE_UNKNOWN, MHD_STATICSTR_LEN_, MHD_str_equal_caseless_(), MHD_TLS_CONN_CONNECTED, MHD_TLS_CONN_NO_TLS, MHD_USE_EPOLL, MHD_YES, MHD_Response::mutex, need_100_continue(), MHD_Daemon::notify_completed, MHD_Daemon::notify_completed_cls, NULL, MHD_Daemon::options, parse_connection_headers(), parse_initial_message_line(), MHD_Connection::pool, MHD_Daemon::pool_size, process_broken_line(), process_header_line(), process_request_body(), MHD_Connection::read_buffer, MHD_Connection::read_buffer_offset, MHD_Connection::read_buffer_size, MHD_Connection::read_closed, MHD_Connection::remaining_upload_size, REQUEST_MALFORMED, MHD_Connection::response, MHD_Connection::response_write_position, MHD_Connection::responseCode, socket_flush_possible(), socket_start_extra_buffering(), socket_start_no_buffering(), socket_start_no_buffering_flush(), socket_start_normal_buffering(), MHD_Connection::state, MHD_Connection::suspended, MHD_Response::total_size, transmit_error_response(), try_ready_chunked_body(), try_ready_normal_body(), MHD_Connection::url, MHD_Connection::version, MHD_Connection::write_buffer, MHD_Connection::write_buffer_append_offset, MHD_Connection::write_buffer_send_offset, and MHD_Connection::write_buffer_size.

Referenced by call_handlers(), MHD_queue_response(), and thread_main_handle_connection().

Here is the caller graph for this function:

◆ MHD_connection_handle_read()

◆ MHD_connection_handle_write()

void MHD_connection_handle_write ( struct MHD_Connection connection)

This function was created to handle writes to sockets when it has been determined that the socket can be written to.

Parameters
connectionconnection to handle

Definition at line 2929 of file connection.c.

References _, check_write_done(), CONNECTION_CLOSE_ERROR, MHD_Connection::continue_message_write_offset, MHD_Response::crc, MHD_Connection::daemon, MHD_Response::data, MHD_Response::data_size, MHD_Response::data_start, HTTP_100_CONTINUE, mhd_assert, MHD_CONNECTION_BODY_RECEIVED, MHD_CONNECTION_BODY_SENT, MHD_CONNECTION_CHUNKED_BODY_READY, MHD_CONNECTION_CHUNKED_BODY_UNREADY, MHD_CONNECTION_CLOSED, MHD_CONNECTION_CONTINUE_SENDING, MHD_CONNECTION_CONTINUE_SENT, MHD_CONNECTION_FOOTER_PART_RECEIVED, MHD_CONNECTION_FOOTERS_RECEIVED, MHD_CONNECTION_FOOTERS_SENDING, MHD_CONNECTION_FOOTERS_SENT, MHD_CONNECTION_HEADER_PART_RECEIVED, MHD_CONNECTION_HEADERS_PROCESSED, MHD_CONNECTION_HEADERS_RECEIVED, MHD_CONNECTION_HEADERS_SENDING, MHD_CONNECTION_HEADERS_SENT, MHD_CONNECTION_IN_CLEANUP, MHD_CONNECTION_INIT, MHD_CONNECTION_NORMAL_BODY_READY, MHD_CONNECTION_NORMAL_BODY_UNREADY, MHD_CONNECTION_URL_RECEIVED, MHD_ERR_AGAIN_, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_PANIC, MHD_run_tls_handshake_(), MHD_STATICSTR_LEN_, MHD_TLS_CONN_CONNECTED, MHD_TLS_CONN_NO_TLS, MHD_update_last_activity_(), MHD_YES, MHD_Response::mutex, NULL, MHD_Connection::response, MHD_Connection::response_write_position, MHD_Connection::send_cls, SIZE_MAX, MHD_Connection::state, MHD_Connection::suspended, MHD_Response::total_size, try_ready_normal_body(), MHD_Connection::url, MHD_Connection::write_buffer, MHD_Connection::write_buffer_append_offset, and MHD_Connection::write_buffer_send_offset.

Referenced by call_handlers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_connection_mark_closed_()

void MHD_connection_mark_closed_ ( struct MHD_Connection connection)

Mark connection as "closed".

Remarks
To be called from any thread.
Parameters
connectionconnection to close

Definition at line 898 of file connection.c.

References MHD_Connection::daemon, MHD_Connection::event_loop_info, MHD_CONNECTION_CLOSED, MHD_EVENT_LOOP_INFO_CLEANUP, MHD_tls_connection_shutdown(), MHD_USE_TLS, MHD_USE_TURBO, MHD_Daemon::options, MHD_Daemon::shutdown, MHD_Connection::socket_fd, and MHD_Connection::state.

Referenced by close_connection(), and MHD_connection_close_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_connection_update_event_loop_info()

static void MHD_connection_update_event_loop_info ( struct MHD_Connection connection)
static

Update the 'event_loop_info' field of this connection based on the state that the connection is now in. May also close the connection or perform other updates to the connection if needed to prepare for the next round of the event loop.

Parameters
connectionconnection to get poll set for

Definition at line 1805 of file connection.c.

References _, CONNECTION_CLOSE_ERROR, MHD_Connection::daemon, MHD_Connection::event_loop_info, INTERNAL_ERROR, mhd_assert, MHD_CONNECTION_BODY_RECEIVED, MHD_CONNECTION_BODY_SENT, MHD_CONNECTION_CHUNKED_BODY_READY, MHD_CONNECTION_CHUNKED_BODY_UNREADY, MHD_CONNECTION_CLOSED, MHD_CONNECTION_CONTINUE_SENDING, MHD_CONNECTION_CONTINUE_SENT, MHD_CONNECTION_FOOTER_PART_RECEIVED, MHD_CONNECTION_FOOTERS_RECEIVED, MHD_CONNECTION_FOOTERS_SENDING, MHD_CONNECTION_FOOTERS_SENT, MHD_CONNECTION_HEADER_PART_RECEIVED, MHD_CONNECTION_HEADERS_PROCESSED, MHD_CONNECTION_HEADERS_RECEIVED, MHD_CONNECTION_HEADERS_SENDING, MHD_CONNECTION_HEADERS_SENT, MHD_CONNECTION_IN_CLEANUP, MHD_CONNECTION_INIT, MHD_CONNECTION_NORMAL_BODY_READY, MHD_CONNECTION_NORMAL_BODY_UNREADY, MHD_CONNECTION_URL_RECEIVED, MHD_EVENT_LOOP_INFO_BLOCK, MHD_EVENT_LOOP_INFO_CLEANUP, MHD_EVENT_LOOP_INFO_READ, MHD_EVENT_LOOP_INFO_WRITE, MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, MHD_HTTP_URI_TOO_LONG, MHD_NO, MHD_TLS_CONN_HANDSHAKING, MHD_TLS_CONN_INIT, MHD_TLS_CONN_NO_TLS, MHD_USE_INTERNAL_POLLING_THREAD, MHD_YES, NULL, MHD_Daemon::options, MHD_Connection::read_buffer_offset, MHD_Connection::read_buffer_size, MHD_Connection::read_closed, REQUEST_TOO_BIG, MHD_Connection::state, MHD_Connection::suspended, transmit_error_response(), try_grow_read_buffer(), and MHD_Connection::url.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_lookup_header_token_ci()

static bool MHD_lookup_header_token_ci ( const struct MHD_Connection connection,
const char *  header,
const char *  token,
size_t  token_len 
)
static

Check whether request header contains particular token.

Token could be surrounded by spaces and tabs and delimited by comma. Case-insensitive match used for header names and tokens.

Parameters
connectionthe connection to get values from
headerthe header name
tokenthe token to find
token_lenthe length of token, not including optional terminating null-character.
Returns
true if token is found in specified header, false otherwise

Definition at line 828 of file connection.c.

References MHD_HTTP_Header::header, MHD_Connection::headers_received, MHD_HTTP_Header::kind, MHD_HEADER_KIND, MHD_str_equal_caseless_(), MHD_str_has_token_caseless_(), MHD_HTTP_Header::next, NULL, and MHD_HTTP_Header::value.

Here is the call graph for this function:

◆ MHD_set_http_callbacks_()

void MHD_set_http_callbacks_ ( struct MHD_Connection connection)

Set callbacks for this connection to those for HTTP.

Parameters
connectionconnection to initialize

Definition at line 3792 of file connection.c.

References MHD_Connection::recv_cls, recv_param_adapter(), MHD_Connection::send_cls, and send_param_adapter().

Referenced by internal_add_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_update_last_activity_()

void MHD_update_last_activity_ ( struct MHD_Connection connection)

Update the 'last_activity' field of the connection to the current time and move the connection to the head of the 'normal_timeout' list if the timeout for the connection uses the default value.

Parameters
connectionthe connection that saw some activity

Definition at line 2784 of file connection.c.

References MHD_Daemon::cleanup_connection_mutex, MHD_Connection::connection_timeout, MHD_Daemon::connection_timeout, MHD_Connection::daemon, MHD_Connection::last_activity, MHD_monotonic_sec_counter(), MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_USE_THREAD_PER_CONNECTION, MHD_Daemon::normal_timeout_head, MHD_Daemon::normal_timeout_tail, MHD_Daemon::options, MHD_Connection::suspended, XDLL_insert, and XDLL_remove.

Referenced by MHD_connection_handle_read(), MHD_connection_handle_write(), MHD_run_tls_handshake_(), and thread_main_handle_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ need_100_continue()

static int need_100_continue ( struct MHD_Connection connection)
static

Do we (still) need to send a 100 continue message for this connection?

Parameters
connectionconnection to test
Returns
0 if we don't need 100 CONTINUE, 1 if we do

Definition at line 873 of file connection.c.

References MHD_Connection::continue_message_write_offset, HTTP_100_CONTINUE, MHD_HEADER_KIND, MHD_HTTP_HEADER_EXPECT, MHD_HTTP_VERSION_1_1, MHD_lookup_connection_value(), MHD_STATICSTR_LEN_, MHD_str_equal_caseless_(), NULL, MHD_Connection::response, and MHD_Connection::version.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_connection_headers()

◆ parse_cookie_header()

static int parse_cookie_header ( struct MHD_Connection connection)
static

Parse the cookie header (see RFC 2109).

Parameters
connectionconnection to parse header of
Returns
MHD_YES for success, MHD_NO for failure (malformed, out of memory)

Definition at line 2066 of file connection.c.

References _, connection_add_header(), MHD_Connection::daemon, MHD_COOKIE_KIND, MHD_HEADER_KIND, MHD_HTTP_HEADER_COOKIE, MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, MHD_lookup_connection_value(), MHD_NO, MHD_pool_allocate(), MHD_YES, NULL, MHD_Connection::pool, REQUEST_TOO_BIG, and transmit_error_response().

Referenced by parse_connection_headers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_initial_message_line()

static int parse_initial_message_line ( struct MHD_Connection connection,
char *  line,
size_t  line_len 
)
static

Parse the first line of the HTTP HEADER.

Parameters
connectionthe connection (updated)
linethe first line, not 0-terminated
line_lenlength of the first line
Returns
MHD_YES if the line is ok, MHD_NO if it is malformed

Definition at line 2180 of file connection.c.

References MHD_Connection::client_aware, MHD_Connection::client_context, connection_add_header(), MHD_Connection::daemon, MHD_Connection::method, MHD_GET_ARGUMENT_KIND, MHD_NO, MHD_parse_arguments_(), MHD_YES, NULL, MHD_Daemon::unescape_callback, MHD_Daemon::unescape_callback_cls, MHD_Daemon::uri_log_callback, MHD_Daemon::uri_log_callback_cls, MHD_Connection::url, and MHD_Connection::version.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_broken_line()

static int process_broken_line ( struct MHD_Connection connection,
char *  line,
enum MHD_ValueKind  kind 
)
static

Process a header value that spans multiple lines. The previous line(s) are in connection->last.

Parameters
connectionconnection we're processing
linethe current input line
kindif the line is complete, add a header of the given kind
Returns
MHD_YES if the line was processed successfully

Definition at line 2621 of file connection.c.

References MHD_Connection::colon, connection_add_header(), MHD_Connection::last, mhd_assert, MHD_HTTP_BAD_REQUEST, MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, MHD_NO, MHD_pool_reallocate(), MHD_YES, NULL, MHD_Connection::pool, process_header_line(), REQUEST_MALFORMED, REQUEST_TOO_BIG, and transmit_error_response().

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_header_line()

static int process_header_line ( struct MHD_Connection connection,
char *  line 
)
static

We have received (possibly the beginning of) a line in the header (or footer). Validate (check for ":") and prepare to process.

Parameters
connectionconnection we're processing
lineline from the header to process
Returns
MHD_YES on success, MHD_NO on error (malformed line)

Definition at line 2562 of file connection.c.

References _, MHD_Connection::colon, CONNECTION_CLOSE_ERROR, MHD_Connection::daemon, MHD_Connection::last, MHD_NO, MHD_YES, NULL, and MHD_Daemon::strict_for_client.

Referenced by MHD_connection_handle_idle(), and process_broken_line().

Here is the caller graph for this function:

◆ process_request_body()

static void process_request_body ( struct MHD_Connection connection)
static

Call the handler of the application for this connection. Handles chunking of the upload as well as normal uploads.

Parameters
connectionconnection we're processing
  1. no chunked encoding, give all to the client
  2. client may send large chunked data, but only a smaller part is available at one time.

Definition at line 2310 of file connection.c.

References _, MHD_Connection::client_aware, MHD_Connection::client_context, CONNECTION_CLOSE_ERROR, MHD_Connection::current_chunk_offset, MHD_Connection::current_chunk_size, MHD_Connection::daemon, MHD_Daemon::default_handler, MHD_Daemon::default_handler_cls, MHD_Connection::have_chunked_upload, MHD_Connection::method, MHD_NO, mhd_panic, mhd_panic_cls, MHD_SIZE_UNKNOWN, MHD_strx_to_uint64_n_(), MHD_USE_INTERNAL_POLLING_THREAD, MHD_YES, NULL, MHD_Daemon::options, MHD_Connection::read_buffer, MHD_Connection::read_buffer_offset, MHD_Connection::remaining_upload_size, MHD_Connection::response, MHD_Connection::suspended, MHD_Connection::url, and MHD_Connection::version.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_param_adapter()

static ssize_t recv_param_adapter ( struct MHD_Connection connection,
void *  other,
size_t  i 
)
static

Callback for receiving data from the socket.

Parameters
connectionthe MHD connection structure
otherwhere to write received data to
imaximum size of other (in bytes)
Returns
positive value for number of bytes actually received or negative value for error number MHD_ERR_xxx_

Definition at line 178 of file connection.c.

References MHD_CONNECTION_CLOSED, MHD_EPOLL_STATE_READ_READY, MHD_ERR_AGAIN_, MHD_ERR_CONNRESET_, MHD_ERR_NOTCONN_, MHD_INVALID_SOCKET, MHD_recv_, MHD_SCKT_ECONNRESET_, MHD_SCKT_ERR_IS_, MHD_SCKT_ERR_IS_EAGAIN_, MHD_SCKT_ERR_IS_EINTR_, MHD_SCKT_SEND_MAX_SIZE_, MHD_socket_get_error_, MHD_Connection::socket_fd, and MHD_Connection::state.

Referenced by MHD_set_http_callbacks_().

Here is the caller graph for this function:

◆ send_param_adapter()

static ssize_t send_param_adapter ( struct MHD_Connection connection,
const void *  other,
size_t  i 
)
static

Callback for writing data to the socket.

Parameters
connectionthe MHD connection structure
otherdata to write
inumber of bytes to write
Returns
positive value for number of bytes actually sent or negative value for error number MHD_ERR_xxx_

Definition at line 231 of file connection.c.

References MHD_CONNECTION_CLOSED, MHD_EPOLL_STATE_WRITE_READY, MHD_ERR_AGAIN_, MHD_ERR_CONNRESET_, MHD_ERR_NOTCONN_, MHD_INVALID_SOCKET, MHD_SCKT_ECONNRESET_, MHD_SCKT_ERR_IS_, MHD_SCKT_ERR_IS_EAGAIN_, MHD_SCKT_ERR_IS_EINTR_, MHD_SCKT_SEND_MAX_SIZE_, MHD_send_, MHD_socket_get_error_, MHD_Connection::socket_fd, and MHD_Connection::state.

Referenced by MHD_set_http_callbacks_().

Here is the caller graph for this function:

◆ socket_flush_possible()

static int socket_flush_possible ( struct MHD_Connection connection)
static

Check whether is possible to force push socket buffer content as partial packet. MHD use different buffering logic depending on whether flushing of socket buffer is possible or not. If flushing IS possible than MHD activates extra buffering before sending data to prevent sending partial packets and flush pending data in socket buffer to push last partial packet to client after sending logical completed part of data (for example: after sending full response header or full response message). If flushing IS NOT possible than MHD activates no buffering (no delay sending) when it going to send formed fully completed logical part of data and activate normal buffering after sending. For idled keep-alive connection MHD always activate normal buffering.

Parameters
connectionconnection to check
Returns
MHD_YES if force push is possible, MHD_NO otherwise

Definition at line 476 of file connection.c.

References MHD_NO, and MHD_YES.

Referenced by MHD_connection_handle_idle().

Here is the caller graph for this function:

◆ socket_start_extra_buffering()

static int socket_start_extra_buffering ( struct MHD_Connection connection)
static

Activate extra buffering mode on connection socket to prevent sending of partial packets.

Parameters
connectionconnection to be processed
Returns
MHD_YES on success, MHD_NO otherwise

Definition at line 495 of file connection.c.

References mhd_assert, MHD_NO, MHD_YES, NULL, and MHD_Connection::socket_fd.

Referenced by MHD_connection_handle_idle().

Here is the caller graph for this function:

◆ socket_start_no_buffering()

static int socket_start_no_buffering ( struct MHD_Connection connection)
static

Activate no buffering mode (no delay sending) on connection socket.

Parameters
connectionconnection to be processed
Returns
MHD_YES on success, MHD_NO otherwise

Definition at line 554 of file connection.c.

References mhd_assert, MHD_NO, MHD_YES, NULL, and MHD_Connection::socket_fd.

Referenced by MHD_connection_handle_idle(), and socket_start_no_buffering_flush().

Here is the caller graph for this function:

◆ socket_start_no_buffering_flush()

static int socket_start_no_buffering_flush ( struct MHD_Connection connection)
static

Activate no buffering mode (no delay sending) on connection socket and push to client data pending in socket buffer.

Parameters
connectionconnection to be processed
Returns
MHD_YES on success, MHD_NO otherwise

Definition at line 607 of file connection.c.

References MHD_NO, MHD_send_, MHD_YES, NULL, MHD_Connection::socket_fd, and socket_start_no_buffering().

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ socket_start_normal_buffering()

static int socket_start_normal_buffering ( struct MHD_Connection connection)
static

Activate normal buffering mode on connection socket.

Parameters
connectionconnection to be processed
Returns
MHD_YES on success, MHD_NO otherwise

Definition at line 637 of file connection.c.

References mhd_assert, MHD_NO, MHD_YES, NULL, and MHD_Connection::socket_fd.

Referenced by MHD_connection_handle_idle().

Here is the caller graph for this function:

◆ transmit_error_response()

static void transmit_error_response ( struct MHD_Connection connection,
unsigned int  status_code,
const char *  message 
)
static

We encountered an error processing the request. Handle it properly by stopping to read data and sending the indicated response code and message.

Parameters
connectionthe connection
status_codethe response code to send (400, 413 or 414)
messagethe error message to send

Definition at line 1748 of file connection.c.

References _, build_header_response(), CONNECTION_CLOSE_ERROR, MHD_Connection::daemon, MHD_Connection::keepalive, mhd_assert, MHD_CONN_MUST_CLOSE, MHD_CONNECTION_FOOTERS_RECEIVED, MHD_CONNECTION_HEADERS_SENDING, MHD_create_response_from_buffer(), MHD_destroy_response(), MHD_HTTP_VERSION_1_0, MHD_NO, MHD_queue_response(), MHD_RESPMEM_PERSISTENT, NULL, MHD_Connection::read_closed, MHD_Connection::response, MHD_Connection::state, and MHD_Connection::version.

Referenced by connection_add_header(), get_next_header_line(), MHD_connection_handle_idle(), MHD_connection_update_event_loop_info(), parse_cookie_header(), and process_broken_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_grow_read_buffer()

static int try_grow_read_buffer ( struct MHD_Connection connection)
static

Try growing the read buffer. We initially claim half the available buffer space for the read buffer (the other half being left for management data structures; the write buffer can in the end take virtually everything as the read buffer can be reduced to the minimum necessary at that point.

Parameters
connectionthe connection
Returns
MHD_YES on success, MHD_NO on failure

Definition at line 1371 of file connection.c.

References MHD_Connection::daemon, MHD_BUF_INC_SIZE, MHD_NO, MHD_pool_reallocate(), MHD_YES, NULL, MHD_Connection::pool, MHD_Daemon::pool_size, MHD_Connection::read_buffer, and MHD_Connection::read_buffer_size.

Referenced by get_next_header_line(), MHD_connection_handle_read(), and MHD_connection_update_event_loop_info().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_ready_chunked_body()

static int try_ready_chunked_body ( struct MHD_Connection connection)
static

Prepare the response buffer of this connection for sending. Assumes that the response mutex is already held. If the transmission is complete, this function may close the socket (and return MHD_NO).

Parameters
connectionthe connection
Returns
MHD_NO if readying the response failed

Definition at line 1137 of file connection.c.

References _, CONNECTION_CLOSE_ERROR, MHD_Response::crc, MHD_Response::crc_cls, MHD_Connection::daemon, MHD_Response::data, MHD_Response::data_size, MHD_Response::data_start, mhd_assert, MHD_CONNECTION_CHUNKED_BODY_UNREADY, MHD_CONTENT_READER_END_OF_STREAM, MHD_CONTENT_READER_END_WITH_ERROR, MHD_MIN, MHD_mutex_unlock_chk_, MHD_NO, MHD_pool_allocate(), MHD_YES, MHD_Response::mutex, NULL, MHD_Connection::pool, MHD_Daemon::pool_size, MHD_Connection::response, MHD_Connection::response_write_position, MHD_Connection::state, MHD_Response::total_size, MHD_Connection::write_buffer, MHD_Connection::write_buffer_append_offset, MHD_Connection::write_buffer_send_offset, and MHD_Connection::write_buffer_size.

Referenced by MHD_connection_handle_idle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_ready_normal_body()

static int try_ready_normal_body ( struct MHD_Connection connection)
static

Prepare the response buffer of this connection for sending. Assumes that the response mutex is already held. If the transmission is complete, this function may close the socket (and return MHD_NO).

Parameters
connectionthe connection
Returns
MHD_NO if readying the response failed (the lock on the response will have been released already in this case).

Definition at line 1071 of file connection.c.

References _, CONNECTION_CLOSE_ERROR, MHD_Response::crc, MHD_Response::crc_cls, MHD_Response::data, MHD_Response::data_buffer_size, MHD_Response::data_size, MHD_Response::data_start, MHD_connection_close_(), MHD_CONNECTION_NORMAL_BODY_UNREADY, MHD_CONTENT_READER_END_OF_STREAM, MHD_CONTENT_READER_END_WITH_ERROR, MHD_MIN, MHD_mutex_unlock_chk_, MHD_NO, MHD_REQUEST_TERMINATED_COMPLETED_OK, MHD_YES, MHD_Response::mutex, NULL, MHD_Connection::response, MHD_Connection::response_write_position, MHD_Connection::state, and MHD_Response::total_size.

Referenced by MHD_connection_handle_idle(), and MHD_connection_handle_write().

Here is the call graph for this function:
Here is the caller graph for this function: