aboutsummaryrefslogtreecommitdiff
path: root/src/include/microhttpd_ws.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/microhttpd_ws.h')
-rw-r--r--src/include/microhttpd_ws.h979
1 files changed, 979 insertions, 0 deletions
diff --git a/src/include/microhttpd_ws.h b/src/include/microhttpd_ws.h
new file mode 100644
index 00000000..915ca339
--- /dev/null
+++ b/src/include/microhttpd_ws.h
@@ -0,0 +1,979 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2021 Christian Grothoff (and other contributing authors)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19/**
20 * @file microhttpd_ws.h
21 * @brief interface for experimental web socket extension to libmicrohttpd
22 * @author David Gausmann
23 */
24#ifndef MHD_MICROHTTPD_WS_H
25#define MHD_MICROHTTPD_WS_H
26
27
28#ifdef __cplusplus
29extern "C"
30{
31#if 0 /* keep Emacsens' auto-indent happy */
32}
33#endif
34#endif
35
36
37/**
38 * @brief Handle for the encoding/decoding of websocket data
39 * (one stream is used per websocket)
40 * @ingroup websocket
41 */
42struct MHD_WebSocketStream;
43
44/**
45 * @brief Flags for the initialization of a websocket stream
46 * `struct MHD_WebSocketStream` used by
47 * #MHD_websocket_stream_init() or
48 * #MHD_websocket_stream_init2().
49 * @ingroup websocket
50 */
51enum MHD_WEBSOCKET_FLAG
52{
53 /**
54 * The websocket is used by the server (default).
55 * Thus all outgoing payload will not be "masked".
56 * All incoming payload must be masked.
57 * This cannot be used together with #MHD_WEBSOCKET_FLAG_CLIENT
58 */
59 MHD_WEBSOCKET_FLAG_SERVER = 0,
60 /**
61 * The websocket is used by the client
62 * (not used if you provide the server).
63 * Thus all outgoing payload will be "masked" (XOR-ed with random values).
64 * All incoming payload must be unmasked.
65 * Please note that this implementation doesn't use a strong random
66 * number generator for the mask as suggested in RFC6455 10.3, because
67 * the main intention of this implemention is the use as server
68 * with MHD, which doesn't need masking.
69 * Instead a weak random number generator is used (`rand()`).
70 * You can set the seed for the random number generator
71 * by calling #MHD_websocket_srand().
72 * This cannot be used together with #MHD_WEBSOCKET_FLAG_SERVER
73 */
74 MHD_WEBSOCKET_FLAG_CLIENT = 1,
75 /**
76 * You don't want to get fragmented data while decoding.
77 * Fragmented frames will be internally put together until
78 * they are complete.
79 * Whether or not data is fragmented is decided
80 * by the sender of the data during encoding.
81 * This cannot be used together with #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
82 */
83 MHD_WEBSOCKET_FLAG_NO_FRAGMENTS = 0,
84 /**
85 * You want fragmented data, if it appears while decoding.
86 * You will receive the content of the fragmented frame,
87 * but if you are decoding text, you will never get an unfinished
88 * UTF-8 sequences (if the sequence appears between two fragments).
89 * Instead the text will end before the unfinished UTF-8 sequence.
90 * With the next fragment, which finishes the UTF-8 sequence,
91 * you will get the complete UTF-8 sequence.
92 * This cannot be used together with #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
93 */
94 MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS = 2,
95 /**
96 * If the websocket stream becomes invalid during decoding due to
97 * protocol errors, a matching close frame will automatically
98 * be generated.
99 * The close frame will be returned via the parameters
100 * result and result_len of #MHD_websocket_decode() and
101 * the return value is negative
102 * (a value of `enum MHD_WEBSOCKET_STATUS`).
103 * The generated close frame must be freed by the caller
104 * with #MHD_websocket_free().
105 */
106 MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR = 4
107};
108
109/**
110 * @brief Enum to specify the fragmenting behavior
111 * while encoding with #MHD_websocket_encode_text() or
112 * #MHD_websocket_encode_binary().
113 * @ingroup websocket
114 */
115enum MHD_WEBSOCKET_FRAGMENTATION
116{
117 /**
118 * You don't want to use fragmentation.
119 * The encoded frame consists of only one frame.
120 */
121 MHD_WEBSOCKET_FRAGMENTATION_NONE = 0,
122 /**
123 * You want to use fragmentation.
124 * The encoded frame is the first frame of
125 * a series of data frames of the same type
126 * (text or binary).
127 * You may send control frames (ping, pong or close)
128 * between these data frames.
129 */
130 MHD_WEBSOCKET_FRAGMENTATION_FIRST = 1,
131 /**
132 * You want to use fragmentation.
133 * The encoded frame is not the first frame of
134 * the series of data frames, but also not the last one.
135 * You may send control frames (ping, pong or close)
136 * between these data frames.
137 */
138 MHD_WEBSOCKET_FRAGMENTATION_FOLLOWING = 2,
139 /**
140 * You want to use fragmentation.
141 * The encoded frame is the last frame of
142 * the series of data frames, but also not the first one.
143 * After this frame, you may send all type of frames again.
144 */
145 MHD_WEBSOCKET_FRAGMENTATION_LAST = 3
146};
147
148/**
149 * @brief Enum of the return value for almost every MHD_websocket function.
150 * Errors are negative and values equal to or above zero mean a success.
151 * Positive values are only used by #MHD_websocket_decode().
152 * @ingroup websocket
153 */
154enum MHD_WEBSOCKET_STATUS
155{
156 /**
157 * The call succeeded.
158 * For #MHD_websocket_decode() this means that no error occurred,
159 * but also no frame has been completed yet.
160 */
161 MHD_WEBSOCKET_STATUS_OK = 0,
162 /**
163 * #MHD_websocket_decode() has decoded a text frame.
164 * The parameters result and result_len are filled with the decoded text
165 * (if any).
166 */
167 MHD_WEBSOCKET_STATUS_TEXT_FRAME = 0x1,
168 /**
169 * #MHD_websocket_decode() has decoded a binary frame.
170 * The parameters result and result_len are filled with the decoded
171 * binary data (if any).
172 */
173 MHD_WEBSOCKET_STATUS_BINARY_FRAME = 0x2,
174 /**
175 * #MHD_websocket_decode() has decoded a close frame.
176 * This means you must close the socket using #MHD_upgrade_action()
177 * with #MHD_UPGRADE_ACTION_CLOSE.
178 * You may respond with a close frame before closing.
179 * The parameters result and result_len are filled with
180 * the close reason (if any).
181 * The close reason starts with a two byte sequence of close code
182 * in network byte order (see `enum MHD_WEBSOCKET_CLOSEREASON`).
183 * After these two bytes a UTF-8 encoded close reason may follow.
184 * Compare with result_len to decide whether there is any close reason.
185 */
186 MHD_WEBSOCKET_STATUS_CLOSE_FRAME = 0x8,
187 /**
188 * #MHD_websocket_decode() has decoded a ping frame.
189 * You should respond to this with a pong frame.
190 * The pong frame must contain the same binary data as
191 * the corresponding ping frame (if it had any).
192 * The parameters result and result_len are filled with
193 * the binary ping data (if any).
194 */
195 MHD_WEBSOCKET_STATUS_PING_FRAME = 0x9,
196 /**
197 * #MHD_websocket_decode() has decoded a pong frame.
198 * You should usually only receive pong frames if you sent
199 * a ping frame before.
200 * The binary data should be equal to your ping frame and can be
201 * used to distinguish the response if you sent multiple ping frames.
202 * The parameters result and result_len are filled with
203 * the binary pong data (if any).
204 */
205 MHD_WEBSOCKET_STATUS_PONG_FRAME = 0xA,
206 /**
207 * #MHD_websocket_decode() has decoded a text frame fragment.
208 * The parameters result and result_len are filled with the decoded text
209 * (if any).
210 * This is like #MHD_WEBSOCKET_STATUS_TEXT_FRAME, but it can only
211 * appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS during
212 * the call of #MHD_websocket_stream_init() or
213 * #MHD_websocket_stream_init2().
214 */
215 MHD_WEBSOCKET_STATUS_TEXT_FRAGMENT = 0x11,
216 /**
217 * #MHD_websocket_decode() has decoded a binary frame fragment.
218 * The parameters result and result_len are filled with the decoded
219 * binary data (if any).
220 * This is like #MHD_WEBSOCKET_STATUS_BINARY_FRAME, but it can only
221 * appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS during
222 * the call of #MHD_websocket_stream_init() or
223 * #MHD_websocket_stream_init2().
224 */
225 MHD_WEBSOCKET_STATUS_BINARY_FRAGMENT = 0x12,
226 /**
227 * #MHD_websocket_decode() has decoded the last text frame fragment.
228 * The parameters result and result_len are filled with the decoded text
229 * (if any).
230 * This is like #MHD_WEBSOCKET_STATUS_TEXT_FRAGMENT, but it appears
231 * only for the last fragment of a series of fragments.
232 * It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
233 * during the call of #MHD_websocket_stream_init() or
234 * #MHD_websocket_stream_init2().
235 */
236 MHD_WEBSOCKET_STATUS_TEXT_LAST_FRAGMENT = 0x21,
237 /**
238 * #MHD_websocket_decode() has decoded the last binary frame fragment.
239 * The parameters result and result_len are filled with the decoded
240 * binary data (if any).
241 * This is like #MHD_WEBSOCKET_STATUS_BINARY_FRAGMENT, but it appears
242 * only for the last fragment of a series of fragments.
243 * It can only appear if you specified #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
244 * during the call of #MHD_websocket_stream_init() or
245 * #MHD_websocket_stream_init2().
246 */
247 MHD_WEBSOCKET_STATUS_BINARY_LAST_FRAGMENT = 0x22,
248 /**
249 * The call failed and the stream is invalid now for decoding.
250 * You must close the websocket now using #MHD_upgrade_action()
251 * with #MHD_UPGRADE_ACTION_CLOSE.
252 * You can send a close frame before closing.
253 * This is only used by #MHD_websocket_decode() and happens
254 * if the stream contains errors (i. e. invalid byte data).
255 */
256 MHD_WEBSOCKET_STATUS_PROTOCOL_ERROR = -1,
257 /**
258 * You tried to decode something, but the stream has already
259 * been marked invalid.
260 * You must close the websocket now using #MHD_upgrade_action()
261 * with #MHD_UPGRADE_ACTION_CLOSE.
262 * You can send a close frame before closing.
263 * This is only used by #MHD_websocket_decode() and happens
264 * if you call #MDM_websocket_decode() again after is
265 * has been invalidated.
266 */
267 MHD_WEBSOCKET_STATUS_STREAM_BROKEN = -2,
268 /**
269 * A memory allocation failed. The stream remains valid.
270 * If this occurred while decoding, the decoding could be
271 * possible later if enough memory is available.
272 * This could happen while decoding if you received a too big data frame.
273 * You could try to specify max_payload_size during the call of
274 * #MHD_websocket_stream_init() or #MHD_websocket_stream_init2() then to
275 * avoid this and close the frame instead.
276 */
277 MHD_WEBSOCKET_STATUS_MEMORY_ERROR = -3,
278 /**
279 * You passed invalid parameters during the function call
280 * (i. e. a NULL pointer for a required parameter).
281 * The stream remains valid.
282 */
283 MHD_WEBSOCKET_STATUS_PARAMETER_ERROR = -4,
284 /**
285 * The maximum payload size has been exceeded.
286 * If you got this return code from #MHD_websocket_decode() then
287 * the stream becomes invalid and the websocket must be closed
288 * using #MHD_upgrade_action() with #MHD_UPGRADE_ACTION_CLOSE.
289 * You can send a close frame before closing.
290 * The maximum payload size is specified during the call of
291 * #MHD_websocket_stream_init() or #MHD_websocket_stream_init2().
292 * This can also appear if you specified 0 as maximum payload size
293 * when the message is greater than the maximum allocatable memory size
294 * (i. e. more than 4 GB on 32 bit systems).
295 * If you got this return code from #MHD_websocket_encode_close(),
296 * #MHD_websocket_encode_ping() or #MHD_websocket_encode_pong() then
297 * you passed to much payload data. The stream remains valid then.
298 */
299 MHD_WEBSOCKET_STATUS_MAXIMUM_SIZE_EXCEEDED = -5,
300 /**
301 * An UTF-8 text is invalid.
302 * If you got this return code from #MHD_websocket_decode() then
303 * the stream becomes invalid and you must close the websocket
304 * using #MHD_upgrade_action() with #MHD_UPGRADE_ACTION_CLOSE.
305 * You can send a close frame before closing.
306 * If you got this from #MHD_websocket_encode_text() or
307 * #MHD_websocket_encode_close() then you passed invalid UTF-8 text.
308 * The stream remains valid then.
309 */
310 MHD_WEBSOCKET_STATUS_UTF8_ENCODING_ERROR = -6
311};
312
313/**
314 * @brief Enumeration of possible close reasons for close frames.
315 *
316 * The possible values are specified in RFC 6455 7.4.1
317 * These close reasons here are the default set specified by RFC 6455,
318 * but also other close reasons could be used.
319 *
320 * The definition is for short:
321 * 0-999 are never used (if you pass 0 in
322 * #MHD_websocket_encode_close() then no close reason is used).
323 * 1000-2999 are specified by RFC 6455.
324 * 3000-3999 are specified by libraries, etc. but must be registered by IANA.
325 * 4000-4999 are reserved for private use.
326 *
327 * @ingroup websocket
328 */
329enum MHD_WEBSOCKET_CLOSEREASON
330{
331 /**
332 * This value is used as placeholder for #MHD_websocket_encode_close()
333 * to tell that you don't want to specify any reason.
334 * If you use this value then no reason text may be used.
335 * This value cannot a result of decoding, because this value
336 * is not a valid close reason for the WebSocket protocol.
337 */
338 MHD_WEBSOCKET_CLOSEREASON_NO_REASON = 0,
339 /**
340 * You close the websocket fulfilled its purpose and shall
341 * now be closed in a normal, planned way.
342 */
343 MHD_WEBSOCKET_CLOSEREASON_REGULAR = 1000,
344 /**
345 * You close the websocket because are shutting down the server or
346 * something similar.
347 */
348 MHD_WEBSOCKET_CLOSEREASON_GOING_AWAY = 1001,
349 /**
350 * You close the websocket because you a protocol error occurred
351 * during decoding (i. e. invalid byte data).
352 */
353 MHD_WEBSOCKET_CLOSEREASON_PROTOCOL_ERROR = 1002,
354 /**
355 * You close the websocket because you received data which you don't accept.
356 * For example if you received a binary frame,
357 * but your application only expects text frames.
358 */
359 MHD_WEBSOCKET_CLOSEREASON_UNSUPPORTED_DATATYPE = 1003,
360 /**
361 * You close the websocket because it contains malformed UTF-8.
362 * The UTF-8 validity is automatically checked by #MHD_websocket_decode(),
363 * so you don't need to check it on your own.
364 * UTF-8 is specified in RFC 3629.
365 */
366 MHD_WEBSOCKET_CLOSEREASON_MALFORMED_UTF8 = 1007,
367 /**
368 * You close the websocket because of any reason.
369 * Usually this close reason is used if no other close reason
370 * is more specific or if you don't want to use any other close reason.
371 */
372 MHD_WEBSOCKET_CLOSEREASON_POLICY_VIOLATED = 1008,
373 /**
374 * You close the websocket because you received a frame which is too big to process.
375 * You can specify the maximum allowed payload size during the call of
376 * #MHD_websocket_stream_init() or #MHD_websocket_stream_init2().
377 */
378 MHD_WEBSOCKET_CLOSEREASON_MAXIMUM_ALLOWED_PAYLOAD_SIZE_EXCEEDED = 1009,
379 /**
380 * This status code can be sent by the client if it
381 * expected a specific extension, but this extension hasn't been negotiated.
382 */
383 MHD_WEBSOCKET_CLOSEREASON_MISSING_EXTENSION = 1010,
384 /**
385 * The server closes the websocket because it encountered
386 * an unexpected condition that prevented it from fulfilling the request.
387 */
388 MHD_WEBSOCKET_CLOSEREASON_UNEXPECTED_CONDITION = 1011
389};
390
391/**
392 * @brief Enumeration of possible UTF-8 check steps
393 *
394 * These values are used during the encoding of fragmented text frames
395 * or for error analysis while encoding text frames.
396 * Its values specify the next step of the UTF-8 check.
397 * UTF-8 sequences consist of one to four bytes.
398 * This enumeration just says how long the current UTF-8 sequence is
399 * and what is the next expected byte.
400 *
401 * @ingroup websocket
402 */
403enum MHD_WEBSOCKET_UTF8STEP
404{
405 /**
406 * There is no open UTF-8 sequence.
407 * The next byte must be 0x00-0x7F or 0xC2-0xF4.
408 */
409 MHD_WEBSOCKET_UTF8STEP_NORMAL = 0,
410 /**
411 * The second byte of a two byte UTF-8 sequence.
412 * The first byte was 0xC2-0xDF.
413 * The next byte must be 0x80-0xBF.
414 */
415 MHD_WEBSOCKET_UTF8STEP_UTF2TAIL_1OF1 = 1,
416 /**
417 * The second byte of a three byte UTF-8 sequence.
418 * The first byte was 0xE0.
419 * The next byte must be 0xA0-0xBF.
420 */
421 MHD_WEBSOCKET_UTF8STEP_UTF3TAIL1_1OF2 = 2,
422 /**
423 * The second byte of a three byte UTF-8 sequence.
424 * The first byte was 0xED.
425 * The next byte must by 0x80-0x9F.
426 */
427 MHD_WEBSOCKET_UTF8STEP_UTF3TAIL2_1OF2 = 3,
428 /**
429 * The second byte of a three byte UTF-8 sequence.
430 * The first byte was 0xE1-0xEC or 0xEE-0xEF.
431 * The next byte must be 0x80-0xBF.
432 */
433 MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_1OF2 = 4,
434 /**
435 * The third byte of a three byte UTF-8 sequence.
436 * The next byte must be 0x80-0xBF.
437 */
438 MHD_WEBSOCKET_UTF8STEP_UTF3TAIL_2OF2 = 5,
439 /**
440 * The second byte of a four byte UTF-8 sequence.
441 * The first byte was 0xF0.
442 * The next byte must be 0x90-0xBF.
443 */
444 MHD_WEBSOCKET_UTF8STEP_UTF4TAIL1_1OF3 = 6,
445 /**
446 * The second byte of a four byte UTF-8 sequence.
447 * The first byte was 0xF4.
448 * The next byte must be 0x80-0x8F.
449 */
450 MHD_WEBSOCKET_UTF8STEP_UTF4TAIL2_1OF3 = 7,
451 /**
452 * The second byte of a four byte UTF-8 sequence.
453 * The first byte was 0xF1-0xF3.
454 * The next byte must be 0x80-0xBF.
455 */
456 MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_1OF3 = 8,
457 /**
458 * The third byte of a four byte UTF-8 sequence.
459 * The next byte must be 0x80-0xBF.
460 */
461 MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_2OF3 = 9,
462 /**
463 * The fourth byte of a four byte UTF-8 sequence.
464 * The next byte must be 0x80-0xBF.
465 */
466 MHD_WEBSOCKET_UTF8STEP_UTF4TAIL_3OF3 = 10
467};
468
469/**
470* @brief Enumeration of validity values
471*
472* These values are used for #MHD_websocket_stream_is_valid()
473* and specifiy the validity status.
474*
475* @ingroup websocket
476*/
477enum MHD_WEBSOCKET_VALIDITY
478{
479 /**
480 * The stream is invalid.
481 * It cannot be used for decoding anymore.
482 */
483 MHD_WEBSOCKET_VALIDITY_INVALID = 0,
484 /**
485 * The stream is valid.
486 * Decoding works as expected.
487 */
488 MHD_WEBSOCKET_VALIDITY_VALID = 1,
489 /**
490 * The stream has received a close frame and
491 * is partly invalid.
492 * You can still use the stream for decoding,
493 * but if a data frame is received an error will be reported.
494 * After a close frame has been sent, no data frames
495 * may follow from the sender of the close frame.
496 */
497 MHD_WEBSOCKET_VALIDITY_ONLY_VALID_FOR_CONTROL_FRAMES = 2
498};
499/**
500 * This method is called by many websocket
501 * functions for allocating data.
502 * By default 'malloc' is used.
503 * This can be used for operating systems like Windows
504 * where malloc, realloc and free are compiler dependent.
505 *
506 * @param len new size
507 * @return allocated memory
508 * @ingroup websocket
509 */
510typedef void*
511(*MHD_WebSocketMallocCallback) (size_t len);
512/**
513 * This method is called by many websocket
514 * functions for reallocating data.
515 * By default 'realloc' is used.
516 * This can be used for operating systems like Windows
517 * where malloc, realloc and free are compiler dependent.
518 *
519 * @param cls closure
520 * @param len new size
521 * @return reallocated memory
522 * @ingroup websocket
523 */
524typedef void*
525(*MHD_WebSocketReallocCallback) (void *cls, size_t len);
526/**
527 * This method is called by many websocket
528 * functions for freeing data.
529 * By default 'free' is used.
530 * This can be used for operating systems like Windows
531 * where malloc, realloc and free are compiler dependent.
532 *
533 * @param cls closure
534 * @ingroup websocket
535 */
536typedef void
537(*MHD_WebSocketFreeCallback) (void *cls);
538
539/**
540 * Creates the response value for the incoming 'Sec-WebSocket-Key' header.
541 * The generated value must be sent to the client as 'Sec-WebSocket-Accept' response header.
542 *
543 * @param sec_websocket_key The value of the 'Sec-WebSocket-Key' request header
544 * @param[out] sec_websocket_accept The response buffer, which will receive
545 * the generated 'Sec-WebSocket-Accept' header.
546 * This buffer must be at least 29 bytes long and
547 * will contain a terminating NUL character.
548 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
549 * Typically 0 on success or less than 0 on errors.
550 * @ingroup websocket
551 */
552_MHD_EXTERN int
553MHD_websocket_create_accept (const char*sec_websocket_key,
554 char*sec_websocket_accept);
555
556/**
557 * Creates a new websocket stream, used for decoding/encoding.
558 *
559 * @param[out] ws The websocket stream
560 * @param flags Combination of `enum MHD_WEBSOCKET_FLAG` values
561 * to modify the behavior of the websocket stream.
562 * @param max_message_size The maximum size for incoming payload
563 * data in bytes. Use 0 to allow each size.
564 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
565 * Typically 0 on success or less than 0 on errors.
566 * @ingroup websocket
567 */
568_MHD_EXTERN int
569MHD_websocket_stream_init (struct MHD_WebSocketStream**ws,
570 int flags,
571 size_t max_payload_size);
572
573/**
574 * Creates a new websocket stream, used for decoding/encoding,
575 * but with custom memory functions for malloc, realloc and free.
576 *
577 * @param[out] ws The websocket stream
578 * @param flags Combination of `enum MHD_WEBSOCKET_FLAG` values
579 * to modify the behavior of the websocket stream.
580 * @param max_message_size The maximum size for incoming payload
581 * data in bytes. Use 0 to allow each size.
582 * @param callback_malloc The callback function for 'malloc'.
583 * @param callback_realloc The callback function for 'realloc'.
584 * @param callback_free The callback function for 'free'.
585 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
586 * Typically 0 on success or less than 0 on errors.
587 * @ingroup websocket
588 */
589_MHD_EXTERN int
590MHD_websocket_stream_init2 (struct MHD_WebSocketStream**ws,
591 int flags,
592 size_t max_payload_size,
593 MHD_WebSocketMallocCallback callback_malloc,
594 MHD_WebSocketReallocCallback callback_realloc,
595 MHD_WebSocketFreeCallback callback_free);
596
597/**
598 * Frees a websocket stream
599 *
600 * @param ws The websocket stream. This value may be NULL.
601 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
602 * Typically 0 on success or less than 0 on errors.
603 * @ingroup websocket
604 */
605_MHD_EXTERN int
606MHD_websocket_stream_free (struct MHD_WebSocketStream*ws);
607
608/**
609 * Invalidates a websocket stream.
610 * After invalidation a websocket stream cannot be used for decoding anymore.
611 * Encoding is still possible.
612 *
613 * @param ws The websocket stream.
614 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
615 * Typically 0 on success or less than 0 on errors.
616 * @ingroup websocket
617 */
618_MHD_EXTERN int
619MHD_websocket_stream_invalidate (struct MHD_WebSocketStream*ws);
620
621/**
622 * Queries whether a websocket stream is valid.
623 * Invalidated websocket streams cannot be used for decoding anymore.
624 * Encoding is still possible.
625 *
626 * @param ws The websocket stream.
627 * @return A value of `enum MHD_WEBSOCKET_VALIDITY`.
628 * @ingroup websocket
629 */
630_MHD_EXTERN int
631MHD_websocket_stream_is_valid (struct MHD_WebSocketStream*ws);
632
633/**
634 * Decodes a byte sequence via this websocket stream.
635 * Decoding is done until either a frame is complete or
636 * the end of the byte sequence is reached.
637 *
638 * @param ws The websocket stream.
639 * @param streambuf The byte sequence for decoding.
640 * Typically that what you received via `recv()`.
641 * @param streambuf_len The length of the byte sequence @a streambuf
642 * @param[out] streambuf_read_len The number of bytes which has been processed
643 * by this call. This value may be less
644 * than @a streambuf_len when a frame is decoded
645 * before the end of the buffer is reached.
646 * The remaining bytes of @a buf must be passed
647 * in the following decoding.
648 * @param[out] payload This variable receives a buffer with the decoded
649 * payload data.
650 * If no decoded data is available this is NULL.
651 * When this variable is not NULL then
652 * the buffer contains always @a payload_len bytes plus
653 * one terminating NUL character.
654 * The caller must free this buffer
655 * using #MHD_websocket_free().
656 * If you passed the flag
657 * #MHD_WEBSOCKET_FLAG_GENERATE_CLOSE_FRAMES_ON_ERROR
658 * upon creation of this websocket stream and
659 * a decoding error occurred
660 * (return value less than 0), then this
661 * buffer contains a generated close frame
662 * which must be sent via the socket to the recipient.
663 * If you passed the flag #MHD_WEBSOCKET_FLAG_WANT_FRAGMENTS
664 * upon creation of this websocket stream then
665 * this payload may only be a part of the complete message.
666 * Only complete UTF-8 sequences are returned
667 * for fragmented text frames.
668 * If necessary the UTF-8 sequence will be completed
669 * with the next text fragment.
670 * @param[out] payload_len The length of the result payload buffer in bytes.
671 *
672 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
673 * This is greater than 0 if a frame has is complete, equal to 0 if more data
674 * is needed an less than 0 on errors.
675 * @ingroup websocket
676 */
677_MHD_EXTERN int
678MHD_websocket_decode (struct MHD_WebSocketStream*ws,
679 const char*streambuf,
680 size_t streambuf_len,
681 size_t*streambuf_read_len,
682 char**payload,
683 size_t*payload_len);
684
685/**
686 * Splits the payload of of a decoded close frame.
687 *
688 * @param payload The payload of the close frame.
689 * This parameter may be NULL if @a payload_len is 0.
690 * @param payload_len The length of @a payload.
691 * @param[out] reason_code The numeric close reason.
692 * If there was no close reason, this is
693 * #MHD_WEBSOCKET_CLOSEREASON_NO_REASON.
694 * Compare with `enum MHD_WEBSOCKET_CLOSEREASON`.
695 * This parameter is optional and can be NULL.
696 * @param[out] reason_utf8 The literal close reason.
697 * If there was no literal close reason, this is NULL.
698 * This parameter is optional and can be NULL.
699 * Please note that no memory is allocated
700 * in this function.
701 * If not NULL the returned value of this parameter
702 * points to a position in the specified @a payload.
703 * @param[out] reason_utf8_len The length of the literal close reason.
704 * If there was no literal close reason, this is 0.
705 * This parameter is optional and can be NULL.
706 *
707 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
708 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
709 * or a value less than 0 on errors.
710 * @ingroup websocket
711 */
712_MHD_EXTERN int
713MHD_websocket_split_close_reason (const char*payload,
714 size_t payload_len,
715 unsigned short*reason_code,
716 const char**reason_utf8,
717 size_t*reason_utf8_len);
718
719/**
720 * Encodes an UTF-8 encoded text into websocket text frame.
721 *
722 * @param ws The websocket stream.
723 * @param payload_utf8 The UTF-8 encoded text to send.
724 * This can be NULL if payload_utf8_len is 0.
725 * @param payload_utf8_len The length of the UTF-8 encoded text in bytes.
726 * @param fragmentation A value of `enum MHD_WEBSOCKET_FRAGMENTATION`
727 * to specifiy the fragmentation behavior.
728 * Specify MHD_WEBSOCKET_FRAGMENTATION_NONE
729 * if you don't want to use fragmentation.
730 * @param[out] frame This variable receives a buffer with the encoded frame.
731 * This is what you typically send via `send()` to the recipient.
732 * If no encoded data is available this is NULL.
733 * When this variable is not NULL then the buffer contains always
734 * @a frame_len bytes plus one terminating NUL character.
735 * The caller must free this buffer using #MHD_websocket_free().
736 * @param[out] frame_len The length of the encoded frame in bytes.
737 * @param[out] utf8_step This parameter is required for fragmentation and
738 * can be NULL if no fragmentation is used.
739 * It contains information about the last encoded
740 * UTF-8 sequence and is required to continue a previous
741 * UTF-8 sequence when fragmentation is used.
742 * The `enum MHD_WEBSOCKET_UTF8STEP` is for this.
743 * If you start a new fragment using
744 * MHD_WEBSOCKET_FRAGMENTATION_NONE or
745 * MHD_WEBSOCKET_FRAGMENTATION_FIRST the value
746 * of this variable will be initialized
747 * to MHD_WEBSOCKET_UTF8STEP_NORMAL.
748 *
749 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
750 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
751 * or a value less than 0 on errors.
752 * @ingroup websocket
753 */
754_MHD_EXTERN int
755MHD_websocket_encode_text (struct MHD_WebSocketStream*ws,
756 const char*payload_utf8,
757 size_t payload_utf8_len,
758 int fragmentation,
759 char**frame,
760 size_t*frame_len,
761 int*utf8_step);
762
763/**
764 * Encodes a binary data into websocket binary frame.
765 *
766 * @param ws The websocket stream.
767 * @param payload The binary data to send.
768 * @param payload_len The length of the binary data in bytes.
769 * @param fragmentation A value of `enum MHD_WEBSOCKET_FRAGMENTATION`
770 * to specifiy the fragmentation behavior.
771 * Specify MHD_WEBSOCKET_FRAGMENTATION_NONE
772 * if you don't want to use fragmentation.
773 * @param[out] frame This variable receives a buffer with
774 * the encoded binary frame.
775 * This is what you typically send via `send()`
776 * to the recipient.
777 * If no encoded frame is available this is NULL.
778 * When this variable is not NULL then the allocated buffer
779 * contains always @a frame_len bytes plus one terminating
780 * NUL character.
781 * The caller must free this buffer using #MHD_websocket_free().
782 * @param[out] frame_len The length of the result frame buffer in bytes.
783 *
784 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
785 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
786 * or a value less than 0 on errors.
787 * @ingroup websocket
788 */
789_MHD_EXTERN int
790MHD_websocket_encode_binary (struct MHD_WebSocketStream*ws,
791 const char*payload,
792 size_t payload_len,
793 int fragmentation,
794 char**frame,
795 size_t*frame_len);
796
797/**
798 * Encodes a websocket ping frame
799 *
800 * @param ws The websocket stream.
801 * @param payload The binary ping payload data to send.
802 * This may be NULL if @a payload_len is 0.
803 * @param payload_len The length of the payload data in bytes.
804 * This may not exceed 125 bytes.
805 * @param[out] frame This variable receives a buffer with the encoded ping frame data.
806 * This is what you typically send via `send()` to the recipient.
807 * If no encoded frame is available this is NULL.
808 * When this variable is not NULL then the buffer contains always
809 * @a frame_len bytes plus one terminating NUL character.
810 * The caller must free this buffer using #MHD_websocket_free().
811 * @param[out] frame_len The length of the result frame buffer in bytes.
812 *
813 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
814 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
815 * or a value less than 0 on errors.
816 * @ingroup websocket
817 */
818_MHD_EXTERN int
819MHD_websocket_encode_ping (struct MHD_WebSocketStream*ws,
820 const char*payload,
821 size_t payload_len,
822 char**frame,
823 size_t*frame_len);
824
825/**
826 * Encodes a websocket pong frame
827 *
828 * @param ws The websocket stream.
829 * @param payload The binary pong payload data, which is typically
830 * the decoded payload from the received ping frame.
831 * This may be NULL if @a payload_len is 0.
832 * @param payload_len The length of the payload data in bytes.
833 * This may not exceed 125 bytes.
834 * @param[out] frame This variable receives a buffer with
835 * the encoded pong frame data.
836 * This is what you typically send via `send()`
837 * to the recipient.
838 * If no encoded frame is available this is NULL.
839 * When this variable is not NULL then the buffer
840 * contains always @a frame_len bytes plus one
841 * terminating NUL character.
842 * The caller must free this buffer
843 * using #MHD_websocket_free().
844 * @param[out] frame_len The length of the result frame buffer in bytes.
845 *
846 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
847 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
848 * or a value less than 0 on errors.
849 * @ingroup websocket
850 */
851_MHD_EXTERN int
852MHD_websocket_encode_pong (struct MHD_WebSocketStream*ws,
853 const char*payload,
854 size_t payload_len,
855 char**frame,
856 size_t*frame_len);
857
858/**
859 * Encodes a websocket close frame
860 *
861 * @param ws The websocket stream.
862 * @param reason_code The reason for close.
863 * You can use `enum MHD_WEBSOCKET_CLOSEREASON`
864 * for typical reasons,
865 * but you are not limited to these values.
866 * The allowed values are specified in RFC 6455 7.4.
867 * If you don't want to enter a reason, you can specify
868 * #MHD_WEBSOCKET_CLOSEREASON_NO_REASON then
869 * no reason is encoded.
870 * @param reason_utf8 An UTF-8 encoded text reason why the connection is closed.
871 * This may be NULL if @a reason_utf8_len is 0.
872 * This must be NULL if @a reason_code is
873 * #MHD_WEBSOCKET_CLOSEREASON_NO_REASON (= 0).
874 * @param reason_utf8_len The length of the UTF-8 encoded text reason in bytes.
875 * This may not exceed 123 bytes.
876 * @param[out] frame This variable receives a buffer with
877 * the encoded close frame.
878 * This is what you typically send via `send()`
879 * to the recipient.
880 * If no encoded frame is available this is NULL.
881 * When this variable is not NULL then the buffer
882 * contains always @a frame_len bytes plus
883 * one terminating NUL character.
884 * The caller must free this buffer
885 * using #MHD_websocket_free().
886 * @param[out] frame_len The length of the result frame buffer in bytes.
887 *
888 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
889 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
890 * or a value less than 0 on errors.
891 * @ingroup websocket
892 */
893_MHD_EXTERN int
894MHD_websocket_encode_close (struct MHD_WebSocketStream*ws,
895 unsigned short reason_code,
896 const char*reason_utf8,
897 size_t reason_utf8_len,
898 char**frame,
899 size_t*frame_len);
900
901/**
902 * Sets the seed for the random number generated used for
903 * the generation of masked frames (this is only used for client websockets).
904 * This seed is used for all websocket streams.
905 * Internally `srand()` is called.
906 * Please note that on some situations
907 * (where `rand()` and `srand()` are shared between your program
908 * and this library) this could cause unwanted results in your program if
909 * your program relies on a specific seed.
910 *
911 * @param seed The seed used for the initialization of
912 * the pseudo random number generator.
913 * Typically `time(NULL)` is used here to
914 * generate a seed.
915 *
916 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
917 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
918 * or a value less than 0 on errors.
919 * @ingroup websocket
920 */
921_MHD_EXTERN int
922MHD_websocket_srand (unsigned long seed);
923
924/**
925 * Allocates memory with the associated 'malloc' function
926 * of the websocket stream
927 *
928 * @param ws The websocket stream.
929 * @param len The length of the memory to allocate in bytes
930 *
931 * @return The allocated memory on success or NULL on failure.
932 * @ingroup websocket
933 */
934_MHD_EXTERN void*
935MHD_websocket_malloc (struct MHD_WebSocketStream*ws,
936 size_t len);
937
938/**
939 * Reallocates memory with the associated 'realloc' function
940 * of the websocket stream
941 *
942 * @param ws The websocket stream.
943 * @param cls The previously allocated memory or NULL
944 * @param len The new length of the memory in bytes
945 *
946 * @return The allocated memory on success or NULL on failure.
947 * If NULL is returned the previously allocated buffer
948 * remains valid.
949 * @ingroup websocket
950 */
951_MHD_EXTERN void*
952MHD_websocket_realloc (struct MHD_WebSocketStream*ws,
953 void*cls,
954 size_t len);
955
956/**
957 * Frees memory with the associated 'free' function
958 * of the websocket stream
959 *
960 * @param ws The websocket stream.
961 * @param cls The previously allocated memory or NULL
962 *
963 * @return A value of `enum MHD_WEBSOCKET_STATUS`.
964 * This is #MHD_WEBSOCKET_STATUS_OK (= 0) on success
965 * or a value less than 0 on errors.
966 * @ingroup websocket
967 */
968_MHD_EXTERN int
969MHD_websocket_free (struct MHD_WebSocketStream*ws,
970 void*cls);
971
972#if 0 /* keep Emacsens' auto-indent happy */
973{
974#endif
975#ifdef __cplusplus
976}
977#endif
978
979#endif