mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-10-09 23:43:54 +03:00
1125 lines
46 KiB
C
1125 lines
46 KiB
C
/*
|
|
This file is part of libmicrohttpd
|
|
Copyright (C) 2021 Christian Grothoff (and other contributing authors)
|
|
|
|
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
|
|
*/
|
|
/**
|
|
* @file microhttpd_ws.h
|
|
* @brief interface for experimental web socket extension to libmicrohttpd
|
|
* @author David Gausmann
|
|
*/
|
|
/*
|
|
* *** WARNING! ***
|
|
* * The websockets interface is currently in "experimental" stage. *
|
|
* * It does not work on architectures with endianness different from *
|
|
* * big endian and little endian and may have some portability issues.*
|
|
* * API and ABI are not yet stable. *
|
|
*/
|
|
#ifndef MHD_MICROHTTPD_WS_H
|
|
#define MHD_MICROHTTPD_WS_H
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#if 0 /* keep Emacsens' auto-indent happy */
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @brief Handle for the encoding/decoding of websocket data
|
|
* (one stream is used per websocket)
|
|
* @ingroup websocket
|
|
*/
|
|
struct MHD_WebSocketStream;
|
|
|
|
/**
|
|
* @brief Flags for the initialization of a websocket stream
|
|
* `struct MHD_WebSocketStream` used by
|
|
* #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_FLAG
|
|
{
|
|
/**
|
|
* The websocket stream is initialized in server mode (default).
|
|
* Thus all outgoing payload will not be "masked".
|
|
* All incoming payload must be masked.
|
|
* This flag cannot be used together with #MHD_WEBSOCKET_FLAG_CLIENT
|
|
*/
|
|
MHD_WEBSOCKET_FLAG_SERVER = 0,
|
|
/**
|
|
* The websocket stream is initialized in client mode.
|
|
* You will usually never use that mode in combination with libmicrohttpd,
|
|
* because libmicrohttpd provides a server and not a client.
|
|
* In client mode all outgoing payload will be "masked"
|
|
* (XOR-ed with random values).
|
|
* All incoming payload must be unmasked.
|
|
* If you use this mode, you must always call #MHD_websocket_stream_init2()
|
|
* instead of #MHD_websocket_stream_init(), because you need
|
|
* to pass a random number generator callback function for masking.
|
|
* This flag cannot be used together with #MHD_WEBSOCKET_FLAG_SERVER
|
|
*/
|
|
MHD_WEBSOCKET_FLAG_CLIENT = 1,
|
|
/**
|
|
* You don't want to get fragmented data while decoding (default).
|
|
* Fragmented frames will be internally put together until
|
|
* they are complete.
|
|
* Whether or not data is fragmented is decided
|
|
* by the sender of the data during encoding.
|
|
* This cannot be used together with #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
*/
|
|
MHD_WEBSOCKET_FLAG_NO_FRAGMENTS = 0,
|
|
/**
|
|
* You want fragmented data, if it appears while decoding.
|
|
* You will receive the content of the fragmented frame,
|
|
* but if you are decoding text, you will never get an unfinished
|
|
* UTF-8 sequence (if the sequence appears between two fragments).
|
|
* Instead the text will end before the unfinished UTF-8 sequence.
|
|
* With the next fragment, which finishes the UTF-8 sequence,
|
|
* you will get the complete UTF-8 sequence.
|
|
* This cannot be used together with #MHD_WEBSOCKET_FLAG_NO_FRAGMENTS
|
|
*/
|
|
MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS = 2,
|
|
/**
|
|
* If the websocket stream becomes invalid during decoding due to
|
|
* protocol errors, a matching close frame will automatically
|
|
* be generated.
|
|
* The close frame will be returned via the parameters
|
|
* `payload` and `payload_len` of #MHD_websocket_decode() and
|
|
* the return value is negative
|
|
* (a value of `enum MHD_WEBSOCKET_STATUS`).
|
|
* The generated close frame must be freed by the caller
|
|
* with #MHD_websocket_free().
|
|
*/
|
|
MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR = 4
|
|
};
|
|
|
|
/**
|
|
* @brief Enum to specify the fragmenting behavior
|
|
* while encoding with #MHD_websocket_encode_text() or
|
|
* #MHD_websocket_encode_binary().
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_FRAGMENTATION
|
|
{
|
|
/**
|
|
* You don't want to use fragmentation.
|
|
* The encoded frame consists of only one frame.
|
|
*/
|
|
MHD_WEBSOCKET_FRAGMENTATION_NONE = 0,
|
|
/**
|
|
* You want to use fragmentation.
|
|
* The encoded frame is the first frame of
|
|
* a series of data frames of the same type
|
|
* (text or binary).
|
|
* You may send control frames (ping, pong or close)
|
|
* between these data frames.
|
|
*/
|
|
MHD_WEBSOCKET_FRAGMENTATION_FIRST = 1,
|
|
/**
|
|
* You want to use fragmentation.
|
|
* The encoded frame is not the first frame of
|
|
* the series of data frames, but also not the last one.
|
|
* You may send control frames (ping, pong or close)
|
|
* between these data frames.
|
|
*/
|
|
MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING = 2,
|
|
/**
|
|
* You want to use fragmentation.
|
|
* The encoded frame is the last frame of
|
|
* the series of data frames, but also not the first one.
|
|
* After this frame, you may send all types of frames again.
|
|
*/
|
|
MHD_WEBSOCKET_FRAGMENTATION_LAST = 3
|
|
};
|
|
|
|
/**
|
|
* @brief Enum of the return value for almost every MHD_websocket function.
|
|
* Errors are negative and values equal to or above zero mean a success.
|
|
* Positive values are only used by #MHD_websocket_decode().
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_STATUS
|
|
{
|
|
/**
|
|
* The call succeeded.
|
|
* For #MHD_websocket_decode() this means that no error occurred,
|
|
* but also no frame has been completed yet.
|
|
* For other functions this means simply a success.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_OK = 0,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a text frame.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded text (if any).
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_TEXT_FRAME = 0x1,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a binary frame.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded binary data (if any).
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_BINARY_FRAME = 0x2,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a close frame.
|
|
* This means you must close the socket using #MHD_upgrade_action()
|
|
* with #MHD_UPGRADE_ACTION_CLOSE.
|
|
* You may respond with a close frame before closing.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the close reason (if any).
|
|
* The close reason starts with a two byte sequence of close code
|
|
* in network byte order (see `enum MHD_WEBSOCKET_CLOSEREASON`).
|
|
* After these two bytes a UTF-8 encoded close reason may follow.
|
|
* You can call #MHD_websocket_split_close_reason() to split that
|
|
* close reason.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_CLOSE_FRAME = 0x8,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a ping frame.
|
|
* You should respond to this with a pong frame.
|
|
* The pong frame must contain the same binary data as
|
|
* the corresponding ping frame (if it had any).
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the binary ping data (if any).
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_PING_FRAME = 0x9,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a pong frame.
|
|
* You should usually only receive pong frames if you sent
|
|
* a ping frame before.
|
|
* The binary data should be equal to your ping frame and can be
|
|
* used to distinguish the response if you sent multiple ping frames.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the binary pong data (if any).
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_PONG_FRAME = 0xA,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a text frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded text (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_TEXT_FRAME, but it can only
|
|
* appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS during
|
|
* the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT = 0x11,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded a binary frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded binary data (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_BINARY_FRAME, but it can only
|
|
* appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS during
|
|
* the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT = 0x12,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded the next text frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded text (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, but it appears
|
|
* only after the first and before the last fragment of a series of fragments.
|
|
* It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
* during the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_TEXT_NEXT_FRAGMENT = 0x21,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded the next binary frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded binary data (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, but it appears
|
|
* only after the first and before the last fragment of a series of fragments.
|
|
* It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
* during the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_BINARY_NEXT_FRAGMENT = 0x22,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded the last text frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded text (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_TEXT_FIRST_FRAGMENT, but it appears
|
|
* only for the last fragment of a series of fragments.
|
|
* It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
* during the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT = 0x41,
|
|
/**
|
|
* #MHD_websocket_decode() has decoded the last binary frame fragment.
|
|
* The parameters `payload` and `payload_len` are filled with
|
|
* the decoded binary data (if any).
|
|
* This is like #MHD_WEBSOCKET_STATUS_BINARY_FIRST_FRAGMENT, but it appears
|
|
* only for the last fragment of a series of fragments.
|
|
* It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
* during the call of #MHD_websocket_stream_init() or
|
|
* #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT = 0x42,
|
|
/**
|
|
* The call failed and the stream is invalid now for decoding.
|
|
* You must close the websocket now using #MHD_upgrade_action()
|
|
* with #MHD_UPGRADE_ACTION_CLOSE.
|
|
* You may send a close frame before closing.
|
|
* This is only used by #MHD_websocket_decode() and happens
|
|
* if the stream contains errors (i. e. invalid byte data).
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR = -1,
|
|
/**
|
|
* You tried to decode something, but the stream has already
|
|
* been marked invalid.
|
|
* You must close the websocket now using #MHD_upgrade_action()
|
|
* with #MHD_UPGRADE_ACTION_CLOSE.
|
|
* You may send a close frame before closing.
|
|
* This is only used by #MHD_websocket_decode() and happens
|
|
* if you call #MDM_websocket_decode() again after
|
|
* has been invalidated.
|
|
* You can call #MHD_websocket_stream_is_valid() at any time
|
|
* to check whether a stream is invalid or not.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_STREAM_BROKEN = -2,
|
|
/**
|
|
* A memory allocation failed. The stream remains valid.
|
|
* If this occurred while decoding, the decoding could be
|
|
* possible later if enough memory is available.
|
|
* This could happen while decoding if you received a too big data frame.
|
|
* You could try to specify max_payload_size during the call of
|
|
* #MHD_websocket_stream_init() or #MHD_websocket_stream_init2() to
|
|
* avoid this and close the websocket instead.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_MEMORY_ERROR = -3,
|
|
/**
|
|
* You passed invalid parameters during the function call
|
|
* (i. e. a NULL pointer for a required parameter).
|
|
* The stream remains valid.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_PARAMETER_ERROR = -4,
|
|
/**
|
|
* The maximum payload size has been exceeded.
|
|
* If you got this return code from #MHD_websocket_decode() then
|
|
* the stream becomes invalid and the websocket must be closed
|
|
* using #MHD_upgrade_action() with #MHD_UPGRADE_ACTION_CLOSE.
|
|
* You may send a close frame before closing.
|
|
* The maximum payload size is specified during the call of
|
|
* #MHD_websocket_stream_init() or #MHD_websocket_stream_init2().
|
|
* This can also appear if you specified 0 as maximum payload size
|
|
* when the message is greater than the maximum allocatable memory size
|
|
* (i. e. more than 4 GiB on 32 bit systems).
|
|
* If you got this return code from #MHD_websocket_encode_close(),
|
|
* #MHD_websocket_encode_ping() or #MHD_websocket_encode_pong() then
|
|
* you passed to much payload data. The stream remains valid then.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED = -5,
|
|
/**
|
|
* An UTF-8 sequence is invalid.
|
|
* If you got this return code from #MHD_websocket_decode() then
|
|
* the stream becomes invalid and you must close the websocket
|
|
* using #MHD_upgrade_action() with #MHD_UPGRADE_ACTION_CLOSE.
|
|
* You may send a close frame before closing.
|
|
* If you got this from #MHD_websocket_encode_text() or
|
|
* #MHD_websocket_encode_close() then you passed invalid UTF-8 text.
|
|
* The stream remains valid then.
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR = -6,
|
|
/**
|
|
* A check routine for the HTTP headers came to the conclusion that
|
|
* the header value isn't valid for a websocket handshake request.
|
|
* This value can only be returned from the following functions:
|
|
* * #MHD_websocket_check_http_version()
|
|
* * #MHD_websocket_check_connection_header()
|
|
* * #MHD_websocket_check_upgrade_header()
|
|
* * #MHD_websocket_check_version_header()
|
|
* * #MHD_websocket_create_accept_header()
|
|
*/
|
|
MHD_WEBSOCKET_STATUS_NO_WEBSOCKET_HANDSHAKE_HEADER = -7
|
|
};
|
|
|
|
/**
|
|
* @brief Enumeration of possible close reasons for close frames.
|
|
*
|
|
* The possible values are specified in RFC 6455 7.4.1
|
|
* These close reasons here are the default set specified by RFC 6455,
|
|
* but also other close reasons could be used.
|
|
*
|
|
* The definition is for short:
|
|
* 0-999 are never used (if you pass 0 in
|
|
* #MHD_websocket_encode_close() then no close reason is used).
|
|
* 1000-2999 are specified by RFC 6455.
|
|
* 3000-3999 are specified by libraries, etc. but must be registered by IANA.
|
|
* 4000-4999 are reserved for private use.
|
|
*
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_CLOSEREASON
|
|
{
|
|
/**
|
|
* This value is used as placeholder for #MHD_websocket_encode_close()
|
|
* to tell that you don't want to specify any reason.
|
|
* If you use this value then no reason text may be used.
|
|
* This value cannot be a result of decoding, because this value
|
|
* is not a valid close reason for the websocket protocol.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_NO_REASON = 0,
|
|
/**
|
|
* You close the websocket because it fulfilled its purpose and shall
|
|
* now be closed in a normal, planned way.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_REGULAR = 1000,
|
|
/**
|
|
* You close the websocket because you are shutting down the server or
|
|
* something similar.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_GOING_AWAY = 1001,
|
|
/**
|
|
* You close the websocket because a protocol error occurred
|
|
* during decoding (i. e. invalid byte data).
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR = 1002,
|
|
/**
|
|
* You close the websocket because you received data which you don't accept.
|
|
* For example if you received a binary frame,
|
|
* but your application only expects text frames.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_UNSUPPORTED_DATATYPE = 1003,
|
|
/**
|
|
* You close the websocket because it contains malformed UTF-8.
|
|
* The UTF-8 validity is automatically checked by #MHD_websocket_decode(),
|
|
* so you don't need to check it on your own.
|
|
* UTF-8 is specified in RFC 3629.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_MALFORMED_UTF8 = 1007,
|
|
/**
|
|
* You close the websocket because of any reason.
|
|
* Usually this close reason is used if no other close reason
|
|
* is more specific or if you don't want to use any other close reason.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_POLICY_VIOLATED = 1008,
|
|
/**
|
|
* You close the websocket because you received a frame which is too big
|
|
* to process.
|
|
* You can specify the maximum allowed payload size during the call of
|
|
* #MHD_websocket_stream_init() or #MHD_websocket_stream_init2().
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED = 1009,
|
|
/**
|
|
* This status code can be sent by the client if it
|
|
* expected a specific extension, but this extension hasn't been negotiated.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_MISSING_EXTENSION = 1010,
|
|
/**
|
|
* The server closes the websocket because it encountered
|
|
* an unexpected condition that prevented it from fulfilling the request.
|
|
*/
|
|
MHD_WEBSOCKET_CLOSEREASON_UNEXPECTED_CONDITION = 1011
|
|
};
|
|
|
|
/**
|
|
* @brief Enumeration of possible UTF-8 check steps
|
|
*
|
|
* These values are used during the encoding of fragmented text frames
|
|
* or for error analysis while encoding text frames.
|
|
* Its values specify the next step of the UTF-8 check.
|
|
* UTF-8 sequences consist of one to four bytes.
|
|
* This enumeration just says how long the current UTF-8 sequence is
|
|
* and what is the next expected byte.
|
|
*
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_UTF8STEP
|
|
{
|
|
/**
|
|
* There is no open UTF-8 sequence.
|
|
* The next byte must be 0x00-0x7F or 0xC2-0xF4.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_NORMAL = 0,
|
|
/**
|
|
* The second byte of a two byte UTF-8 sequence.
|
|
* The first byte was 0xC2-0xDF.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 = 1,
|
|
/**
|
|
* The second byte of a three byte UTF-8 sequence.
|
|
* The first byte was 0xE0.
|
|
* The next byte must be 0xA0-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2 = 2,
|
|
/**
|
|
* The second byte of a three byte UTF-8 sequence.
|
|
* The first byte was 0xED.
|
|
* The next byte must by 0x80-0x9F.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2 = 3,
|
|
/**
|
|
* The second byte of a three byte UTF-8 sequence.
|
|
* The first byte was 0xE1-0xEC or 0xEE-0xEF.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2 = 4,
|
|
/**
|
|
* The third byte of a three byte UTF-8 sequence.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2 = 5,
|
|
/**
|
|
* The second byte of a four byte UTF-8 sequence.
|
|
* The first byte was 0xF0.
|
|
* The next byte must be 0x90-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3 = 6,
|
|
/**
|
|
* The second byte of a four byte UTF-8 sequence.
|
|
* The first byte was 0xF4.
|
|
* The next byte must be 0x80-0x8F.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3 = 7,
|
|
/**
|
|
* The second byte of a four byte UTF-8 sequence.
|
|
* The first byte was 0xF1-0xF3.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3 = 8,
|
|
/**
|
|
* The third byte of a four byte UTF-8 sequence.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3 = 9,
|
|
/**
|
|
* The fourth byte of a four byte UTF-8 sequence.
|
|
* The next byte must be 0x80-0xBF.
|
|
*/
|
|
MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3 = 10
|
|
};
|
|
|
|
/**
|
|
* @brief Enumeration of validity values
|
|
*
|
|
* These values are used for #MHD_websocket_stream_is_valid()
|
|
* and specify the validity status.
|
|
*
|
|
* @ingroup websocket
|
|
*/
|
|
enum MHD_WEBSOCKET_VALIDITY
|
|
{
|
|
/**
|
|
* The stream is invalid.
|
|
* It cannot be used for decoding anymore.
|
|
*/
|
|
MHD_WEBSOCKET_VALIDITY_INVALID = 0,
|
|
/**
|
|
* The stream is valid.
|
|
* Decoding works as expected.
|
|
*/
|
|
MHD_WEBSOCKET_VALIDITY_VALID = 1,
|
|
/**
|
|
* The stream has received a close frame and
|
|
* is partly invalid.
|
|
* You can still use the stream for decoding,
|
|
* but if a data frame is received an error will be reported.
|
|
* After a close frame has been sent, no data frames
|
|
* may follow from the sender of the close frame.
|
|
*/
|
|
MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES = 2
|
|
};
|
|
/**
|
|
* This callback function is used internally by many websocket functions
|
|
* for allocating data.
|
|
* By default `malloc()` is used.
|
|
* You can use your own allocation function with
|
|
* #MHD_websocket_stream_init2() if you wish to.
|
|
* This can be useful for operating systems like Windows
|
|
* where `malloc()`, `realloc()` and `free()` are compiler-dependent.
|
|
* You can call the associated `malloc()` callback of
|
|
* a websocket stream with #MHD_websocket_malloc().
|
|
*
|
|
* @param buf_len buffer size in bytes
|
|
* @return allocated memory
|
|
* @ingroup websocket
|
|
*/
|
|
typedef void *
|
|
(*MHD_WebSocketMallocCallback) (size_t buf_len);
|
|
/**
|
|
* This callback function is used internally by many websocket
|
|
* functions for reallocating data.
|
|
* By default `realloc()` is used.
|
|
* You can use your own reallocation function with
|
|
* #MHD_websocket_stream_init2() if you wish to.
|
|
* This can be useful for operating systems like Windows
|
|
* where `malloc()`, `realloc()` and `free()` are compiler-dependent.
|
|
* You can call the associated `realloc()` callback of
|
|
* a websocket stream with #MHD_websocket_realloc().
|
|
*
|
|
* @param buf buffer
|
|
* @param new_buf_len new buffer size in bytes
|
|
* @return reallocated memory
|
|
* @ingroup websocket
|
|
*/
|
|
typedef void *
|
|
(*MHD_WebSocketReallocCallback) (void *buf, size_t new_buf_len);
|
|
/**
|
|
* This callback function is used internally by many websocket
|
|
* functions for freeing data.
|
|
* By default `free()` is used.
|
|
* You can use your own free function with
|
|
* #MHD_websocket_stream_init2() if you wish to.
|
|
* This can be useful for operating systems like Windows
|
|
* where `malloc()`, `realloc()` and `free()` are compiler-dependent.
|
|
* You can call the associated `free()` callback of
|
|
* a websocket stream with #MHD_websocket_free().
|
|
*
|
|
* @param buf buffer
|
|
* @ingroup websocket
|
|
*/
|
|
typedef void
|
|
(*MHD_WebSocketFreeCallback) (void *buf);
|
|
/**
|
|
* This callback function is used for generating random numbers
|
|
* for masking payload data in client mode.
|
|
* If you use websockets in server mode with libmicrohttpd then
|
|
* you don't need a random number generator, because
|
|
* the server doesn't mask its outgoing messageses.
|
|
* However if you wish to use a websocket stream in client mode,
|
|
* you must pass this callback function to #MHD_websocket_stream_init2().
|
|
*
|
|
* @param cls closure specified in #MHD_websocket_stream_init2()
|
|
* @param buf buffer to fill with random values
|
|
* @param buf_len size of buffer in bytes
|
|
* @return The number of generated random bytes.
|
|
* Should usually equal to buf_len.
|
|
* @ingroup websocket
|
|
*/
|
|
typedef size_t
|
|
(*MHD_WebSocketRandomNumberGenerator) (void *cls, void *buf, size_t buf_len);
|
|
|
|
/**
|
|
* Checks the HTTP version of the incoming request.
|
|
* Websocket requests are only allowed for HTTP/1.1 or above.
|
|
*
|
|
* @param http_version The value of the 'version' parameter of your
|
|
* access_handler callback
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* 0 means the HTTP version is correct for a websocket request,
|
|
* a value less than zero means that the HTTP version isn't
|
|
* valid for a websocket request.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_check_http_version (const char *http_version);
|
|
|
|
/**
|
|
* Checks the value of the 'Connection' HTTP request header.
|
|
* Websocket requests require the token 'Upgrade' in
|
|
* the 'Connection' HTTP request header.
|
|
*
|
|
* @param connection_header The value of the 'Connection' request header.
|
|
* You can get this request header value by passing
|
|
* #MHD_HTTP_HEADER_CONNECTION to
|
|
* #MHD_lookup_connection_value().
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* 0 means the 'Connection' request header is correct
|
|
* for a websocket request,
|
|
* a value less than zero means that the 'Connection' header isn't
|
|
* valid for a websocket request.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_check_connection_header (const char *connection_header);
|
|
|
|
/**
|
|
* Checks the value of the 'Upgrade' HTTP request header.
|
|
* Websocket requests require the value 'websocket' in
|
|
* the 'Upgrade' HTTP request header.
|
|
*
|
|
* @param upgrade_header The value of the 'Upgrade' request header.
|
|
* You can get this request header value by passing
|
|
* #MHD_HTTP_HEADER_UPGRADE to
|
|
* #MHD_lookup_connection_value().
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* 0 means the 'Upgrade' request header is correct
|
|
* for a websocket request,
|
|
* a value less than zero means that the 'Upgrade' header isn't
|
|
* valid for a websocket request.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_check_upgrade_header (const char *upgrade_header);
|
|
|
|
/**
|
|
* Checks the value of the 'Sec-WebSocket-Version' HTTP request header.
|
|
* Websocket requests require the value '13'
|
|
* in the 'Sec-WebSocket-Version' HTTP request header.
|
|
*
|
|
* @param version_header The value of the 'Sec-WebSocket-Version'
|
|
* request header.
|
|
* You can get this request header value by passing
|
|
* #MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION to
|
|
* #MHD_lookup_connection_value().
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* 0 means the 'Sec-WebSocket-Version' request header is correct
|
|
* for a websocket request,
|
|
* a value less than zero means that the 'Sec-WebSocket-Version'
|
|
* header isn't valid for a websocket request.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_check_version_header (const char *version_header);
|
|
|
|
/**
|
|
* Creates the response value for the 'Sec-WebSocket-Key' HTTP request header.
|
|
* The generated value must be sent to the client
|
|
* as 'Sec-WebSocket-Accept' HTTP response header.
|
|
*
|
|
* @param sec_websocket_key The value of the 'Sec-WebSocket-Key'
|
|
* request header.
|
|
* You can get this request header value by passing
|
|
* #MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY to
|
|
* #MHD_lookup_connection_value().
|
|
* @param[out] sec_websocket_accept The response buffer, which will receive
|
|
* the generated 'Sec-WebSocket-Accept' header.
|
|
* This buffer must be at least 29 bytes long and
|
|
* will contain the response value plus
|
|
* a terminating NUL on success.
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* Typically 0 on success or less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_create_accept_header (const char *sec_websocket_key,
|
|
char *sec_websocket_accept);
|
|
|
|
/**
|
|
* Creates a new websocket stream, used for decoding/encoding.
|
|
*
|
|
* @param[out] ws The websocket stream
|
|
* @param flags Combination of `enum MHD_WEBSOCKET_FLAG` values
|
|
* to modify the behavior of the websocket stream.
|
|
* @param max_payload_size The maximum size for incoming payload
|
|
* data in bytes. Use 0 to allow each size.
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* Typically 0 on success or less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_stream_init (struct MHD_WebSocketStream **ws,
|
|
int flags,
|
|
size_t max_payload_size);
|
|
|
|
/**
|
|
* Creates a new websocket stream, used for decoding/encoding,
|
|
* but with custom memory functions for malloc, realloc and free.
|
|
* Also a random number generator can be specified for client mode.
|
|
*
|
|
* @param[out] ws The websocket stream
|
|
* @param flags Combination of `enum MHD_WEBSOCKET_FLAG` values
|
|
* to modify the behavior of the websocket stream.
|
|
* @param max_payload_size The maximum size for incoming payload
|
|
* data in bytes. Use 0 to allow each size.
|
|
* @param callback_malloc The callback function for `malloc()`.
|
|
* @param callback_realloc The callback function for `realloc()`.
|
|
* @param callback_free The callback function for `free()`.
|
|
* @param cls_rng A closure for the random number generator callback.
|
|
* This is only required when
|
|
* MHD_WEBSOCKET_FLAG_CLIENT is passed in `flags`.
|
|
* The given value is passed to
|
|
* the random number generator.
|
|
* May be NULL if not needed.
|
|
* Should be NULL when you are
|
|
* not using MHD_WEBSOCKET_FLAG_CLIENT.
|
|
* @param callback_rng A callback function for a
|
|
* secure random number generator.
|
|
* This is only required when
|
|
* MHD_WEBSOCKET_FLAG_CLIENT is passed in `flags`.
|
|
* Should be NULL otherwise.
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* Typically 0 on success or less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_stream_init2 (struct MHD_WebSocketStream **ws,
|
|
int flags,
|
|
size_t max_payload_size,
|
|
MHD_WebSocketMallocCallback callback_malloc,
|
|
MHD_WebSocketReallocCallback callback_realloc,
|
|
MHD_WebSocketFreeCallback callback_free,
|
|
void *cls_rng,
|
|
MHD_WebSocketRandomNumberGenerator callback_rng);
|
|
|
|
/**
|
|
* Frees a websocket stream
|
|
*
|
|
* @param ws The websocket stream. This value may be NULL.
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* Typically 0 on success or less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_stream_free (struct MHD_WebSocketStream *ws);
|
|
|
|
/**
|
|
* Invalidates a websocket stream.
|
|
* After invalidation a websocket stream cannot be used for decoding anymore.
|
|
* Encoding is still possible.
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* Typically 0 on success or less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_stream_invalidate (struct MHD_WebSocketStream *ws);
|
|
|
|
/**
|
|
* Queries whether a websocket stream is valid.
|
|
* Invalidated websocket streams cannot be used for decoding anymore.
|
|
* Encoding is still possible.
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @return A value of `enum MHD_WEBSOCKET_VALIDITY`.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_VALIDITY
|
|
MHD_websocket_stream_is_valid (struct MHD_WebSocketStream *ws);
|
|
|
|
/**
|
|
* Decodes a byte sequence for a websocket stream.
|
|
* Decoding is done until either a frame is complete or
|
|
* the end of the byte sequence is reached.
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param streambuf The byte sequence for decoding.
|
|
* Typically that what you received via `recv()`.
|
|
* @param streambuf_len The length of the byte sequence @a streambuf
|
|
* @param[out] streambuf_read_len The number of bytes which has been processed
|
|
* by this call. This value may be less
|
|
* than @a streambuf_len when a frame is decoded
|
|
* before the end of the buffer is reached.
|
|
* The remaining bytes of @a buf must be passed
|
|
* to the next call of this function.
|
|
* @param[out] payload Pointer to a variable, which receives a buffer
|
|
* with the decoded payload data.
|
|
* If no decoded data is available this is NULL.
|
|
* When the returned value is not NULL then
|
|
* the buffer contains always @a payload_len bytes plus
|
|
* one terminating NUL character.
|
|
* The caller must free this buffer
|
|
* using #MHD_websocket_free().
|
|
* If you passed the flag
|
|
* #MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR
|
|
* upon creation of this websocket stream and
|
|
* a decoding error occurred
|
|
* (function return value less than 0), then this
|
|
* buffer contains a generated close frame
|
|
* which must be sent via the socket to the recipient.
|
|
* If you passed the flag #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
|
|
* upon creation of the websocket stream then
|
|
* this payload may only be a part of the complete message.
|
|
* Only complete UTF-8 sequences are returned
|
|
* for fragmented text frames.
|
|
* If necessary the UTF-8 sequence will be completed
|
|
* with the next text fragment.
|
|
* @param[out] payload_len The length of the result payload buffer in bytes.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is greater than 0 if a frame has is complete,
|
|
* equal to 0 if more data is needed an less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_decode (struct MHD_WebSocketStream *ws,
|
|
const char *streambuf,
|
|
size_t streambuf_len,
|
|
size_t *streambuf_read_len,
|
|
char **payload,
|
|
size_t *payload_len);
|
|
|
|
/**
|
|
* Splits the payload of a decoded close frame.
|
|
*
|
|
* @param payload The payload of the close frame.
|
|
* This parameter may only be NULL if @a payload_len is 0.
|
|
* @param payload_len The length of @a payload.
|
|
* @param[out] reason_code The numeric close reason.
|
|
* If there was no close reason, this is
|
|
* #MHD_WEBSOCKET_CLOSEREASON_NO_REASON.
|
|
* Compare with `enum MHD_WEBSOCKET_CLOSEREASON`.
|
|
* This parameter is optional and may be NULL.
|
|
* @param[out] reason_utf8 The literal close reason.
|
|
* If there was no literal close reason, this is NULL.
|
|
* This parameter is optional and may be NULL.
|
|
* Please note that no memory is allocated
|
|
* in this function.
|
|
* If not NULL the returned value of this parameter
|
|
* points to a position in the specified @a payload.
|
|
* @param[out] reason_utf8_len The length of the literal close reason.
|
|
* If there was no literal close reason, this is 0.
|
|
* This parameter is optional and may be NULL.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_split_close_reason (const char *payload,
|
|
size_t payload_len,
|
|
unsigned short *reason_code,
|
|
const char **reason_utf8,
|
|
size_t *reason_utf8_len);
|
|
|
|
/**
|
|
* Encodes an UTF-8 encoded text into websocket text frame.
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param payload_utf8 The UTF-8 encoded text to send.
|
|
* This may be NULL if payload_utf8_len is 0.
|
|
* @param payload_utf8_len The length of the UTF-8 encoded text in bytes.
|
|
* @param fragmentation A value of `enum MHD_WEBSOCKET_FRAGMENTATION`
|
|
* to specify the fragmentation behavior.
|
|
* Specify MHD_WEBSOCKET_FRAGMENTATION_NONE
|
|
* if you don't want to use fragmentation.
|
|
* @param[out] frame This variable receives a buffer with the encoded frame.
|
|
* This is what you typically send via `send()` to the recipient.
|
|
* If no encoded data is available this is NULL.
|
|
* When this variable is not NULL then the buffer contains always
|
|
* @a frame_len bytes plus one terminating NUL character.
|
|
* The caller must free this buffer using #MHD_websocket_free().
|
|
* @param[out] frame_len The length of the encoded frame in bytes.
|
|
* @param[out] utf8_step This parameter is required for fragmentation and
|
|
* should be NULL if no fragmentation is used.
|
|
* It contains information about the last encoded
|
|
* UTF-8 sequence and is required to continue a previous
|
|
* UTF-8 sequence when fragmentation is used.
|
|
* `enum MHD_WEBSOCKET_UTF8STEP` is for this value.
|
|
* If you start a new fragment using
|
|
* MHD_WEBSOCKET_FRAGMENTATION_NONE or
|
|
* MHD_WEBSOCKET_FRAGMENTATION_FIRST the value
|
|
* of this variable will be initialized
|
|
* to MHD_WEBSOCKET_UTF8STEP_NORMAL.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_encode_text (struct MHD_WebSocketStream *ws,
|
|
const char *payload_utf8,
|
|
size_t payload_utf8_len,
|
|
int fragmentation,
|
|
char **frame,
|
|
size_t *frame_len,
|
|
int *utf8_step);
|
|
|
|
/**
|
|
* Encodes binary data into websocket binary frame.
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param payload The binary data to send.
|
|
* @param payload_len The length of the binary data in bytes.
|
|
* @param fragmentation A value of `enum MHD_WEBSOCKET_FRAGMENTATION`
|
|
* to specify the fragmentation behavior.
|
|
* Specify MHD_WEBSOCKET_FRAGMENTATION_NONE
|
|
* if you don't want to use fragmentation.
|
|
* @param[out] frame This variable receives a buffer with
|
|
* the encoded binary frame.
|
|
* This is what you typically send via `send()`
|
|
* to the recipient.
|
|
* If no encoded frame is available this is NULL.
|
|
* When this variable is not NULL then the allocated buffer
|
|
* contains always @a frame_len bytes plus one terminating
|
|
* NUL character.
|
|
* The caller must free this buffer using #MHD_websocket_free().
|
|
* @param[out] frame_len The length of the result frame buffer in bytes.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_encode_binary (struct MHD_WebSocketStream *ws,
|
|
const char *payload,
|
|
size_t payload_len,
|
|
int fragmentation,
|
|
char **frame,
|
|
size_t *frame_len);
|
|
|
|
/**
|
|
* Encodes a websocket ping frame
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param payload The binary ping payload data to send.
|
|
* This may be NULL if @a payload_len is 0.
|
|
* @param payload_len The length of the payload data in bytes.
|
|
* This may not exceed 125 bytes.
|
|
* @param[out] frame This variable receives a buffer with the encoded ping frame data.
|
|
* This is what you typically send via `send()` to the recipient.
|
|
* If no encoded frame is available this is NULL.
|
|
* When this variable is not NULL then the buffer contains always
|
|
* @a frame_len bytes plus one terminating NUL character.
|
|
* The caller must free this buffer using #MHD_websocket_free().
|
|
* @param[out] frame_len The length of the result frame buffer in bytes.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_encode_ping (struct MHD_WebSocketStream *ws,
|
|
const char *payload,
|
|
size_t payload_len,
|
|
char **frame,
|
|
size_t *frame_len);
|
|
|
|
/**
|
|
* Encodes a websocket pong frame
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param payload The binary pong payload data, which should be
|
|
* the decoded payload from the received ping frame.
|
|
* This may be NULL if @a payload_len is 0.
|
|
* @param payload_len The length of the payload data in bytes.
|
|
* This may not exceed 125 bytes.
|
|
* @param[out] frame This variable receives a buffer with
|
|
* the encoded pong frame data.
|
|
* This is what you typically send via `send()`
|
|
* to the recipient.
|
|
* If no encoded frame is available this is NULL.
|
|
* When this variable is not NULL then the buffer
|
|
* contains always @a frame_len bytes plus one
|
|
* terminating NUL character.
|
|
* The caller must free this buffer
|
|
* using #MHD_websocket_free().
|
|
* @param[out] frame_len The length of the result frame buffer in bytes.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_encode_pong (struct MHD_WebSocketStream *ws,
|
|
const char *payload,
|
|
size_t payload_len,
|
|
char **frame,
|
|
size_t *frame_len);
|
|
|
|
/**
|
|
* Encodes a websocket close frame
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param reason_code The reason for close.
|
|
* You can use `enum MHD_WEBSOCKET_CLOSEREASON`
|
|
* for typical reasons,
|
|
* but you are not limited to these values.
|
|
* The allowed values are specified in RFC 6455 7.4.
|
|
* If you don't want to enter a reason, you can specify
|
|
* #MHD_WEBSOCKET_CLOSEREASON_NO_REASON then
|
|
* no reason is encoded.
|
|
* @param reason_utf8 An UTF-8 encoded text reason why the connection is closed.
|
|
* This may be NULL if @a reason_utf8_len is 0.
|
|
* This must be NULL if @a reason_code is
|
|
* #MHD_WEBSOCKET_CLOSEREASON_NO_REASON (= 0).
|
|
* @param reason_utf8_len The length of the UTF-8 encoded text reason in bytes.
|
|
* This may not exceed 123 bytes.
|
|
* @param[out] frame This variable receives a buffer with
|
|
* the encoded close frame.
|
|
* This is what you typically send via `send()`
|
|
* to the recipient.
|
|
* If no encoded frame is available this is NULL.
|
|
* When this variable is not NULL then the buffer
|
|
* contains always @a frame_len bytes plus
|
|
* one terminating NUL character.
|
|
* The caller must free this buffer
|
|
* using #MHD_websocket_free().
|
|
* @param[out] frame_len The length of the result frame buffer in bytes.
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN enum MHD_WEBSOCKET_STATUS
|
|
MHD_websocket_encode_close (struct MHD_WebSocketStream *ws,
|
|
unsigned short reason_code,
|
|
const char *reason_utf8,
|
|
size_t reason_utf8_len,
|
|
char **frame,
|
|
size_t *frame_len);
|
|
|
|
/**
|
|
* Allocates memory with the associated 'malloc' function
|
|
* of the websocket stream
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param buf_len The length of the memory to allocate in bytes
|
|
*
|
|
* @return The allocated memory on success or NULL on failure.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN void *
|
|
MHD_websocket_malloc (struct MHD_WebSocketStream *ws,
|
|
size_t buf_len);
|
|
|
|
/**
|
|
* Reallocates memory with the associated 'realloc' function
|
|
* of the websocket stream
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param buf The previously allocated memory or NULL
|
|
* @param new_buf_len The new length of the memory in bytes
|
|
*
|
|
* @return The allocated memory on success or NULL on failure.
|
|
* If NULL is returned the previously allocated buffer
|
|
* remains valid.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN void *
|
|
MHD_websocket_realloc (struct MHD_WebSocketStream *ws,
|
|
void *buf,
|
|
size_t new_buf_len);
|
|
|
|
/**
|
|
* Frees memory with the associated 'free' function
|
|
* of the websocket stream
|
|
*
|
|
* @param ws The websocket stream.
|
|
* @param buf The previously allocated memory or NULL
|
|
*
|
|
* @return A value of `enum MHD_WEBSOCKET_STATUS`.
|
|
* This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
|
|
* or a value less than 0 on errors.
|
|
* @ingroup websocket
|
|
*/
|
|
_MHD_EXTERN int
|
|
MHD_websocket_free (struct MHD_WebSocketStream *ws,
|
|
void *buf);
|
|
|
|
#if 0 /* keep Emacsens' auto-indent happy */
|
|
{
|
|
#endif
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|