diff --git a/scripts/d_options.rec b/scripts/d_options.rec index 49b47550..d032c013 100644 --- a/scripts/d_options.rec +++ b/scripts/d_options.rec @@ -2,7 +2,7 @@ # # MHD option registry # -%rec: MHD_Option +%rec: D_Options # recutils supports only signed 32 bit values %typedef: enum_value range 1 0x7FFFFFFF %key: Name diff --git a/scripts/d_options.sh b/scripts/d_options.sh index 71f3de75..74df14bd 100755 --- a/scripts/d_options.sh +++ b/scripts/d_options.sh @@ -76,11 +76,32 @@ fi unset test_var +if [[ "${0}" =~ (^|/|\\)'d_options.sh'$ ]]; then + options_type='daemon' +elif [[ "${0}" =~ (^|/|\\)'r_options.sh'$ ]]; then + options_type='response' +else + echo "Wrong name ('$0') of the script file" >&2 + exit 1 +fi + # parameters max_width=79 -input_rec="d_options.rec" -tmp_rec_name="D_Options_preproc" -tmp_rec_file="d_options_preproc.rec" +if [[ "$options_type" = 'daemon' ]]; then + input_rec='d_options.rec' + rec_name='D_Options' + hdr_marker="Daemon" + one_char_opt_name='D' + short_opt_name="$options_type" +else + input_rec="r_options.rec" + rec_name='R_Options' + hdr_marker="Response" + one_char_opt_name='R' + short_opt_name="resp" +fi +tmp_rec_name="${rec_name}_preproc" +tmp_rec_file="${input_rec%.rec}_preproc.rec" # fixed strings flat_arg_descr='the value of the parameter' @@ -91,7 +112,7 @@ err_exit() { [[ -z $msg ]] && msg="Error!" ( [[ -z $err ]] || (( err < 1 )) ) && err=2 - echo "$msg" >&1 + echo "$msg" >&2 exit $err } @@ -199,29 +220,30 @@ cat << _EOF_ > "$tmp_rec_file" %mandatory: Name %type: Value int %sort: Value -%singular: EName UName Value +%singular: EName UName SName Value _EOF_ echo "Processing input file..." -for N in $(recsel -t MHD_Option -R Value "$input_rec") +for N in $(recsel -t "${rec_name}" -R Value "$input_rec") do - NAME=$(recsel -t MHD_Option -P Name -e "Value = $N" "$input_rec") + NAME=$(recsel -t "${rec_name}" -P Name -e "Value = $N" "$input_rec") if [[ -z $NAME ]]; then echo "The 'Name' field is empty for 'Value=$N'" >&2 exit 2 fi echo -n '.' - COMMENT=$(recsel -t MHD_Option -P Comment -e "Value = $N" "$input_rec") + COMMENT=$(recsel -t "${rec_name}" -P Comment -e "Value = $N" "$input_rec") if [[ -z $COMMENT ]]; then echo "The 'Comment' field is empty for '$NAME' ('Value=$N')" >&2 exit 2 fi - TYPE=$(recsel -t MHD_Option -P Type -e "Value = $N" "$input_rec") + TYPE=$(recsel -t "${rec_name}" -P Type -e "Value = $N" "$input_rec") EComment="" # The initial part of doxy comment for the enum value EName="" # The name of the enum value UName="" # The name of the union member UType="" # The type of the union member + UTypeSp='' # The type of the union member with space at the end for non-pointers SComment="" # The doxy comment for the set macro/function SName="" # The name of the set macro/function MArguments="" # The arguments for the macro @@ -238,12 +260,12 @@ do echo -n "$N: ${clean_name// /_}" EName="${clean_name^^}" - EName="MHD_D_O_${EName// /_}" # Uppercase '_'-joined + EName="MHD_${one_char_opt_name^^}_O_${EName// /_}" # Uppercase '_'-joined UName="v_${clean_name// /_}" # lowercase '_'-joined SName="${clean_name^^}" - SName="MHD_DAEMON_OPTION_${SName// /_}" # Uppercase '_'-joined + SName="MHD_${one_char_opt_name^^}_OPTION_${SName// /_}" # Uppercase '_'-joined format_doxy ' * ' "$COMMENT" || err_exit EComment="$format_doxy_res" @@ -257,12 +279,12 @@ do MEMBERS=( ) M=1 while - ARGM=$(recsel -t MHD_Option -P Argument${M} -e "Value = $N" "$input_rec") + ARGM=$(recsel -t "${rec_name}" -P Argument${M} -e "Value = $N" "$input_rec") [[ -n $ARGM ]] do ARGS[$M]="$ARGM" - DESCRS[$M]="$(recsel -t MHD_Option -P Description${M} -e "Value = $N" "$input_rec")" - MEMBERS[$M]="$(recsel -t MHD_Option -P Member${M} -e "Value = $N" "$input_rec")" + DESCRS[$M]=$(recsel -t "${rec_name}" -P Description${M} -e "Value = $N" "$input_rec") + MEMBERS[$M]=$(recsel -t "${rec_name}" -P Member${M} -e "Value = $N" "$input_rec") (( M++ )) echo -n '.' done @@ -400,14 +422,17 @@ do else need_struct_decl='no' fi + [[ "$UType" =~ \*$ ]] && UTypeSp="$UType" || UTypeSp="$UType " # Position '*' correctly recins -t "${tmp_rec_name}" \ -f Name -v "$NAME" \ -f Value -v "$N" \ + -f hdr_marker -v "$hdr_marker" \ -f EComment -v "$EComment" \ -f EName -v "$EName" \ -f UName -v "$UName" \ -f UType -v "$UType" \ + -f UTypeSp -v "$UTypeSp" \ -f SComment -v "$SComment" \ -f SName -v "$SName" \ -f MArguments -v "$MArguments" \ @@ -422,7 +447,7 @@ echo "finished." echo "Updating header file..." header_name='microhttpd2.h' -start_of_marker=' = MHD Daemon Option ' +start_of_marker=" = MHD ${hdr_marker} Option " end_of_start_marker=' below are generated automatically = ' end_of_end_marker=' above are generated automatically = ' I=0 @@ -433,7 +458,7 @@ middle_of_marker='enum values' echo "${middle_of_marker}..." in_file="${header_name}" out_file="${header_name%.h}_tmp$((++I)).h" -recfmt -f d_options_enum.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit +recfmt -f options_enum.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit middle_of_marker='enum values' start_marker="${start_of_marker}${middle_of_marker}${end_of_start_marker}" && end_marker="${start_of_marker}${middle_of_marker}${end_of_end_marker}" || err_exit ${SED-sed} -e '/'"$start_marker"'/{p; r header_insert'"$I"'.h @@ -445,7 +470,7 @@ middle_of_marker='structures' echo "${middle_of_marker}..." in_file="${out_file}" out_file="${header_name%.h}_tmp$((++I)).h" -recsel -e "StBody != ''" "$tmp_rec_file" | recfmt -f d_options_struct.template > "header_insert${I}.h" || err_exit +recsel -e "StBody != ''" "$tmp_rec_file" | recfmt -f options_struct.template > "header_insert${I}.h" || err_exit start_marker="${start_of_marker}${middle_of_marker}${end_of_start_marker}" && end_marker="${start_of_marker}${middle_of_marker}${end_of_end_marker}" || err_exit ${SED-sed} -e '/'"$start_marker"'/{p; r header_insert'"$I"'.h } @@ -456,7 +481,7 @@ middle_of_marker='union members' echo "${middle_of_marker}..." in_file="${out_file}" out_file="${header_name%.h}_tmp$((++I)).h" -recfmt -f d_options_union.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit +recfmt -f options_union.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit start_marker="${start_of_marker}${middle_of_marker}${end_of_start_marker}" && end_marker="${start_of_marker}${middle_of_marker}${end_of_end_marker}" || err_exit ${SED-sed} -e '/'"$start_marker"'/{p; r header_insert'"$I"'.h } @@ -467,7 +492,7 @@ middle_of_marker='macros' echo "${middle_of_marker}..." in_file="${out_file}" out_file="${header_name%.h}_tmp$((++I)).h" -recfmt -f d_options_macro.template < "$tmp_rec_file" | ${SED-sed} -e 's/##removeme##//g' - > "header_insert${I}.h" || err_exit +recfmt -f options_macro.template < "$tmp_rec_file" | ${SED-sed} -e 's/##removeme##//g' - > "header_insert${I}.h" || err_exit start_marker="${start_of_marker}${middle_of_marker}${end_of_start_marker}" && end_marker="${start_of_marker}${middle_of_marker}${end_of_end_marker}" || err_exit ${SED-sed} -e '/'"$start_marker"'/{p; r header_insert'"$I"'.h } @@ -478,7 +503,7 @@ middle_of_marker='static functions' echo "${middle_of_marker}..." in_file="${out_file}" out_file="${header_name%.h}_tmp$((++I)).h" -recfmt -f d_options_func.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit +recfmt -f options_func.template < "$tmp_rec_file" > "header_insert${I}.h" || err_exit start_marker="${start_of_marker}${middle_of_marker}${end_of_start_marker}" && end_marker="${start_of_marker}${middle_of_marker}${end_of_end_marker}" || err_exit ${SED-sed} -e '/'"$start_marker"'/{p; r header_insert'"$I"'.h } @@ -495,5 +520,5 @@ else fi echo "Cleanup..." -rm -f "$tmp_rec_file" ${header_name%.h}_tmp?.h +rm -f "$tmp_rec_file" ${header_name%.h}_tmp?.h header_insert?.h echo "completed." diff --git a/scripts/d_options_func.template b/scripts/d_options_func.template deleted file mode 100644 index e1580fd4..00000000 --- a/scripts/d_options_func.template +++ /dev/null @@ -1,17 +0,0 @@ -/** -{{SComment}} - * @return the object of struct MHD_DaemonOptionAndValue with the requested - * values - */ -static MHD_INLINE struct MHD_DaemonOptionAndValue -{{SName}} ({{SFArguments}}) -{ - struct MHD_DaemonOptionAndValue opt_val; - - opt_val.opt = {{EName}}; - {{SFBody}} - - return opt_val; -} - - diff --git a/scripts/d_options_enum.template b/scripts/options_enum.template similarity index 100% rename from scripts/d_options_enum.template rename to scripts/options_enum.template diff --git a/scripts/options_func.template b/scripts/options_func.template new file mode 100644 index 00000000..f0202505 --- /dev/null +++ b/scripts/options_func.template @@ -0,0 +1,17 @@ +/** +{{SComment}} + * @return the object of struct MHD_{{hdr_marker}}OptionAndValue with the requested + * values + */ +static MHD_INLINE struct MHD_{{hdr_marker}}OptionAndValue +{{SName}} ({{SFArguments}}) +{ + struct MHD_{{hdr_marker}}OptionAndValue opt_val; + + opt_val.opt = {{EName}}; + {{SFBody}} + + return opt_val; +} + + diff --git a/scripts/d_options_macro.template b/scripts/options_macro.template similarity index 61% rename from scripts/d_options_macro.template rename to scripts/options_macro.template index 2f8c3d37..048afcd5 100644 --- a/scripts/d_options_macro.template +++ b/scripts/options_macro.template @@ -1,11 +1,11 @@ /** {{SComment}} - * @return the object of struct MHD_DaemonOptionAndValue with the requested + * @return the object of struct MHD_{{hdr_marker}}OptionAndValue with the requested * values */ # define {{SName}}({{MArguments}}) \ MHD_NOWARN_COMPOUND_LITERALS_ \ - (const struct MHD_DaemonOptionAndValue) \ + (const struct MHD_{{hdr_marker}}OptionAndValue) \ { \ .opt = ({{EName}}), \ {{CLBody}} \ diff --git a/scripts/d_options_struct.template b/scripts/options_struct.template similarity index 100% rename from scripts/d_options_struct.template rename to scripts/options_struct.template diff --git a/scripts/d_options_union.template b/scripts/options_union.template similarity index 61% rename from scripts/d_options_union.template rename to scripts/options_union.template index 17cd9e3c..56a1d2b3 100644 --- a/scripts/d_options_union.template +++ b/scripts/options_union.template @@ -1,4 +1,4 @@ /** * Value for #{{EName}} */ - {{UType}} {{UName}}; + {{UTypeSp}}{{UName}}; diff --git a/scripts/r_options.rec b/scripts/r_options.rec new file mode 100644 index 00000000..22e52e2b --- /dev/null +++ b/scripts/r_options.rec @@ -0,0 +1,91 @@ +# *-* mode: rec -*- +# +# response option registry +# +%rec: R_Options +# recutils supports only signed 32 bit values +%typedef: enum_value range 1 0x7FFFFFFF +%key: Name +%singular: Value +%type: Value enum_value +%auto: Value +%mandatory: Value +%mandatory: Comment +%allowed: Type Argument1 Description1 Member1 Argument2 Description2 Member2 Argument3 Description3 Member3 +%type: Name,Type,Argument1,Member1,Argument2,Member2,Argument3,Member3 line +%unique: Type Value Argument1 Description1 Member1 Argument2 Description2 Member2 Argument3 Description3 Member3 + +# General properties + +Name: REUSABLE +Value: 20 +Type: enum MHD_Bool +Comment: Make the response object re-usable. ++ The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). ++ Useful if the same response is often used to reply. + +# Content control + +Name: HEAD_ONLY_RESPONSE +Value: 40 +Type: enum MHD_Bool +Comment: Enable special processing of the response as body-less (with undefined body size). No automatic "Content-Length" or "Transfer-Encoding: chunked" headers are added when the response is used with #MHD_HTTP_NOT_MODIFIED code or to respond to HEAD request. ++ The flag also allow to set arbitrary "Content-Length" by #MHD_response_add_header() function. ++ This flag value can be used only with responses created without body (zero-size body). ++ Responses with this flag enabled cannot be used in situations where reply body must be sent to the client. ++ This flag is primarily intended to be used when automatic "Content-Length" header is undesirable in response to HEAD requests. + +Name: CHUNKED_ENC +Value: 41 +Type: enum MHD_Bool +Comment: Force use of chunked encoding even if the response content size is known. ++ Ignored when the reply cannot have body/content. + +# Connection control + +Name: CONN_CLOSE +Value: 60 +Type: enum MHD_Bool +Comment: Force close connection after sending the response, prevents keep-alive connections and adds "Connection: close" header. + +# Compatibility settings + +Name: HTTP_1_0_COMPATIBLE_STRIC +Value: 80 +Type: enum MHD_Bool +Comment: Only respond in conservative (dumb) HTTP/1.0-compatible mode. ++ Response still use HTTP/1.1 version in header, but always close the connection after sending the response and do not use chunked encoding for the response. ++ You can also set the #MHD_R_O_HTTP_1_0_SERVER flag to force HTTP/1.0 version in the response. ++ Responses are still compatible with HTTP/1.1. ++ This option can be used to communicate with some broken client, which does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. + +Name: HTTP_1_0_SERVER +Value: 81 +Type: enum MHD_Bool +Comment: Only respond in HTTP/1.0-mode. ++ Contrary to the #MHD_R_O_HTTP_1_0_COMPATIBLE_STRICT flag, the response's HTTP version will always be set to 1.0 and keep-alive connections will be used if explicitly requested by the client. ++ The "Connection:" header will be added for both "close" and "keep-alive" connections. ++ Chunked encoding will not be used for the response. ++ Due to backward compatibility, responses still can be used with HTTP/1.1 clients. ++ This option can be used to emulate HTTP/1.0 server (for response part only as chunked encoding in requests (if any) is processed by MHD). ++ With this option HTTP/1.0 server is emulated (with support for "keep-alive" connections). + +# Violate HTTP and/or RFCs + +Name: INSANITY_HEADER_CONTENT_LENGTH +Value: 100 +Type: enum MHD_Bool +Comment: Disable sanity check preventing clients from manually setting the HTTP content length option. ++ Allow to set several "Content-Length" headers. These headers will be used even with replies without body. + +# Callbacks + +Name: termination_callback +Value: 121 +Type: struct MHD_ResponeOptionValueTermCB +Comment: Set a function to be called once MHD is finished with the request. +Argument1: MHD_RequestTerminationCallback term_cb +Description1: the function to call, ++ NULL to not use the callback +Argument2: void *term_cb_cls +Description2: the closure for the callback diff --git a/scripts/r_options.sh b/scripts/r_options.sh new file mode 100755 index 00000000..8587ba41 --- /dev/null +++ b/scripts/r_options.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# This file is part of GNU libmicrohttpd +# Copyright (C) 2024 Karlson2k (Evgeny Grin) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA + +source ./d_options.sh diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h index 7bb39637..c7c9ca27 100644 --- a/src/include/microhttpd2.h +++ b/src/include/microhttpd2.h @@ -7329,133 +7329,6 @@ MHD_action_from_response (struct MHD_Request *request, struct MHD_Response *response); -/** - * Flags for special handling of responses. - */ -enum MHD_ResponseOptionBool -{ - /** - * Not a real option, terminate the list of options - */ - MHD_RESP_OPT_BOOL_END = 0 - , - /** - * Make the response object re-usable. - * The response will not be consumed by MHD_action_from_response() and - * must be destroyed by MHD_response_destroy(). - * Useful if the response is often used to reply. - */ - MHD_RESP_OPT_BOOL_REUSABLE = 1 - , - /** - * Force close connection after sending the response, prevents keep-alive - * connections and adds "Connection: close" header. - */ - MHD_RESP_OPT_BOOL_CONN_CLOSE = 21 - , - /** - * Force use of chunked encoding even if the response content size is known. - * Ignored when the reply cannot have body/content. - */ - MHD_RESP_OPT_BOOL_CHUNKED_ENC = 22 - , - /** - * Enable sending of "Connection: keep-alive" header even for - * HTTP/1.1 clients when "Keep-Alive" connection is used. - * Disabled by default for HTTP/1.1 clients as per RFC. - */ - MHD_RESP_OPT_BOOL_SEND_KEEP_ALIVE_HEADER = 41 - , - /** - * Only respond in conservative (dumb) HTTP/1.0-compatible mode. - * Response still use HTTP/1.1 version in header, but always close - * the connection after sending the response and do not use chunked - * encoding for the response. - * You can also set the #MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER flag to force - * HTTP/1.0 version in the response. - * Responses are still compatible with HTTP/1.1. - * This option can be used to communicate with some broken client, which - * does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. - */ - MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT = 42 - , - /** - * Only respond in HTTP/1.0-mode. - * Contrary to the #MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT flag, the response's - * HTTP version will always be set to 1.0 and keep-alive connections - * will be used if explicitly requested by the client. - * The "Connection:" header will be added for both "close" and "keep-alive" - * connections. - * Chunked encoding will not be used for the response. - * Due to backward compatibility, responses still can be used with - * HTTP/1.1 clients. - * This option can be used to emulate HTTP/1.0 server (for response part - * only as chunked encoding in requests (if any) is processed by MHD). - */ - MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER = 43 - , - /** - * Disable sanity check preventing clients from manually - * setting the HTTP content length option. - * Allow to set several "Content-Length" headers. These headers will - * be used even with replies without body. - */ - MHD_RESP_OPT_BOOL_INSANITY_HEADER_CONTENT_LENGTH = 61 - , - /** - * Enable special processing of the response as body-less (with undefined - * body size). No automatic "Content-Length" or "Transfer-Encoding: chunked" - * headers are added when the response is used with #MHD_HTTP_NOT_MODIFIED - * code or to respond to HEAD request. - * The flag also allow to set arbitrary "Content-Length" by - * MHD_add_response_header() function. - * This flag value can be used only with responses created without body - * (zero-size body). - * Responses with this flag enabled cannot be used in situations where - * reply body must be sent to the client. - * This flag is primarily intended to be used when automatic "Content-Length" - * header is undesirable in response to HEAD requests. - */ - MHD_RESP_OPT_BOOL_HEAD_ONLY_RESPONSE = 81 -}; - - -// FIXME: use the same approach as for the daemon -MHD_EXTERN_ enum MHD_StatusCode -MHD_response_set_option_bool (struct MHD_Response *response, - enum MHD_ResponseOption ro, - enum MHD_Bool value) -MHD_FN_PAR_NONNULL_ALL_; - -// FIXME: the suggested approach - -struct MHD_ResponseOptionBoolSet -{ - enum MHD_ResponseOptionBool option; - enum MHD_Bool value; -}; - -// FIXME: fully type-safe, options array can be built incrementally -// See https://github.com/babelouest/ulfius/blob/1ed26069fd7e1decd38e8d403a5649b0337893ff/src/ulfius.c#L1073 -// for incrementally built options - -/** - * Set several options for the response object - * @param response the response to set the options - * @param options_array the pointer to the array with the options; - * the array is read until first ::MHD_RESP_OPT_BOOL_END - * option, but not more than @a max_num_options elements - * @param max_num_options the maximum number of elements to read - * from @a options_array, ignored if set to SIZE_MAX - * @return #MHD_SC_OK if found, - * error code otherwise - */ -MHD_EXTERN_ enum MHD_StatusCode -MHD_response_set_options_bool (struct MHD_Response *response, - struct MHD_ResponseOptionBoolSet *options_array, - size_t max_num_options) -MHD_FN_PAR_NONNULL_ALL_; - /** * The `enum MHD_RequestTerminationCode` specifies reasons @@ -7564,19 +7437,275 @@ typedef void /** - * Set a function to be called once MHD is finished with the - * request. + * The options (parameters) for responses. + */ +enum MHD_FIXED_ENUM_APP_SET_ MHD_ResponseOption +{ + /** + * Not a real option, terminate the list of options + */ + MHD_R_O_END = 0 + , + + /* = MHD Response Option enum values below are generated automatically = */ + /** + * Make the response object re-usable. + * The response will not be consumed by MHD_action_from_response() and + * must be destroyed by MHD_response_destroy(). + * Useful if the response is often used to reply. + */ + MHD_RESP_OPT_BOOL_REUSABLE = 1 + , + /** + * Force close connection after sending the response, prevents keep-alive + * connections and adds "Connection: close" header. + */ + MHD_RESP_OPT_BOOL_CONN_CLOSE = 21 + , + /** + * Force use of chunked encoding even if the response content size is known. + * Ignored when the reply cannot have body/content. + */ + MHD_RESP_OPT_BOOL_CHUNKED_ENC = 22 + , + /** + * Enable sending of "Connection: keep-alive" header even for + * HTTP/1.1 clients when "Keep-Alive" connection is used. + * Disabled by default for HTTP/1.1 clients as per RFC. + */ + MHD_RESP_OPT_BOOL_SEND_KEEP_ALIVE_HEADER = 41 + , + /** + * Only respond in conservative (dumb) HTTP/1.0-compatible mode. + * Response still use HTTP/1.1 version in header, but always close + * the connection after sending the response and do not use chunked + * encoding for the response. + * You can also set the #MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER flag to force + * HTTP/1.0 version in the response. + * Responses are still compatible with HTTP/1.1. + * This option can be used to communicate with some broken client, which + * does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. + */ + MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT = 42 + , + /** + * Only respond in HTTP/1.0-mode. + * Contrary to the #MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT flag, the response's + * HTTP version will always be set to 1.0 and keep-alive connections + * will be used if explicitly requested by the client. + * The "Connection:" header will be added for both "close" and "keep-alive" + * connections. + * Chunked encoding will not be used for the response. + * Due to backward compatibility, responses still can be used with + * HTTP/1.1 clients. + * This option can be used to emulate HTTP/1.0 server (for response part + * only as chunked encoding in requests (if any) is processed by MHD). + */ + MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER = 43 + , + /** + * Disable sanity check preventing clients from manually + * setting the HTTP content length option. + * Allow to set several "Content-Length" headers. These headers will + * be used even with replies without body. + */ + MHD_RESP_OPT_BOOL_INSANITY_HEADER_CONTENT_LENGTH = 61 + , + /** + * Enable special processing of the response as body-less (with undefined + * body size). No automatic "Content-Length" or "Transfer-Encoding: chunked" + * headers are added when the response is used with #MHD_HTTP_NOT_MODIFIED + * code or to respond to HEAD request. + * The flag also allow to set arbitrary "Content-Length" by + * MHD_add_response_header() function. + * This flag value can be used only with responses created without body + * (zero-size body). + * Responses with this flag enabled cannot be used in situations where + * reply body must be sent to the client. + * This flag is primarily intended to be used when automatic "Content-Length" + * header is undesirable in response to HEAD requests. + */ + MHD_RESP_OPT_BOOL_HEAD_ONLY_RESPONSE = 81 + , + /* = MHD Response Option enum values above are generated automatically = */ + + /* * Sentinel * */ + /** + * The sentinel value. + * This value enforces specific underlying integer type for the enum. + * Do not use. + */ + MHD_R_O_SENTINEL = 65535 + +}; + +/* = MHD Response Option structures below are generated automatically = */ + +/* = MHD Response Option structures above are generated automatically = */ + +/** + * Parameters for response options + */ +union MHD_ResponseOptionValue +{ + /* = MHD Response Option union members below are generated automatically = */ + + /* = MHD Response Option union members above are generated automatically = */ +}; + +/** + * Combination of response option with parameters values + */ +struct MHD_ResponseOptionAndValue +{ + /** + * The response configuration option + */ + enum MHD_ResponseOption opt; + /** + * The value for the @a opt option + */ + union MHD_ResponseOptionValue val; +}; + + + + +#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT) +/* = MHD Response Option macros below are generated automatically = */ + + +/* = MHD Response Option macros above are generated automatically = */ + +/** + * Terminate the list of the options + * @return the terminating object of struct MHD_ResponseOptionAndValue + */ +# define MHD_R_OPTION_TERMINATE() \ + MHD_NOWARN_COMPOUND_LITERALS_ \ + (const struct MHD_DaemonOptionAndValue) \ + { \ + .opt = (MHD_R_O_END) \ + } \ + MHD_RESTORE_WARN_COMPOUND_LITERALS_ + +#else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */ +MHD_NOWARN_UNUSED_FUNC_ +/* = MHD Response Option static functions below are generated automatically = */ + + + +/* = MHD Response Option static functions above are generated automatically = */ +/** + * Terminate the list of the options + * @return the terminating object of struct MHD_ResponseOptionAndValue + */ +static MHD_INLINE struct MHD_DaemonOptionAndValue +MHD_R_OPTION_TERMINATE (void) +{ + struct MHD_DaemonOptionAndValue opt_val; + + opt_val.opt = MHD_R_O_END; + + return opt_val; +} + +MHD_RESTORE_WARN_UNUSED_FUNC_ +#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */ + + +/** + * Set the requested options for the response. * - * @param[in,out] response which response to set the callback for - * @param termination_cb function to call, can be NULL to not use the callback - * @param termination_cb_cls closure for @e termination_cb + * If any option fail other options may be or may be not applied. + * @param response the response to set the options + * @param[in] options the pointer to the array with the options; + * the array processing stops at the first ::MHD_D_O_END + * option, but not later than after processing + * @a options_max_num entries + * @param options_max_num the maximum number of entries in the @a options, + * use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing + * must stop only at zero-termination option + * @return ::MHD_SC_OK on success, + * error code otherwise */ MHD_EXTERN_ enum MHD_StatusCode -MHD_response_set_option_termination_callback ( - struct MHD_Response *response, - MHD_RequestTerminationCallback termination_cb, - void *termination_cb_cls) -MHD_FN_PAR_NONNULL_ (1); +MHD_response_options_set(struct MHD_Response *daemon, + const struct MHD_ResponseOptionAndValue *options, + size_t options_max_num) +MHD_FN_PAR_NONNULL_ALL_; + + +/** + * Set the requested single option for the response. + * + * @param response the response to set the option + * @param[in] options the pointer to the option + * @return ::MHD_SC_OK on success, + * error code otherwise + */ +#define MHD_response_option_set(response,option_ptr) \ + MHD_response_options_set(response,options_ptr,1) + + +#ifdef MHD_USE_VARARG_MACROS +MHD_NOWARN_VARIADIC_MACROS_ +# if defined(MHD_USE_COMPOUND_LITERALS) && \ + defined(MHD_USE_COMP_LIT_FUNC_PARAMS) +/** + * Set the requested options for the response. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that creates required options, for example: + * + * MHD_RESPONE_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES), // TODO: use correct macros + * MHD_D_OPTION_SOCK_ADDR(sa_len, sa)) + * + * @param response the response to set the option + * @param ... the list of the options, each option must be created + * by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value) + * @return ::MHD_SC_OK on success, + * error code otherwise + */ +# define MHD_RESPONSE_OPTIONS_SET(response,...) \ + MHD_NOWARN_COMPOUND_LITERALS_ \ + MHD_response_options_set(daemon, \ + ((const struct MHD_ResponseOptionAndValue[]) \ + {__VA_ARGS__, MHD_R_OPTION_TERMINATE()}), \ + MHD_OPTIONS_ARRAY_MAX_SIZE) \ + MHD_RESTORE_WARN_COMPOUND_LITERALS_ +# elif defined(MHD_USE_CPP_INIT_LIST) +} /* extern "C" */ +# include +extern "C" +{ +/** + * Set the requested options for the daemon. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that creates required options, for example: + * + * MHD_DAEMON_OPTIONS_SET(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES), // TODO: use correct macros + * MHD_D_OPTION_SOCK_ADDR(sa_len, sa)) + * + * @param daemon the daemon to set the options + * @param ... the list of the options, each option must be created + * by helpers MHD_D_OPTION_NameOfOption(option_value) + * @return ::MHD_SC_OK on success, + * error code otherwise + */ +# define MHD_DAEMON_OPTIONS_SET(daemon,...) \ + MHD_NOWARN_CPP_INIT_LIST_ \ + MHD_daemon_options_set(daemon, \ + (std::vector \ + {__VA_ARGS__,MHD_R_OPTION_TERMINATE()}).data(), \ + MHD_OPTIONS_ARRAY_MAX_SIZE) \ + MHD_RESTORE_WARN_CPP_INIT_LIST_ +# endif +MHD_RESTORE_WARN_VARIADIC_MACROS_ +#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */ /**