From e9bc42a63c0a724d22bec43f5d5c5a7e80f93a97 Mon Sep 17 00:00:00 2001 From: def Date: Wed, 7 Feb 2018 00:07:06 +0100 Subject: [PATCH 1/3] Update websockets implementation (fixes #1022) seems to work with libwebsockets 2.4 --- src/engine/shared/websockets.cpp | 45 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/engine/shared/websockets.cpp b/src/engine/shared/websockets.cpp index f77632290..13559936c 100644 --- a/src/engine/shared/websockets.cpp +++ b/src/engine/shared/websockets.cpp @@ -3,7 +3,7 @@ #include #include -#include "engine/external/libwebsockets/libwebsockets.h" +#include #include "base/system.h" #include "protocol.h" #include "ringbuffer.h" @@ -31,7 +31,7 @@ typedef struct struct per_session_data { - struct libwebsocket *wsi; + struct lws *wsi; int port; sockaddr_in addr; TSendBuffer send_buffer; @@ -39,7 +39,7 @@ struct per_session_data struct context_data { - libwebsocket_context *context; + lws_context *context; per_session_data *port_map[WS_CLIENTS]; TRecvBuffer recv_buffer; int last_used_port; @@ -57,10 +57,11 @@ static int receive_chunk(context_data *ctx_data, struct per_session_data *pss, v return 0; } -static int websocket_callback(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) +static int websocket_callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct per_session_data *pss = (struct per_session_data *)user; - context_data *ctx_data = (context_data *)libwebsocket_context_user(context); + lws_context *context = lws_get_context(wsi); + context_data *ctx_data = (context_data *)lws_context_user(context); switch(reason) { @@ -85,7 +86,7 @@ static int websocket_callback(struct libwebsocket_context *context, struct libwe } ctx_data->last_used_port = port; pss->wsi = wsi; - int fd = libwebsocket_get_socket_fd(wsi); + int fd = lws_get_socket_fd(wsi); socklen_t addr_size = sizeof(pss->addr); getpeername(fd, (struct sockaddr *)&pss->addr, &addr_size); int orig_port = ntohs(pss->addr.sin_port); @@ -117,17 +118,17 @@ static int websocket_callback(struct libwebsocket_context *context, struct libwe if(chunk == NULL) break; int len = chunk->size - chunk->read; - int n = libwebsocket_write(wsi, &chunk->data[LWS_SEND_BUFFER_PRE_PADDING + chunk->read], chunk->size - chunk->read, LWS_WRITE_BINARY); + int n = lws_write(wsi, &chunk->data[LWS_SEND_BUFFER_PRE_PADDING + chunk->read], chunk->size - chunk->read, LWS_WRITE_BINARY); if(n < 0) return 1; if(n < len) { chunk->read += n; - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(wsi); break; } pss->send_buffer.PopFirst(); - libwebsocket_callback_on_writable(context, wsi); + lws_callback_on_writable(wsi); } break; @@ -145,7 +146,7 @@ static int websocket_callback(struct libwebsocket_context *context, struct libwe return 0; } -static struct libwebsocket_protocols protocols[] = { { +static struct lws_protocols protocols[] = { { "binary", /* name */ websocket_callback, /* callback */ sizeof(struct per_session_data) /* per_session_data_size */ @@ -182,7 +183,7 @@ int websocket_create(const char *addr, int port) context_data *ctx_data = &contexts[first_free]; info.user = (void *)ctx_data; - ctx_data->context = libwebsocket_create_context(&info); + ctx_data->context = lws_create_context(&info); if(ctx_data->context == NULL) { return -1; @@ -195,23 +196,23 @@ int websocket_create(const char *addr, int port) int websocket_destroy(int socket) { - libwebsocket_context *context = contexts[socket].context; + lws_context *context = contexts[socket].context; if(context == NULL) return -1; - libwebsocket_context_destroy(context); + lws_context_destroy(context); contexts[socket].context = NULL; return 0; } int websocket_recv(int socket, unsigned char *data, size_t maxsize, struct sockaddr_in *sockaddrbuf, size_t fromLen) { - libwebsocket_context *context = contexts[socket].context; + lws_context *context = contexts[socket].context; if(context == NULL) return -1; - int n = libwebsocket_service(context, 0); + int n = lws_service(context, 0); if(n < 0) return n; - context_data *ctx_data = (context_data *)libwebsocket_context_user(context); + context_data *ctx_data = (context_data *)lws_context_user(context); websocket_chunk *chunk = (websocket_chunk *)ctx_data->recv_buffer.First(); if(chunk == 0) return 0; @@ -234,10 +235,10 @@ int websocket_recv(int socket, unsigned char *data, size_t maxsize, struct socka int websocket_send(int socket, const unsigned char *data, size_t size, int port) { - libwebsocket_context *context = contexts[socket].context; + lws_context *context = contexts[socket].context; if(context == NULL) return -1; - context_data *ctx_data = (context_data *)libwebsocket_context_user(context); + context_data *ctx_data = (context_data *)lws_context_user(context); struct per_session_data *pss = ctx_data->port_map[port]; if(pss == NULL) return -1; @@ -248,23 +249,23 @@ int websocket_send(int socket, const unsigned char *data, size_t size, int port) chunk->read = 0; memcpy(&chunk->addr, &pss->addr, sizeof(sockaddr_in)); memcpy(&chunk->data[LWS_SEND_BUFFER_PRE_PADDING], data, size); - libwebsocket_callback_on_writable(context, pss->wsi); + lws_callback_on_writable(pss->wsi); return size; } int websocket_fd_set(int socket, fd_set *set) { - libwebsocket_context *context = contexts[socket].context; + lws_context *context = contexts[socket].context; if(context == NULL) return -1; - context_data *ctx_data = (context_data *)libwebsocket_context_user(context); + context_data *ctx_data = (context_data *)lws_context_user(context); int max = 0; for(int i = 0; i < WS_CLIENTS; i++) { per_session_data *pss = ctx_data->port_map[i]; if(pss == NULL) continue; - int fd = libwebsocket_get_socket_fd(pss->wsi); + int fd = lws_get_socket_fd(pss->wsi); if(fd > max) max = fd; FD_SET(fd, set); From 38b96791f68bd3a7d2f0de950788066740f45b6f Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Wed, 14 Feb 2018 12:55:04 +0100 Subject: [PATCH 2/3] Try to find `libwebsockets` on the host system --- CMakeLists.txt | 54 ++++++++++++-------------------------- cmake/FindWebsockets.cmake | 31 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 37 deletions(-) create mode 100644 cmake/FindWebsockets.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c34517c0..b8c3b859c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,6 +282,13 @@ find_package(PythonInterp) find_package(SDL2) find_package(Threads) find_package(Wavpack) +if(WEBSOCKETS) + find_package(Websockets) +else() + set(WEBSOCKETS_LIBRARIES) + set(WEBSOCKETS_INCLUDE_DIRS) +endif() + if(TARGET_OS AND TARGET_OS STREQUAL "mac") find_program(DMG dmg) @@ -338,6 +345,9 @@ show_dependency_status("PythonInterp" PYTHONINTERP) show_dependency_status("SDL2" SDL2) show_dependency_status("Wavpack" WAVPACK) show_dependency_status("Zlib" ZLIB) +if(WEBSOCKETS) + show_dependency_status("Websockets" WEBSOCKETS) +endif() if(NOT(PYTHONINTERP_FOUND)) message(SEND_ERROR "You must install Python to compile DDNet") @@ -347,6 +357,10 @@ if(MYSQL AND NOT(MYSQL_FOUND)) message(SEND_ERROR "You must install MySQL to compile the DDNet server with MySQL support") endif() +if(WEBSOCKETS AND NOT(WEBSOCKETS_FOUND)) + message(SEND_ERROR "You must install libwebsockets to compile the DDNet server with websocket support") +endif() + if(CLIENT AND NOT(CURL_FOUND)) message(SEND_ERROR "You must install Curl to compile the DDNet client") endif() @@ -664,45 +678,10 @@ add_library(md5 EXCLUDE_FROM_ALL OBJECT ${DEP_MD5_SRC}) set(DEP_MD5 $) list(APPEND TARGETS_DEP md5) -if(WEBSOCKETS) - set_glob(DEP_WEBSOCKETS_SRC GLOB src/engine/external/libwebsockets - alloc.c - base64-decode.c - config.h - context.c - extension-deflate-frame.c - extension-deflate-frame.h - extension-deflate-stream.c - extension-deflate-stream.h - extension.c - getifaddrs.h - handshake.c - huftable.h - lextable-strings.h - lextable.h - libwebsockets.c - libwebsockets.h - lws-plat-unix.c - output.c - parsers.c - pollfd.c - private-libwebsockets.h - server-handshake.c - server.c - service.c - sha-1.c - ) - add_library(websockets EXCLUDE_FROM_ALL OBJECT ${DEP_WEBSOCKETS_SRC}) - list(APPEND TARGETS_DEP websockets) - set(DEP_WEBSOCKETS $) -else() - set(DEP_WEBSOCKETS) -endif() - -set(DEPS ${DEP_MD5} ${DEP_WEBSOCKETS} ${ZLIB_DEP}) +set(DEPS ${DEP_MD5} ${ZLIB_DEP}) # Libraries -set(LIBS ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES} ${PLATFORM_LIBS}) +set(LIBS ${CMAKE_THREAD_LIBS_INIT} ${WEBSOCKETS_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_LIBS}) # Targets add_library(engine-shared EXCLUDE_FROM_ALL OBJECT ${ENGINE_INTERFACE} ${ENGINE_SHARED} ${ENGINE_GENERATED_SHARED} ${BASE}) @@ -1511,6 +1490,7 @@ foreach(target ${TARGETS_OWN}) target_compile_definitions(${target} PRIVATE GLEW_STATIC) if(WEBSOCKETS) target_compile_definitions(${target} PRIVATE CONF_WEBSOCKETS) + target_include_directories(${target} PRIVATE ${WEBSOCKETS_INCLUDE_DIRS}) endif() if(MYSQL) target_compile_definitions(${target} PRIVATE CONF_SQL) diff --git a/cmake/FindWebsockets.cmake b/cmake/FindWebsockets.cmake new file mode 100644 index 000000000..a3d3ee102 --- /dev/null +++ b/cmake/FindWebsockets.cmake @@ -0,0 +1,31 @@ +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_WEBSOCKETS libwebsockets) +endif() + +set_extra_dirs_lib(WEBSOCKETS websockets) +find_library(WEBSOCKETS_LIBRARY + NAMES websockets + HINTS ${HINTS_WEBSOCKETS_LIBDIR} ${PC_WEBSOCKETS_LIBDIR} ${PC_WEBSOCKETS_LIBRARY_DIRS} + PATHS ${PATHS_WEBSOCKETS_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} +) +set_extra_dirs_include(WEBSOCKETS websockets "${WEBSOCKETS_LIBRARY}") +find_path(WEBSOCKETS_INCLUDEDIR + NAMES libwebsockets.h + HINTS ${HINTS_WEBSOCKETS_INCLUDEDIR} ${PC_WEBSOCKETS_INCLUDEDIR} ${PC_WEBSOCKETS_INCLUDE_DIRS} + PATHS ${PATHS_WEBSOCKETS_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Websockets DEFAULT_MSG WEBSOCKETS_LIBRARY WEBSOCKETS_INCLUDEDIR) + +mark_as_advanced(WEBSOCKETS_LIBRARY WEBSOCKETS_INCLUDEDIR) + +if(WEBSOCKETS_FOUND) + set(WEBSOCKETS_LIBRARIES ${WEBSOCKETS_LIBRARY}) + set(WEBSOCKETS_INCLUDE_DIRS ${WEBSOCKETS_INCLUDEDIR}) + + is_bundled(WEBSOCKETS_BUNDLED "${WEBSOCKETS_LIBRARY}") +endif() From c2aaef2adfec532de56b5d5d88699ba0f6fa2363 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Wed, 14 Feb 2018 12:54:33 +0100 Subject: [PATCH 3/3] Remove vendored `libwebsockets` --- src/engine/external/libwebsockets/LICENSE | 526 ------- src/engine/external/libwebsockets/alloc.c | 30 - .../external/libwebsockets/base64-decode.c | 185 --- src/engine/external/libwebsockets/config.h | 174 --- src/engine/external/libwebsockets/context.c | 337 ---- .../libwebsockets/extension-deflate-frame.c | 288 ---- .../libwebsockets/extension-deflate-frame.h | 25 - .../libwebsockets/extension-deflate-stream.c | 166 -- .../libwebsockets/extension-deflate-stream.h | 20 - src/engine/external/libwebsockets/extension.c | 208 --- .../external/libwebsockets/getifaddrs.h | 76 - src/engine/external/libwebsockets/handshake.c | 232 --- src/engine/external/libwebsockets/huftable.h | 530 ------- .../external/libwebsockets/lextable-strings.h | 86 -- src/engine/external/libwebsockets/lextable.h | 745 --------- .../external/libwebsockets/libwebsockets.c | 850 ---------- .../external/libwebsockets/libwebsockets.h | 1371 ----------------- .../external/libwebsockets/lws-plat-unix.c | 442 ------ src/engine/external/libwebsockets/output.c | 606 -------- src/engine/external/libwebsockets/parsers.c | 1015 ------------ src/engine/external/libwebsockets/pollfd.c | 293 ---- .../libwebsockets/private-libwebsockets.h | 1211 --------------- .../external/libwebsockets/server-handshake.c | 274 ---- src/engine/external/libwebsockets/server.c | 1162 -------------- src/engine/external/libwebsockets/service.c | 636 -------- src/engine/external/libwebsockets/sha-1.c | 301 ---- 26 files changed, 11789 deletions(-) delete mode 100644 src/engine/external/libwebsockets/LICENSE delete mode 100644 src/engine/external/libwebsockets/alloc.c delete mode 100644 src/engine/external/libwebsockets/base64-decode.c delete mode 100644 src/engine/external/libwebsockets/config.h delete mode 100644 src/engine/external/libwebsockets/context.c delete mode 100644 src/engine/external/libwebsockets/extension-deflate-frame.c delete mode 100644 src/engine/external/libwebsockets/extension-deflate-frame.h delete mode 100644 src/engine/external/libwebsockets/extension-deflate-stream.c delete mode 100644 src/engine/external/libwebsockets/extension-deflate-stream.h delete mode 100644 src/engine/external/libwebsockets/extension.c delete mode 100644 src/engine/external/libwebsockets/getifaddrs.h delete mode 100644 src/engine/external/libwebsockets/handshake.c delete mode 100644 src/engine/external/libwebsockets/huftable.h delete mode 100644 src/engine/external/libwebsockets/lextable-strings.h delete mode 100644 src/engine/external/libwebsockets/lextable.h delete mode 100644 src/engine/external/libwebsockets/libwebsockets.c delete mode 100644 src/engine/external/libwebsockets/libwebsockets.h delete mode 100644 src/engine/external/libwebsockets/lws-plat-unix.c delete mode 100644 src/engine/external/libwebsockets/output.c delete mode 100644 src/engine/external/libwebsockets/parsers.c delete mode 100644 src/engine/external/libwebsockets/pollfd.c delete mode 100644 src/engine/external/libwebsockets/private-libwebsockets.h delete mode 100644 src/engine/external/libwebsockets/server-handshake.c delete mode 100644 src/engine/external/libwebsockets/server.c delete mode 100644 src/engine/external/libwebsockets/service.c delete mode 100644 src/engine/external/libwebsockets/sha-1.c diff --git a/src/engine/external/libwebsockets/LICENSE b/src/engine/external/libwebsockets/LICENSE deleted file mode 100644 index 7c8986558..000000000 --- a/src/engine/external/libwebsockets/LICENSE +++ /dev/null @@ -1,526 +0,0 @@ -Libwebsockets and included programs are provided under the terms of the GNU -Library General Public License (LGPL) 2.1, with the following exceptions: - -1) Static linking of programs with the libwebsockets library does not -constitute a derivative work and does not require the author to provide -source code for the program, use the shared libwebsockets libraries, or -link their program against a user-supplied version of libwebsockets. - -If you link the program to a modified version of libwebsockets, then the -changes to libwebsockets must be provided under the terms of the LGPL in -sections 1, 2, and 4. - -2) You do not have to provide a copy of the libwebsockets license with -programs that are linked to the libwebsockets library, nor do you have to -identify the libwebsockets license in your program or documentation as -required by section 6 of the LGPL. - -However, programs must still identify their use of libwebsockets. The -following example statement can be included in user documentation to -satisfy this requirement: - -"[program] is based in part on the work of the libwebsockets project -(http://libwebsockets.org)" - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/src/engine/external/libwebsockets/alloc.c b/src/engine/external/libwebsockets/alloc.c deleted file mode 100644 index 3bc5260ee..000000000 --- a/src/engine/external/libwebsockets/alloc.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "private-libwebsockets.h" - -static void *_realloc(void *ptr, size_t size) -{ - if (size) - return realloc(ptr, size); - else if (ptr) - free(ptr); - return NULL; -} - -void *(*_lws_realloc)(void *ptr, size_t size) = _realloc; - -void *lws_realloc(void *ptr, size_t size) -{ - return _lws_realloc(ptr, size); -} - -void *lws_zalloc(size_t size) -{ - void *ptr = _lws_realloc(NULL, size); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -void lws_set_allocator(void *(*cb)(void *ptr, size_t size)) -{ - _lws_realloc = cb; -} diff --git a/src/engine/external/libwebsockets/base64-decode.c b/src/engine/external/libwebsockets/base64-decode.c deleted file mode 100644 index 92501b032..000000000 --- a/src/engine/external/libwebsockets/base64-decode.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This code originally came from here - * - * http://base64.sourceforge.net/b64.c - * - * with the following license: - * - * LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the - * Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS - * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * VERSION HISTORY: - * Bob Trower 08/04/01 -- Create Version 0.00.00B - * - * I cleaned it up quite a bit to match the (linux kernel) style of the rest - * of libwebsockets; this version is under LGPL2 like the rest of libwebsockets - * since he explictly allows sublicensing, but I give the URL above so you can - * get the original with Bob's super-liberal terms directly if you prefer. - */ - - -#include -#include -#include "private-libwebsockets.h" - -static const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" - "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; - -LWS_VISIBLE int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) -{ - unsigned char triple[3]; - int i; - int len; - int line = 0; - int done = 0; - - while (in_len) { - len = 0; - for (i = 0; i < 3; i++) { - if (in_len) { - triple[i] = *in++; - len++; - in_len--; - } else - triple[i] = 0; - } - - if (done + 4 >= out_size) - return -1; - - *out++ = encode[triple[0] >> 2]; - *out++ = encode[((triple[0] & 0x03) << 4) | - ((triple[1] & 0xf0) >> 4)]; - *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | - ((triple[2] & 0xc0) >> 6)] : '='); - *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); - - done += 4; - line += 4; - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; -} - -/* - * returns length of decoded string in out, or -1 if out was too small - * according to out_size - */ - -LWS_VISIBLE int -lws_b64_decode_string(const char *in, char *out, int out_size) -{ - int len; - int i; - int done = 0; - unsigned char v; - unsigned char quad[4]; - - while (*in) { - - len = 0; - for (i = 0; i < 4 && *in; i++) { - - v = 0; - while (*in && !v) { - - v = *in++; - v = (v < 43 || v > 122) ? 0 : decode[v - 43]; - if (v) - v = (v == '$') ? 0 : v - 61; - if (*in) { - len++; - if (v) - quad[i] = v - 1; - } else - quad[i] = 0; - } - } - - if (out_size < (done + len - 1)) - /* out buffer is too small */ - return -1; - - if (len >= 2) - *out++ = quad[0] << 2 | quad[1] >> 4; - if (len >= 3) - *out++ = quad[1] << 4 | quad[2] >> 2; - if (len >= 4) - *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; - - done += len - 1; - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; -} - -int -lws_b64_selftest(void) -{ - char buf[64]; - int n; - int test; - static const char * const plaintext[] = { - "sanity check base 64" - }; - static const char * const coded[] = { - "c2FuaXR5IGNoZWNrIGJhc2UgNjQ=" - }; - - for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) { - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_encode_string(plaintext[test], - strlen(plaintext[test]), buf, sizeof buf); - if (n != strlen(coded[test]) || strcmp(buf, coded[test])) { - lwsl_err("Failed lws_b64 encode selftest " - "%d result '%s' %d\n", test, buf, n); - return -1; - } - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_decode_string(coded[test], buf, sizeof buf); - if (n != strlen(plaintext[test]) || - strcmp(buf, plaintext[test])) { - lwsl_err("Failed lws_b64 decode selftest " - "%d result '%s' %d\n", test, buf, n); - return -1; - } - } - - return 0; -} diff --git a/src/engine/external/libwebsockets/config.h b/src/engine/external/libwebsockets/config.h deleted file mode 100644 index 617c897bf..000000000 --- a/src/engine/external/libwebsockets/config.h +++ /dev/null @@ -1,174 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -#ifndef WIN32 -/* #undef _DEBUG */ -#endif - -/* Define to 1 to use CyaSSL as a replacement for OpenSSL. - * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ -/* #undef USE_CYASSL */ - -/* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "1.3" - -/* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "080e6dd" - -/* Build with OpenSSL support */ -/* #undef LWS_OPENSSL_SUPPORT */ - -/* The client should load and trust CA root certs it finds in the OS */ -/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */ - -/* Sets the path where the client certs should be installed. */ -#define LWS_OPENSSL_CLIENT_CERTS "../share" - -/* Turn off websocket extensions */ -/* #undef LWS_NO_EXTENSIONS */ - -/* Enable libev io loop */ -/* #undef LWS_USE_LIBEV */ - -/* Build with support for ipv6 */ -/* #undef LWS_USE_IPV6 */ - -/* Build with support for HTTP2 */ -/* #undef LWS_USE_HTTP2 */ - -/* Turn on latency measuring code */ -/* #undef LWS_LATENCY */ - -/* Don't build the daemonizeation api */ -#define LWS_NO_DAEMONIZE - -/* Build without server support */ -/* #undef LWS_NO_SERVER */ - -/* Build without client support */ -#define LWS_NO_CLIENT - -/* If we should compile with MinGW support */ -/* #undef LWS_MINGW_SUPPORT */ - -/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */ -/* #undef LWS_BUILTIN_GETIFADDRS */ - -/* Define to 1 if you have the `bzero' function. */ -#define HAVE_BZERO - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK - -/* Define to 1 if you have the `getenv’ function. */ -#define HAVE_GETENV - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IN6ADDR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/* #undef HAVE_LIBSSL */ - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define HAVE_REALLOC - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_PRCTL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H - -/* Define to 1 if you have the `vfork' function. */ -#define HAVE_VFORK - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK - -/* Define to 1 if you have the header file. */ -#define HAVE_ZLIB_H - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR // We're not using libtool - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS - -/* Version number of package */ -#define VERSION - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to 1 if we have getifaddrs */ -#define HAVE_GETIFADDRS - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ - -/* Define if the inline keyword doesn't exist. */ -/* #undef inline */ diff --git a/src/engine/external/libwebsockets/context.c b/src/engine/external/libwebsockets/context.c deleted file mode 100644 index 2ea9c60de..000000000 --- a/src/engine/external/libwebsockets/context.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -#ifndef LWS_BUILD_HASH -#define LWS_BUILD_HASH "unknown-build-hash" -#endif - -static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH; - -/** - * lws_get_library_version: get version and git hash library built from - * - * returns a const char * to a string like "1.1 178d78c" - * representing the library version followed by the git head hash it - * was built from - */ - -LWS_VISIBLE const char * -lws_get_library_version(void) -{ - return library_version; -} - -/** - * libwebsocket_create_context() - Create the websocket handler - * @info: pointer to struct with parameters - * - * This function creates the listening socket (if serving) and takes care - * of all initialization in one step. - * - * After initialization, it returns a struct libwebsocket_context * that - * represents this server. After calling, user code needs to take care - * of calling libwebsocket_service() with the context pointer to get the - * server's sockets serviced. This must be done in the same process - * context as the initialization call. - * - * The protocol callback functions are called for a handful of events - * including http requests coming in, websocket connections becoming - * established, and data arriving; it's also called periodically to allow - * async transmission. - * - * HTTP requests are sent always to the FIRST protocol in @protocol, since - * at that time websocket protocol has not been negotiated. Other - * protocols after the first one never see any HTTP callack activity. - * - * The server created is a simple http server by default; part of the - * websocket standard is upgrading this http connection to a websocket one. - * - * This allows the same server to provide files like scripts and favicon / - * images or whatever over http and dynamic data over websockets all in - * one place; they're all handled in the user callback. - */ - -LWS_VISIBLE struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info) -{ - struct libwebsocket_context *context = NULL; - char *p; - - int pid_daemon = get_daemonize_pid(); - - lwsl_notice("Initial logging level %d\n", log_level); - lwsl_notice("Library version: %s\n", library_version); -#ifdef LWS_USE_IPV6 - if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6)) - lwsl_notice("IPV6 compiled in and enabled\n"); - else - lwsl_notice("IPV6 compiled in but disabled\n"); -#else - lwsl_notice("IPV6 not compiled in\n"); -#endif - lws_feature_status_libev(info); - lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN); - lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS); - - lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED); - lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT); - lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH); - lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER); - - if (lws_plat_context_early_init()) - return NULL; - - context = lws_zalloc(sizeof(struct libwebsocket_context)); - if (!context) { - lwsl_err("No memory for websocket context\n"); - return NULL; - } - - if (pid_daemon) { - context->started_with_parent = pid_daemon; - lwsl_notice(" Started with daemon pid %d\n", pid_daemon); - } - - context->listen_service_extraseen = 0; - context->protocols = info->protocols; - context->token_limits = info->token_limits; - context->listen_port = info->port; - context->http_proxy_port = 0; - context->http_proxy_address[0] = '\0'; - context->options = info->options; - context->iface = info->iface; - context->ka_time = info->ka_time; - context->ka_interval = info->ka_interval; - context->ka_probes = info->ka_probes; - - /* to reduce this allocation, */ - context->max_fds = getdtablesize(); - lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n", - sizeof(struct libwebsocket_context), - sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *), - context->max_fds, - sizeof(struct libwebsocket_context) + - ((sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *)) * - context->max_fds)); - - context->fds = lws_zalloc(sizeof(struct libwebsocket_pollfd) * - context->max_fds); - if (context->fds == NULL) { - lwsl_err("Unable to allocate fds array for %d connections\n", - context->max_fds); - lws_free(context); - return NULL; - } - - context->lws_lookup = lws_zalloc(sizeof(struct libwebsocket *) * context->max_fds); - if (context->lws_lookup == NULL) { - lwsl_err( - "Unable to allocate lws_lookup array for %d connections\n", - context->max_fds); - lws_free(context->fds); - lws_free(context); - return NULL; - } - - if (lws_plat_init_fd_tables(context)) { - lws_free(context->lws_lookup); - lws_free(context->fds); - lws_free(context); - return NULL; - } - - lws_context_init_extensions(info, context); - - context->user_space = info->user; - - strcpy(context->canonical_hostname, "unknown"); - - lws_server_get_canonical_hostname(context, info); - - /* split the proxy ads:port if given */ - - if (info->http_proxy_address) { - strncpy(context->http_proxy_address, info->http_proxy_address, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - context->http_proxy_port = info->http_proxy_port; - } else { -#ifdef HAVE_GETENV - p = getenv("http_proxy"); - if (p) { - strncpy(context->http_proxy_address, p, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - - p = strchr(context->http_proxy_address, ':'); - if (p == NULL) { - lwsl_err("http_proxy needs to be ads:port\n"); - goto bail; - } - *p = '\0'; - context->http_proxy_port = atoi(p + 1); - } -#endif - } - - if (context->http_proxy_address[0]) - lwsl_notice(" Proxy %s:%u\n", - context->http_proxy_address, - context->http_proxy_port); - - lwsl_notice( - " per-conn mem: %u + %u headers + protocol rx buf\n", - sizeof(struct libwebsocket), - sizeof(struct allocated_headers)); - - if (lws_context_init_server_ssl(info, context)) - goto bail; - - if (lws_context_init_client_ssl(info, context)) - goto bail; - - if (lws_context_init_server(info, context)) - goto bail; - - /* - * drop any root privs for this process - * to listen on port < 1023 we would have needed root, but now we are - * listening, we don't want the power for anything else - */ - lws_plat_drop_app_privileges(info); - - /* initialize supported protocols */ - - for (context->count_protocols = 0; - info->protocols[context->count_protocols].callback; - context->count_protocols++) { - - lwsl_parser(" Protocol: %s\n", - info->protocols[context->count_protocols].name); - - info->protocols[context->count_protocols].owning_server = - context; - info->protocols[context->count_protocols].protocol_index = - context->count_protocols; - - /* - * inform all the protocols that they are doing their one-time - * initialization if they want to - */ - info->protocols[context->count_protocols].callback(context, - NULL, LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0); - } - - /* - * give all extensions a chance to create any per-context - * allocations they need - */ - - if (info->port != CONTEXT_PORT_NO_LISTEN) { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - NULL, 0) < 0) - goto bail; - } else - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - NULL, 0) < 0) - goto bail; - - return context; - -bail: - libwebsocket_context_destroy(context); - return NULL; -} - -/** - * libwebsocket_context_destroy() - Destroy the websocket context - * @context: Websocket context - * - * This function closes any active connections and then frees the - * context. After calling this, any further use of the context is - * undefined. - */ -LWS_VISIBLE void -libwebsocket_context_destroy(struct libwebsocket_context *context) -{ - int n; - struct libwebsocket_protocols *protocol = context->protocols; - - lwsl_notice("%s\n", __func__); - -#ifdef LWS_LATENCY - if (context->worst_latency_info[0]) - lwsl_notice("Worst latency: %s\n", context->worst_latency_info); -#endif - - for (n = 0; n < context->fds_count; n++) { - struct libwebsocket *wsi = - context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS /* no protocol close */); - n--; - } - - /* - * give all extensions a chance to clean up any per-context - * allocations they might have made - */ - if (context->listen_port != CONTEXT_PORT_NO_LISTEN) { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0) - return; - } else - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0) - return; - - /* - * inform all the protocols that they are done and will have no more - * callbacks - */ - - while (protocol->callback) { - protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY, - NULL, NULL, 0); - protocol++; - } - - lws_plat_context_early_destroy(context); - - lws_ssl_context_destroy(context); - - lws_free(context->fds); - lws_free(context->lws_lookup); - - lws_plat_context_late_destroy(context); - - lws_free(context); -} diff --git a/src/engine/external/libwebsockets/extension-deflate-frame.c b/src/engine/external/libwebsockets/extension-deflate-frame.c deleted file mode 100644 index 13b2b8ded..000000000 --- a/src/engine/external/libwebsockets/extension-deflate-frame.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "private-libwebsockets.h" -#include "extension-deflate-frame.h" -#include -#include -#include - -#define LWS_ZLIB_WINDOW_BITS 15 -#define LWS_ZLIB_MEMLEVEL 8 - -int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ext_deflate_frame_conn *conn = - (struct lws_ext_deflate_frame_conn *)user; - struct lws_tokens *eff_buf = (struct lws_tokens *)in; - size_t current_payload, remaining_payload, total_payload; - int n; - size_t len_so_far; - - switch (reason) { - - /* - * for deflate-frame, both client and server sides act the same - */ - - case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: - case LWS_EXT_CALLBACK_CONSTRUCT: - conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL; - conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL; - conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL; - n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS); - if (n != Z_OK) { - lwsl_ext("deflateInit returned %d\n", n); - return 1; - } - n = deflateInit2(&conn->zs_out, - (context->listen_port ? - DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER : - DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT), - Z_DEFLATED, - -LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL, - Z_DEFAULT_STRATEGY); - if (n != Z_OK) { - lwsl_ext("deflateInit2 returned %d\n", n); - return 1; - } - conn->buf_pre_used = 0; - conn->buf_pre_length = 0; - conn->buf_in_length = sizeof(conn->buf_in); - conn->buf_out_length = sizeof(conn->buf_out); - conn->compressed_out = 0; - conn->buf_pre = NULL; - conn->buf_in = lws_malloc(LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_in_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_in) - goto bail; - conn->buf_out = lws_malloc(LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_out_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_out) - goto bail; - lwsl_ext("zlibs constructed\n"); - break; -bail: - lwsl_err("Out of mem\n"); - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - return -1; - - case LWS_EXT_CALLBACK_DESTROY: - lws_free(conn->buf_pre); - lws_free(conn->buf_in); - lws_free(conn->buf_out); - conn->buf_pre_used = 0; - conn->buf_pre_length = 0; - conn->buf_in_length = 0; - conn->buf_out_length = 0; - conn->compressed_out = 0; - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - lwsl_ext("zlibs destructed\n"); - break; - - case LWS_EXT_CALLBACK_PAYLOAD_RX: - if (!(wsi->u.ws.rsv & 0x40)) - return 0; - - /* - * inflate the incoming payload - */ - current_payload = eff_buf->token_len; - - remaining_payload = wsi->u.ws.rx_packet_length; - if (remaining_payload) { - total_payload = conn->buf_pre_used + - current_payload + - remaining_payload; - - if (conn->buf_pre_length < total_payload) { - conn->buf_pre_length = total_payload; - lws_free(conn->buf_pre); - conn->buf_pre = lws_malloc(total_payload + 4); - if (!conn->buf_pre) { - lwsl_err("Out of memory\n"); - return -1; - } - } - - memcpy(conn->buf_pre + conn->buf_pre_used, - eff_buf->token, current_payload); - conn->buf_pre_used += current_payload; - - eff_buf->token = NULL; - eff_buf->token_len = 0; - - return 0; - } - if (conn->buf_pre_used) { - total_payload = conn->buf_pre_used + - current_payload; - - memcpy(conn->buf_pre + conn->buf_pre_used, - eff_buf->token, current_payload); - conn->buf_pre_used = 0; - - conn->zs_in.next_in = conn->buf_pre; - } else { - total_payload = current_payload; - - conn->zs_in.next_in = (unsigned char *)eff_buf->token; - } - - conn->zs_in.next_in[total_payload + 0] = 0; - conn->zs_in.next_in[total_payload + 1] = 0; - conn->zs_in.next_in[total_payload + 2] = 0xff; - conn->zs_in.next_in[total_payload + 3] = 0xff; - - conn->zs_in.avail_in = total_payload + 4; - - conn->zs_in.next_out = - conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING; - conn->zs_in.avail_out = conn->buf_in_length; - - while (1) { - n = inflate(&conn->zs_in, Z_SYNC_FLUSH); - switch (n) { - case Z_NEED_DICT: - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - /* - * screwed.. close the connection... - * we will get a destroy callback to take care - * of closing nicely - */ - lwsl_info("zlib error inflate %d: %s\n", - n, conn->zs_in.msg); - return -1; - } - - if (conn->zs_in.avail_out) - break; - - len_so_far = conn->zs_in.next_out - - (conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING); - - conn->buf_in_length *= 2; - if (conn->buf_in_length > LWS_MAX_ZLIB_CONN_BUFFER) { - lwsl_ext("zlib in buffer hit limit %u\n", - LWS_MAX_ZLIB_CONN_BUFFER); - return -1; - } - conn->buf_in = lws_realloc(conn->buf_in, - LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_in_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_in) { - lwsl_err("Out of memory\n"); - return -1; - } - lwsl_debug( - "deflate-frame ext RX did realloc to %ld\n", - conn->buf_in_length); - conn->zs_in.next_out = conn->buf_in + - LWS_SEND_BUFFER_PRE_PADDING + len_so_far; - conn->zs_in.avail_out = - conn->buf_in_length - len_so_far; - } - - /* rewrite the buffer pointers and length */ - eff_buf->token = - (char *)(conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING); - eff_buf->token_len = (int)(conn->zs_in.next_out - - (conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING)); - - return 0; - - case LWS_EXT_CALLBACK_PAYLOAD_TX: - /* - * deflate the outgoing payload - */ - current_payload = eff_buf->token_len; - - conn->zs_out.next_in = (unsigned char *)eff_buf->token; - conn->zs_out.avail_in = current_payload; - - conn->zs_out.next_out = - conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING; - conn->zs_out.avail_out = conn->buf_out_length; - - while (1) { - n = deflate(&conn->zs_out, Z_SYNC_FLUSH); - if (n == Z_STREAM_ERROR) { - /* - * screwed.. close the connection... we will - * get a destroy callback to take care of - * closing nicely - */ - lwsl_ext("zlib error deflate\n"); - - return -1; - } - - if (conn->zs_out.avail_out) - break; - - len_so_far = (conn->zs_out.next_out - - (conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING)); - conn->buf_out_length *= 2; - if (conn->buf_out_length > LWS_MAX_ZLIB_CONN_BUFFER) { - lwsl_ext("zlib out hit limit %u\n", - LWS_MAX_ZLIB_CONN_BUFFER); - return -1; - } - conn->buf_out = lws_realloc(conn->buf_out, - LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_out_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_out) { - lwsl_err("Out of memory\n"); - return -1; - } - lwsl_debug( - "deflate-frame ext TX did realloc to %ld\n", - conn->buf_in_length); - - conn->zs_out.next_out = (conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING + len_so_far); - conn->zs_out.avail_out = - (conn->buf_out_length - len_so_far); - } - - conn->compressed_out = 1; - - /* rewrite the buffer pointers and length */ - eff_buf->token = (char *)(conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING); - eff_buf->token_len = (int)(conn->zs_out.next_out - - (conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING)) - 4; - - return 0; - - case LWS_EXT_CALLBACK_PACKET_TX_PRESEND: - if (conn->compressed_out) { - conn->compressed_out = 0; - *((unsigned char *)eff_buf->token) |= 0x40; - } - break; - - case LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION: - /* Avoid x-webkit-deflate-frame extension on client */ - if (!strcmp((char *)in, "x-webkit-deflate-frame")) - return 1; - break; - - default: - break; - } - - return 0; -} - diff --git a/src/engine/external/libwebsockets/extension-deflate-frame.h b/src/engine/external/libwebsockets/extension-deflate-frame.h deleted file mode 100644 index 00a4447aa..000000000 --- a/src/engine/external/libwebsockets/extension-deflate-frame.h +++ /dev/null @@ -1,25 +0,0 @@ - -#include - -#define DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER 1 -#define DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT Z_DEFAULT_COMPRESSION - -struct lws_ext_deflate_frame_conn { - z_stream zs_in; - z_stream zs_out; - size_t buf_pre_used; - size_t buf_pre_length; - size_t buf_in_length; - size_t buf_out_length; - int compressed_out; - unsigned char *buf_pre; - unsigned char *buf_in; - unsigned char *buf_out; -}; - -extern int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); diff --git a/src/engine/external/libwebsockets/extension-deflate-stream.c b/src/engine/external/libwebsockets/extension-deflate-stream.c deleted file mode 100644 index addaa2c7e..000000000 --- a/src/engine/external/libwebsockets/extension-deflate-stream.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "private-libwebsockets.h" -#include "extension-deflate-stream.h" -#include -#include -#include - -#define LWS_ZLIB_WINDOW_BITS 15 -#define LWS_ZLIB_MEMLEVEL 8 - -int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ext_deflate_stream_conn *conn = - (struct lws_ext_deflate_stream_conn *)user; - int n; - struct lws_tokens *eff_buf = (struct lws_tokens *)in; - - switch (reason) { - - /* - * for deflate-stream, both client and server sides act the same - */ - - case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: - case LWS_EXT_CALLBACK_CONSTRUCT: - conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL; - conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL; - conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL; - n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS); - if (n != Z_OK) { - lwsl_err("deflateInit returned %d\n", n); - return 1; - } - n = deflateInit2(&conn->zs_out, - DEFLATE_STREAM_COMPRESSION_LEVEL, Z_DEFLATED, - -LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL, - Z_DEFAULT_STRATEGY); - if (n != Z_OK) { - lwsl_err("deflateInit returned %d\n", n); - return 1; - } - lwsl_ext("zlibs constructed\n"); - conn->remaining_in = 0; - break; - - case LWS_EXT_CALLBACK_DESTROY: - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - lwsl_ext("zlibs destructed\n"); - break; - - case LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: - - /* - * inflate the incoming compressed data - * Notice, length may be 0 and pointer NULL - * in the case we are flushing with nothing new coming in - */ - if (conn->remaining_in) { - conn->zs_in.next_in = conn->buf_in; - conn->zs_in.avail_in = conn->remaining_in; - conn->remaining_in = 0; - } else { - conn->zs_in.next_in = (unsigned char *)eff_buf->token; - conn->zs_in.avail_in = eff_buf->token_len; - } - - conn->zs_in.next_out = conn->buf_out; - conn->zs_in.avail_out = sizeof(conn->buf_out); - - n = inflate(&conn->zs_in, Z_SYNC_FLUSH); - switch (n) { - case Z_NEED_DICT: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - /* - * screwed.. close the connection... we will get a - * destroy callback to take care of closing nicely - */ - lwsl_err("zlib error inflate %d\n", n); - return -1; - } - - /* rewrite the buffer pointers and length */ - - eff_buf->token = (char *)conn->buf_out; - eff_buf->token_len = - sizeof(conn->buf_out) - conn->zs_in.avail_out; - - /* copy avail data if not consumed */ - if (conn->zs_in.avail_in > 0) { - conn->remaining_in = conn->zs_in.avail_in; - memcpy(conn->buf_in, conn->zs_in.next_in, - conn->zs_in.avail_in); - return 1; - } - - /* - * if we filled the output buffer, signal that we likely have - * more and need to be called again - */ - - if (eff_buf->token_len == sizeof(conn->buf_out)) - return 1; - - /* we don't need calling again until new input data comes */ - - return 0; - - case LWS_EXT_CALLBACK_FLUSH_PENDING_TX: - case LWS_EXT_CALLBACK_PACKET_TX_PRESEND: - - /* - * deflate the outgoing compressed data - */ - - conn->zs_out.next_in = (unsigned char *)eff_buf->token; - conn->zs_out.avail_in = eff_buf->token_len; - - conn->zs_out.next_out = conn->buf_out; - conn->zs_out.avail_out = sizeof(conn->buf_out); - - n = Z_PARTIAL_FLUSH; - if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX) - n = Z_FULL_FLUSH; - - n = deflate(&conn->zs_out, n); - if (n == Z_STREAM_ERROR) { - /* - * screwed.. close the connection... we will get a - * destroy callback to take care of closing nicely - */ - lwsl_ext("zlib error deflate\n"); - - return -1; - } - - /* rewrite the buffer pointers and length */ - - eff_buf->token = (char *)conn->buf_out; - eff_buf->token_len = - sizeof(conn->buf_out) - conn->zs_out.avail_out; - - /* - * if we filled the output buffer, signal that we likely have - * more and need to be called again... even in deflate case - * we might sometimes need to spill more than came in - */ - - if (eff_buf->token_len == sizeof(conn->buf_out)) - return 1; - - /* we don't need calling again until new input data comes */ - - return 0; - - default: - break; - } - - return 0; -} diff --git a/src/engine/external/libwebsockets/extension-deflate-stream.h b/src/engine/external/libwebsockets/extension-deflate-stream.h deleted file mode 100644 index fcadc07ab..000000000 --- a/src/engine/external/libwebsockets/extension-deflate-stream.h +++ /dev/null @@ -1,20 +0,0 @@ - -#include - -#define DEFLATE_STREAM_CHUNK 128 -#define DEFLATE_STREAM_COMPRESSION_LEVEL 1 - -struct lws_ext_deflate_stream_conn { - z_stream zs_in; - z_stream zs_out; - int remaining_in; - unsigned char buf_in[LWS_MAX_SOCKET_IO_BUF]; - unsigned char buf_out[LWS_MAX_SOCKET_IO_BUF]; -}; - -extern int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); diff --git a/src/engine/external/libwebsockets/extension.c b/src/engine/external/libwebsockets/extension.c deleted file mode 100644 index b7a5792bf..000000000 --- a/src/engine/external/libwebsockets/extension.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "private-libwebsockets.h" - -#include "extension-deflate-frame.h" -#include "extension-deflate-stream.h" - -struct libwebsocket_extension libwebsocket_internal_extensions[] = { -#ifdef LWS_EXT_DEFLATE_STREAM - { - "deflate-stream", - lws_extension_callback_deflate_stream, - sizeof(struct lws_ext_deflate_stream_conn) - }, -#else - { - "x-webkit-deflate-frame", - lws_extension_callback_deflate_frame, - sizeof(struct lws_ext_deflate_frame_conn) - }, - { - "deflate-frame", - lws_extension_callback_deflate_frame, - sizeof(struct lws_ext_deflate_frame_conn) - }, -#endif - { /* terminator */ - NULL, NULL, 0 - } -}; - -LWS_VISIBLE void -lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context) -{ - context->extensions = info->extensions; - lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE); -} - -LWS_VISIBLE struct libwebsocket_extension *libwebsocket_get_internal_extensions() -{ - return libwebsocket_internal_extensions; -} - - -/* 0 = nobody had nonzero return, 1 = somebody had positive return, -1 = fail */ - -int lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, - void *arg, int len) -{ - int n, m, handled = 0; - - for (n = 0; n < wsi->count_active_extensions; n++) { - m = wsi->active_extensions[n]->callback( - wsi->protocol->owning_server, - wsi->active_extensions[n], wsi, - reason, - wsi->active_extensions_user[n], - arg, len); - if (m < 0) { - lwsl_ext( - "Extension '%s' failed to handle callback %d!\n", - wsi->active_extensions[n]->name, reason); - return -1; - } - if (m > handled) - handled = m; - } - - return handled; -} - -int lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, - int reason, void *arg, int len) -{ - int n = 0, m, handled = 0; - struct libwebsocket_extension *ext = context->extensions; - - while (ext && ext->callback && !handled) { - m = ext->callback(context, ext, wsi, reason, - (void *)(long)n, arg, len); - if (m < 0) { - lwsl_ext( - "Extension '%s' failed to handle callback %d!\n", - wsi->active_extensions[n]->name, reason); - return -1; - } - if (m) - handled = 1; - - ext++; - n++; - } - - return 0; -} - -int -lws_issue_raw_ext_access(struct libwebsocket *wsi, - unsigned char *buf, size_t len) -{ - int ret; - struct lws_tokens eff_buf; - int m; - int n = 0; - - eff_buf.token = (char *)buf; - eff_buf.token_len = len; - - /* - * while we have original buf to spill ourselves, or extensions report - * more in their pipeline - */ - - ret = 1; - while (ret == 1) { - - /* default to nobody has more to spill */ - - ret = 0; - - /* show every extension the new incoming data */ - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, &eff_buf, 0); - if (m < 0) - return -1; - if (m) /* handled */ - ret = 1; - - if ((char *)buf != eff_buf.token) - /* - * extension recreated it: - * need to buffer this if not all sent - */ - wsi->u.ws.clean_buffer = 0; - - /* assuming they left us something to send, send it */ - - if (eff_buf.token_len) { - n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - lwsl_info("closing from ext access\n"); - return -1; - } - - /* always either sent it all or privately buffered */ - if (wsi->u.ws.clean_buffer) - len = n; - } - - lwsl_parser("written %d bytes to client\n", n); - - /* no extension has more to spill? Then we can go */ - - if (!ret) - break; - - /* we used up what we had */ - - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* - * Did that leave the pipe choked? - * Or we had to hold on to some of it? - */ - - if (!lws_send_pipe_choked(wsi) && !wsi->truncated_send_len) - /* no we could add more, lets's do that */ - continue; - - lwsl_debug("choked\n"); - - /* - * Yes, he's choked. Don't spill the rest now get a callback - * when he is ready to send and take care of it there - */ - libwebsocket_callback_on_writable( - wsi->protocol->owning_server, wsi); - wsi->extension_data_pending = 1; - ret = 0; - } - - return len; -} - -int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, - void *v, size_t len) -{ - int n; - int handled = 0; - - /* maybe an extension will take care of it for us */ - - for (n = 0; n < wsi->count_active_extensions && !handled; n++) { - if (!wsi->active_extensions[n]->callback) - continue; - - handled |= wsi->active_extensions[n]->callback(context, - wsi->active_extensions[n], wsi, - r, wsi->active_extensions_user[n], v, len); - } - - return handled; -} diff --git a/src/engine/external/libwebsockets/getifaddrs.h b/src/engine/external/libwebsockets/getifaddrs.h deleted file mode 100644 index da69b50e6..000000000 --- a/src/engine/external/libwebsockets/getifaddrs.h +++ /dev/null @@ -1,76 +0,0 @@ -#if HAVE_GETIFADDRS -#include -#include -#else -#ifdef __cplusplus -extern "C" { -#endif -/* - * Copyright (c) 2000 Kungliga Tekniska H�gskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $KTH: ifaddrs.hin,v 1.3 2000/12/11 00:01:13 assar Exp $ */ - -#ifndef ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 -#define ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 - -/* - * the interface is defined in terms of the fields below, and this is - * sometimes #define'd, so there seems to be no simple way of solving - * this and this seemed the best. */ - -#undef ifa_dstaddr - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - struct sockaddr *ifa_dstaddr; - void *ifa_data; -}; - -#ifndef ifa_broadaddr -#define ifa_broadaddr ifa_dstaddr -#endif - -int getifaddrs(struct ifaddrs **); - -void freeifaddrs(struct ifaddrs *); - -#endif /* __ifaddrs_h__ */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/engine/external/libwebsockets/handshake.c b/src/engine/external/libwebsockets/handshake.c deleted file mode 100644 index 856297db2..000000000 --- a/src/engine/external/libwebsockets/handshake.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -/* - * -04 of the protocol (actually the 80th version) has a radically different - * handshake. The 04 spec gives the following idea - * - * The handshake from the client looks as follows: - * - * GET /chat HTTP/1.1 - * Host: server.example.com - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== - * Sec-WebSocket-Origin: http://example.com - * Sec-WebSocket-Protocol: chat, superchat - * Sec-WebSocket-Version: 4 - * - * The handshake from the server looks as follows: - * - * HTTP/1.1 101 Switching Protocols - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo= - * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC== - * Sec-WebSocket-Protocol: chat - */ - -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif -/* - * We have to take care about parsing because the headers may be split - * into multiple fragments. They may contain unknown headers with arbitrary - * argument lengths. So, we parse using a single-character at a time state - * machine that is completely independent of packet size. - */ - -LWS_VISIBLE int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, size_t len) -{ - size_t n; - int body_chunk_len; - unsigned char *last_char; - - switch (wsi->state) { -#ifdef LWS_USE_HTTP2 - case WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE: - case WSI_STATE_HTTP2_ESTABLISHED_PRE_SETTINGS: - case WSI_STATE_HTTP2_ESTABLISHED: - n = 0; - while (n < len) { - /* - * we were accepting input but now we stopped doing so - */ - if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) { - lws_rxflow_cache(wsi, buf, n, len); - - return 1; - } - - /* account for what we're using in rxflow buffer */ - if (wsi->rxflow_buffer) - wsi->rxflow_pos++; - if (lws_http2_parser(context, wsi, buf[n++])) - goto bail; - } - break; -#endif -http_new: - case WSI_STATE_HTTP: - wsi->hdr_parsing_completed = 0; - /* fallthru */ - case WSI_STATE_HTTP_ISSUING_FILE: - wsi->state = WSI_STATE_HTTP_HEADERS; - wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; - wsi->u.hdr.lextable_pos = 0; - /* fallthru */ - case WSI_STATE_HTTP_HEADERS: - lwsl_parser("issuing %d bytes to parser\n", (int)len); - - if (lws_handshake_client(wsi, &buf, len)) - goto bail; - - last_char = buf; - if (lws_handshake_server(context, wsi, &buf, len)) - /* Handshake indicates this session is done. */ - goto bail; - - /* It's possible that we've exhausted our data already, but - * lws_handshake_server doesn't update len for us. Figure out how - * much was read, so that we can proceed appropriately: */ - len -= (buf - last_char); - - if (!wsi->hdr_parsing_completed) - /* More header content on the way */ - goto read_ok; - - switch (wsi->state) { - case WSI_STATE_HTTP: - case WSI_STATE_HTTP_HEADERS: - goto http_complete; - case WSI_STATE_HTTP_ISSUING_FILE: - goto read_ok; - case WSI_STATE_HTTP_BODY: - wsi->u.http.content_remain = wsi->u.http.content_length; - goto http_postbody; - default: - break; - } - break; - - case WSI_STATE_HTTP_BODY: -http_postbody: - while (len && wsi->u.http.content_remain) { - /* Copy as much as possible, up to the limit of: - * what we have in the read buffer (len) - * remaining portion of the POST body (content_remain) - */ - body_chunk_len = min(wsi->u.http.content_remain,len); - wsi->u.http.content_remain -= body_chunk_len; - len -= body_chunk_len; - - if (wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY, wsi->user_space, - buf, body_chunk_len); - if (n) - goto bail; - } - buf += body_chunk_len; - - if (!wsi->u.http.content_remain) { - /* he sent the content in time */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - if (wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - wsi->user_space, NULL, 0); - if (n) - goto bail; - } - goto http_complete; - } else - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_HTTP_CONTENT, - AWAITING_TIMEOUT); - } - break; - - case WSI_STATE_ESTABLISHED: - case WSI_STATE_AWAITING_CLOSE_ACK: - if (lws_handshake_client(wsi, &buf, len)) - goto bail; - switch (wsi->mode) { - case LWS_CONNMODE_WS_SERVING: - - if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) { - lwsl_info("interpret_incoming_packet has bailed\n"); - goto bail; - } - break; - } - break; - default: - lwsl_err("libwebsocket_read: Unhandled state\n"); - break; - } - -read_ok: - /* Nothing more to do for now. */ - lwsl_debug("libwebsocket_read: read_ok\n"); - - return 0; - -http_complete: - lwsl_debug("libwebsocket_read: http_complete\n"); - - /* Did the client want to keep the HTTP connection going? */ - - if (wsi->u.http.connection_type == HTTP_CONNECTION_KEEP_ALIVE) { - lwsl_debug("libwebsocket_read: keep-alive\n"); - wsi->state = WSI_STATE_HTTP; - wsi->mode = LWS_CONNMODE_HTTP_SERVING; - - /* He asked for it to stay alive indefinitely */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - if (lws_allocate_header_table(wsi)) - goto bail; - - /* If we're (re)starting on headers, need other implied init */ - wsi->u.hdr.ues = URIES_IDLE; - - /* If we have more data, loop back around: */ - if (len) - goto http_new; - - return 0; - } - -bail: - lwsl_debug("closing connection at libwebsocket_read bail:\n"); - - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - - return -1; -} diff --git a/src/engine/external/libwebsockets/huftable.h b/src/engine/external/libwebsockets/huftable.h deleted file mode 100644 index 385a83be3..000000000 --- a/src/engine/external/libwebsockets/huftable.h +++ /dev/null @@ -1,530 +0,0 @@ -static unsigned char lextable[] = { -/* pos 0000: 0 */ /* 0 */ 0x42 /* (to 0x0084 state 98) */, - /* 1 */ 0x01 /* (to 0x0002 state 1) */, -/* pos 0002: 1 */ /* 0 */ 0x5C /* (to 0x00BA state 151) */, - /* 1 */ 0x01 /* (to 0x0004 state 2) */, -/* pos 0004: 2 */ /* 0 */ 0x66 /* (to 0x00D0 state 173) */, - /* 1 */ 0x01 /* (to 0x0006 state 3) */, -/* pos 0006: 3 */ /* 0 */ 0x74 /* (to 0x00EE state 204) */, - /* 1 */ 0x01 /* (to 0x0008 state 4) */, -/* pos 0008: 4 */ /* 0 */ 0x8C /* (to 0x0120 state 263) */, - /* 1 */ 0x01 /* (to 0x000A state 5) */, -/* pos 000a: 5 */ /* 0 */ 0x46 /* (to 0x0096 state 113) */, - /* 1 */ 0x01 /* (to 0x000C state 6) */, -/* pos 000c: 6 */ /* 0 */ 0x75 /* (to 0x00F6 state 211) */, - /* 1 */ 0x01 /* (to 0x000E state 7) */, -/* pos 000e: 7 */ /* 0 */ 0x40 /* (to 0x008E state 104) */, - /* 1 */ 0x01 /* (to 0x0010 state 8) */, -/* pos 0010: 8 */ /* 0 */ 0x45 /* (to 0x009A state 116) */, - /* 1 */ 0x01 /* (to 0x0012 state 9) */, -/* pos 0012: 9 */ /* 0 */ 0x40 /* (to 0x0092 state 108) */, - /* 1 */ 0x01 /* (to 0x0014 state 10) */, -/* pos 0014: 10 */ /* 0 */ 0x01 /* (to 0x0016 state 11) */, - /* 1 */ 0x03 /* (to 0x001A state 14) */, -/* pos 0016: 11 */ /* 0 */ 0x01 /* (to 0x0018 state 12) */, - /* 1 */ 0x5B /* (to 0x00CC state 166) */, -/* pos 0018: 12 */ /* terminal 0 */ 0x00, - /* terminal 36 */ 0x24, -/* pos 001a: 14 */ /* 0 */ 0x72 /* (to 0x00FE state 220) */, - /* 1 */ 0x01 /* (to 0x001C state 15) */, -/* pos 001c: 15 */ /* 0 */ 0x72 /* (to 0x0100 state 222) */, - /* 1 */ 0x01 /* (to 0x001E state 16) */, -/* pos 001e: 16 */ /* 0 */ 0x53 /* (to 0x00C4 state 158) */, - /* 1 */ 0x01 /* (to 0x0020 state 17) */, -/* pos 0020: 17 */ /* terminal 123 */ 0x7B, - /* 1 */ 0x01 /* (to 0x0022 state 18) */, -/* pos 0022: 18 */ /* 0 */ 0x6B /* (to 0x00F8 state 216) */, - /* 1 */ 0x01 /* (to 0x0024 state 19) */, -/* pos 0024: 19 */ /* 0 */ 0x84 /* (to 0x012C state 279) */, - /* 1 */ 0x01 /* (to 0x0026 state 20) */, -/* pos 0026: 20 */ /* 0 */ 0x01 /* (to 0x0028 state 21) */, - /* 1 */ 0x06 /* (to 0x0032 state 27) */, -/* pos 0028: 21 */ /* 0 */ 0xB3 /* (to 0x018E state 377) */, - /* 1 */ 0x01 /* (to 0x002A state 22) */, -/* pos 002a: 22 */ /* 0 */ 0xC3 /* (to 0x01B0 state 414) */, - /* 1 */ 0x01 /* (to 0x002C state 23) */, -/* pos 002c: 23 */ /* 0 */ 0x01 /* (to 0x002E state 24) */, - /* 1 */ 0x8C /* (to 0x0144 state 301) */, -/* pos 002e: 24 */ /* 0 */ 0x01 /* (to 0x0030 state 25) */, - /* 1 */ 0x8A /* (to 0x0142 state 298) */, -/* pos 0030: 25 */ /* terminal 1 */ 0x01, - /* terminal 135 */ 0x87, -/* pos 0032: 27 */ /* 0 */ 0x8E /* (to 0x014E state 314) */, - /* 1 */ 0x01 /* (to 0x0034 state 28) */, -/* pos 0034: 28 */ /* 0 */ 0x0F /* (to 0x0052 state 50) */, - /* 1 */ 0x01 /* (to 0x0036 state 29) */, -/* pos 0036: 29 */ /* 0 */ 0xA4 /* (to 0x017E state 362) */, - /* 1 */ 0x01 /* (to 0x0038 state 30) */, -/* pos 0038: 30 */ /* 0 */ 0xB7 /* (to 0x01A6 state 403) */, - /* 1 */ 0x01 /* (to 0x003A state 31) */, -/* pos 003a: 31 */ /* 0 */ 0xC8 /* (to 0x01CA state 440) */, - /* 1 */ 0x01 /* (to 0x003C state 32) */, -/* pos 003c: 32 */ /* 0 */ 0x01 /* (to 0x003E state 33) */, - /* 1 */ 0x0F /* (to 0x005A state 55) */, -/* pos 003e: 33 */ /* 0 */ 0x01 /* (to 0x0040 state 34) */, - /* 1 */ 0x07 /* (to 0x004C state 46) */, -/* pos 0040: 34 */ /* 0 */ 0x01 /* (to 0x0042 state 35) */, - /* 1 */ 0x03 /* (to 0x0046 state 39) */, -/* pos 0042: 35 */ /* terminal 254 */ 0xFE, - /* 1 */ 0x01 /* (to 0x0044 state 36) */, -/* pos 0044: 36 */ /* terminal 2 */ 0x02, - /* terminal 3 */ 0x03, -/* pos 0046: 39 */ /* 0 */ 0x01 /* (to 0x0048 state 40) */, - /* 1 */ 0x02 /* (to 0x004A state 43) */, -/* pos 0048: 40 */ /* terminal 4 */ 0x04, - /* terminal 5 */ 0x05, -/* pos 004a: 43 */ /* terminal 6 */ 0x06, - /* terminal 7 */ 0x07, -/* pos 004c: 46 */ /* 0 */ 0x01 /* (to 0x004E state 47) */, - /* 1 */ 0x0E /* (to 0x0068 state 67) */, -/* pos 004e: 47 */ /* 0 */ 0x01 /* (to 0x0050 state 48) */, - /* 1 */ 0x0C /* (to 0x0066 state 63) */, -/* pos 0050: 48 */ /* terminal 8 */ 0x08, - /* terminal 11 */ 0x0B, -/* pos 0052: 50 */ /* 0 */ 0xA7 /* (to 0x01A0 state 396) */, - /* 1 */ 0x01 /* (to 0x0054 state 51) */, -/* pos 0054: 51 */ /* 0 */ 0x01 /* (to 0x0056 state 52) */, - /* 1 */ 0x7B /* (to 0x014A state 309) */, -/* pos 0056: 52 */ /* terminal 239 */ 0xEF, - /* 1 */ 0x01 /* (to 0x0058 state 53) */, -/* pos 0058: 53 */ /* terminal 9 */ 0x09, - /* terminal 142 */ 0x8E, -/* pos 005a: 55 */ /* 0 */ 0x0A /* (to 0x006E state 74) */, - /* 1 */ 0x01 /* (to 0x005C state 56) */, -/* pos 005c: 56 */ /* 0 */ 0x11 /* (to 0x007E state 91) */, - /* 1 */ 0x01 /* (to 0x005E state 57) */, -/* pos 005e: 57 */ /* 0 */ 0x64 /* (to 0x0126 state 274) */, - /* 1 */ 0x01 /* (to 0x0060 state 58) */, -/* pos 0060: 58 */ /* terminal 249 */ 0xF9, - /* 1 */ 0x01 /* (to 0x0062 state 59) */, -/* pos 0062: 59 */ /* 0 */ 0x01 /* (to 0x0064 state 60) */, - /* 1 */ 0x0A /* (to 0x0076 state 81) */, -/* pos 0064: 60 */ /* terminal 10 */ 0x0A, - /* terminal 13 */ 0x0D, -/* pos 0066: 63 */ /* terminal 12 */ 0x0C, - /* terminal 14 */ 0x0E, -/* pos 0068: 67 */ /* 0 */ 0x01 /* (to 0x006A state 68) */, - /* 1 */ 0x02 /* (to 0x006C state 71) */, -/* pos 006a: 68 */ /* terminal 15 */ 0x0F, - /* terminal 16 */ 0x10, -/* pos 006c: 71 */ /* terminal 17 */ 0x11, - /* terminal 18 */ 0x12, -/* pos 006e: 74 */ /* 0 */ 0x01 /* (to 0x0070 state 75) */, - /* 1 */ 0x05 /* (to 0x0078 state 84) */, -/* pos 0070: 75 */ /* 0 */ 0x01 /* (to 0x0072 state 76) */, - /* 1 */ 0x02 /* (to 0x0074 state 79) */, -/* pos 0072: 76 */ /* terminal 19 */ 0x13, - /* terminal 20 */ 0x14, -/* pos 0074: 79 */ /* terminal 21 */ 0x15, - /* terminal 23 */ 0x17, -/* pos 0076: 81 */ /* terminal 22 */ 0x16, - /* terminal 256 */ 0x00, -/* pos 0078: 84 */ /* 0 */ 0x01 /* (to 0x007A state 85) */, - /* 1 */ 0x02 /* (to 0x007C state 88) */, -/* pos 007a: 85 */ /* terminal 24 */ 0x18, - /* terminal 25 */ 0x19, -/* pos 007c: 88 */ /* terminal 26 */ 0x1A, - /* terminal 27 */ 0x1B, -/* pos 007e: 91 */ /* 0 */ 0x01 /* (to 0x0080 state 92) */, - /* 1 */ 0x02 /* (to 0x0082 state 95) */, -/* pos 0080: 92 */ /* terminal 28 */ 0x1C, - /* terminal 29 */ 0x1D, -/* pos 0082: 95 */ /* terminal 30 */ 0x1E, - /* terminal 31 */ 0x1F, -/* pos 0084: 98 */ /* 0 */ 0x13 /* (to 0x00AA state 133) */, - /* 1 */ 0x01 /* (to 0x0086 state 99) */, -/* pos 0086: 99 */ /* 0 */ 0x01 /* (to 0x0088 state 100) */, - /* 1 */ 0x0F /* (to 0x00A4 state 129) */, -/* pos 0088: 100 */ /* 0 */ 0x4B /* (to 0x011E state 258) */, - /* 1 */ 0x01 /* (to 0x008A state 101) */, -/* pos 008a: 101 */ /* 0 */ 0x01 /* (to 0x008C state 102) */, - /* 1 */ 0x0C /* (to 0x00A2 state 126) */, -/* pos 008c: 102 */ /* terminal 32 */ 0x20, - /* terminal 37 */ 0x25, -/* pos 008e: 104 */ /* 0 */ 0x01 /* (to 0x0090 state 105) */, - /* 1 */ 0x08 /* (to 0x009E state 119) */, -/* pos 0090: 105 */ /* terminal 33 */ 0x21, - /* terminal 34 */ 0x22, -/* pos 0092: 108 */ /* terminal 124 */ 0x7C, - /* 1 */ 0x01 /* (to 0x0094 state 109) */, -/* pos 0094: 109 */ /* terminal 35 */ 0x23, - /* terminal 62 */ 0x3E, -/* pos 0096: 113 */ /* 0 */ 0x01 /* (to 0x0098 state 114) */, - /* 1 */ 0x05 /* (to 0x00A0 state 124) */, -/* pos 0098: 114 */ /* terminal 38 */ 0x26, - /* terminal 42 */ 0x2A, -/* pos 009a: 116 */ /* terminal 63 */ 0x3F, - /* 1 */ 0x01 /* (to 0x009C state 117) */, -/* pos 009c: 117 */ /* terminal 39 */ 0x27, - /* terminal 43 */ 0x2B, -/* pos 009e: 119 */ /* terminal 40 */ 0x28, - /* terminal 41 */ 0x29, -/* pos 00a0: 124 */ /* terminal 44 */ 0x2C, - /* terminal 59 */ 0x3B, -/* pos 00a2: 126 */ /* terminal 45 */ 0x2D, - /* terminal 46 */ 0x2E, -/* pos 00a4: 129 */ /* 0 */ 0x01 /* (to 0x00A6 state 130) */, - /* 1 */ 0x08 /* (to 0x00B4 state 144) */, -/* pos 00a6: 130 */ /* 0 */ 0x01 /* (to 0x00A8 state 131) */, - /* 1 */ 0x06 /* (to 0x00B2 state 141) */, -/* pos 00a8: 131 */ /* terminal 47 */ 0x2F, - /* terminal 51 */ 0x33, -/* pos 00aa: 133 */ /* 0 */ 0x01 /* (to 0x00AC state 134) */, - /* 1 */ 0x2D /* (to 0x0104 state 229) */, -/* pos 00ac: 134 */ /* 0 */ 0x01 /* (to 0x00AE state 135) */, - /* 1 */ 0x02 /* (to 0x00B0 state 138) */, -/* pos 00ae: 135 */ /* terminal 48 */ 0x30, - /* terminal 49 */ 0x31, -/* pos 00b0: 138 */ /* terminal 50 */ 0x32, - /* terminal 97 */ 0x61, -/* pos 00b2: 141 */ /* terminal 52 */ 0x34, - /* terminal 53 */ 0x35, -/* pos 00b4: 144 */ /* 0 */ 0x01 /* (to 0x00B6 state 145) */, - /* 1 */ 0x02 /* (to 0x00B8 state 148) */, -/* pos 00b6: 145 */ /* terminal 54 */ 0x36, - /* terminal 55 */ 0x37, -/* pos 00b8: 148 */ /* terminal 56 */ 0x38, - /* terminal 57 */ 0x39, -/* pos 00ba: 151 */ /* 0 */ 0x06 /* (to 0x00C6 state 160) */, - /* 1 */ 0x01 /* (to 0x00BC state 152) */, -/* pos 00bc: 152 */ /* 0 */ 0x2C /* (to 0x0114 state 246) */, - /* 1 */ 0x01 /* (to 0x00BE state 153) */, -/* pos 00be: 153 */ /* 0 */ 0x2F /* (to 0x011C state 256) */, - /* 1 */ 0x01 /* (to 0x00C0 state 154) */, -/* pos 00c0: 154 */ /* 0 */ 0x01 /* (to 0x00C2 state 155) */, - /* 1 */ 0x07 /* (to 0x00CE state 170) */, -/* pos 00c2: 155 */ /* terminal 58 */ 0x3A, - /* terminal 66 */ 0x42, -/* pos 00c4: 158 */ /* terminal 60 */ 0x3C, - /* terminal 96 */ 0x60, -/* pos 00c6: 160 */ /* 0 */ 0x01 /* (to 0x00C8 state 161) */, - /* 1 */ 0x21 /* (to 0x0108 state 232) */, -/* pos 00c8: 161 */ /* 0 */ 0x01 /* (to 0x00CA state 162) */, - /* 1 */ 0x1D /* (to 0x0102 state 224) */, -/* pos 00ca: 162 */ /* terminal 61 */ 0x3D, - /* terminal 65 */ 0x41, -/* pos 00cc: 166 */ /* terminal 64 */ 0x40, - /* terminal 91 */ 0x5B, -/* pos 00ce: 170 */ /* terminal 67 */ 0x43, - /* terminal 68 */ 0x44, -/* pos 00d0: 173 */ /* 0 */ 0x01 /* (to 0x00D2 state 174) */, - /* 1 */ 0x08 /* (to 0x00E0 state 189) */, -/* pos 00d2: 174 */ /* 0 */ 0x01 /* (to 0x00D4 state 175) */, - /* 1 */ 0x04 /* (to 0x00DA state 182) */, -/* pos 00d4: 175 */ /* 0 */ 0x01 /* (to 0x00D6 state 176) */, - /* 1 */ 0x02 /* (to 0x00D8 state 179) */, -/* pos 00d6: 176 */ /* terminal 69 */ 0x45, - /* terminal 70 */ 0x46, -/* pos 00d8: 179 */ /* terminal 71 */ 0x47, - /* terminal 72 */ 0x48, -/* pos 00da: 182 */ /* 0 */ 0x01 /* (to 0x00DC state 183) */, - /* 1 */ 0x02 /* (to 0x00DE state 186) */, -/* pos 00dc: 183 */ /* terminal 73 */ 0x49, - /* terminal 74 */ 0x4A, -/* pos 00de: 186 */ /* terminal 75 */ 0x4B, - /* terminal 76 */ 0x4C, -/* pos 00e0: 189 */ /* 0 */ 0x01 /* (to 0x00E2 state 190) */, - /* 1 */ 0x04 /* (to 0x00E8 state 197) */, -/* pos 00e2: 190 */ /* 0 */ 0x01 /* (to 0x00E4 state 191) */, - /* 1 */ 0x02 /* (to 0x00E6 state 194) */, -/* pos 00e4: 191 */ /* terminal 77 */ 0x4D, - /* terminal 78 */ 0x4E, -/* pos 00e6: 194 */ /* terminal 79 */ 0x4F, - /* terminal 80 */ 0x50, -/* pos 00e8: 197 */ /* 0 */ 0x01 /* (to 0x00EA state 198) */, - /* 1 */ 0x02 /* (to 0x00EC state 201) */, -/* pos 00ea: 198 */ /* terminal 81 */ 0x51, - /* terminal 82 */ 0x52, -/* pos 00ec: 201 */ /* terminal 83 */ 0x53, - /* terminal 84 */ 0x54, -/* pos 00ee: 204 */ /* 0 */ 0x01 /* (to 0x00F0 state 205) */, - /* 1 */ 0x11 /* (to 0x0110 state 242) */, -/* pos 00f0: 205 */ /* 0 */ 0x01 /* (to 0x00F2 state 206) */, - /* 1 */ 0x02 /* (to 0x00F4 state 209) */, -/* pos 00f2: 206 */ /* terminal 85 */ 0x55, - /* terminal 86 */ 0x56, -/* pos 00f4: 209 */ /* terminal 87 */ 0x57, - /* terminal 89 */ 0x59, -/* pos 00f6: 211 */ /* terminal 88 */ 0x58, - /* terminal 90 */ 0x5A, -/* pos 00f8: 216 */ /* 0 */ 0x01 /* (to 0x00FA state 217) */, - /* 1 */ 0x1F /* (to 0x0136 state 286) */, -/* pos 00fa: 217 */ /* 0 */ 0x01 /* (to 0x00FC state 218) */, - /* 1 */ 0x17 /* (to 0x0128 state 276) */, -/* pos 00fc: 218 */ /* terminal 92 */ 0x5C, - /* terminal 195 */ 0xC3, -/* pos 00fe: 220 */ /* terminal 93 */ 0x5D, - /* terminal 126 */ 0x7E, -/* pos 0100: 222 */ /* terminal 94 */ 0x5E, - /* terminal 125 */ 0x7D, -/* pos 0102: 224 */ /* terminal 95 */ 0x5F, - /* terminal 98 */ 0x62, -/* pos 0104: 229 */ /* 0 */ 0x01 /* (to 0x0106 state 230) */, - /* 1 */ 0x05 /* (to 0x010E state 240) */, -/* pos 0106: 230 */ /* terminal 99 */ 0x63, - /* terminal 101 */ 0x65, -/* pos 0108: 232 */ /* 0 */ 0x01 /* (to 0x010A state 233) */, - /* 1 */ 0x02 /* (to 0x010C state 237) */, -/* pos 010a: 233 */ /* terminal 100 */ 0x64, - /* terminal 102 */ 0x66, -/* pos 010c: 237 */ /* terminal 103 */ 0x67, - /* terminal 104 */ 0x68, -/* pos 010e: 240 */ /* terminal 105 */ 0x69, - /* terminal 111 */ 0x6F, -/* pos 0110: 242 */ /* 0 */ 0x01 /* (to 0x0112 state 243) */, - /* 1 */ 0x05 /* (to 0x011A state 254) */, -/* pos 0112: 243 */ /* terminal 106 */ 0x6A, - /* terminal 107 */ 0x6B, -/* pos 0114: 246 */ /* 0 */ 0x01 /* (to 0x0116 state 247) */, - /* 1 */ 0x02 /* (to 0x0118 state 250) */, -/* pos 0116: 247 */ /* terminal 108 */ 0x6C, - /* terminal 109 */ 0x6D, -/* pos 0118: 250 */ /* terminal 110 */ 0x6E, - /* terminal 112 */ 0x70, -/* pos 011a: 254 */ /* terminal 113 */ 0x71, - /* terminal 118 */ 0x76, -/* pos 011c: 256 */ /* terminal 114 */ 0x72, - /* terminal 117 */ 0x75, -/* pos 011e: 258 */ /* terminal 115 */ 0x73, - /* terminal 116 */ 0x74, -/* pos 0120: 263 */ /* 0 */ 0x01 /* (to 0x0122 state 264) */, - /* 1 */ 0x02 /* (to 0x0124 state 267) */, -/* pos 0122: 264 */ /* terminal 119 */ 0x77, - /* terminal 120 */ 0x78, -/* pos 0124: 267 */ /* terminal 121 */ 0x79, - /* terminal 122 */ 0x7A, -/* pos 0126: 274 */ /* terminal 127 */ 0x7F, - /* terminal 220 */ 0xDC, -/* pos 0128: 276 */ /* terminal 208 */ 0xD0, - /* 1 */ 0x01 /* (to 0x012A state 277) */, -/* pos 012a: 277 */ /* terminal 128 */ 0x80, - /* terminal 130 */ 0x82, -/* pos 012c: 279 */ /* 0 */ 0x2E /* (to 0x0188 state 372) */, - /* 1 */ 0x01 /* (to 0x012E state 280) */, -/* pos 012e: 280 */ /* 0 */ 0x01 /* (to 0x0130 state 281) */, - /* 1 */ 0x1B /* (to 0x0164 state 332) */, -/* pos 0130: 281 */ /* 0 */ 0x01 /* (to 0x0132 state 282) */, - /* 1 */ 0x06 /* (to 0x013C state 291) */, -/* pos 0132: 282 */ /* terminal 230 */ 0xE6, - /* 1 */ 0x01 /* (to 0x0134 state 283) */, -/* pos 0134: 283 */ /* terminal 129 */ 0x81, - /* terminal 132 */ 0x84, -/* pos 0136: 286 */ /* 0 */ 0x01 /* (to 0x0138 state 287) */, - /* 1 */ 0x14 /* (to 0x015E state 328) */, -/* pos 0138: 287 */ /* 0 */ 0x01 /* (to 0x013A state 288) */, - /* 1 */ 0x30 /* (to 0x0198 state 388) */, -/* pos 013a: 288 */ /* terminal 131 */ 0x83, - /* terminal 162 */ 0xA2, -/* pos 013c: 291 */ /* 0 */ 0x01 /* (to 0x013E state 292) */, - /* 1 */ 0x02 /* (to 0x0140 state 296) */, -/* pos 013e: 292 */ /* terminal 133 */ 0x85, - /* terminal 134 */ 0x86, -/* pos 0140: 296 */ /* terminal 136 */ 0x88, - /* terminal 146 */ 0x92, -/* pos 0142: 298 */ /* terminal 137 */ 0x89, - /* terminal 138 */ 0x8A, -/* pos 0144: 301 */ /* 0 */ 0x01 /* (to 0x0146 state 302) */, - /* 1 */ 0x02 /* (to 0x0148 state 305) */, -/* pos 0146: 302 */ /* terminal 139 */ 0x8B, - /* terminal 140 */ 0x8C, -/* pos 0148: 305 */ /* terminal 141 */ 0x8D, - /* terminal 143 */ 0x8F, -/* pos 014a: 309 */ /* 0 */ 0x01 /* (to 0x014C state 310) */, - /* 1 */ 0x06 /* (to 0x0156 state 319) */, -/* pos 014c: 310 */ /* terminal 144 */ 0x90, - /* terminal 145 */ 0x91, -/* pos 014e: 314 */ /* 0 */ 0x01 /* (to 0x0150 state 315) */, - /* 1 */ 0x12 /* (to 0x0172 state 350) */, -/* pos 0150: 315 */ /* 0 */ 0x01 /* (to 0x0152 state 316) */, - /* 1 */ 0x05 /* (to 0x015A state 325) */, -/* pos 0152: 316 */ /* 0 */ 0x01 /* (to 0x0154 state 317) */, - /* 1 */ 0x03 /* (to 0x0158 state 322) */, -/* pos 0154: 317 */ /* terminal 147 */ 0x93, - /* terminal 149 */ 0x95, -/* pos 0156: 319 */ /* terminal 148 */ 0x94, - /* terminal 159 */ 0x9F, -/* pos 0158: 322 */ /* terminal 150 */ 0x96, - /* terminal 151 */ 0x97, -/* pos 015a: 325 */ /* 0 */ 0x01 /* (to 0x015C state 326) */, - /* 1 */ 0x08 /* (to 0x016A state 338) */, -/* pos 015c: 326 */ /* terminal 152 */ 0x98, - /* terminal 155 */ 0x9B, -/* pos 015e: 328 */ /* 0 */ 0x42 /* (to 0x01E2 state 465) */, - /* 1 */ 0x01 /* (to 0x0160 state 329) */, -/* pos 0160: 329 */ /* 0 */ 0x01 /* (to 0x0162 state 330) */, - /* 1 */ 0x0C /* (to 0x0178 state 355) */, -/* pos 0162: 330 */ /* terminal 153 */ 0x99, - /* terminal 161 */ 0xA1, -/* pos 0164: 332 */ /* 0 */ 0x01 /* (to 0x0166 state 333) */, - /* 1 */ 0x05 /* (to 0x016E state 347) */, -/* pos 0166: 333 */ /* 0 */ 0x01 /* (to 0x0168 state 334) */, - /* 1 */ 0x03 /* (to 0x016C state 342) */, -/* pos 0168: 334 */ /* terminal 154 */ 0x9A, - /* terminal 156 */ 0x9C, -/* pos 016a: 338 */ /* terminal 157 */ 0x9D, - /* terminal 158 */ 0x9E, -/* pos 016c: 342 */ /* terminal 160 */ 0xA0, - /* terminal 163 */ 0xA3, -/* pos 016e: 347 */ /* 0 */ 0x01 /* (to 0x0170 state 348) */, - /* 1 */ 0x07 /* (to 0x017C state 360) */, -/* pos 0170: 348 */ /* terminal 164 */ 0xA4, - /* terminal 169 */ 0xA9, -/* pos 0172: 350 */ /* 0 */ 0x01 /* (to 0x0174 state 351) */, - /* 1 */ 0x09 /* (to 0x0184 state 369) */, -/* pos 0174: 351 */ /* 0 */ 0x01 /* (to 0x0176 state 352) */, - /* 1 */ 0x03 /* (to 0x017A state 357) */, -/* pos 0176: 352 */ /* terminal 165 */ 0xA5, - /* terminal 166 */ 0xA6, -/* pos 0178: 355 */ /* terminal 167 */ 0xA7, - /* terminal 172 */ 0xAC, -/* pos 017a: 357 */ /* terminal 168 */ 0xA8, - /* terminal 174 */ 0xAE, -/* pos 017c: 360 */ /* terminal 170 */ 0xAA, - /* terminal 173 */ 0xAD, -/* pos 017e: 362 */ /* 0 */ 0x01 /* (to 0x0180 state 363) */, - /* 1 */ 0x1B /* (to 0x01B4 state 417) */, -/* pos 0180: 363 */ /* 0 */ 0x01 /* (to 0x0182 state 364) */, - /* 1 */ 0x2A /* (to 0x01D4 state 449) */, -/* pos 0182: 364 */ /* terminal 171 */ 0xAB, - /* terminal 206 */ 0xCE, -/* pos 0184: 369 */ /* 0 */ 0x01 /* (to 0x0186 state 370) */, - /* 1 */ 0x09 /* (to 0x0196 state 385) */, -/* pos 0186: 370 */ /* terminal 175 */ 0xAF, - /* terminal 180 */ 0xB4, -/* pos 0188: 372 */ /* 0 */ 0x01 /* (to 0x018A state 373) */, - /* 1 */ 0x27 /* (to 0x01D6 state 451) */, -/* pos 018a: 373 */ /* 0 */ 0x01 /* (to 0x018C state 374) */, - /* 1 */ 0x05 /* (to 0x0194 state 381) */, -/* pos 018c: 374 */ /* terminal 176 */ 0xB0, - /* terminal 177 */ 0xB1, -/* pos 018e: 377 */ /* 0 */ 0x01 /* (to 0x0190 state 378) */, - /* 1 */ 0x07 /* (to 0x019C state 393) */, -/* pos 0190: 378 */ /* 0 */ 0x01 /* (to 0x0192 state 379) */, - /* 1 */ 0x05 /* (to 0x019A state 390) */, -/* pos 0192: 379 */ /* terminal 178 */ 0xB2, - /* terminal 181 */ 0xB5, -/* pos 0194: 381 */ /* terminal 179 */ 0xB3, - /* terminal 209 */ 0xD1, -/* pos 0196: 385 */ /* terminal 182 */ 0xB6, - /* terminal 183 */ 0xB7, -/* pos 0198: 388 */ /* terminal 184 */ 0xB8, - /* terminal 194 */ 0xC2, -/* pos 019a: 390 */ /* terminal 185 */ 0xB9, - /* terminal 186 */ 0xBA, -/* pos 019c: 393 */ /* 0 */ 0x01 /* (to 0x019E state 394) */, - /* 1 */ 0x04 /* (to 0x01A4 state 400) */, -/* pos 019e: 394 */ /* terminal 187 */ 0xBB, - /* terminal 189 */ 0xBD, -/* pos 01a0: 396 */ /* 0 */ 0x01 /* (to 0x01A2 state 397) */, - /* 1 */ 0x07 /* (to 0x01AE state 412) */, -/* pos 01a2: 397 */ /* terminal 188 */ 0xBC, - /* terminal 191 */ 0xBF, -/* pos 01a4: 400 */ /* terminal 190 */ 0xBE, - /* terminal 196 */ 0xC4, -/* pos 01a6: 403 */ /* 0 */ 0x01 /* (to 0x01A8 state 404) */, - /* 1 */ 0x0D /* (to 0x01C0 state 427) */, -/* pos 01a8: 404 */ /* 0 */ 0x01 /* (to 0x01AA state 405) */, - /* 1 */ 0x0A /* (to 0x01BC state 424) */, -/* pos 01aa: 405 */ /* 0 */ 0x01 /* (to 0x01AC state 406) */, - /* 1 */ 0x08 /* (to 0x01BA state 421) */, -/* pos 01ac: 406 */ /* terminal 192 */ 0xC0, - /* terminal 193 */ 0xC1, -/* pos 01ae: 412 */ /* terminal 197 */ 0xC5, - /* terminal 231 */ 0xE7, -/* pos 01b0: 414 */ /* 0 */ 0x01 /* (to 0x01B2 state 415) */, - /* 1 */ 0x1B /* (to 0x01E6 state 475) */, -/* pos 01b2: 415 */ /* terminal 198 */ 0xC6, - /* terminal 228 */ 0xE4, -/* pos 01b4: 417 */ /* 0 */ 0x1B /* (to 0x01EA state 481) */, - /* 1 */ 0x01 /* (to 0x01B6 state 418) */, -/* pos 01b6: 418 */ /* 0 */ 0x01 /* (to 0x01B8 state 419) */, - /* 1 */ 0x19 /* (to 0x01E8 state 478) */, -/* pos 01b8: 419 */ /* terminal 199 */ 0xC7, - /* terminal 207 */ 0xCF, -/* pos 01ba: 421 */ /* terminal 200 */ 0xC8, - /* terminal 201 */ 0xC9, -/* pos 01bc: 424 */ /* 0 */ 0x01 /* (to 0x01BE state 425) */, - /* 1 */ 0x06 /* (to 0x01C8 state 438) */, -/* pos 01be: 425 */ /* terminal 202 */ 0xCA, - /* terminal 205 */ 0xCD, -/* pos 01c0: 427 */ /* 0 */ 0x0D /* (to 0x01DA state 455) */, - /* 1 */ 0x01 /* (to 0x01C2 state 428) */, -/* pos 01c2: 428 */ /* 0 */ 0x17 /* (to 0x01F0 state 490) */, - /* 1 */ 0x01 /* (to 0x01C4 state 429) */, -/* pos 01c4: 429 */ /* terminal 255 */ 0xFF, - /* 1 */ 0x01 /* (to 0x01C6 state 430) */, -/* pos 01c6: 430 */ /* terminal 203 */ 0xCB, - /* terminal 204 */ 0xCC, -/* pos 01c8: 438 */ /* terminal 210 */ 0xD2, - /* terminal 213 */ 0xD5, -/* pos 01ca: 440 */ /* 0 */ 0x01 /* (to 0x01CC state 441) */, - /* 1 */ 0x14 /* (to 0x01F2 state 494) */, -/* pos 01cc: 441 */ /* 0 */ 0x01 /* (to 0x01CE state 442) */, - /* 1 */ 0x09 /* (to 0x01DE state 461) */, -/* pos 01ce: 442 */ /* 0 */ 0x01 /* (to 0x01D0 state 443) */, - /* 1 */ 0x02 /* (to 0x01D2 state 447) */, -/* pos 01d0: 443 */ /* terminal 211 */ 0xD3, - /* terminal 212 */ 0xD4, -/* pos 01d2: 447 */ /* terminal 214 */ 0xD6, - /* terminal 221 */ 0xDD, -/* pos 01d4: 449 */ /* terminal 215 */ 0xD7, - /* terminal 225 */ 0xE1, -/* pos 01d6: 451 */ /* 0 */ 0x01 /* (to 0x01D8 state 452) */, - /* 1 */ 0x07 /* (to 0x01E4 state 469) */, -/* pos 01d8: 452 */ /* terminal 216 */ 0xD8, - /* terminal 217 */ 0xD9, -/* pos 01da: 455 */ /* 0 */ 0x01 /* (to 0x01DC state 456) */, - /* 1 */ 0x09 /* (to 0x01EC state 484) */, -/* pos 01dc: 456 */ /* terminal 218 */ 0xDA, - /* terminal 219 */ 0xDB, -/* pos 01de: 461 */ /* 0 */ 0x01 /* (to 0x01E0 state 462) */, - /* 1 */ 0x08 /* (to 0x01EE state 488) */, -/* pos 01e0: 462 */ /* terminal 222 */ 0xDE, - /* terminal 223 */ 0xDF, -/* pos 01e2: 465 */ /* terminal 224 */ 0xE0, - /* terminal 226 */ 0xE2, -/* pos 01e4: 469 */ /* terminal 227 */ 0xE3, - /* terminal 229 */ 0xE5, -/* pos 01e6: 475 */ /* terminal 232 */ 0xE8, - /* terminal 233 */ 0xE9, -/* pos 01e8: 478 */ /* terminal 234 */ 0xEA, - /* terminal 235 */ 0xEB, -/* pos 01ea: 481 */ /* terminal 236 */ 0xEC, - /* terminal 237 */ 0xED, -/* pos 01ec: 484 */ /* terminal 238 */ 0xEE, - /* terminal 240 */ 0xF0, -/* pos 01ee: 488 */ /* terminal 241 */ 0xF1, - /* terminal 244 */ 0xF4, -/* pos 01f0: 490 */ /* terminal 242 */ 0xF2, - /* terminal 243 */ 0xF3, -/* pos 01f2: 494 */ /* 0 */ 0x01 /* (to 0x01F4 state 495) */, - /* 1 */ 0x04 /* (to 0x01FA state 503) */, -/* pos 01f4: 495 */ /* 0 */ 0x01 /* (to 0x01F6 state 496) */, - /* 1 */ 0x02 /* (to 0x01F8 state 499) */, -/* pos 01f6: 496 */ /* terminal 245 */ 0xF5, - /* terminal 246 */ 0xF6, -/* pos 01f8: 499 */ /* terminal 247 */ 0xF7, - /* terminal 248 */ 0xF8, -/* pos 01fa: 503 */ /* 0 */ 0x01 /* (to 0x01FC state 504) */, - /* 1 */ 0x02 /* (to 0x01FE state 507) */, -/* pos 01fc: 504 */ /* terminal 250 */ 0xFA, - /* terminal 251 */ 0xFB, -/* pos 01fe: 507 */ /* terminal 252 */ 0xFC, - /* terminal 253 */ 0xFD, -/* total size 512 bytes, biggest jump 200/256, fails=0 */ -}; - - static unsigned char lextable_terms[] = { - - 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, - 0x34, 0x0f, 0x43, 0x03, 0xf1, 0x3c, 0xfc, 0x3c, - 0x0f, 0x30, 0x37, 0xf7, 0x0f, 0xc3, 0xcf, 0x03, - 0x3c, 0xfc, 0xc0, 0xf3, 0xf0, 0x3c, 0xfc, 0xf0, - 0xcf, 0xfc, 0xcc, 0xff, 0xfc, 0x0d, 0x34, 0xcc, - 0xcf, 0x33, 0xf0, 0x33, 0x0c, 0x3f, 0xc3, 0x3f, - 0xcc, 0x30, 0xfc, 0xcf, 0x3c, 0xf0, 0x0c, 0xcf, - 0xd0, 0x03, 0x3f, 0x33, 0xff, 0xff, 0xc3, 0xf3, -}; - -/* state that points to 0x100 for disambiguation with 0x0 */ -#define HUFTABLE_0x100_PREV 118 diff --git a/src/engine/external/libwebsockets/lextable-strings.h b/src/engine/external/libwebsockets/lextable-strings.h deleted file mode 100644 index c0f1f2ee2..000000000 --- a/src/engine/external/libwebsockets/lextable-strings.h +++ /dev/null @@ -1,86 +0,0 @@ -/* set of parsable strings -- ALL LOWER CASE */ - -static const char *set[] = { - "get ", - "post ", - "options ", - "host:", - "connection:", - "upgrade:", - "origin:", - "sec-websocket-draft:", - "\x0d\x0a", - - "sec-websocket-extensions:", - "sec-websocket-key1:", - "sec-websocket-key2:", - "sec-websocket-protocol:", - - "sec-websocket-accept:", - "sec-websocket-nonce:", - "http/1.1 ", - "http2-settings:", - - "accept:", - "access-control-request-headers:", - "if-modified-since:", - "if-none-match:", - "accept-encoding:", - "accept-language:", - "pragma:", - "cache-control:", - "authorization:", - "cookie:", - "content-length:", - "content-type:", - "date:", - "range:", - "referer:", - "sec-websocket-key:", - "sec-websocket-version:", - "sec-websocket-origin:", - - ":authority:", - ":method:", - ":path:", - ":scheme:", - ":status:", - - "accept-charset:", - "accept-ranges:", - "access-control-allow-origin:", - "age:", - "allow:", - "content-disposition:", - "content-encoding:", - "content-language:", - "content-location:", - "content-range:", - "etag:", - "expect:", - "expires:", - "from:", - "if-match:", - "if-range:", - "if-unmodified-since:", - "last-modified:", - "link:", - "location:", - "max-forwards:", - "proxy-authenticate:", - "proxy-authorization:", - "refresh:", - "retry-after:", - "server:", - "set-cookie:", - "strict-transport-security:", - "transfer-encoding:", - "user-agent:", - "vary:", - "via:", - "www-authenticate:", - "proxy ", - - "", /* not matchable */ - -}; diff --git a/src/engine/external/libwebsockets/lextable.h b/src/engine/external/libwebsockets/lextable.h deleted file mode 100644 index 80d318eff..000000000 --- a/src/engine/external/libwebsockets/lextable.h +++ /dev/null @@ -1,745 +0,0 @@ -/* pos 0000: 0 */ 0x67 /* 'g' */, 0x3D, 0x00 /* (to 0x003D state 1) */, - 0x70 /* 'p' */, 0x3F, 0x00 /* (to 0x0042 state 5) */, - 0x6F /* 'o' */, 0x48, 0x00 /* (to 0x004E state 10) */, - 0x68 /* 'h' */, 0x54, 0x00 /* (to 0x005D state 18) */, - 0x63 /* 'c' */, 0x5D, 0x00 /* (to 0x0069 state 23) */, - 0x75 /* 'u' */, 0x78, 0x00 /* (to 0x0087 state 34) */, - 0x73 /* 's' */, 0x8B, 0x00 /* (to 0x009D state 48) */, - 0x0D /* '.' */, 0xC4, 0x00 /* (to 0x00D9 state 68) */, - 0x61 /* 'a' */, 0x16, 0x01 /* (to 0x012E state 129) */, - 0x69 /* 'i' */, 0x55, 0x01 /* (to 0x0170 state 163) */, - 0x64 /* 'd' */, 0xFE, 0x01 /* (to 0x021C state 265) */, - 0x72 /* 'r' */, 0x01, 0x02 /* (to 0x0222 state 270) */, - 0x3A /* ':' */, 0x32, 0x02 /* (to 0x0256 state 299) */, - 0x65 /* 'e' */, 0xC3, 0x02 /* (to 0x02EA state 414) */, - 0x66 /* 'f' */, 0xDF, 0x02 /* (to 0x0309 state 430) */, - 0x6C /* 'l' */, 0x01, 0x03 /* (to 0x032E state 463) */, - 0x6D /* 'm' */, 0x24, 0x03 /* (to 0x0354 state 489) */, - 0x74 /* 't' */, 0x93, 0x03 /* (to 0x03C6 state 583) */, - 0x76 /* 'v' */, 0xAE, 0x03 /* (to 0x03E4 state 611) */, - 0x77 /* 'w' */, 0xBB, 0x03 /* (to 0x03F4 state 619) */, - 0x08, /* fail */ -/* pos 003d: 1 */ 0xE5 /* 'e' -> */, -/* pos 003e: 2 */ 0xF4 /* 't' -> */, -/* pos 003f: 3 */ 0xA0 /* ' ' -> */, -/* pos 0040: 4 */ 0x00, 0x00 /* - terminal marker 0 - */, -/* pos 0042: 5 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0049 state 6) */, - 0x72 /* 'r' */, 0x7D, 0x01 /* (to 0x01C2 state 211) */, - 0x08, /* fail */ -/* pos 0049: 6 */ 0xF3 /* 's' -> */, -/* pos 004a: 7 */ 0xF4 /* 't' -> */, -/* pos 004b: 8 */ 0xA0 /* ' ' -> */, -/* pos 004c: 9 */ 0x00, 0x01 /* - terminal marker 1 - */, -/* pos 004e: 10 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x0055 state 11) */, - 0x72 /* 'r' */, 0x45, 0x00 /* (to 0x0096 state 42) */, - 0x08, /* fail */ -/* pos 0055: 11 */ 0xF4 /* 't' -> */, -/* pos 0056: 12 */ 0xE9 /* 'i' -> */, -/* pos 0057: 13 */ 0xEF /* 'o' -> */, -/* pos 0058: 14 */ 0xEE /* 'n' -> */, -/* pos 0059: 15 */ 0xF3 /* 's' -> */, -/* pos 005a: 16 */ 0xA0 /* ' ' -> */, -/* pos 005b: 17 */ 0x00, 0x02 /* - terminal marker 2 - */, -/* pos 005d: 18 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0064 state 19) */, - 0x74 /* 't' */, 0xB3, 0x00 /* (to 0x0113 state 110) */, - 0x08, /* fail */ -/* pos 0064: 19 */ 0xF3 /* 's' -> */, -/* pos 0065: 20 */ 0xF4 /* 't' -> */, -/* pos 0066: 21 */ 0xBA /* ':' -> */, -/* pos 0067: 22 */ 0x00, 0x03 /* - terminal marker 3 - */, -/* pos 0069: 23 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0070 state 24) */, - 0x61 /* 'a' */, 0x63, 0x01 /* (to 0x01CF state 217) */, - 0x08, /* fail */ -/* pos 0070: 24 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0077 state 25) */, - 0x6F /* 'o' */, 0x78, 0x01 /* (to 0x01EB state 243) */, - 0x08, /* fail */ -/* pos 0077: 25 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x007E state 26) */, - 0x74 /* 't' */, 0x77, 0x01 /* (to 0x01F1 state 248) */, - 0x08, /* fail */ -/* pos 007e: 26 */ 0xE5 /* 'e' -> */, -/* pos 007f: 27 */ 0xE3 /* 'c' -> */, -/* pos 0080: 28 */ 0xF4 /* 't' -> */, -/* pos 0081: 29 */ 0xE9 /* 'i' -> */, -/* pos 0082: 30 */ 0xEF /* 'o' -> */, -/* pos 0083: 31 */ 0xEE /* 'n' -> */, -/* pos 0084: 32 */ 0xBA /* ':' -> */, -/* pos 0085: 33 */ 0x00, 0x04 /* - terminal marker 4 - */, -/* pos 0087: 34 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x008E state 35) */, - 0x73 /* 's' */, 0x4F, 0x03 /* (to 0x03D9 state 601) */, - 0x08, /* fail */ -/* pos 008e: 35 */ 0xE7 /* 'g' -> */, -/* pos 008f: 36 */ 0xF2 /* 'r' -> */, -/* pos 0090: 37 */ 0xE1 /* 'a' -> */, -/* pos 0091: 38 */ 0xE4 /* 'd' -> */, -/* pos 0092: 39 */ 0xE5 /* 'e' -> */, -/* pos 0093: 40 */ 0xBA /* ':' -> */, -/* pos 0094: 41 */ 0x00, 0x05 /* - terminal marker 5 - */, -/* pos 0096: 42 */ 0xE9 /* 'i' -> */, -/* pos 0097: 43 */ 0xE7 /* 'g' -> */, -/* pos 0098: 44 */ 0xE9 /* 'i' -> */, -/* pos 0099: 45 */ 0xEE /* 'n' -> */, -/* pos 009a: 46 */ 0xBA /* ':' -> */, -/* pos 009b: 47 */ 0x00, 0x06 /* - terminal marker 6 - */, -/* pos 009d: 48 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x00A4 state 49) */, - 0x74 /* 't' */, 0x0C, 0x03 /* (to 0x03AC state 558) */, - 0x08, /* fail */ -/* pos 00a4: 49 */ 0x63 /* 'c' */, 0x0A, 0x00 /* (to 0x00AE state 50) */, - 0x72 /* 'r' */, 0xF5, 0x02 /* (to 0x039C state 544) */, - 0x74 /* 't' */, 0xF8, 0x02 /* (to 0x03A2 state 549) */, - 0x08, /* fail */ -/* pos 00ae: 50 */ 0xAD /* '-' -> */, -/* pos 00af: 51 */ 0xF7 /* 'w' -> */, -/* pos 00b0: 52 */ 0xE5 /* 'e' -> */, -/* pos 00b1: 53 */ 0xE2 /* 'b' -> */, -/* pos 00b2: 54 */ 0xF3 /* 's' -> */, -/* pos 00b3: 55 */ 0xEF /* 'o' -> */, -/* pos 00b4: 56 */ 0xE3 /* 'c' -> */, -/* pos 00b5: 57 */ 0xEB /* 'k' -> */, -/* pos 00b6: 58 */ 0xE5 /* 'e' -> */, -/* pos 00b7: 59 */ 0xF4 /* 't' -> */, -/* pos 00b8: 60 */ 0xAD /* '-' -> */, -/* pos 00b9: 61 */ 0x64 /* 'd' */, 0x19, 0x00 /* (to 0x00D2 state 62) */, - 0x65 /* 'e' */, 0x20, 0x00 /* (to 0x00DC state 70) */, - 0x6B /* 'k' */, 0x29, 0x00 /* (to 0x00E8 state 81) */, - 0x70 /* 'p' */, 0x38, 0x00 /* (to 0x00FA state 88) */, - 0x61 /* 'a' */, 0x3F, 0x00 /* (to 0x0104 state 97) */, - 0x6E /* 'n' */, 0x44, 0x00 /* (to 0x010C state 104) */, - 0x76 /* 'v' */, 0x7A, 0x01 /* (to 0x0245 state 284) */, - 0x6F /* 'o' */, 0x80, 0x01 /* (to 0x024E state 292) */, - 0x08, /* fail */ -/* pos 00d2: 62 */ 0xF2 /* 'r' -> */, -/* pos 00d3: 63 */ 0xE1 /* 'a' -> */, -/* pos 00d4: 64 */ 0xE6 /* 'f' -> */, -/* pos 00d5: 65 */ 0xF4 /* 't' -> */, -/* pos 00d6: 66 */ 0xBA /* ':' -> */, -/* pos 00d7: 67 */ 0x00, 0x07 /* - terminal marker 7 - */, -/* pos 00d9: 68 */ 0x8A /* '.' -> */, -/* pos 00da: 69 */ 0x00, 0x08 /* - terminal marker 8 - */, -/* pos 00dc: 70 */ 0xF8 /* 'x' -> */, -/* pos 00dd: 71 */ 0xF4 /* 't' -> */, -/* pos 00de: 72 */ 0xE5 /* 'e' -> */, -/* pos 00df: 73 */ 0xEE /* 'n' -> */, -/* pos 00e0: 74 */ 0xF3 /* 's' -> */, -/* pos 00e1: 75 */ 0xE9 /* 'i' -> */, -/* pos 00e2: 76 */ 0xEF /* 'o' -> */, -/* pos 00e3: 77 */ 0xEE /* 'n' -> */, -/* pos 00e4: 78 */ 0xF3 /* 's' -> */, -/* pos 00e5: 79 */ 0xBA /* ':' -> */, -/* pos 00e6: 80 */ 0x00, 0x09 /* - terminal marker 9 - */, -/* pos 00e8: 81 */ 0xE5 /* 'e' -> */, -/* pos 00e9: 82 */ 0xF9 /* 'y' -> */, -/* pos 00ea: 83 */ 0x31 /* '1' */, 0x0A, 0x00 /* (to 0x00F4 state 84) */, - 0x32 /* '2' */, 0x0A, 0x00 /* (to 0x00F7 state 86) */, - 0x3A /* ':' */, 0x53, 0x01 /* (to 0x0243 state 283) */, - 0x08, /* fail */ -/* pos 00f4: 84 */ 0xBA /* ':' -> */, -/* pos 00f5: 85 */ 0x00, 0x0A /* - terminal marker 10 - */, -/* pos 00f7: 86 */ 0xBA /* ':' -> */, -/* pos 00f8: 87 */ 0x00, 0x0B /* - terminal marker 11 - */, -/* pos 00fa: 88 */ 0xF2 /* 'r' -> */, -/* pos 00fb: 89 */ 0xEF /* 'o' -> */, -/* pos 00fc: 90 */ 0xF4 /* 't' -> */, -/* pos 00fd: 91 */ 0xEF /* 'o' -> */, -/* pos 00fe: 92 */ 0xE3 /* 'c' -> */, -/* pos 00ff: 93 */ 0xEF /* 'o' -> */, -/* pos 0100: 94 */ 0xEC /* 'l' -> */, -/* pos 0101: 95 */ 0xBA /* ':' -> */, -/* pos 0102: 96 */ 0x00, 0x0C /* - terminal marker 12 - */, -/* pos 0104: 97 */ 0xE3 /* 'c' -> */, -/* pos 0105: 98 */ 0xE3 /* 'c' -> */, -/* pos 0106: 99 */ 0xE5 /* 'e' -> */, -/* pos 0107: 100 */ 0xF0 /* 'p' -> */, -/* pos 0108: 101 */ 0xF4 /* 't' -> */, -/* pos 0109: 102 */ 0xBA /* ':' -> */, -/* pos 010a: 103 */ 0x00, 0x0D /* - terminal marker 13 - */, -/* pos 010c: 104 */ 0xEF /* 'o' -> */, -/* pos 010d: 105 */ 0xEE /* 'n' -> */, -/* pos 010e: 106 */ 0xE3 /* 'c' -> */, -/* pos 010f: 107 */ 0xE5 /* 'e' -> */, -/* pos 0110: 108 */ 0xBA /* ':' -> */, -/* pos 0111: 109 */ 0x00, 0x0E /* - terminal marker 14 - */, -/* pos 0113: 110 */ 0xF4 /* 't' -> */, -/* pos 0114: 111 */ 0xF0 /* 'p' -> */, -/* pos 0115: 112 */ 0x2F /* '/' */, 0x07, 0x00 /* (to 0x011C state 113) */, - 0x32 /* '2' */, 0x0A, 0x00 /* (to 0x0122 state 118) */, - 0x08, /* fail */ -/* pos 011c: 113 */ 0xB1 /* '1' -> */, -/* pos 011d: 114 */ 0xAE /* '.' -> */, -/* pos 011e: 115 */ 0xB1 /* '1' -> */, -/* pos 011f: 116 */ 0xA0 /* ' ' -> */, -/* pos 0120: 117 */ 0x00, 0x0F /* - terminal marker 15 - */, -/* pos 0122: 118 */ 0xAD /* '-' -> */, -/* pos 0123: 119 */ 0xF3 /* 's' -> */, -/* pos 0124: 120 */ 0xE5 /* 'e' -> */, -/* pos 0125: 121 */ 0xF4 /* 't' -> */, -/* pos 0126: 122 */ 0xF4 /* 't' -> */, -/* pos 0127: 123 */ 0xE9 /* 'i' -> */, -/* pos 0128: 124 */ 0xEE /* 'n' -> */, -/* pos 0129: 125 */ 0xE7 /* 'g' -> */, -/* pos 012a: 126 */ 0xF3 /* 's' -> */, -/* pos 012b: 127 */ 0xBA /* ':' -> */, -/* pos 012c: 128 */ 0x00, 0x10 /* - terminal marker 16 - */, -/* pos 012e: 129 */ 0x63 /* 'c' */, 0x0D, 0x00 /* (to 0x013B state 130) */, - 0x75 /* 'u' */, 0xAC, 0x00 /* (to 0x01DD state 230) */, - 0x67 /* 'g' */, 0x7C, 0x01 /* (to 0x02B0 state 363) */, - 0x6C /* 'l' */, 0x7D, 0x01 /* (to 0x02B4 state 366) */, - 0x08, /* fail */ -/* pos 013b: 130 */ 0xE3 /* 'c' -> */, -/* pos 013c: 131 */ 0xE5 /* 'e' -> */, -/* pos 013d: 132 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x0144 state 133) */, - 0x73 /* 's' */, 0x0E, 0x00 /* (to 0x014E state 136) */, - 0x08, /* fail */ -/* pos 0144: 133 */ 0xF4 /* 't' -> */, -/* pos 0145: 134 */ 0x3A /* ':' */, 0x07, 0x00 /* (to 0x014C state 135) */, - 0x2D /* '-' */, 0x59, 0x00 /* (to 0x01A1 state 192) */, - 0x08, /* fail */ -/* pos 014c: 135 */ 0x00, 0x11 /* - terminal marker 17 - */, -/* pos 014e: 136 */ 0xF3 /* 's' -> */, -/* pos 014f: 137 */ 0xAD /* '-' -> */, -/* pos 0150: 138 */ 0xE3 /* 'c' -> */, -/* pos 0151: 139 */ 0xEF /* 'o' -> */, -/* pos 0152: 140 */ 0xEE /* 'n' -> */, -/* pos 0153: 141 */ 0xF4 /* 't' -> */, -/* pos 0154: 142 */ 0xF2 /* 'r' -> */, -/* pos 0155: 143 */ 0xEF /* 'o' -> */, -/* pos 0156: 144 */ 0xEC /* 'l' -> */, -/* pos 0157: 145 */ 0xAD /* '-' -> */, -/* pos 0158: 146 */ 0x72 /* 'r' */, 0x07, 0x00 /* (to 0x015F state 147) */, - 0x61 /* 'a' */, 0x47, 0x01 /* (to 0x02A2 state 350) */, - 0x08, /* fail */ -/* pos 015f: 147 */ 0xE5 /* 'e' -> */, -/* pos 0160: 148 */ 0xF1 /* 'q' -> */, -/* pos 0161: 149 */ 0xF5 /* 'u' -> */, -/* pos 0162: 150 */ 0xE5 /* 'e' -> */, -/* pos 0163: 151 */ 0xF3 /* 's' -> */, -/* pos 0164: 152 */ 0xF4 /* 't' -> */, -/* pos 0165: 153 */ 0xAD /* '-' -> */, -/* pos 0166: 154 */ 0xE8 /* 'h' -> */, -/* pos 0167: 155 */ 0xE5 /* 'e' -> */, -/* pos 0168: 156 */ 0xE1 /* 'a' -> */, -/* pos 0169: 157 */ 0xE4 /* 'd' -> */, -/* pos 016a: 158 */ 0xE5 /* 'e' -> */, -/* pos 016b: 159 */ 0xF2 /* 'r' -> */, -/* pos 016c: 160 */ 0xF3 /* 's' -> */, -/* pos 016d: 161 */ 0xBA /* ':' -> */, -/* pos 016e: 162 */ 0x00, 0x12 /* - terminal marker 18 - */, -/* pos 0170: 163 */ 0xE6 /* 'f' -> */, -/* pos 0171: 164 */ 0xAD /* '-' -> */, -/* pos 0172: 165 */ 0x6D /* 'm' */, 0x0D, 0x00 /* (to 0x017F state 166) */, - 0x6E /* 'n' */, 0x20, 0x00 /* (to 0x0195 state 181) */, - 0x72 /* 'r' */, 0x9D, 0x01 /* (to 0x0315 state 440) */, - 0x75 /* 'u' */, 0xA1, 0x01 /* (to 0x031C state 446) */, - 0x08, /* fail */ -/* pos 017f: 166 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0186 state 167) */, - 0x61 /* 'a' */, 0x8D, 0x01 /* (to 0x030F state 435) */, - 0x08, /* fail */ -/* pos 0186: 167 */ 0xE4 /* 'd' -> */, -/* pos 0187: 168 */ 0xE9 /* 'i' -> */, -/* pos 0188: 169 */ 0xE6 /* 'f' -> */, -/* pos 0189: 170 */ 0xE9 /* 'i' -> */, -/* pos 018a: 171 */ 0xE5 /* 'e' -> */, -/* pos 018b: 172 */ 0xE4 /* 'd' -> */, -/* pos 018c: 173 */ 0xAD /* '-' -> */, -/* pos 018d: 174 */ 0xF3 /* 's' -> */, -/* pos 018e: 175 */ 0xE9 /* 'i' -> */, -/* pos 018f: 176 */ 0xEE /* 'n' -> */, -/* pos 0190: 177 */ 0xE3 /* 'c' -> */, -/* pos 0191: 178 */ 0xE5 /* 'e' -> */, -/* pos 0192: 179 */ 0xBA /* ':' -> */, -/* pos 0193: 180 */ 0x00, 0x13 /* - terminal marker 19 - */, -/* pos 0195: 181 */ 0xEF /* 'o' -> */, -/* pos 0196: 182 */ 0xEE /* 'n' -> */, -/* pos 0197: 183 */ 0xE5 /* 'e' -> */, -/* pos 0198: 184 */ 0xAD /* '-' -> */, -/* pos 0199: 185 */ 0xED /* 'm' -> */, -/* pos 019a: 186 */ 0xE1 /* 'a' -> */, -/* pos 019b: 187 */ 0xF4 /* 't' -> */, -/* pos 019c: 188 */ 0xE3 /* 'c' -> */, -/* pos 019d: 189 */ 0xE8 /* 'h' -> */, -/* pos 019e: 190 */ 0xBA /* ':' -> */, -/* pos 019f: 191 */ 0x00, 0x14 /* - terminal marker 20 - */, -/* pos 01a1: 192 */ 0x65 /* 'e' */, 0x0D, 0x00 /* (to 0x01AE state 193) */, - 0x6C /* 'l' */, 0x14, 0x00 /* (to 0x01B8 state 202) */, - 0x63 /* 'c' */, 0xEA, 0x00 /* (to 0x0291 state 335) */, - 0x72 /* 'r' */, 0xF0, 0x00 /* (to 0x029A state 343) */, - 0x08, /* fail */ -/* pos 01ae: 193 */ 0xEE /* 'n' -> */, -/* pos 01af: 194 */ 0xE3 /* 'c' -> */, -/* pos 01b0: 195 */ 0xEF /* 'o' -> */, -/* pos 01b1: 196 */ 0xE4 /* 'd' -> */, -/* pos 01b2: 197 */ 0xE9 /* 'i' -> */, -/* pos 01b3: 198 */ 0xEE /* 'n' -> */, -/* pos 01b4: 199 */ 0xE7 /* 'g' -> */, -/* pos 01b5: 200 */ 0xBA /* ':' -> */, -/* pos 01b6: 201 */ 0x00, 0x15 /* - terminal marker 21 - */, -/* pos 01b8: 202 */ 0xE1 /* 'a' -> */, -/* pos 01b9: 203 */ 0xEE /* 'n' -> */, -/* pos 01ba: 204 */ 0xE7 /* 'g' -> */, -/* pos 01bb: 205 */ 0xF5 /* 'u' -> */, -/* pos 01bc: 206 */ 0xE1 /* 'a' -> */, -/* pos 01bd: 207 */ 0xE7 /* 'g' -> */, -/* pos 01be: 208 */ 0xE5 /* 'e' -> */, -/* pos 01bf: 209 */ 0xBA /* ':' -> */, -/* pos 01c0: 210 */ 0x00, 0x16 /* - terminal marker 22 - */, -/* pos 01c2: 211 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x01C9 state 212) */, - 0x6F /* 'o' */, 0x9D, 0x01 /* (to 0x0362 state 502) */, - 0x08, /* fail */ -/* pos 01c9: 212 */ 0xE7 /* 'g' -> */, -/* pos 01ca: 213 */ 0xED /* 'm' -> */, -/* pos 01cb: 214 */ 0xE1 /* 'a' -> */, -/* pos 01cc: 215 */ 0xBA /* ':' -> */, -/* pos 01cd: 216 */ 0x00, 0x17 /* - terminal marker 23 - */, -/* pos 01cf: 217 */ 0xE3 /* 'c' -> */, -/* pos 01d0: 218 */ 0xE8 /* 'h' -> */, -/* pos 01d1: 219 */ 0xE5 /* 'e' -> */, -/* pos 01d2: 220 */ 0xAD /* '-' -> */, -/* pos 01d3: 221 */ 0xE3 /* 'c' -> */, -/* pos 01d4: 222 */ 0xEF /* 'o' -> */, -/* pos 01d5: 223 */ 0xEE /* 'n' -> */, -/* pos 01d6: 224 */ 0xF4 /* 't' -> */, -/* pos 01d7: 225 */ 0xF2 /* 'r' -> */, -/* pos 01d8: 226 */ 0xEF /* 'o' -> */, -/* pos 01d9: 227 */ 0xEC /* 'l' -> */, -/* pos 01da: 228 */ 0xBA /* ':' -> */, -/* pos 01db: 229 */ 0x00, 0x18 /* - terminal marker 24 - */, -/* pos 01dd: 230 */ 0xF4 /* 't' -> */, -/* pos 01de: 231 */ 0xE8 /* 'h' -> */, -/* pos 01df: 232 */ 0xEF /* 'o' -> */, -/* pos 01e0: 233 */ 0xF2 /* 'r' -> */, -/* pos 01e1: 234 */ 0xE9 /* 'i' -> */, -/* pos 01e2: 235 */ 0xFA /* 'z' -> */, -/* pos 01e3: 236 */ 0xE1 /* 'a' -> */, -/* pos 01e4: 237 */ 0xF4 /* 't' -> */, -/* pos 01e5: 238 */ 0xE9 /* 'i' -> */, -/* pos 01e6: 239 */ 0xEF /* 'o' -> */, -/* pos 01e7: 240 */ 0xEE /* 'n' -> */, -/* pos 01e8: 241 */ 0xBA /* ':' -> */, -/* pos 01e9: 242 */ 0x00, 0x19 /* - terminal marker 25 - */, -/* pos 01eb: 243 */ 0xEB /* 'k' -> */, -/* pos 01ec: 244 */ 0xE9 /* 'i' -> */, -/* pos 01ed: 245 */ 0xE5 /* 'e' -> */, -/* pos 01ee: 246 */ 0xBA /* ':' -> */, -/* pos 01ef: 247 */ 0x00, 0x1A /* - terminal marker 26 - */, -/* pos 01f1: 248 */ 0xE5 /* 'e' -> */, -/* pos 01f2: 249 */ 0xEE /* 'n' -> */, -/* pos 01f3: 250 */ 0xF4 /* 't' -> */, -/* pos 01f4: 251 */ 0xAD /* '-' -> */, -/* pos 01f5: 252 */ 0x6C /* 'l' */, 0x10, 0x00 /* (to 0x0205 state 253) */, - 0x74 /* 't' */, 0x1E, 0x00 /* (to 0x0216 state 260) */, - 0x64 /* 'd' */, 0xBF, 0x00 /* (to 0x02BA state 371) */, - 0x65 /* 'e' */, 0xC9, 0x00 /* (to 0x02C7 state 383) */, - 0x72 /* 'r' */, 0xE2, 0x00 /* (to 0x02E3 state 408) */, - 0x08, /* fail */ -/* pos 0205: 253 */ 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x020F state 254) */, - 0x61 /* 'a' */, 0xC9, 0x00 /* (to 0x02D1 state 392) */, - 0x6F /* 'o' */, 0xCF, 0x00 /* (to 0x02DA state 400) */, - 0x08, /* fail */ -/* pos 020f: 254 */ 0xEE /* 'n' -> */, -/* pos 0210: 255 */ 0xE7 /* 'g' -> */, -/* pos 0211: 256 */ 0xF4 /* 't' -> */, -/* pos 0212: 257 */ 0xE8 /* 'h' -> */, -/* pos 0213: 258 */ 0xBA /* ':' -> */, -/* pos 0214: 259 */ 0x00, 0x1B /* - terminal marker 27 - */, -/* pos 0216: 260 */ 0xF9 /* 'y' -> */, -/* pos 0217: 261 */ 0xF0 /* 'p' -> */, -/* pos 0218: 262 */ 0xE5 /* 'e' -> */, -/* pos 0219: 263 */ 0xBA /* ':' -> */, -/* pos 021a: 264 */ 0x00, 0x1C /* - terminal marker 28 - */, -/* pos 021c: 265 */ 0xE1 /* 'a' -> */, -/* pos 021d: 266 */ 0xF4 /* 't' -> */, -/* pos 021e: 267 */ 0xE5 /* 'e' -> */, -/* pos 021f: 268 */ 0xBA /* ':' -> */, -/* pos 0220: 269 */ 0x00, 0x1D /* - terminal marker 29 - */, -/* pos 0222: 270 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0229 state 271) */, - 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x022F state 276) */, - 0x08, /* fail */ -/* pos 0229: 271 */ 0xEE /* 'n' -> */, -/* pos 022a: 272 */ 0xE7 /* 'g' -> */, -/* pos 022b: 273 */ 0xE5 /* 'e' -> */, -/* pos 022c: 274 */ 0xBA /* ':' -> */, -/* pos 022d: 275 */ 0x00, 0x1E /* - terminal marker 30 - */, -/* pos 022f: 276 */ 0x66 /* 'f' */, 0x07, 0x00 /* (to 0x0236 state 277) */, - 0x74 /* 't' */, 0x5F, 0x01 /* (to 0x0391 state 534) */, - 0x08, /* fail */ -/* pos 0236: 277 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x023D state 278) */, - 0x72 /* 'r' */, 0x52, 0x01 /* (to 0x038B state 529) */, - 0x08, /* fail */ -/* pos 023d: 278 */ 0xF2 /* 'r' -> */, -/* pos 023e: 279 */ 0xE5 /* 'e' -> */, -/* pos 023f: 280 */ 0xF2 /* 'r' -> */, -/* pos 0240: 281 */ 0xBA /* ':' -> */, -/* pos 0241: 282 */ 0x00, 0x1F /* - terminal marker 31 - */, -/* pos 0243: 283 */ 0x00, 0x20 /* - terminal marker 32 - */, -/* pos 0245: 284 */ 0xE5 /* 'e' -> */, -/* pos 0246: 285 */ 0xF2 /* 'r' -> */, -/* pos 0247: 286 */ 0xF3 /* 's' -> */, -/* pos 0248: 287 */ 0xE9 /* 'i' -> */, -/* pos 0249: 288 */ 0xEF /* 'o' -> */, -/* pos 024a: 289 */ 0xEE /* 'n' -> */, -/* pos 024b: 290 */ 0xBA /* ':' -> */, -/* pos 024c: 291 */ 0x00, 0x21 /* - terminal marker 33 - */, -/* pos 024e: 292 */ 0xF2 /* 'r' -> */, -/* pos 024f: 293 */ 0xE9 /* 'i' -> */, -/* pos 0250: 294 */ 0xE7 /* 'g' -> */, -/* pos 0251: 295 */ 0xE9 /* 'i' -> */, -/* pos 0252: 296 */ 0xEE /* 'n' -> */, -/* pos 0253: 297 */ 0xBA /* ':' -> */, -/* pos 0254: 298 */ 0x00, 0x22 /* - terminal marker 34 - */, -/* pos 0256: 299 */ 0x61 /* 'a' */, 0x0D, 0x00 /* (to 0x0263 state 300) */, - 0x6D /* 'm' */, 0x15, 0x00 /* (to 0x026E state 310) */, - 0x70 /* 'p' */, 0x1A, 0x00 /* (to 0x0276 state 317) */, - 0x73 /* 's' */, 0x1D, 0x00 /* (to 0x027C state 322) */, - 0x08, /* fail */ -/* pos 0263: 300 */ 0xF5 /* 'u' -> */, -/* pos 0264: 301 */ 0xF4 /* 't' -> */, -/* pos 0265: 302 */ 0xE8 /* 'h' -> */, -/* pos 0266: 303 */ 0xEF /* 'o' -> */, -/* pos 0267: 304 */ 0xF2 /* 'r' -> */, -/* pos 0268: 305 */ 0xE9 /* 'i' -> */, -/* pos 0269: 306 */ 0xF4 /* 't' -> */, -/* pos 026a: 307 */ 0xF9 /* 'y' -> */, -/* pos 026b: 308 */ 0xBA /* ':' -> */, -/* pos 026c: 309 */ 0x00, 0x23 /* - terminal marker 35 - */, -/* pos 026e: 310 */ 0xE5 /* 'e' -> */, -/* pos 026f: 311 */ 0xF4 /* 't' -> */, -/* pos 0270: 312 */ 0xE8 /* 'h' -> */, -/* pos 0271: 313 */ 0xEF /* 'o' -> */, -/* pos 0272: 314 */ 0xE4 /* 'd' -> */, -/* pos 0273: 315 */ 0xBA /* ':' -> */, -/* pos 0274: 316 */ 0x00, 0x24 /* - terminal marker 36 - */, -/* pos 0276: 317 */ 0xE1 /* 'a' -> */, -/* pos 0277: 318 */ 0xF4 /* 't' -> */, -/* pos 0278: 319 */ 0xE8 /* 'h' -> */, -/* pos 0279: 320 */ 0xBA /* ':' -> */, -/* pos 027a: 321 */ 0x00, 0x25 /* - terminal marker 37 - */, -/* pos 027c: 322 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x0283 state 323) */, - 0x74 /* 't' */, 0x0B, 0x00 /* (to 0x028A state 329) */, - 0x08, /* fail */ -/* pos 0283: 323 */ 0xE8 /* 'h' -> */, -/* pos 0284: 324 */ 0xE5 /* 'e' -> */, -/* pos 0285: 325 */ 0xED /* 'm' -> */, -/* pos 0286: 326 */ 0xE5 /* 'e' -> */, -/* pos 0287: 327 */ 0xBA /* ':' -> */, -/* pos 0288: 328 */ 0x00, 0x26 /* - terminal marker 38 - */, -/* pos 028a: 329 */ 0xE1 /* 'a' -> */, -/* pos 028b: 330 */ 0xF4 /* 't' -> */, -/* pos 028c: 331 */ 0xF5 /* 'u' -> */, -/* pos 028d: 332 */ 0xF3 /* 's' -> */, -/* pos 028e: 333 */ 0xBA /* ':' -> */, -/* pos 028f: 334 */ 0x00, 0x27 /* - terminal marker 39 - */, -/* pos 0291: 335 */ 0xE8 /* 'h' -> */, -/* pos 0292: 336 */ 0xE1 /* 'a' -> */, -/* pos 0293: 337 */ 0xF2 /* 'r' -> */, -/* pos 0294: 338 */ 0xF3 /* 's' -> */, -/* pos 0295: 339 */ 0xE5 /* 'e' -> */, -/* pos 0296: 340 */ 0xF4 /* 't' -> */, -/* pos 0297: 341 */ 0xBA /* ':' -> */, -/* pos 0298: 342 */ 0x00, 0x28 /* - terminal marker 40 - */, -/* pos 029a: 343 */ 0xE1 /* 'a' -> */, -/* pos 029b: 344 */ 0xEE /* 'n' -> */, -/* pos 029c: 345 */ 0xE7 /* 'g' -> */, -/* pos 029d: 346 */ 0xE5 /* 'e' -> */, -/* pos 029e: 347 */ 0xF3 /* 's' -> */, -/* pos 029f: 348 */ 0xBA /* ':' -> */, -/* pos 02a0: 349 */ 0x00, 0x29 /* - terminal marker 41 - */, -/* pos 02a2: 350 */ 0xEC /* 'l' -> */, -/* pos 02a3: 351 */ 0xEC /* 'l' -> */, -/* pos 02a4: 352 */ 0xEF /* 'o' -> */, -/* pos 02a5: 353 */ 0xF7 /* 'w' -> */, -/* pos 02a6: 354 */ 0xAD /* '-' -> */, -/* pos 02a7: 355 */ 0xEF /* 'o' -> */, -/* pos 02a8: 356 */ 0xF2 /* 'r' -> */, -/* pos 02a9: 357 */ 0xE9 /* 'i' -> */, -/* pos 02aa: 358 */ 0xE7 /* 'g' -> */, -/* pos 02ab: 359 */ 0xE9 /* 'i' -> */, -/* pos 02ac: 360 */ 0xEE /* 'n' -> */, -/* pos 02ad: 361 */ 0xBA /* ':' -> */, -/* pos 02ae: 362 */ 0x00, 0x2A /* - terminal marker 42 - */, -/* pos 02b0: 363 */ 0xE5 /* 'e' -> */, -/* pos 02b1: 364 */ 0xBA /* ':' -> */, -/* pos 02b2: 365 */ 0x00, 0x2B /* - terminal marker 43 - */, -/* pos 02b4: 366 */ 0xEC /* 'l' -> */, -/* pos 02b5: 367 */ 0xEF /* 'o' -> */, -/* pos 02b6: 368 */ 0xF7 /* 'w' -> */, -/* pos 02b7: 369 */ 0xBA /* ':' -> */, -/* pos 02b8: 370 */ 0x00, 0x2C /* - terminal marker 44 - */, -/* pos 02ba: 371 */ 0xE9 /* 'i' -> */, -/* pos 02bb: 372 */ 0xF3 /* 's' -> */, -/* pos 02bc: 373 */ 0xF0 /* 'p' -> */, -/* pos 02bd: 374 */ 0xEF /* 'o' -> */, -/* pos 02be: 375 */ 0xF3 /* 's' -> */, -/* pos 02bf: 376 */ 0xE9 /* 'i' -> */, -/* pos 02c0: 377 */ 0xF4 /* 't' -> */, -/* pos 02c1: 378 */ 0xE9 /* 'i' -> */, -/* pos 02c2: 379 */ 0xEF /* 'o' -> */, -/* pos 02c3: 380 */ 0xEE /* 'n' -> */, -/* pos 02c4: 381 */ 0xBA /* ':' -> */, -/* pos 02c5: 382 */ 0x00, 0x2D /* - terminal marker 45 - */, -/* pos 02c7: 383 */ 0xEE /* 'n' -> */, -/* pos 02c8: 384 */ 0xE3 /* 'c' -> */, -/* pos 02c9: 385 */ 0xEF /* 'o' -> */, -/* pos 02ca: 386 */ 0xE4 /* 'd' -> */, -/* pos 02cb: 387 */ 0xE9 /* 'i' -> */, -/* pos 02cc: 388 */ 0xEE /* 'n' -> */, -/* pos 02cd: 389 */ 0xE7 /* 'g' -> */, -/* pos 02ce: 390 */ 0xBA /* ':' -> */, -/* pos 02cf: 391 */ 0x00, 0x2E /* - terminal marker 46 - */, -/* pos 02d1: 392 */ 0xEE /* 'n' -> */, -/* pos 02d2: 393 */ 0xE7 /* 'g' -> */, -/* pos 02d3: 394 */ 0xF5 /* 'u' -> */, -/* pos 02d4: 395 */ 0xE1 /* 'a' -> */, -/* pos 02d5: 396 */ 0xE7 /* 'g' -> */, -/* pos 02d6: 397 */ 0xE5 /* 'e' -> */, -/* pos 02d7: 398 */ 0xBA /* ':' -> */, -/* pos 02d8: 399 */ 0x00, 0x2F /* - terminal marker 47 - */, -/* pos 02da: 400 */ 0xE3 /* 'c' -> */, -/* pos 02db: 401 */ 0xE1 /* 'a' -> */, -/* pos 02dc: 402 */ 0xF4 /* 't' -> */, -/* pos 02dd: 403 */ 0xE9 /* 'i' -> */, -/* pos 02de: 404 */ 0xEF /* 'o' -> */, -/* pos 02df: 405 */ 0xEE /* 'n' -> */, -/* pos 02e0: 406 */ 0xBA /* ':' -> */, -/* pos 02e1: 407 */ 0x00, 0x30 /* - terminal marker 48 - */, -/* pos 02e3: 408 */ 0xE1 /* 'a' -> */, -/* pos 02e4: 409 */ 0xEE /* 'n' -> */, -/* pos 02e5: 410 */ 0xE7 /* 'g' -> */, -/* pos 02e6: 411 */ 0xE5 /* 'e' -> */, -/* pos 02e7: 412 */ 0xBA /* ':' -> */, -/* pos 02e8: 413 */ 0x00, 0x31 /* - terminal marker 49 - */, -/* pos 02ea: 414 */ 0x74 /* 't' */, 0x07, 0x00 /* (to 0x02F1 state 415) */, - 0x78 /* 'x' */, 0x09, 0x00 /* (to 0x02F6 state 419) */, - 0x08, /* fail */ -/* pos 02f1: 415 */ 0xE1 /* 'a' -> */, -/* pos 02f2: 416 */ 0xE7 /* 'g' -> */, -/* pos 02f3: 417 */ 0xBA /* ':' -> */, -/* pos 02f4: 418 */ 0x00, 0x32 /* - terminal marker 50 - */, -/* pos 02f6: 419 */ 0xF0 /* 'p' -> */, -/* pos 02f7: 420 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x02FE state 421) */, - 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x0303 state 425) */, - 0x08, /* fail */ -/* pos 02fe: 421 */ 0xE3 /* 'c' -> */, -/* pos 02ff: 422 */ 0xF4 /* 't' -> */, -/* pos 0300: 423 */ 0xBA /* ':' -> */, -/* pos 0301: 424 */ 0x00, 0x33 /* - terminal marker 51 - */, -/* pos 0303: 425 */ 0xF2 /* 'r' -> */, -/* pos 0304: 426 */ 0xE5 /* 'e' -> */, -/* pos 0305: 427 */ 0xF3 /* 's' -> */, -/* pos 0306: 428 */ 0xBA /* ':' -> */, -/* pos 0307: 429 */ 0x00, 0x34 /* - terminal marker 52 - */, -/* pos 0309: 430 */ 0xF2 /* 'r' -> */, -/* pos 030a: 431 */ 0xEF /* 'o' -> */, -/* pos 030b: 432 */ 0xED /* 'm' -> */, -/* pos 030c: 433 */ 0xBA /* ':' -> */, -/* pos 030d: 434 */ 0x00, 0x35 /* - terminal marker 53 - */, -/* pos 030f: 435 */ 0xF4 /* 't' -> */, -/* pos 0310: 436 */ 0xE3 /* 'c' -> */, -/* pos 0311: 437 */ 0xE8 /* 'h' -> */, -/* pos 0312: 438 */ 0xBA /* ':' -> */, -/* pos 0313: 439 */ 0x00, 0x36 /* - terminal marker 54 - */, -/* pos 0315: 440 */ 0xE1 /* 'a' -> */, -/* pos 0316: 441 */ 0xEE /* 'n' -> */, -/* pos 0317: 442 */ 0xE7 /* 'g' -> */, -/* pos 0318: 443 */ 0xE5 /* 'e' -> */, -/* pos 0319: 444 */ 0xBA /* ':' -> */, -/* pos 031a: 445 */ 0x00, 0x37 /* - terminal marker 55 - */, -/* pos 031c: 446 */ 0xEE /* 'n' -> */, -/* pos 031d: 447 */ 0xED /* 'm' -> */, -/* pos 031e: 448 */ 0xEF /* 'o' -> */, -/* pos 031f: 449 */ 0xE4 /* 'd' -> */, -/* pos 0320: 450 */ 0xE9 /* 'i' -> */, -/* pos 0321: 451 */ 0xE6 /* 'f' -> */, -/* pos 0322: 452 */ 0xE9 /* 'i' -> */, -/* pos 0323: 453 */ 0xE5 /* 'e' -> */, -/* pos 0324: 454 */ 0xE4 /* 'd' -> */, -/* pos 0325: 455 */ 0xAD /* '-' -> */, -/* pos 0326: 456 */ 0xF3 /* 's' -> */, -/* pos 0327: 457 */ 0xE9 /* 'i' -> */, -/* pos 0328: 458 */ 0xEE /* 'n' -> */, -/* pos 0329: 459 */ 0xE3 /* 'c' -> */, -/* pos 032a: 460 */ 0xE5 /* 'e' -> */, -/* pos 032b: 461 */ 0xBA /* ':' -> */, -/* pos 032c: 462 */ 0x00, 0x38 /* - terminal marker 56 - */, -/* pos 032e: 463 */ 0x61 /* 'a' */, 0x0A, 0x00 /* (to 0x0338 state 464) */, - 0x69 /* 'i' */, 0x15, 0x00 /* (to 0x0346 state 477) */, - 0x6F /* 'o' */, 0x17, 0x00 /* (to 0x034B state 481) */, - 0x08, /* fail */ -/* pos 0338: 464 */ 0xF3 /* 's' -> */, -/* pos 0339: 465 */ 0xF4 /* 't' -> */, -/* pos 033a: 466 */ 0xAD /* '-' -> */, -/* pos 033b: 467 */ 0xED /* 'm' -> */, -/* pos 033c: 468 */ 0xEF /* 'o' -> */, -/* pos 033d: 469 */ 0xE4 /* 'd' -> */, -/* pos 033e: 470 */ 0xE9 /* 'i' -> */, -/* pos 033f: 471 */ 0xE6 /* 'f' -> */, -/* pos 0340: 472 */ 0xE9 /* 'i' -> */, -/* pos 0341: 473 */ 0xE5 /* 'e' -> */, -/* pos 0342: 474 */ 0xE4 /* 'd' -> */, -/* pos 0343: 475 */ 0xBA /* ':' -> */, -/* pos 0344: 476 */ 0x00, 0x39 /* - terminal marker 57 - */, -/* pos 0346: 477 */ 0xEE /* 'n' -> */, -/* pos 0347: 478 */ 0xEB /* 'k' -> */, -/* pos 0348: 479 */ 0xBA /* ':' -> */, -/* pos 0349: 480 */ 0x00, 0x3A /* - terminal marker 58 - */, -/* pos 034b: 481 */ 0xE3 /* 'c' -> */, -/* pos 034c: 482 */ 0xE1 /* 'a' -> */, -/* pos 034d: 483 */ 0xF4 /* 't' -> */, -/* pos 034e: 484 */ 0xE9 /* 'i' -> */, -/* pos 034f: 485 */ 0xEF /* 'o' -> */, -/* pos 0350: 486 */ 0xEE /* 'n' -> */, -/* pos 0351: 487 */ 0xBA /* ':' -> */, -/* pos 0352: 488 */ 0x00, 0x3B /* - terminal marker 59 - */, -/* pos 0354: 489 */ 0xE1 /* 'a' -> */, -/* pos 0355: 490 */ 0xF8 /* 'x' -> */, -/* pos 0356: 491 */ 0xAD /* '-' -> */, -/* pos 0357: 492 */ 0xE6 /* 'f' -> */, -/* pos 0358: 493 */ 0xEF /* 'o' -> */, -/* pos 0359: 494 */ 0xF2 /* 'r' -> */, -/* pos 035a: 495 */ 0xF7 /* 'w' -> */, -/* pos 035b: 496 */ 0xE1 /* 'a' -> */, -/* pos 035c: 497 */ 0xF2 /* 'r' -> */, -/* pos 035d: 498 */ 0xE4 /* 'd' -> */, -/* pos 035e: 499 */ 0xF3 /* 's' -> */, -/* pos 035f: 500 */ 0xBA /* ':' -> */, -/* pos 0360: 501 */ 0x00, 0x3C /* - terminal marker 60 - */, -/* pos 0362: 502 */ 0xF8 /* 'x' -> */, -/* pos 0363: 503 */ 0xF9 /* 'y' -> */, -/* pos 0364: 504 */ 0x2D /* '-' */, 0x07, 0x00 /* (to 0x036B state 505) */, - 0x20 /* ' ' */, 0x9F, 0x00 /* (to 0x0406 state 636) */, - 0x08, /* fail */ -/* pos 036b: 505 */ 0xE1 /* 'a' -> */, -/* pos 036c: 506 */ 0xF5 /* 'u' -> */, -/* pos 036d: 507 */ 0xF4 /* 't' -> */, -/* pos 036e: 508 */ 0xE8 /* 'h' -> */, -/* pos 036f: 509 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0376 state 510) */, - 0x6F /* 'o' */, 0x0E, 0x00 /* (to 0x0380 state 519) */, - 0x08, /* fail */ -/* pos 0376: 510 */ 0xEE /* 'n' -> */, -/* pos 0377: 511 */ 0xF4 /* 't' -> */, -/* pos 0378: 512 */ 0xE9 /* 'i' -> */, -/* pos 0379: 513 */ 0xE3 /* 'c' -> */, -/* pos 037a: 514 */ 0xE1 /* 'a' -> */, -/* pos 037b: 515 */ 0xF4 /* 't' -> */, -/* pos 037c: 516 */ 0xE5 /* 'e' -> */, -/* pos 037d: 517 */ 0xBA /* ':' -> */, -/* pos 037e: 518 */ 0x00, 0x3D /* - terminal marker 61 - */, -/* pos 0380: 519 */ 0xF2 /* 'r' -> */, -/* pos 0381: 520 */ 0xE9 /* 'i' -> */, -/* pos 0382: 521 */ 0xFA /* 'z' -> */, -/* pos 0383: 522 */ 0xE1 /* 'a' -> */, -/* pos 0384: 523 */ 0xF4 /* 't' -> */, -/* pos 0385: 524 */ 0xE9 /* 'i' -> */, -/* pos 0386: 525 */ 0xEF /* 'o' -> */, -/* pos 0387: 526 */ 0xEE /* 'n' -> */, -/* pos 0388: 527 */ 0xBA /* ':' -> */, -/* pos 0389: 528 */ 0x00, 0x3E /* - terminal marker 62 - */, -/* pos 038b: 529 */ 0xE5 /* 'e' -> */, -/* pos 038c: 530 */ 0xF3 /* 's' -> */, -/* pos 038d: 531 */ 0xE8 /* 'h' -> */, -/* pos 038e: 532 */ 0xBA /* ':' -> */, -/* pos 038f: 533 */ 0x00, 0x3F /* - terminal marker 63 - */, -/* pos 0391: 534 */ 0xF2 /* 'r' -> */, -/* pos 0392: 535 */ 0xF9 /* 'y' -> */, -/* pos 0393: 536 */ 0xAD /* '-' -> */, -/* pos 0394: 537 */ 0xE1 /* 'a' -> */, -/* pos 0395: 538 */ 0xE6 /* 'f' -> */, -/* pos 0396: 539 */ 0xF4 /* 't' -> */, -/* pos 0397: 540 */ 0xE5 /* 'e' -> */, -/* pos 0398: 541 */ 0xF2 /* 'r' -> */, -/* pos 0399: 542 */ 0xBA /* ':' -> */, -/* pos 039a: 543 */ 0x00, 0x40 /* - terminal marker 64 - */, -/* pos 039c: 544 */ 0xF6 /* 'v' -> */, -/* pos 039d: 545 */ 0xE5 /* 'e' -> */, -/* pos 039e: 546 */ 0xF2 /* 'r' -> */, -/* pos 039f: 547 */ 0xBA /* ':' -> */, -/* pos 03a0: 548 */ 0x00, 0x41 /* - terminal marker 65 - */, -/* pos 03a2: 549 */ 0xAD /* '-' -> */, -/* pos 03a3: 550 */ 0xE3 /* 'c' -> */, -/* pos 03a4: 551 */ 0xEF /* 'o' -> */, -/* pos 03a5: 552 */ 0xEF /* 'o' -> */, -/* pos 03a6: 553 */ 0xEB /* 'k' -> */, -/* pos 03a7: 554 */ 0xE9 /* 'i' -> */, -/* pos 03a8: 555 */ 0xE5 /* 'e' -> */, -/* pos 03a9: 556 */ 0xBA /* ':' -> */, -/* pos 03aa: 557 */ 0x00, 0x42 /* - terminal marker 66 - */, -/* pos 03ac: 558 */ 0xF2 /* 'r' -> */, -/* pos 03ad: 559 */ 0xE9 /* 'i' -> */, -/* pos 03ae: 560 */ 0xE3 /* 'c' -> */, -/* pos 03af: 561 */ 0xF4 /* 't' -> */, -/* pos 03b0: 562 */ 0xAD /* '-' -> */, -/* pos 03b1: 563 */ 0xF4 /* 't' -> */, -/* pos 03b2: 564 */ 0xF2 /* 'r' -> */, -/* pos 03b3: 565 */ 0xE1 /* 'a' -> */, -/* pos 03b4: 566 */ 0xEE /* 'n' -> */, -/* pos 03b5: 567 */ 0xF3 /* 's' -> */, -/* pos 03b6: 568 */ 0xF0 /* 'p' -> */, -/* pos 03b7: 569 */ 0xEF /* 'o' -> */, -/* pos 03b8: 570 */ 0xF2 /* 'r' -> */, -/* pos 03b9: 571 */ 0xF4 /* 't' -> */, -/* pos 03ba: 572 */ 0xAD /* '-' -> */, -/* pos 03bb: 573 */ 0xF3 /* 's' -> */, -/* pos 03bc: 574 */ 0xE5 /* 'e' -> */, -/* pos 03bd: 575 */ 0xE3 /* 'c' -> */, -/* pos 03be: 576 */ 0xF5 /* 'u' -> */, -/* pos 03bf: 577 */ 0xF2 /* 'r' -> */, -/* pos 03c0: 578 */ 0xE9 /* 'i' -> */, -/* pos 03c1: 579 */ 0xF4 /* 't' -> */, -/* pos 03c2: 580 */ 0xF9 /* 'y' -> */, -/* pos 03c3: 581 */ 0xBA /* ':' -> */, -/* pos 03c4: 582 */ 0x00, 0x43 /* - terminal marker 67 - */, -/* pos 03c6: 583 */ 0xF2 /* 'r' -> */, -/* pos 03c7: 584 */ 0xE1 /* 'a' -> */, -/* pos 03c8: 585 */ 0xEE /* 'n' -> */, -/* pos 03c9: 586 */ 0xF3 /* 's' -> */, -/* pos 03ca: 587 */ 0xE6 /* 'f' -> */, -/* pos 03cb: 588 */ 0xE5 /* 'e' -> */, -/* pos 03cc: 589 */ 0xF2 /* 'r' -> */, -/* pos 03cd: 590 */ 0xAD /* '-' -> */, -/* pos 03ce: 591 */ 0xE5 /* 'e' -> */, -/* pos 03cf: 592 */ 0xEE /* 'n' -> */, -/* pos 03d0: 593 */ 0xE3 /* 'c' -> */, -/* pos 03d1: 594 */ 0xEF /* 'o' -> */, -/* pos 03d2: 595 */ 0xE4 /* 'd' -> */, -/* pos 03d3: 596 */ 0xE9 /* 'i' -> */, -/* pos 03d4: 597 */ 0xEE /* 'n' -> */, -/* pos 03d5: 598 */ 0xE7 /* 'g' -> */, -/* pos 03d6: 599 */ 0xBA /* ':' -> */, -/* pos 03d7: 600 */ 0x00, 0x44 /* - terminal marker 68 - */, -/* pos 03d9: 601 */ 0xE5 /* 'e' -> */, -/* pos 03da: 602 */ 0xF2 /* 'r' -> */, -/* pos 03db: 603 */ 0xAD /* '-' -> */, -/* pos 03dc: 604 */ 0xE1 /* 'a' -> */, -/* pos 03dd: 605 */ 0xE7 /* 'g' -> */, -/* pos 03de: 606 */ 0xE5 /* 'e' -> */, -/* pos 03df: 607 */ 0xEE /* 'n' -> */, -/* pos 03e0: 608 */ 0xF4 /* 't' -> */, -/* pos 03e1: 609 */ 0xBA /* ':' -> */, -/* pos 03e2: 610 */ 0x00, 0x45 /* - terminal marker 69 - */, -/* pos 03e4: 611 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x03EB state 612) */, - 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x03F0 state 616) */, - 0x08, /* fail */ -/* pos 03eb: 612 */ 0xF2 /* 'r' -> */, -/* pos 03ec: 613 */ 0xF9 /* 'y' -> */, -/* pos 03ed: 614 */ 0xBA /* ':' -> */, -/* pos 03ee: 615 */ 0x00, 0x46 /* - terminal marker 70 - */, -/* pos 03f0: 616 */ 0xE1 /* 'a' -> */, -/* pos 03f1: 617 */ 0xBA /* ':' -> */, -/* pos 03f2: 618 */ 0x00, 0x47 /* - terminal marker 71 - */, -/* pos 03f4: 619 */ 0xF7 /* 'w' -> */, -/* pos 03f5: 620 */ 0xF7 /* 'w' -> */, -/* pos 03f6: 621 */ 0xAD /* '-' -> */, -/* pos 03f7: 622 */ 0xE1 /* 'a' -> */, -/* pos 03f8: 623 */ 0xF5 /* 'u' -> */, -/* pos 03f9: 624 */ 0xF4 /* 't' -> */, -/* pos 03fa: 625 */ 0xE8 /* 'h' -> */, -/* pos 03fb: 626 */ 0xE5 /* 'e' -> */, -/* pos 03fc: 627 */ 0xEE /* 'n' -> */, -/* pos 03fd: 628 */ 0xF4 /* 't' -> */, -/* pos 03fe: 629 */ 0xE9 /* 'i' -> */, -/* pos 03ff: 630 */ 0xE3 /* 'c' -> */, -/* pos 0400: 631 */ 0xE1 /* 'a' -> */, -/* pos 0401: 632 */ 0xF4 /* 't' -> */, -/* pos 0402: 633 */ 0xE5 /* 'e' -> */, -/* pos 0403: 634 */ 0xBA /* ':' -> */, -/* pos 0404: 635 */ 0x00, 0x48 /* - terminal marker 72 - */, -/* pos 0406: 636 */ 0x00, 0x49 /* - terminal marker 73 - */, -/* total size 1032 bytes */ diff --git a/src/engine/external/libwebsockets/libwebsockets.c b/src/engine/external/libwebsockets/libwebsockets.c deleted file mode 100644 index b9be442ff..000000000 --- a/src/engine/external/libwebsockets/libwebsockets.c +++ /dev/null @@ -1,850 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE; -static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr; - -static const char * const log_level_names[] = { - "ERR", - "WARN", - "NOTICE", - "INFO", - "DEBUG", - "PARSER", - "HEADER", - "EXTENSION", - "CLIENT", - "LATENCY", -}; - - -void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status reason) -{ - int n, m, ret; - int old_state; - unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + - LWS_SEND_BUFFER_POST_PADDING]; - struct lws_tokens eff_buf; - - if (!wsi) - return; - - old_state = wsi->state; - - if (wsi->socket_is_permanently_unusable) - goto just_kill_connection; - - switch (old_state) { - case WSI_STATE_DEAD_SOCKET: - return; - - /* we tried the polite way... */ - case WSI_STATE_AWAITING_CLOSE_ACK: - goto just_kill_connection; - - case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE: - if (wsi->truncated_send_len) { - libwebsocket_callback_on_writable(context, wsi); - return; - } - lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); - goto just_kill_connection; - default: - if (wsi->truncated_send_len) { - lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); - wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE; - return; - } - break; - } - - wsi->u.ws.close_reason = reason; - - if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT || - wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) { - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, wsi->user_space, NULL, 0); - - lws_free_header_table(wsi); - goto just_kill_connection; - } - - if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { - if (wsi->u.http.fd != LWS_INVALID_FILE) { - lwsl_debug("closing http file\n"); - compatible_file_close(wsi->u.http.fd); - wsi->u.http.fd = LWS_INVALID_FILE; - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); - } - } - - /* - * are his extensions okay with him closing? Eg he might be a mux - * parent and just his ch1 aspect is closing? - */ - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) { - lwsl_ext("extension vetoed close\n"); - return; - } - - /* - * flush any tx pending from extensions, since we may send close packet - * if there are problems with send, just nuke the connection - */ - - do { - ret = 0; - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* show every extension the new incoming data */ - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0); - if (m < 0) { - lwsl_ext("Extension reports fatal error\n"); - goto just_kill_connection; - } - if (m) - /* - * at least one extension told us he has more - * to spill, so we will go around again after - */ - ret = 1; - - /* assuming they left us something to send, send it */ - - if (eff_buf.token_len) - if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len) != eff_buf.token_len) { - lwsl_debug("close: ext spill failed\n"); - goto just_kill_connection; - } - } while (ret); - - /* - * signal we are closing, libwebsocket_write will - * add any necessary version-specific stuff. If the write fails, - * no worries we are closing anyway. If we didn't initiate this - * close, then our state has been changed to - * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this. - * - * Likewise if it's a second call to close this connection after we - * sent the close indication to the peer already, we are in state - * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time. - */ - - if (old_state == WSI_STATE_ESTABLISHED && - reason != LWS_CLOSE_STATUS_NOSTATUS) { - - lwsl_debug("sending close indication...\n"); - - /* make valgrind happy */ - memset(buf, 0, sizeof(buf)); - n = libwebsocket_write(wsi, - &buf[LWS_SEND_BUFFER_PRE_PADDING + 2], - 0, LWS_WRITE_CLOSE); - if (n >= 0) { - /* - * we have sent a nice protocol level indication we - * now wish to close, we should not send anything more - */ - - wsi->state = WSI_STATE_AWAITING_CLOSE_ACK; - - /* - * ...and we should wait for a reply for a bit - * out of politeness - */ - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_CLOSE_ACK, 1); - - lwsl_debug("sent close indication, awaiting ack\n"); - - return; - } - - lwsl_info("close: sending close packet failed, hanging up\n"); - - /* else, the send failed and we should just hang up */ - } - -just_kill_connection: - - lwsl_debug("close: just_kill_connection\n"); - - /* - * we won't be servicing or receiving anything further from this guy - * delete socket from the internal poll list if still present - */ - - remove_wsi_socket_from_fds(context, wsi); - - wsi->state = WSI_STATE_DEAD_SOCKET; - - lws_free2(wsi->rxflow_buffer); - - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING && wsi->u.hdr.ah) { - lws_free2(wsi->u.hdr.ah); - } - - if ((old_state == WSI_STATE_ESTABLISHED || - wsi->mode == LWS_CONNMODE_WS_SERVING || - wsi->mode == LWS_CONNMODE_WS_CLIENT)) { - - lws_free2(wsi->u.ws.rx_user_buffer); - - if (wsi->truncated_send_malloc) { - /* not going to be completed... nuke it */ - lws_free2(wsi->truncated_send_malloc); - wsi->truncated_send_len = 0; - } - if (wsi->u.ws.ping_payload_buf) { - lws_free2(wsi->u.ws.ping_payload_buf); - wsi->u.ws.ping_payload_alloc = 0; - wsi->u.ws.ping_payload_len = 0; - } - } - - /* tell the user it's all over for this guy */ - - if (wsi->protocol && wsi->protocol->callback && - ((old_state == WSI_STATE_ESTABLISHED) || - (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) || - (old_state == WSI_STATE_AWAITING_CLOSE_ACK) || - (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) { - lwsl_debug("calling back CLOSED\n"); - wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED, - wsi->user_space, NULL, 0); - } else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { - lwsl_debug("calling back CLOSED_HTTP\n"); - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 ); - } else - lwsl_debug("not calling back closed\n"); - - /* deallocate any active extension contexts */ - - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0) - lwsl_warn("extension destruction failed\n"); -#ifndef LWS_NO_EXTENSIONS - for (n = 0; n < wsi->count_active_extensions; n++) - lws_free(wsi->active_extensions_user[n]); -#endif - /* - * inform all extensions in case they tracked this guy out of band - * even though not active on him specifically - */ - if (lws_ext_callback_for_each_extension_type(context, wsi, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0) - lwsl_warn("ext destroy wsi failed\n"); - -/* lwsl_info("closing fd=%d\n", wsi->sock); */ - - if (!lws_ssl_close(wsi) && wsi->sock >= 0) { - n = shutdown(wsi->sock, SHUT_RDWR); - if (n) - lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO); - - n = compatible_close(wsi->sock); - if (n) - lwsl_debug("closing: close ret %d\n", LWS_ERRNO); - } - - /* outermost destroy notification for wsi (user_space still intact) */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0); - - if (wsi->protocol && wsi->protocol->per_session_data_size && - wsi->user_space && !wsi->user_space_externally_allocated) - lws_free(wsi->user_space); - - /* As a precaution, free the header table in case it lingered: */ - lws_free_header_table(wsi); - lws_free(wsi); -} - -/** - * libwebsockets_get_peer_addresses() - Get client address information - * @context: Libwebsockets context - * @wsi: Local struct libwebsocket associated with - * @fd: Connection socket descriptor - * @name: Buffer to take client address name - * @name_len: Length of client address name buffer - * @rip: Buffer to take client address IP dotted quad - * @rip_len: Length of client address IP buffer - * - * This function fills in @name and @rip with the name and IP of - * the client connected with socket descriptor @fd. Names may be - * truncated if there is not enough room. If either cannot be - * determined, they will be returned as valid zero-length strings. - */ - -LWS_VISIBLE void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, - char *rip, int rip_len) -{ - socklen_t len; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_in sin4; - struct hostent *host; - struct hostent *host1; - char ip[128]; - unsigned char *p; - int n; -#ifdef AF_LOCAL - struct sockaddr_un *un; -#endif - int ret = -1; - - rip[0] = '\0'; - name[0] = '\0'; - - lws_latency_pre(context, wsi); - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - - len = sizeof(sin6); - if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - - if (!lws_plat_inet_ntop(AF_INET6, &sin6.sin6_addr, rip, rip_len)) { - lwsl_err("inet_ntop", strerror(LWS_ERRNO)); - goto bail; - } - - // Strip off the IPv4 to IPv6 header if one exists - if (strncmp(rip, "::ffff:", 7) == 0) - memmove(rip, rip + 7, strlen(rip) - 6); - - getnameinfo((struct sockaddr *)&sin6, - sizeof(struct sockaddr_in6), name, - name_len, NULL, 0, 0); - - } else -#endif - { - len = sizeof(sin4); - if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - host = gethostbyaddr((char *) &sin4.sin_addr, - sizeof(sin4.sin_addr), AF_INET); - if (host == NULL) { - lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - - strncpy(name, host->h_name, name_len); - name[name_len - 1] = '\0'; - - host1 = gethostbyname(host->h_name); - if (host1 == NULL) - goto bail; - p = (unsigned char *)host1; - n = 0; - while (p != NULL) { - p = (unsigned char *)host1->h_addr_list[n++]; - if (p == NULL) - continue; - if ((host1->h_addrtype != AF_INET) -#ifdef AF_LOCAL - && (host1->h_addrtype != AF_LOCAL) -#endif - ) - continue; - - if (host1->h_addrtype == AF_INET) - sprintf(ip, "%u.%u.%u.%u", - p[0], p[1], p[2], p[3]); -#ifdef AF_LOCAL - else { - un = (struct sockaddr_un *)p; - strncpy(ip, un->sun_path, sizeof(ip) - 1); - ip[sizeof(ip) - 1] = '\0'; - } -#endif - p = NULL; - strncpy(rip, ip, rip_len); - rip[rip_len - 1] = '\0'; - } - } - - ret = 0; -bail: - lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1); -} - - - -/** - * libwebsocket_context_user() - get the user data associated with the context - * @context: Websocket context - * - * This returns the optional user allocation that can be attached to - * the context the sockets live in at context_create time. It's a way - * to let all sockets serviced in the same context share data without - * using globals statics in the user code. - */ -LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context) -{ - return context->user_space; -} - - -/** - * libwebsocket_callback_all_protocol() - Callback all connections using - * the given protocol with the given reason - * - * @protocol: Protocol whose connections will get callbacks - * @reason: Callback reason index - */ - -LWS_VISIBLE int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - protocol->callback(context, wsi, - reason, wsi->user_space, NULL, 0); - } - - return 0; -} - -/** - * libwebsocket_set_timeout() - marks the wsi as subject to a timeout - * - * You will not need this unless you are doing something special - * - * @wsi: Websocket connection instance - * @reason: timeout reason - * @secs: how many seconds - */ - -LWS_VISIBLE void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs) -{ - time_t now; - - time(&now); - - wsi->pending_timeout_limit = now + secs; - wsi->pending_timeout = reason; -} - - -/** - * libwebsocket_get_socket_fd() - returns the socket file descriptor - * - * You will not need this unless you are doing something special - * - * @wsi: Websocket connection instance - */ - -LWS_VISIBLE int -libwebsocket_get_socket_fd(struct libwebsocket *wsi) -{ - return wsi->sock; -} - -#ifdef LWS_LATENCY -void -lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, - const char *action, int ret, int completed) -{ - unsigned long long u; - char buf[256]; - - u = time_in_microseconds(); - - if (!action) { - wsi->latency_start = u; - if (!wsi->action_start) - wsi->action_start = u; - return; - } - if (completed) { - if (wsi->action_start == wsi->latency_start) - sprintf(buf, - "Completion first try lat %lluus: %p: ret %d: %s\n", - u - wsi->latency_start, - (void *)wsi, ret, action); - else - sprintf(buf, - "Completion %lluus: lat %lluus: %p: ret %d: %s\n", - u - wsi->action_start, - u - wsi->latency_start, - (void *)wsi, ret, action); - wsi->action_start = 0; - } else - sprintf(buf, "lat %lluus: %p: ret %d: %s\n", - u - wsi->latency_start, (void *)wsi, ret, action); - - if (u - wsi->latency_start > context->worst_latency) { - context->worst_latency = u - wsi->latency_start; - strcpy(context->worst_latency_info, buf); - } - lwsl_latency("%s", buf); -} -#endif - - - -/** - * libwebsocket_rx_flow_control() - Enable and disable socket servicing for - * received packets. - * - * If the output side of a server process becomes choked, this allows flow - * control for the input side. - * - * @wsi: Websocket connection instance to get callback for - * @enable: 0 = disable read servicing for this connection, 1 = enable - */ - -LWS_VISIBLE int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable) -{ - if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) - return 0; - - lwsl_info("libwebsocket_rx_flow_control(0x%p, %d)\n", wsi, enable); - wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable; - - return 0; -} - -/** - * libwebsocket_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive - * - * When the user server code realizes it can accept more input, it can - * call this to have the RX flow restriction removed from all connections using - * the given protocol. - * - * @protocol: all connections using this protocol will be allowed to receive - */ - -LWS_VISIBLE void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - libwebsocket_rx_flow_control(wsi, LWS_RXFLOW_ALLOW); - } -} - - -/** - * libwebsocket_canonical_hostname() - returns this host's hostname - * - * This is typically used by client code to fill in the host parameter - * when making a client connection. You can only call it after the context - * has been created. - * - * @context: Websocket context - */ -LWS_VISIBLE extern const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context) -{ - return (const char *)context->canonical_hostname; -} - -int user_callback_handle_rxflow(callback_function callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len) -{ - int n; - - n = callback_function(context, wsi, reason, user, in, len); - if (!n) - n = _libwebsocket_rx_flow_control(wsi); - - return n; -} - - -/** - * libwebsocket_set_proxy() - Setups proxy to libwebsocket_context. - * @context: pointer to struct libwebsocket_context you want set proxy to - * @proxy: pointer to c string containing proxy in format address:port - * - * Returns 0 if proxy string was parsed and proxy was setup. - * Returns -1 if @proxy is NULL or has incorrect format. - * - * This is only required if your OS does not provide the http_proxy - * environment variable (eg, OSX) - * - * IMPORTANT! You should call this function right after creation of the - * libwebsocket_context and before call to connect. If you call this - * function after connect behavior is undefined. - * This function will override proxy settings made on libwebsocket_context - * creation with genenv() call. - */ - -LWS_VISIBLE int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy) -{ - char *p; - - if (!proxy) - return -1; - - strncpy(context->http_proxy_address, proxy, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - - p = strchr(context->http_proxy_address, ':'); - if (!p) { - lwsl_err("http_proxy needs to be ads:port\n"); - - return -1; - } - *p = '\0'; - context->http_proxy_port = atoi(p + 1); - - lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address, - context->http_proxy_port); - - return 0; -} - -/** - * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket - * connection. - * @wsi: pointer to struct websocket you want to know the protocol of - * - * - * Some apis can act on all live connections of a given protocol, - * this is how you can get a pointer to the active protocol if needed. - */ - -LWS_VISIBLE const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi) -{ - return wsi->protocol; -} - -LWS_VISIBLE int -libwebsocket_is_final_fragment(struct libwebsocket *wsi) -{ - return wsi->u.ws.final; -} - -LWS_VISIBLE unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi) -{ - return wsi->u.ws.rsv; -} - -int -libwebsocket_ensure_user_space(struct libwebsocket *wsi) -{ - lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol); - if (!wsi->protocol) - return 1; - - /* allocate the per-connection user memory (if any) */ - - if (wsi->protocol->per_session_data_size && !wsi->user_space) { - wsi->user_space = lws_zalloc(wsi->protocol->per_session_data_size); - if (wsi->user_space == NULL) { - lwsl_err("Out of memory for conn user space\n"); - return 1; - } - } else - lwsl_info("%s: %p protocol pss %u, user_space=%d\n", __func__, wsi, wsi->protocol->per_session_data_size, wsi->user_space); - return 0; -} - -LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line) -{ - char buf[300]; - unsigned long long now; - int n; - - buf[0] = '\0'; - for (n = 0; n < LLL_COUNT; n++) - if (level == (1 << n)) { - now = time_in_microseconds() / 100; - sprintf(buf, "[%lu:%04d] %s: ", (unsigned long) now / 10000, - (int)(now % 10000), log_level_names[n]); - break; - } - - fprintf(stderr, "%s%s", buf, line); -} - - -LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl) -{ - char buf[256]; - - if (!(log_level & filter)) - return; - - vsnprintf(buf, sizeof(buf), format, vl); - buf[sizeof(buf) - 1] = '\0'; - - lwsl_emit(filter, buf); -} - -LWS_VISIBLE void _lws_log(int filter, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - _lws_logv(filter, format, ap); - va_end(ap); -} - -/** - * lws_set_log_level() - Set the logging bitfield - * @level: OR together the LLL_ debug contexts you want output from - * @log_emit_function: NULL to leave it as it is, or a user-supplied - * function to perform log string emission instead of - * the default stderr one. - * - * log level defaults to "err", "warn" and "notice" contexts enabled and - * emission on stderr. - */ - -LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level, - const char *line)) -{ - log_level = level; - if (log_emit_function) - lwsl_emit = log_emit_function; -} - -/** - * lws_use_ssl() - Find out if connection is using SSL - * @wsi: websocket connection to check - * - * Returns 0 if the connection is not using SSL, 1 if using SSL and - * using verified cert, and 2 if using SSL but the cert was not - * checked (appears for client wsi told to skip check on connection) - */ -LWS_VISIBLE int -lws_is_ssl(struct libwebsocket *wsi) -{ -#ifdef LWS_OPENSSL_SUPPORT - return wsi->use_ssl; -#else - return 0; -#endif -} - -/** - * lws_partial_buffered() - find out if lws buffered the last write - * @wsi: websocket connection to check - * - * Returns 1 if you cannot use libwebsocket_write because the last - * write on this connection is still buffered, and can't be cleared without - * returning to the service loop and waiting for the connection to be - * writeable again. - * - * If you will try to do >1 libwebsocket_write call inside a single - * WRITEABLE callback, you must check this after every write and bail if - * set, ask for a new writeable callback and continue writing from there. - * - * This is never set at the start of a writeable callback, but any write - * may set it. - */ - -LWS_VISIBLE int -lws_partial_buffered(struct libwebsocket *wsi) -{ - return !!wsi->truncated_send_len; -} - -void lws_set_protocol_write_pending(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_pending_protocol_send pend) -{ - lwsl_info("setting pps %d\n", pend); - - if (wsi->pps) - lwsl_err("pps overwrite\n"); - wsi->pps = pend; - libwebsocket_rx_flow_control(wsi, 0); - libwebsocket_callback_on_writable(context, wsi); -} - -LWS_VISIBLE size_t -lws_get_peer_write_allowance(struct libwebsocket *wsi) -{ -#ifdef LWS_USE_HTTP2 - /* only if we are using HTTP2 on this connection */ - if (wsi->mode != LWS_CONNMODE_HTTP2_SERVING) - return -1; - /* user is only interested in how much he can send, or that he can't */ - if (wsi->u.http2.tx_credit <= 0) - return 0; - - return wsi->u.http2.tx_credit; -#else - return -1; -#endif -} - -LWS_VISIBLE void -lws_union_transition(struct libwebsocket *wsi, enum connection_mode mode) -{ - memset(&wsi->u, 0, sizeof(wsi->u)); - wsi->mode = mode; -} diff --git a/src/engine/external/libwebsockets/libwebsockets.h b/src/engine/external/libwebsockets/libwebsockets.h deleted file mode 100644 index 3c717ff4c..000000000 --- a/src/engine/external/libwebsockets/libwebsockets.h +++ /dev/null @@ -1,1371 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C -#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C - -#ifdef __cplusplus -#include -#include -extern "C" { -#endif - -#ifdef CMAKE_BUILD -#include "lws_config.h" -#endif - -#if defined(WIN32) || defined(_WIN32) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#include -#include -#include - -#define strcasecmp stricmp -#define getdtablesize() 30000 - -#define LWS_VISIBLE - -#ifdef LWS_DLL -#ifdef LWS_INTERNAL -#define LWS_EXTERN extern __declspec(dllexport) -#else -#define LWS_EXTERN extern __declspec(dllimport) -#endif -#else -#define LWS_EXTERN -#endif - -#else // NOT WIN32 - -#include -#include - -#if defined(__GNUC__) -#define LWS_VISIBLE __attribute__((visibility("default"))) -#else -#define LWS_VISIBLE -#endif - -#endif - -#ifdef LWS_USE_LIBEV -#include -#endif /* LWS_USE_LIBEV */ - -#include - -#ifndef LWS_EXTERN -#define LWS_EXTERN extern -#endif - -#ifdef _WIN32 -#define random rand -#else -#include -#include -#endif - -#ifdef LWS_OPENSSL_SUPPORT -#ifdef USE_CYASSL -#include -#else -#include -#endif /* not USE_CYASSL */ -#endif - -#define CONTEXT_PORT_NO_LISTEN -1 -#define MAX_MUX_RECURSION 2 - -enum lws_log_levels { - LLL_ERR = 1 << 0, - LLL_WARN = 1 << 1, - LLL_NOTICE = 1 << 2, - LLL_INFO = 1 << 3, - LLL_DEBUG = 1 << 4, - LLL_PARSER = 1 << 5, - LLL_HEADER = 1 << 6, - LLL_EXT = 1 << 7, - LLL_CLIENT = 1 << 8, - LLL_LATENCY = 1 << 9, - - LLL_COUNT = 10 /* set to count of valid flags */ -}; - -LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...); -LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl); - -/* notice, warn and log are always compiled in */ -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) -/* - * weaker logging can be deselected at configure time using --disable-debug - * that gets rid of the overhead of checking while keeping _warn and _err - * active - */ -#ifdef _DEBUG - -#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) -#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) -#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) -#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) -#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) -#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) -#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) -LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); - -#else /* no debug */ - -#define lwsl_info(...) -#define lwsl_debug(...) -#define lwsl_parser(...) -#define lwsl_header(...) -#define lwsl_ext(...) -#define lwsl_client(...) -#define lwsl_latency(...) -#define lwsl_hexdump(a, b) - -#endif - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -/* api change list for user code to test against */ - -#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG - -/* the struct libwebsocket_protocols has the id field present */ -#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD - -/* you can call lws_get_peer_write_allowance */ -#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE - -/* extra parameter introduced in 917f43ab821 */ -#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN - -enum libwebsocket_context_options { - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2, - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4, - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8, - LWS_SERVER_OPTION_LIBEV = 16, - LWS_SERVER_OPTION_DISABLE_IPV6 = 32, - LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = 64, -}; - -enum libwebsocket_callback_reasons { - LWS_CALLBACK_ESTABLISHED, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - LWS_CALLBACK_CLIENT_ESTABLISHED, - LWS_CALLBACK_CLOSED, - LWS_CALLBACK_CLOSED_HTTP, - LWS_CALLBACK_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE_PONG, - LWS_CALLBACK_CLIENT_WRITEABLE, - LWS_CALLBACK_SERVER_WRITEABLE, - LWS_CALLBACK_HTTP, - LWS_CALLBACK_HTTP_BODY, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - LWS_CALLBACK_HTTP_WRITEABLE, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - LWS_CALLBACK_PROTOCOL_INIT, - LWS_CALLBACK_PROTOCOL_DESTROY, - LWS_CALLBACK_WSI_CREATE, /* always protocol[0] */ - LWS_CALLBACK_WSI_DESTROY, /* always protocol[0] */ - LWS_CALLBACK_GET_THREAD_ID, - - /* external poll() management support */ - LWS_CALLBACK_ADD_POLL_FD, - LWS_CALLBACK_DEL_POLL_FD, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - LWS_CALLBACK_LOCK_POLL, - LWS_CALLBACK_UNLOCK_POLL, - - LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY, - - LWS_CALLBACK_USER = 1000, /* user code can use any including / above */ -}; - -// argument structure for all external poll related calls -// passed in via 'in' -struct libwebsocket_pollargs { - int fd; // applicable file descriptor - int events; // the new event mask - int prev_events; // the previous event mask -}; - -#ifdef _WIN32 -struct libwebsocket_pollfd { - SOCKET fd; - SHORT events; - SHORT revents; -}; -#else -#define libwebsocket_pollfd pollfd -#endif - -enum libwebsocket_extension_callback_reasons { - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, - LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - LWS_EXT_CALLBACK_DESTROY, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, - LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - LWS_EXT_CALLBACK_1HZ, - LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, - LWS_EXT_CALLBACK_IS_WRITEABLE, - LWS_EXT_CALLBACK_PAYLOAD_TX, - LWS_EXT_CALLBACK_PAYLOAD_RX, -}; - -enum libwebsocket_write_protocol { - LWS_WRITE_TEXT, - LWS_WRITE_BINARY, - LWS_WRITE_CONTINUATION, - LWS_WRITE_HTTP, - - /* special 04+ opcodes */ - - LWS_WRITE_CLOSE, - LWS_WRITE_PING, - LWS_WRITE_PONG, - - /* Same as write_http but we know this write ends the transaction */ - LWS_WRITE_HTTP_FINAL, - - /* HTTP2 */ - - LWS_WRITE_HTTP_HEADERS, - - /* flags */ - - LWS_WRITE_NO_FIN = 0x40, - /* - * client packet payload goes out on wire unmunged - * only useful for security tests since normal servers cannot - * decode the content if used - */ - LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 -}; - -/* - * you need these to look at headers that have been parsed if using the - * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum - * list below is absent, .token = NULL and token_len = 0. Otherwise .token - * points to .token_len chars containing that header content. - */ - -struct lws_tokens { - char *token; - int token_len; -}; - -/* - * don't forget to update test server header dump accordingly - * - * these have to be kept in sync with lextable.h / minilex.c - */ - -enum lws_token_indexes { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_OPTIONS_URI, - WSI_TOKEN_HOST, - WSI_TOKEN_CONNECTION, - WSI_TOKEN_UPGRADE, - WSI_TOKEN_ORIGIN, - WSI_TOKEN_DRAFT, - WSI_TOKEN_CHALLENGE, - WSI_TOKEN_EXTENSIONS, - WSI_TOKEN_KEY1, - WSI_TOKEN_KEY2, - WSI_TOKEN_PROTOCOL, - WSI_TOKEN_ACCEPT, - WSI_TOKEN_NONCE, - WSI_TOKEN_HTTP, - WSI_TOKEN_HTTP2_SETTINGS, - WSI_TOKEN_HTTP_ACCEPT, - WSI_TOKEN_HTTP_AC_REQUEST_HEADERS, - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, - WSI_TOKEN_HTTP_IF_NONE_MATCH, - WSI_TOKEN_HTTP_ACCEPT_ENCODING, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, - WSI_TOKEN_HTTP_PRAGMA, - WSI_TOKEN_HTTP_CACHE_CONTROL, - WSI_TOKEN_HTTP_AUTHORIZATION, - WSI_TOKEN_HTTP_COOKIE, - WSI_TOKEN_HTTP_CONTENT_LENGTH, - WSI_TOKEN_HTTP_CONTENT_TYPE, - WSI_TOKEN_HTTP_DATE, - WSI_TOKEN_HTTP_RANGE, - WSI_TOKEN_HTTP_REFERER, - WSI_TOKEN_KEY, - WSI_TOKEN_VERSION, - WSI_TOKEN_SWORIGIN, - - WSI_TOKEN_HTTP_COLON_AUTHORITY, - WSI_TOKEN_HTTP_COLON_METHOD, - WSI_TOKEN_HTTP_COLON_PATH, - WSI_TOKEN_HTTP_COLON_SCHEME, - WSI_TOKEN_HTTP_COLON_STATUS, - - WSI_TOKEN_HTTP_ACCEPT_CHARSET, - WSI_TOKEN_HTTP_ACCEPT_RANGES, - WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN, - WSI_TOKEN_HTTP_AGE, - WSI_TOKEN_HTTP_ALLOW, - WSI_TOKEN_HTTP_CONTENT_DISPOSITION, - WSI_TOKEN_HTTP_CONTENT_ENCODING, - WSI_TOKEN_HTTP_CONTENT_LANGUAGE, - WSI_TOKEN_HTTP_CONTENT_LOCATION, - WSI_TOKEN_HTTP_CONTENT_RANGE, - WSI_TOKEN_HTTP_ETAG, - WSI_TOKEN_HTTP_EXPECT, - WSI_TOKEN_HTTP_EXPIRES, - WSI_TOKEN_HTTP_FROM, - WSI_TOKEN_HTTP_IF_MATCH, - WSI_TOKEN_HTTP_IF_RANGE, - WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE, - WSI_TOKEN_HTTP_LAST_MODIFIED, - WSI_TOKEN_HTTP_LINK, - WSI_TOKEN_HTTP_LOCATION, - WSI_TOKEN_HTTP_MAX_FORWARDS, - WSI_TOKEN_HTTP_PROXY_AUTHENTICATE, - WSI_TOKEN_HTTP_PROXY_AUTHORIZATION, - WSI_TOKEN_HTTP_REFRESH, - WSI_TOKEN_HTTP_RETRY_AFTER, - WSI_TOKEN_HTTP_SERVER, - WSI_TOKEN_HTTP_SET_COOKIE, - WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY, - WSI_TOKEN_HTTP_TRANSFER_ENCODING, - WSI_TOKEN_HTTP_USER_AGENT, - WSI_TOKEN_HTTP_VARY, - WSI_TOKEN_HTTP_VIA, - WSI_TOKEN_HTTP_WWW_AUTHENTICATE, - WSI_TOKEN_PROXY, - - WSI_TOKEN_HTTP_URI_ARGS, - - /* use token storage to stash these */ - - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - _WSI_TOKEN_CLIENT_URI, - _WSI_TOKEN_CLIENT_HOST, - _WSI_TOKEN_CLIENT_ORIGIN, - - /* always last real token index*/ - WSI_TOKEN_COUNT, - /* parser state additions */ - WSI_TOKEN_NAME_PART, - WSI_TOKEN_SKIPPING, - WSI_TOKEN_SKIPPING_SAW_CR, - WSI_PARSING_COMPLETE, - WSI_INIT_TOKEN_MUXURL, -}; - -struct lws_token_limits { - unsigned short token_limit[WSI_TOKEN_COUNT]; -}; - -/* - * From RFC 6455 - 1000 - - 1000 indicates a normal closure, meaning that the purpose for - which the connection was established has been fulfilled. - - 1001 - - 1001 indicates that an endpoint is "going away", such as a server - going down or a browser having navigated away from a page. - - 1002 - - 1002 indicates that an endpoint is terminating the connection due - to a protocol error. - - 1003 - - 1003 indicates that an endpoint is terminating the connection - because it has received a type of data it cannot accept (e.g., an - endpoint that understands only text data MAY send this if it - receives a binary message). - - 1004 - - Reserved. The specific meaning might be defined in the future. - - 1005 - - 1005 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that no status - code was actually present. - - 1006 - - 1006 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed abnormally, e.g., without sending or - receiving a Close control frame. - - 1007 - - 1007 indicates that an endpoint is terminating the connection - because it has received data within a message that was not - consistent with the type of the message (e.g., non-UTF-8 [RFC3629] - data within a text message). - - 1008 - - 1008 indicates that an endpoint is terminating the connection - because it has received a message that violates its policy. This - is a generic status code that can be returned when there is no - other more suitable status code (e.g., 1003 or 1009) or if there - is a need to hide specific details about the policy. - - 1009 - - 1009 indicates that an endpoint is terminating the connection - because it has received a message that is too big for it to - process. - - 1010 - - 1010 indicates that an endpoint (client) is terminating the - connection because it has expected the server to negotiate one or - more extension, but the server didn't return them in the response - message of the WebSocket handshake. The list of extensions that - are needed SHOULD appear in the /reason/ part of the Close frame. - Note that this status code is not used by the server, because it - can fail the WebSocket handshake instead. - - 1011 - - 1011 indicates that a server is terminating the connection because - it encountered an unexpected condition that prevented it from - fulfilling the request. - - 1015 - - 1015 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed due to a failure to perform a TLS handshake - (e.g., the server certificate can't be verified). -*/ - -enum lws_close_status { - LWS_CLOSE_STATUS_NOSTATUS = 0, - LWS_CLOSE_STATUS_NORMAL = 1000, - LWS_CLOSE_STATUS_GOINGAWAY = 1001, - LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, - LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, - LWS_CLOSE_STATUS_RESERVED = 1004, - LWS_CLOSE_STATUS_NO_STATUS = 1005, - LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, - LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, - LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, - LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, - LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, - LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, - LWS_CLOSE_STATUS_TLS_FAILURE = 1015, -}; - -enum http_status { - HTTP_STATUS_OK = 200, - HTTP_STATUS_NO_CONTENT = 204, - - HTTP_STATUS_BAD_REQUEST = 400, - HTTP_STATUS_UNAUTHORIZED, - HTTP_STATUS_PAYMENT_REQUIRED, - HTTP_STATUS_FORBIDDEN, - HTTP_STATUS_NOT_FOUND, - HTTP_STATUS_METHOD_NOT_ALLOWED, - HTTP_STATUS_NOT_ACCEPTABLE, - HTTP_STATUS_PROXY_AUTH_REQUIRED, - HTTP_STATUS_REQUEST_TIMEOUT, - HTTP_STATUS_CONFLICT, - HTTP_STATUS_GONE, - HTTP_STATUS_LENGTH_REQUIRED, - HTTP_STATUS_PRECONDITION_FAILED, - HTTP_STATUS_REQ_ENTITY_TOO_LARGE, - HTTP_STATUS_REQ_URI_TOO_LONG, - HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, - HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, - HTTP_STATUS_EXPECTATION_FAILED, - - HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, - HTTP_STATUS_NOT_IMPLEMENTED, - HTTP_STATUS_BAD_GATEWAY, - HTTP_STATUS_SERVICE_UNAVAILABLE, - HTTP_STATUS_GATEWAY_TIMEOUT, - HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, -}; - -struct libwebsocket; -struct libwebsocket_context; -/* needed even with extensions disabled for create context */ -struct libwebsocket_extension; - -/** - * callback_function() - User server actions - * @context: Websockets context - * @wsi: Opaque websocket instance pointer - * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library - * @in: Pointer used for some callback reasons - * @len: Length set for some callback reasons - * - * This callback is the way the user controls what is served. All the - * protocol detail is hidden and handled by the library. - * - * For each connection / session there is user data allocated that is - * pointed to by "user". You set the size of this user data area when - * the library is initialized with libwebsocket_create_server. - * - * You get an opportunity to initialize user data when called back with - * LWS_CALLBACK_ESTABLISHED reason. - * - * LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with - * an incoming client - * - * LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has - * been unable to complete a handshake with the remote server - * - * LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the - * client user code to examine the http headers - * and decide to reject the connection. If the - * content in the headers is interesting to the - * client (url, etc) it needs to copy it out at - * this point since it will be destroyed before - * the CLIENT_ESTABLISHED call - * - * LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed - * a handshake with the remote server - * - * LWS_CALLBACK_CLOSED: when the websocket session ends - * - * LWS_CALLBACK_CLOSED_HTTP: when a HTTP (non-websocket) session ends - * - * LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a - * remote client, it can be found at *in and is - * len bytes long - * - * LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets, - * they appear with this callback reason. PONG - * packets only exist in 04+ protocol - * - * LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the - * client connection, it can be found at *in and - * is len bytes long - * - * LWS_CALLBACK_HTTP: an http request has come from a client that is not - * asking to upgrade the connection to a websocket - * one. This is a chance to serve http content, - * for example, to send a script to the client - * which will then open the websockets connection. - * @in points to the URI path requested and - * libwebsockets_serve_http_file() makes it very - * simple to send back a file to the client. - * Normally after sending the file you are done - * with the http connection, since the rest of the - * activity will come by websockets from the script - * that was delivered by http, so you will want to - * return 1; to close and free up the connection. - * That's important because it uses a slot in the - * total number of client connections allowed set - * by MAX_CLIENTS. - * - * LWS_CALLBACK_HTTP_BODY: the next @len bytes data from the http - * request body HTTP connection is now available in @in. - * - * LWS_CALLBACK_HTTP_BODY_COMPLETION: the expected amount of http request - * body has been delivered - * - * LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protocol - * link now. - * - * LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down - * http link has completed. - * - * LWS_CALLBACK_CLIENT_WRITEABLE: - * LWS_CALLBACK_SERVER_WRITEABLE: If you call - * libwebsocket_callback_on_writable() on a connection, you will - * get one of these callbacks coming when the connection socket - * is able to accept another write packet without blocking. - * If it already was able to take another packet without blocking, - * you'll get this callback at the next call to the service loop - * function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE - * and servers get LWS_CALLBACK_SERVER_WRITEABLE. - * - * LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to - * the server at network level; the connection is accepted but then - * passed to this callback to decide whether to hang up immediately - * or not, based on the client IP. @in contains the connection - * socket's descriptor. Since the client connection information is - * not available yet, @wsi still pointing to the main server socket. - * Return non-zero to terminate the connection before sending or - * receiving anything. Because this happens immediately after the - * network connection from the client, there's no websocket protocol - * selected yet so this callback is issued only to protocol 0. - * - * LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: A new client just had - * been connected, accepted, and instantiated into the pool. This - * callback allows setting any relevant property to it. Because this - * happens immediately after the instantiation of a new client, - * there's no websocket protocol selected yet so this callback is - * issued only to protocol 0. Only @wsi is defined, pointing to the - * new client, and the return value is ignored. - * - * LWS_CALLBACK_FILTER_HTTP_CONNECTION: called when the request has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * @user is a pointer to the connection user space allocation, - * @in is the URI, eg, "/" - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the http - * connection to proceed or to kill the connection. - * - * LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * @user is a pointer to the connection user space allocation, - * @in is the requested protocol name - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the handshake - * to proceed or to kill the connection. - * - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for - * including OpenSSL support, this callback allows your user code - * to perform extra SSL_CTX_load_verify_locations() or similar - * calls to direct OpenSSL where to find certificates the client - * can use to confirm the remote server identity. @user is the - * OpenSSL SSL_CTX* - * - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for - * including OpenSSL support, this callback allows your user code - * to load extra certifcates into the server which allow it to - * verify the validity of certificates returned by clients. @user - * is the server's OpenSSL SSL_CTX* - * - * LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY: if configured for - * including OpenSSL support but no private key file has been specified - * (ssl_private_key_filepath is NULL), this callback is called to - * allow the user to set the private key directly via libopenssl - * and perform further operations if required; this might be useful - * in situations where the private key is not directly accessible by - * the OS, for example if it is stored on a smartcard - * @user is the server's OpenSSL SSL_CTX* - * - * LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the - * libwebsockets context was created with the option - * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this - * callback is generated during OpenSSL verification of the cert - * sent from the client. It is sent to protocol[0] callback as - * no protocol has been negotiated on the connection yet. - * Notice that the libwebsockets context and wsi are both NULL - * during this callback. See - * http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html - * to understand more detail about the OpenSSL callback that - * generates this libwebsockets callback and the meanings of the - * arguments passed. In this callback, @user is the x509_ctx, - * @in is the ssl pointer and @len is preverify_ok - * Notice that this callback maintains libwebsocket return - * conventions, return 0 to mean the cert is OK or 1 to fail it. - * This also means that if you don't handle this callback then - * the default callback action of returning 0 allows the client - * certificates. - * - * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens - * when a client handshake is being compiled. @user is NULL, - * @in is a char **, it's pointing to a char * which holds the - * next location in the header buffer where you can add - * headers, and @len is the remaining space in the header buffer, - * which is typically some hundreds of bytes. So, to add a canned - * cookie, your handler code might look similar to: - * - * char **p = (char **)in; - * - * if (len < 100) - * return 1; - * - * *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); - * - * return 0; - * - * Notice if you add anything, you just have to take care about - * the CRLF on the line you added. Obviously this callback is - * optional, if you don't handle it everything is fine. - * - * Notice the callback is coming to protocols[0] all the time, - * because there is no specific protocol handshook yet. - * - * LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code - * sees that it does support a requested extension, before - * accepting the extension by additing to the list sent back to - * the client it gives this callback just to check that it's okay - * to use that extension. It calls back to the requested protocol - * and with @in being the extension name, @len is 0 and @user is - * valid. Note though at this time the ESTABLISHED callback hasn't - * happened yet so if you initialize @user content there, @user - * content during this callback might not be useful for anything. - * Notice this callback comes to protocols[0]. - * - * LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client - * connection is being prepared to start a handshake to a server, - * each supported extension is checked with protocols[0] callback - * with this reason, giving the user code a chance to suppress the - * claim to support that extension by returning non-zero. If - * unhandled, by default 0 will be returned and the extension - * support included in the header to the server. Notice this - * callback comes to protocols[0]. - * - * LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can - * do initial setup / allocations etc - * - * LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating - * this protocol won't get used at all after this callback, the - * context is getting destroyed. Take the opportunity to - * deallocate everything that was allocated by the protocol. - * - * LWS_CALLBACK_WSI_CREATE: outermost (earliest) wsi create notification - * - * LWS_CALLBACK_WSI_DESTROY: outermost (latest) wsi destroy notification - * - * The next five reasons are optional and only need taking care of if you - * will be integrating libwebsockets sockets into an external polling - * array. - * - * For these calls, @in points to a struct libwebsocket_pollargs that - * contains @fd, @events and @prev_events members - * - * LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop - * internally, but in the case you are integrating with another - * server you will need to have libwebsocket sockets share a - * polling array with the other server. This and the other - * POLL_FD related callbacks let you put your specialized - * poll array interface code in the callback for protocol 0, the - * first protocol you support, usually the HTTP protocol in the - * serving case. - * This callback happens when a socket needs to be - * added to the polling loop: @in points to a struct - * libwebsocket_pollargs; the @fd member of the struct is the file - * descriptor, and @events contains the active events. - * - * If you are using the internal polling loop (the "service" - * callback), you can just ignore these callbacks. - * - * LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor - * needs to be removed from an external polling array. @in is - * again the struct libwebsocket_pollargs containing the @fd member - * to be removed. If you are using the internal polling - * loop, you can just ignore it. - * - * LWS_CALLBACK_CHANGE_MODE_POLL_FD: This callback happens when - * libwebsockets wants to modify the events for a connectiion. - * @in is the struct libwebsocket_pollargs with the @fd to change. - * The new event mask is in @events member and the old mask is in - * the @prev_events member. - * If you are using the internal polling loop, you can just ignore - * it. - * - * LWS_CALLBACK_LOCK_POLL: - * LWS_CALLBACK_UNLOCK_POLL: These allow the external poll changes driven - * by libwebsockets to participate in an external thread locking - * scheme around the changes, so the whole thing is threadsafe. - */ -LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -typedef int (callback_function)(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -#ifndef LWS_NO_EXTENSIONS -/** - * extension_callback_function() - Hooks to allow extensions to operate - * @context: Websockets context - * @ext: This extension - * @wsi: Opaque websocket instance pointer - * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library - * @in: Pointer used for some callback reasons - * @len: Length set for some callback reasons - * - * Each extension that is active on a particular connection receives - * callbacks during the connection lifetime to allow the extension to - * operate on websocket data and manage itself. - * - * Libwebsockets takes care of allocating and freeing "user" memory for - * each active extension on each connection. That is what is pointed to - * by the @user parameter. - * - * LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to - * select this extension from the list provided by the client, - * just before the server will send back the handshake accepting - * the connection with this extension active. This gives the - * extension a chance to initialize its connection context found - * in @user. - * - * LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT - * but called when client is instantiating this extension. Some - * extensions will work the same on client and server side and then - * you can just merge handlers for both CONSTRUCTS. - * - * LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was - * being used on is about to be closed and deallocated. It's the - * last chance for the extension to deallocate anything it has - * allocated in the user data (pointed to by @user) before the - * user data is deleted. This same callback is used whether you - * are in client or server instantiation context. - * - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on - * a connection, and a packet of data arrived at the connection, - * it is passed to this callback to give the extension a chance to - * change the data, eg, decompress it. @user is pointing to the - * extension's private connection context data, @in is pointing - * to an lws_tokens struct, it consists of a char * pointer called - * token, and an int called token_len. At entry, these are - * set to point to the received buffer and set to the content - * length. If the extension will grow the content, it should use - * a new buffer allocated in its private user context data and - * set the pointed-to lws_tokens members to point to its buffer. - * - * LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the - * extension a chance to change websocket data just before it will - * be sent out. Using the same lws_token pointer scheme in @in, - * the extension can change the buffer and the length to be - * transmitted how it likes. Again if it wants to grow the - * buffer safely, it should copy the data into its own buffer and - * set the lws_tokens token pointer to it. - */ -LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); - -typedef int (extension_callback_function)(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); -#endif - -/** - * struct libwebsocket_protocols - List of protocols and handlers server - * supports. - * @name: Protocol name that must match the one given in the client - * Javascript new WebSocket(url, 'protocol') name. - * @callback: The service callback used for this protocol. It allows the - * service action for an entire protocol to be encapsulated in - * the protocol-specific callback - * @per_session_data_size: Each new connection using this protocol gets - * this much memory allocated on connection establishment and - * freed on connection takedown. A pointer to this per-connection - * allocation is passed into the callback in the 'user' parameter - * @rx_buffer_size: if you want atomic frames delivered to the callback, you - * should set this to the size of the biggest legal frame that - * you support. If the frame size is exceeded, there is no - * error, but the buffer will spill to the user callback when - * full, which you can detect by using - * libwebsockets_remaining_packet_payload(). Notice that you - * just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING - * and post-padding are automatically also allocated on top. - * @id: ignored by lws, but useful to contain user information bound - * to the selected protocol. For example if this protocol was - * called "myprotocol-v2", you might set id to 2, and the user - * code that acts differently according to the version can do so by - * switch (wsi->protocol->id), user code might use some bits as - * capability flags based on selected protocol version, etc. - * @user: User provided context data at the protocol level. - * Accessible via libwebsockets_get_protocol(wsi)->user - * This should not be confused with wsi->user, it is not the same. - * The library completely ignores any value in here. - * @owning_server: the server init call fills in this opaque pointer when - * registering this protocol with the server. - * @protocol_index: which protocol we are starting from zero - * - * This structure represents one protocol supported by the server. An - * array of these structures is passed to libwebsocket_create_server() - * allows as many protocols as you like to be handled by one server. - * - * The first protocol given has its callback used for user callbacks when - * there is no agreed protocol name, that's true during HTTP part of the - * connection and true if the client did not send a Protocol: header. - */ - -struct libwebsocket_protocols { - const char *name; - callback_function *callback; - size_t per_session_data_size; - size_t rx_buffer_size; - unsigned int id; - void *user; - - /* - * below are filled in on server init and can be left uninitialized, - * no need for user to use them directly either - */ - - struct libwebsocket_context *owning_server; - int protocol_index; -}; - -#ifndef LWS_NO_EXTENSIONS -/** - * struct libwebsocket_extension - An extension we know how to cope with - * - * @name: Formal extension name, eg, "deflate-stream" - * @callback: Service callback - * @per_session_data_size: Libwebsockets will auto-malloc this much - * memory for the use of the extension, a pointer - * to it comes in the @user callback parameter - * @per_context_private_data: Optional storage for this extension that - * is per-context, so it can track stuff across - * all sessions, etc, if it wants - */ - -struct libwebsocket_extension { - const char *name; - extension_callback_function *callback; - size_t per_session_data_size; - void *per_context_private_data; -}; -#endif - -/** - * struct lws_context_creation_info: parameters to create context with - * - * @port: Port to listen on... you can use CONTEXT_PORT_NO_LISTEN to - * suppress listening on any port, that's what you want if you are - * not running a websocket server at all but just using it as a - * client - * @iface: NULL to bind the listen socket to all interfaces, or the - * interface name, eg, "eth2" - * @protocols: Array of structures listing supported protocols and a protocol- - * specific callback for each one. The list is ended with an - * entry that has a NULL callback pointer. - * It's not const because we write the owning_server member - * @extensions: NULL or array of libwebsocket_extension structs listing the - * extensions this context supports. If you configured with - * --without-extensions, you should give NULL here. - * @token_limits: NULL or struct lws_token_limits pointer which is initialized - * with a token length limit for each possible WSI_TOKEN_*** - * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want - * to listen using SSL, set to the filepath to fetch the - * server cert from, otherwise NULL for unencrypted - * @ssl_private_key_filepath: filepath to private key if wanting SSL mode; - * if this is set to NULL but sll_cert_filepath is set, the - * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called to allow - * setting of the private key directly via openSSL library calls - * @ssl_ca_filepath: CA certificate filepath or NULL - * @ssl_cipher_list: List of valid ciphers to use (eg, - * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - * or you can leave it as NULL to get "DEFAULT" - * @gid: group id to change to after setting listen socket, or -1. - * @uid: user id to change to after setting listen socket, or -1. - * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK - * @user: optional user pointer that can be recovered via the context - * pointer using libwebsocket_context_user - * @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to - * all libwebsocket sockets, client or server - * @ka_probes: if ka_time was nonzero, after the timeout expires how many - * times to try to get a response from the peer before giving up - * and killing the connection - * @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes - * attempt - * @provided_client_ssl_ctx: If non-null, swap out libwebsockets ssl - * implementation for the one provided by provided_ssl_ctx. - * Libwebsockets no longer is responsible for freeing the context - * if this option is selected. - */ - -struct lws_context_creation_info { - int port; - const char *iface; - struct libwebsocket_protocols *protocols; - struct libwebsocket_extension *extensions; - struct lws_token_limits *token_limits; - const char *ssl_private_key_password; - const char *ssl_cert_filepath; - const char *ssl_private_key_filepath; - const char *ssl_ca_filepath; - const char *ssl_cipher_list; - const char *http_proxy_address; - unsigned int http_proxy_port; - int gid; - int uid; - unsigned int options; - void *user; - int ka_time; - int ka_probes; - int ka_interval; -#ifdef LWS_OPENSSL_SUPPORT - SSL_CTX *provided_client_ssl_ctx; -#else /* maintain structure layout either way */ - void *provided_client_ssl_ctx; -#endif -}; - -LWS_VISIBLE LWS_EXTERN -void lws_set_log_level(int level, - void (*log_emit_function)(int level, const char *line)); - -LWS_VISIBLE LWS_EXTERN void -lwsl_emit_syslog(int level, const char *line); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_context_destroy(struct libwebsocket_context *context); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_cancel_service(struct libwebsocket_context *context); - -LWS_VISIBLE LWS_EXTERN const unsigned char * -lws_token_to_string(enum lws_token_indexes token); - -LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, - const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); -LWS_VISIBLE LWS_EXTERN int -lws_finalize_http_header(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char **p, - unsigned char *end); -LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); -LWS_VISIBLE LWS_EXTERN int lws_add_http_header_content_length(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned long content_length, - unsigned char **p, - unsigned char *end); -LWS_VISIBLE LWS_EXTERN int -lws_add_http_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, - unsigned char *end); - -LWS_EXTERN int lws_http_transaction_completed(struct libwebsocket *wsi); - -#ifdef LWS_USE_LIBEV -LWS_VISIBLE LWS_EXTERN int -libwebsocket_initloop( - struct libwebsocket_context *context, struct ev_loop *loop); - -LWS_VISIBLE void -libwebsocket_sigint_cb( - struct ev_loop *loop, struct ev_signal *watcher, int revents); -#endif /* LWS_USE_LIBEV */ - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd); - -LWS_VISIBLE LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context); - -enum pending_timeout { - NO_PENDING_TIMEOUT = 0, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - PENDING_TIMEOUT_AWAITING_PING, - PENDING_TIMEOUT_CLOSE_ACK, - PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, - PENDING_TIMEOUT_SSL_ACCEPT, - PENDING_TIMEOUT_HTTP_CONTENT, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, -}; - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs); - -/* - * IMPORTANT NOTICE! - * - * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY) - * the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE - * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len). - * - * This allows us to add protocol info before and after the data, and send as - * one packet on the network without payload copying, for maximum efficiency. - * - * So for example you need this kind of code to use libwebsocket_write with a - * 128-byte payload - * - * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING]; - * - * // fill your part of the buffer... for example here it's all zeros - * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128); - * - * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, - * LWS_WRITE_TEXT); - * - * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just - * use the whole buffer without taking care of the above. - */ - -/* - * this is the frame nonce plus two header plus 8 length - * there's an additional two for mux extension per mux nesting level - * 2 byte prepend on close will already fit because control frames cannot use - * the big length style - */ - -#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION)) -#define LWS_SEND_BUFFER_POST_PADDING 4 - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, - enum libwebsocket_write_protocol protocol); - -/* helper for case where buffer may be const */ -#define libwebsocket_write_http(wsi, buf, len) \ - libwebsocket_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) - -LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers, - int other_headers_len); -LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int libwebsockets_return_http_status( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int code, - const char *html_body); - -LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_get_socket_fd(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_is_final_fragment(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol); - -LWS_VISIBLE LWS_EXTERN size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi); - -/* - * if the protocol does not have any guidence, returns -1. Currently only - * http2 connections get send window information from this API. But your code - * should use it so it can work properly with any protocol. - * - * If nonzero return is the amount of payload data the peer or intermediary has - * reported it has buffer space for. That has NO relationship with the amount - * of buffer space your OS can accept on this connection for a write action. - * - * This number represents the maximum you could send to the peer or intermediary - * on this connection right now without it complaining. - * - * lws manages accounting for send window updates and payload writes - * automatically, so this number reflects the situation at the peer or - * intermediary dynamically. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_get_peer_write_allowance(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata); - -LWS_VISIBLE LWS_EXTERN const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context); - - -LWS_VISIBLE LWS_EXTERN void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, - char *rip, int rip_len); - -LWS_VISIBLE LWS_EXTERN int -libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len); - -LWS_VISIBLE LWS_EXTERN int -lws_daemonize(const char *_lock_path); - -LWS_VISIBLE LWS_EXTERN int -lws_send_pipe_choked(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_partial_buffered(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_frame_is_binary(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_is_ssl(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md); - -LWS_VISIBLE LWS_EXTERN int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); - -LWS_VISIBLE LWS_EXTERN int -lws_b64_decode_string(const char *in, char *out, int out_size); - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_library_version(void); - -/* access to headers... only valid while headers valid */ - -LWS_VISIBLE LWS_EXTERN int -lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h); - -LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h); - -/* - * Note: this is not normally needed as a user api. It's provided in case it is - * useful when integrating with other app poll loop service code. - */ - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char *buf, size_t len); - -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions(); -#endif - -/* - * custom allocator support - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_allocator(void *(*realloc)(void *ptr, size_t size)); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/engine/external/libwebsockets/lws-plat-unix.c b/src/engine/external/libwebsockets/lws-plat-unix.c deleted file mode 100644 index 9af4bdfd9..000000000 --- a/src/engine/external/libwebsockets/lws-plat-unix.c +++ /dev/null @@ -1,442 +0,0 @@ -#include "private-libwebsockets.h" - -/* - * included from libwebsockets.c for unix builds - */ - -unsigned long long time_in_microseconds(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000000) + tv.tv_usec; -} - -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len) -{ - return read(context->fd_random, (char *)buf, len); -} - -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) -{ - struct libwebsocket_pollfd fds; - - /* treat the fact we got a truncated send pending as if we're choked */ - if (wsi->truncated_send_len) - return 1; - - fds.fd = wsi->sock; - fds.events = POLLOUT; - fds.revents = 0; - - if (poll(&fds, 1, 0) != 1) - return 1; - - if ((fds.revents & POLLOUT) == 0) - return 1; - - /* okay to send another packet without blocking */ - - return 0; -} - -LWS_VISIBLE int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd) -{ - return poll(fd, 1, 0); -} - -/* - * This is just used to interrupt poll waiting - * we don't have to do anything with it. - */ -static void lws_sigusr2(int sig) -{ -} - -/** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity - * @context: Websocket context - * - * This function let a call to libwebsocket_service() waiting for a timeout - * immediately return. - */ -LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) -{ - char buf = 0; - - if (write(context->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1) - lwsl_err("Cannot write to dummy pipe"); -} - -LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) -{ - int syslog_level = LOG_DEBUG; - - switch (level) { - case LLL_ERR: - syslog_level = LOG_ERR; - break; - case LLL_WARN: - syslog_level = LOG_WARNING; - break; - case LLL_NOTICE: - syslog_level = LOG_NOTICE; - break; - case LLL_INFO: - syslog_level = LOG_INFO; - break; - } - syslog(syslog_level, "%s", line); -} - -LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) -{ - int n; - int m; - char buf; - - /* stay dead once we are dead */ - - if (!context) - return 1; - - lws_libev_run(context); - - context->service_tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - -#ifdef LWS_OPENSSL_SUPPORT - /* if we know we have non-network pending data, do not wait in poll */ - if (context->ssl_flag_buffered_reads) - timeout_ms = 0; -#endif - n = poll(context->fds, context->fds_count, timeout_ms); - context->service_tid = 0; - -#ifdef LWS_OPENSSL_SUPPORT - if (!context->ssl_flag_buffered_reads && n == 0) { -#else - if (n == 0) /* poll timeout */ { -#endif - libwebsocket_service_fd(context, NULL); - return 0; - } - -#ifdef LWS_OPENSSL_SUPPORT - /* any more will have to set it fresh this time around */ - context->ssl_flag_buffered_reads = 0; -#endif - - if (n < 0) { - if (LWS_ERRNO != LWS_EINTR) - return -1; - return 0; - } - - /* any socket with events to service? */ - - for (n = 0; n < context->fds_count; n++) { -#ifdef LWS_OPENSSL_SUPPORT - struct libwebsocket *wsi; - - wsi = context->lws_lookup[context->fds[n].fd]; - if (wsi == NULL) - continue; - /* - * if he's not flowcontrolled, make sure we service ssl - * pending read data - */ - if (wsi->ssl && wsi->buffered_reads_pending) { - lwsl_debug("wsi %p: forcing POLLIN\n", wsi); - context->fds[n].revents |= context->fds[n].events & POLLIN; - if (context->fds[n].revents & POLLIN) - wsi->buffered_reads_pending = 0; - else - /* somebody left with pending SSL read data */ - context->ssl_flag_buffered_reads = 1; - } -#endif - if (!context->fds[n].revents) - continue; - - if (context->fds[n].fd == context->dummy_pipe_fds[0]) { - if (read(context->fds[n].fd, &buf, 1) != 1) - lwsl_err("Cannot read from dummy pipe."); - continue; - } - - m = libwebsocket_service_fd(context, &context->fds[n]); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } - - return 0; -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd) -{ - int optval = 1; - socklen_t optlen = sizeof(optval); - -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) - struct protoent *tcp_proto; -#endif - - if (context->ka_time) { - /* enable keepalive on this socket */ - optval = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *)&optval, optlen) < 0) - return 1; - -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__CYGWIN__) || defined(__OpenBSD__) - - /* - * didn't find a way to set these per-socket, need to - * tune kernel systemwide values - */ -#else - /* set the keepalive conditions we want on it too */ - optval = context->ka_time; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, - (const void *)&optval, optlen) < 0) - return 1; - - optval = context->ka_interval; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, - (const void *)&optval, optlen) < 0) - return 1; - - optval = context->ka_probes; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, - (const void *)&optval, optlen) < 0) - return 1; -#endif - } - - /* Disable Nagle */ - optval = 1; -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ - !defined(__OpenBSD__) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0) - return 1; -#else - tcp_proto = getprotobyname("TCP"); - if (setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen) < 0) - return 1; -#endif - - /* We are nonblocking... */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - return 1; - - return 0; -} - -LWS_VISIBLE void -lws_plat_drop_app_privileges(struct lws_context_creation_info *info) -{ - if (info->gid != -1) - if (setgid(info->gid)) - lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO)); - if (info->uid != -1) - if (setuid(info->uid)) - lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO)); -} - -LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) -{ - if (lws_libev_init_fd_table(context)) - /* libev handled it instead */ - return 0; - - if (pipe(context->dummy_pipe_fds)) { - lwsl_err("Unable to create pipe\n"); - return 1; - } - - /* use the read end of pipe as first item */ - context->fds[0].fd = context->dummy_pipe_fds[0]; - context->fds[0].events = LWS_POLLIN; - context->fds[0].revents = 0; - context->fds_count = 1; - - context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY); - if (context->fd_random < 0) { - lwsl_err("Unable to open random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, context->fd_random); - return 1; - } - - return 0; -} - -static void sigpipe_handler(int x) -{ -} - - -LWS_VISIBLE int -lws_plat_context_early_init(void) -{ - sigset_t mask; - - signal(SIGUSR2, lws_sigusr2); - sigemptyset(&mask); - sigaddset(&mask, SIGUSR2); - - sigprocmask(SIG_BLOCK, &mask, NULL); - - signal(SIGPIPE, sigpipe_handler); - - return 0; -} - -LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) -{ -} - -LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) -{ - close(context->dummy_pipe_fds[0]); - close(context->dummy_pipe_fds[1]); - close(context->fd_random); -} - -/* cast a struct sockaddr_in6 * into addr for ipv6 */ - -LWS_VISIBLE int -interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen) -{ - int rc = -1; - - struct ifaddrs *ifr; - struct ifaddrs *ifc; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; -#endif - - getifaddrs(&ifr); - for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) { - if (!ifc->ifa_addr) - continue; - - lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname); - - if (strcmp(ifc->ifa_name, ifname)) - continue; - - switch (ifc->ifa_addr->sa_family) { - case AF_INET: -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - /* map IPv4 to IPv6 */ - bzero((char *)&addr6->sin6_addr, - sizeof(struct in6_addr)); - addr6->sin6_addr.s6_addr[10] = 0xff; - addr6->sin6_addr.s6_addr[11] = 0xff; - memcpy(&addr6->sin6_addr.s6_addr[12], - &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr, - sizeof(struct in_addr)); - } else -#endif - memcpy(addr, - (struct sockaddr_in *)ifc->ifa_addr, - sizeof(struct sockaddr_in)); - break; -#ifdef LWS_USE_IPV6 - case AF_INET6: - memcpy(&addr6->sin6_addr, - &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr, - sizeof(struct in6_addr)); - break; -#endif - default: - continue; - } - rc = 0; - } - - freeifaddrs(ifr); - - if (rc == -1) { - /* check if bind to IP adddress */ -#ifdef LWS_USE_IPV6 - if (inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) - rc = 0; - else -#endif - if (inet_pton(AF_INET, ifname, &addr->sin_addr) == 1) - rc = 0; - } - - return rc; -} - -LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ); - context->fds[context->fds_count++].revents = 0; -} - -LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) -{ -} - -LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) -{ - /* if our parent went down, don't linger around */ - if (context->started_with_parent && - kill(context->started_with_parent, 0) < 0) - kill(getpid(), SIGTERM); -} - -LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) -{ - return 0; -} - -LWS_VISIBLE int -lws_plat_open_file(const char* filename, unsigned long* filelen) -{ - struct stat stat_buf; - int ret = open(filename, O_RDONLY); - - if (ret < 0) - return LWS_INVALID_FILE; - - if (fstat(ret, &stat_buf) < 0) { - close(ret); - return LWS_INVALID_FILE; - } - *filelen = stat_buf.st_size; - return ret; -} - -#ifdef LWS_USE_IPV6 -LWS_VISIBLE const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) -{ - return inet_ntop(af, src, dst, cnt); -} -#endif diff --git a/src/engine/external/libwebsockets/output.c b/src/engine/external/libwebsockets/output.c deleted file mode 100644 index b914f281c..000000000 --- a/src/engine/external/libwebsockets/output.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -static int -libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi) -{ - int n; - - /* fetch the per-frame nonce */ - - n = libwebsockets_get_random(wsi->protocol->owning_server, - wsi->u.ws.frame_masking_nonce_04, 4); - if (n != 4) { - lwsl_parser("Unable to read from random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, n); - return 1; - } - - /* start masking from first byte of masking key buffer */ - wsi->u.ws.frame_mask_index = 0; - - return 0; -} - -#ifdef _DEBUG - -LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len) -{ - int n; - int m; - int start; - unsigned char *buf = (unsigned char *)vbuf; - char line[80]; - char *p; - - lwsl_parser("\n"); - - for (n = 0; n < len;) { - start = n; - p = line; - - p += sprintf(p, "%04X: ", start); - - for (m = 0; m < 16 && n < len; m++) - p += sprintf(p, "%02X ", buf[n++]); - while (m++ < 16) - p += sprintf(p, " "); - - p += sprintf(p, " "); - - for (m = 0; m < 16 && (start + m) < len; m++) { - if (buf[start + m] >= ' ' && buf[start + m] < 127) - *p++ = buf[start + m]; - else - *p++ = '.'; - } - while (m++ < 16) - *p++ = ' '; - - *p++ = '\n'; - *p = '\0'; - lwsl_debug("%s", line); - } - lwsl_debug("\n"); -} - -#endif - -/* - * notice this returns number of bytes consumed, or -1 - */ - -int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) -{ - struct libwebsocket_context *context = wsi->protocol->owning_server; - int n; - size_t real_len = len; - int m; - - if (!len) - return 0; - /* just ignore sends after we cleared the truncation buffer */ - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE && - !wsi->truncated_send_len) - return len; - - if (wsi->truncated_send_len && (buf < wsi->truncated_send_malloc || - buf > (wsi->truncated_send_malloc + - wsi->truncated_send_len + - wsi->truncated_send_offset))) { - lwsl_err("****** %x Sending new, pending truncated ...\n", wsi); - assert(0); - } - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, &buf, len); - if (m < 0) - return -1; - if (m) /* handled */ { - n = m; - goto handle_truncated_send; - } - if (wsi->sock < 0) - lwsl_warn("** error invalid sock but expected to send\n"); - - /* - * nope, send it on the socket directly - */ - lws_latency_pre(context, wsi); - n = lws_ssl_capable_write(wsi, buf, len); - lws_latency(context, wsi, "send lws_issue_raw", n, n == len); - - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - /* we're going to close, let close know sends aren't possible */ - wsi->socket_is_permanently_unusable = 1; - return -1; - case LWS_SSL_CAPABLE_MORE_SERVICE: - /* nothing got sent, not fatal, retry the whole thing later */ - n = 0; - break; - } - -handle_truncated_send: - /* - * we were already handling a truncated send? - */ - if (wsi->truncated_send_len) { - lwsl_info("***** %x partial send moved on by %d (vs %d)\n", - wsi, n, real_len); - wsi->truncated_send_offset += n; - wsi->truncated_send_len -= n; - - if (!wsi->truncated_send_len) { - lwsl_info("***** %x partial send completed\n", wsi); - /* done with it, but don't free it */ - n = real_len; - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - lwsl_info("***** %x signalling to close now\n", wsi); - return -1; /* retry closing now */ - } - } - /* always callback on writeable */ - libwebsocket_callback_on_writable( - wsi->protocol->owning_server, wsi); - - return n; - } - - if (n == real_len) - /* what we just sent went out cleanly */ - return n; - - if (n && wsi->u.ws.clean_buffer) - /* - * This buffer unaffected by extension rewriting. - * It means the user code is expected to deal with - * partial sends. (lws knows the header was already - * sent, so on next send will just resume sending - * payload) - */ - return n; - - /* - * Newly truncated send. Buffer the remainder (it will get - * first priority next time the socket is writable) - */ - lwsl_info("***** %x new partial sent %d from %d total\n", - wsi, n, real_len); - - /* - * - if we still have a suitable malloc lying around, use it - * - or, if too small, reallocate it - * - or, if no buffer, create it - */ - if (!wsi->truncated_send_malloc || - real_len - n > wsi->truncated_send_allocation) { - lws_free(wsi->truncated_send_malloc); - - wsi->truncated_send_allocation = real_len - n; - wsi->truncated_send_malloc = lws_malloc(real_len - n); - if (!wsi->truncated_send_malloc) { - lwsl_err("truncated send: unable to malloc %d\n", - real_len - n); - return -1; - } - } - wsi->truncated_send_offset = 0; - wsi->truncated_send_len = real_len - n; - memcpy(wsi->truncated_send_malloc, buf + n, real_len - n); - - /* since something buffered, force it to get another chance to send */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); - - return real_len; -} - -/** - * libwebsocket_write() - Apply protocol then write data to client - * @wsi: Websocket instance (available from user callback) - * @buf: The data to send. For data being sent on a websocket - * connection (ie, not default http), this buffer MUST have - * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer - * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid - * in the buffer after (buf + len). This is so the protocol - * header and trailer data can be added in-situ. - * @len: Count of the data bytes in the payload starting from buf - * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one - * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate - * data on a websockets connection. Remember to allow the extra - * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT - * are used. - * - * This function provides the way to issue data back to the client - * for both http and websocket protocols. - * - * In the case of sending using websocket protocol, be sure to allocate - * valid storage before and after buf as explained above. This scheme - * allows maximum efficiency of sending data and protocol in a single - * packet while not burdening the user code with any protocol knowledge. - * - * Return may be -1 for a fatal error needing connection close, or a - * positive number reflecting the amount of bytes actually sent. This - * can be less than the requested number of bytes due to OS memory - * pressure at any given time. - */ - -LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, - size_t len, enum libwebsocket_write_protocol protocol) -{ - int n; - int pre = 0; - int post = 0; - int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT; - unsigned char *dropmask = NULL; - unsigned char is_masked_bit = 0; - size_t orig_len = len; - struct lws_tokens eff_buf; - - if (len == 0 && protocol != LWS_WRITE_CLOSE && - protocol != LWS_WRITE_PING && protocol != LWS_WRITE_PONG) { - lwsl_warn("zero length libwebsocket_write attempt\n"); - return 0; - } - - if (protocol == LWS_WRITE_HTTP || - protocol == LWS_WRITE_HTTP_FINAL || - protocol == LWS_WRITE_HTTP_HEADERS) - goto send_raw; - - /* websocket protocol, either binary or text */ - - if (wsi->state != WSI_STATE_ESTABLISHED) - return -1; - - /* if we are continuing a frame that already had its header done */ - - if (wsi->u.ws.inside_frame) - goto do_more_inside_frame; - - wsi->u.ws.clean_buffer = 1; - - /* - * give a chance to the extensions to modify payload - * pre-TX mangling is not allowed to truncate - */ - eff_buf.token = (char *)buf; - eff_buf.token_len = len; - - switch (protocol) { - case LWS_WRITE_PING: - case LWS_WRITE_PONG: - case LWS_WRITE_CLOSE: - break; - default: - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_TX, &eff_buf, 0) < 0) - return -1; - } - - /* - * an extension did something we need to keep... for example, if - * compression extension, it has already updated its state according - * to this being issued - */ - if ((char *)buf != eff_buf.token) - /* - * extension recreated it: - * need to buffer this if not all sent - */ - wsi->u.ws.clean_buffer = 0; - - buf = (unsigned char *)eff_buf.token; - len = eff_buf.token_len; - - switch (wsi->ietf_spec_revision) { - case 13: - - if (masked7) { - pre += 4; - dropmask = &buf[0 - pre]; - is_masked_bit = 0x80; - } - - switch (protocol & 0xf) { - case LWS_WRITE_TEXT: - n = LWS_WS_OPCODE_07__TEXT_FRAME; - break; - case LWS_WRITE_BINARY: - n = LWS_WS_OPCODE_07__BINARY_FRAME; - break; - case LWS_WRITE_CONTINUATION: - n = LWS_WS_OPCODE_07__CONTINUATION; - break; - - case LWS_WRITE_CLOSE: - n = LWS_WS_OPCODE_07__CLOSE; - - /* - * 06+ has a 2-byte status code in network order - * we can do this because we demand post-buf - */ - - if (wsi->u.ws.close_reason) { - /* reason codes count as data bytes */ - buf -= 2; - buf[0] = wsi->u.ws.close_reason >> 8; - buf[1] = wsi->u.ws.close_reason; - len += 2; - } - break; - case LWS_WRITE_PING: - n = LWS_WS_OPCODE_07__PING; - break; - case LWS_WRITE_PONG: - n = LWS_WS_OPCODE_07__PONG; - break; - default: - lwsl_warn("lws_write: unknown write opc / protocol\n"); - return -1; - } - - if (!(protocol & LWS_WRITE_NO_FIN)) - n |= 1 << 7; - - if (len < 126) { - pre += 2; - buf[-pre] = n; - buf[-pre + 1] = len | is_masked_bit; - } else { - if (len < 65536) { - pre += 4; - buf[-pre] = n; - buf[-pre + 1] = 126 | is_masked_bit; - buf[-pre + 2] = len >> 8; - buf[-pre + 3] = len; - } else { - pre += 10; - buf[-pre] = n; - buf[-pre + 1] = 127 | is_masked_bit; -#if defined __LP64__ - buf[-pre + 2] = (len >> 56) & 0x7f; - buf[-pre + 3] = len >> 48; - buf[-pre + 4] = len >> 40; - buf[-pre + 5] = len >> 32; -#else - buf[-pre + 2] = 0; - buf[-pre + 3] = 0; - buf[-pre + 4] = 0; - buf[-pre + 5] = 0; -#endif - buf[-pre + 6] = len >> 24; - buf[-pre + 7] = len >> 16; - buf[-pre + 8] = len >> 8; - buf[-pre + 9] = len; - } - } - break; - } - -do_more_inside_frame: - - /* - * Deal with masking if we are in client -> server direction and - * the protocol demands it - */ - - if (wsi->mode == LWS_CONNMODE_WS_CLIENT) { - - if (!wsi->u.ws.inside_frame) - if (libwebsocket_0405_frame_mask_generate(wsi)) { - lwsl_err("frame mask generation failed\n"); - return -1; - } - - /* - * in v7, just mask the payload - */ - if (dropmask) { /* never set if already inside frame */ - for (n = 4; n < (int)len + 4; n++) - dropmask[n] = dropmask[n] ^ - wsi->u.ws.frame_masking_nonce_04[ - (wsi->u.ws.frame_mask_index++) & 3]; - - /* copy the frame nonce into place */ - memcpy(dropmask, wsi->u.ws.frame_masking_nonce_04, 4); - } - } - -send_raw: - switch (protocol) { - case LWS_WRITE_CLOSE: -/* lwsl_hexdump(&buf[-pre], len + post); */ - case LWS_WRITE_HTTP: - case LWS_WRITE_HTTP_FINAL: - case LWS_WRITE_HTTP_HEADERS: - case LWS_WRITE_PONG: - case LWS_WRITE_PING: -#ifdef LWS_USE_HTTP2 - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) { - unsigned char flags = 0; - - n = LWS_HTTP2_FRAME_TYPE_DATA; - if (protocol == LWS_WRITE_HTTP_HEADERS) { - n = LWS_HTTP2_FRAME_TYPE_HEADERS; - flags = LWS_HTTP2_FLAG_END_HEADERS; - if (wsi->u.http2.send_END_STREAM) - flags |= LWS_HTTP2_FLAG_END_STREAM; - } - - if ((protocol == LWS_WRITE_HTTP || protocol == LWS_WRITE_HTTP_FINAL) && wsi->u.http.content_length) { - wsi->u.http.content_remain -= len; - lwsl_info("%s: content_remain = %lu\n", __func__, wsi->u.http.content_remain); - if (!wsi->u.http.content_remain) { - lwsl_info("%s: selecting final write mode\n", __func__); - protocol = LWS_WRITE_HTTP_FINAL; - } - } - - if (protocol == LWS_WRITE_HTTP_FINAL && wsi->u.http2.END_STREAM) { - lwsl_info("%s: setting END_STREAM\n", __func__); - flags |= LWS_HTTP2_FLAG_END_STREAM; - } - - return lws_http2_frame_write(wsi, n, flags, wsi->u.http2.my_stream_id, len, buf); - } -#endif - return lws_issue_raw(wsi, (unsigned char *)buf - pre, - len + pre + post); - default: - break; - } - - wsi->u.ws.inside_frame = 1; - - /* - * give any active extensions a chance to munge the buffer - * before send. We pass in a pointer to an lws_tokens struct - * prepared with the default buffer and content length that's in - * there. Rather than rewrite the default buffer, extensions - * that expect to grow the buffer can adapt .token to - * point to their own per-connection buffer in the extension - * user allocation. By default with no extensions or no - * extension callback handling, just the normal input buffer is - * used then so it is efficient. - * - * callback returns 1 in case it wants to spill more buffers - * - * This takes care of holding the buffer if send is incomplete, ie, - * if wsi->u.ws.clean_buffer is 0 (meaning an extension meddled with - * the buffer). If wsi->u.ws.clean_buffer is 1, it will instead - * return to the user code how much OF THE USER BUFFER was consumed. - */ - - n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post); - if (n <= 0) - return n; - - if (n == len + pre + post) { - /* everything in the buffer was handled (or rebuffered...) */ - wsi->u.ws.inside_frame = 0; - return orig_len; - } - - /* - * it is how many bytes of user buffer got sent... may be < orig_len - * in which case callback when writable has already been arranged - * and user code can call libwebsocket_write() again with the rest - * later. - */ - - return n - (pre + post); -} - -LWS_VISIBLE int libwebsockets_serve_http_file_fragment( - struct libwebsocket_context *context, struct libwebsocket *wsi) -{ - int n; - int m; - - while (!lws_send_pipe_choked(wsi)) { - - if (wsi->truncated_send_len) { - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from libwebsockets_serve_http_file_fragment\n"); - return -1; - } - continue; - } - - if (wsi->u.http.filepos == wsi->u.http.filelen) - goto all_sent; - - compatible_file_read(n, wsi->u.http.fd, context->service_buffer, - sizeof(context->service_buffer)); - if (n < 0) - return -1; /* caller will close */ - if (n) { - wsi->u.http.filepos += n; - m = libwebsocket_write(wsi, context->service_buffer, n, - wsi->u.http.filepos == wsi->u.http.filelen ? LWS_WRITE_HTTP_FINAL : LWS_WRITE_HTTP); - if (m < 0) - return -1; - - if (m != n) - /* adjust for what was not sent */ - if (compatible_file_seek_cur(wsi->u.http.fd, m - n) < 0) - return -1; - } -all_sent: - if (!wsi->truncated_send_len && - wsi->u.http.filepos == wsi->u.http.filelen) { - wsi->state = WSI_STATE_HTTP; - - if (wsi->protocol->callback) - /* ignore callback returned value */ - user_callback_handle_rxflow( - wsi->protocol->callback, context, wsi, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - wsi->user_space, NULL, 0); - return 1; /* >0 indicates completed */ - } - } - - lwsl_info("choked before able to send whole file (post)\n"); - libwebsocket_callback_on_writable(context, wsi); - - return 0; /* indicates further processing must be done */ -} - -LWS_VISIBLE int -lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len) -{ - int n; - - n = recv(wsi->sock, buf, len, 0); - if (n >= 0) - return n; - - lwsl_warn("error on reading from skt\n"); - return LWS_SSL_CAPABLE_ERROR; -} - -LWS_VISIBLE int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) -{ - int n; - - n = send(wsi->sock, buf, len, 0); - if (n >= 0) - return n; - - if (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK || - LWS_ERRNO == LWS_EINTR) { - if (LWS_ERRNO == LWS_EWOULDBLOCK) - lws_set_blocking_send(wsi); - - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - lwsl_debug("ERROR writing len %d to skt %d\n", len, n); - return LWS_SSL_CAPABLE_ERROR; -} diff --git a/src/engine/external/libwebsockets/parsers.c b/src/engine/external/libwebsockets/parsers.c deleted file mode 100644 index 2b4a900b0..000000000 --- a/src/engine/external/libwebsockets/parsers.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -unsigned char lextable[] = { - #include "lextable.h" -}; - -#define FAIL_CHAR 0x08 - -int lextable_decode(int pos, char c) -{ - - c = tolower(c); - - while (1) { - if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */ - if ((lextable[pos] & 0x7f) != c) - return -1; - /* fall thru */ - pos++; - if (lextable[pos] == FAIL_CHAR) - return -1; - return pos; - } - - if (lextable[pos] == FAIL_CHAR) - return -1; - - /* b7 = 0, end or 3-byte */ - if (lextable[pos] < FAIL_CHAR) /* terminal marker */ - return pos; - - if (lextable[pos] == c) /* goto */ - return pos + (lextable[pos + 1]) + - (lextable[pos + 2] << 8); - /* fall thru goto */ - pos += 3; - /* continue */ - } -} - -int lws_allocate_header_table(struct libwebsocket *wsi) -{ - /* Be sure to free any existing header data to avoid mem leak: */ - lws_free_header_table(wsi); - wsi->u.hdr.ah = lws_malloc(sizeof(*wsi->u.hdr.ah)); - if (wsi->u.hdr.ah == NULL) { - lwsl_err("Out of memory\n"); - return -1; - } - memset(wsi->u.hdr.ah->frag_index, 0, sizeof(wsi->u.hdr.ah->frag_index)); - wsi->u.hdr.ah->next_frag_index = 0; - wsi->u.hdr.ah->pos = 0; - - return 0; -} - -int lws_free_header_table(struct libwebsocket *wsi) -{ - lws_free2(wsi->u.hdr.ah); - wsi->u.hdr.ah = NULL; - return 0; -}; - -LWS_VISIBLE int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h) -{ - int n; - int len = 0; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return 0; - do { - len += wsi->u.hdr.ah->frags[n].len; - n = wsi->u.hdr.ah->frags[n].next_frag_index; - } while (n); - - return len; -} - -LWS_VISIBLE int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h) -{ - int toklen = lws_hdr_total_length(wsi, h); - int n; - - if (toklen >= len) - return -1; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return 0; - - do { - strcpy(dest, - &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]); - dest += wsi->u.hdr.ah->frags[n].len; - n = wsi->u.hdr.ah->frags[n].next_frag_index; - } while (n); - - return toklen; -} - -char *lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h) -{ - int n; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return NULL; - - return &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]; -} - -int lws_hdr_simple_create(struct libwebsocket *wsi, - enum lws_token_indexes h, const char *s) -{ - wsi->u.hdr.ah->next_frag_index++; - if (wsi->u.hdr.ah->next_frag_index == - sizeof(wsi->u.hdr.ah->frags) / sizeof(wsi->u.hdr.ah->frags[0])) { - lwsl_warn("More hdr frags than we can deal with, dropping\n"); - return -1; - } - - wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->next_frag_index; - - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].next_frag_index = - 0; - - do { - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_err("Ran out of header data space\n"); - return -1; - } - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s; - if (*s) - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].len++; - } while (*s++); - - return 0; -} - -static char char_to_hex(const char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - return -1; -} - -static int issue_char(struct libwebsocket *wsi, unsigned char c) -{ - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_warn("excessive header content\n"); - return -1; - } - - if( wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >= - wsi->u.hdr.current_token_limit) { - lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state); - return 1; - }; - - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c; - if (c) - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; - - return 0; -} - -int libwebsocket_parse( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c) -{ - int n; - - switch (wsi->u.hdr.parser_state) { - default: - - lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c); - - /* collect into malloc'd buffers */ - /* optional initial space swallow */ - if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->frag_index[ - wsi->u.hdr.parser_state]].len && c == ' ') - break; - - if ((wsi->u.hdr.parser_state != WSI_TOKEN_GET_URI) && - (wsi->u.hdr.parser_state != WSI_TOKEN_POST_URI) && - (wsi->u.hdr.parser_state != WSI_TOKEN_OPTIONS_URI)) - goto check_eol; - - /* special URI processing... end at space */ - - if (c == ' ') { - /* enforce starting with / */ - if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len) - if (issue_char(wsi, '/') < 0) - return -1; - - /* begin parsing HTTP version: */ - if (issue_char(wsi, '\0') < 0) - return -1; - wsi->u.hdr.parser_state = WSI_TOKEN_HTTP; - goto start_fragment; - } - - /* special URI processing... convert %xx */ - - switch (wsi->u.hdr.ues) { - case URIES_IDLE: - if (c == '%') { - wsi->u.hdr.ues = URIES_SEEN_PERCENT; - goto swallow; - } - break; - case URIES_SEEN_PERCENT: - if (char_to_hex(c) < 0) { - /* regurgitate */ - if (issue_char(wsi, '%') < 0) - return -1; - wsi->u.hdr.ues = URIES_IDLE; - /* continue on to assess c */ - break; - } - wsi->u.hdr.esc_stash = c; - wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1; - goto swallow; - - case URIES_SEEN_PERCENT_H1: - if (char_to_hex(c) < 0) { - /* regurgitate */ - issue_char(wsi, '%'); - wsi->u.hdr.ues = URIES_IDLE; - /* regurgitate + assess */ - if (libwebsocket_parse(context, wsi, wsi->u.hdr.esc_stash) < 0) - return -1; - /* continue on to assess c */ - break; - } - c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) | - char_to_hex(c); - wsi->u.hdr.ues = URIES_IDLE; - break; - } - - /* - * special URI processing... - * convert /.. or /... or /../ etc to / - * convert /./ to / - * convert // or /// etc to / - * leave /.dir or whatever alone - */ - - switch (wsi->u.hdr.ups) { - case URIPS_IDLE: - /* issue the first / always */ - if (c == '/') - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - break; - case URIPS_SEEN_SLASH: - /* swallow subsequent slashes */ - if (c == '/') - goto swallow; - /* track and swallow the first . after / */ - if (c == '.') { - wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT; - goto swallow; - } - wsi->u.hdr.ups = URIPS_IDLE; - break; - case URIPS_SEEN_SLASH_DOT: - /* swallow second . */ - if (c == '.') { - /* - * back up one dir level if possible - * safe against header fragmentation because - * the method URI can only be in 1 fragment - */ - if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 2) { - wsi->u.hdr.ah->pos--; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--; - do { - wsi->u.hdr.ah->pos--; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--; - } while (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 1 && - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos] != '/'); - } - wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT; - goto swallow; - } - /* change /./ to / */ - if (c == '/') { - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - goto swallow; - } - /* it was like /.dir ... regurgitate the . */ - wsi->u.hdr.ups = URIPS_IDLE; - issue_char(wsi, '.'); - break; - - case URIPS_SEEN_SLASH_DOT_DOT: - /* swallow prior .. chars and any subsequent . */ - if (c == '.') - goto swallow; - /* last issued was /, so another / == // */ - if (c == '/') - goto swallow; - /* last we issued was / so SEEN_SLASH */ - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - break; - case URIPS_ARGUMENTS: - /* leave them alone */ - break; - } - - if (c == '?') { /* start of URI arguments */ - /* seal off uri header */ - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0'; - - /* move to using WSI_TOKEN_HTTP_URI_ARGS */ - wsi->u.hdr.ah->next_frag_index++; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].next_frag_index = 0; - - wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = - wsi->u.hdr.ah->next_frag_index; - - /* defeat normal uri path processing */ - wsi->u.hdr.ups = URIPS_ARGUMENTS; - goto swallow; - } - -check_eol: - - /* bail at EOL */ - if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE && - c == '\x0d') { - c = '\0'; - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - lwsl_parser("*\n"); - } - - n = issue_char(wsi, c); - if (n < 0) - return -1; - if (n > 0) - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - -swallow: - /* per-protocol end of headers management */ - - if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - break; - - /* collecting and checking a name part */ - case WSI_TOKEN_NAME_PART: - lwsl_parser("WSI_TOKEN_NAME_PART '%c'\n", c); - - wsi->u.hdr.lextable_pos = - lextable_decode(wsi->u.hdr.lextable_pos, c); - - if (wsi->u.hdr.lextable_pos < 0) { - /* this is not a header we know about */ - if (wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI] || - wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] || - wsi->u.hdr.ah->frag_index[WSI_TOKEN_OPTIONS_URI] || - wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP]) { - /* - * already had the method, no idea what - * this crap is, ignore - */ - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - break; - } - /* - * hm it's an unknown http method in fact, - * treat as dangerous - */ - - lwsl_info("Unknown method - dropping\n"); - return -1; - } - if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) { - - /* terminal state */ - - n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) | - lextable[wsi->u.hdr.lextable_pos + 1]; - - lwsl_parser("known hdr %d\n", n); - if (n == WSI_TOKEN_GET_URI && - wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI]) { - lwsl_warn("Duplicated GET\n"); - return -1; - } - if (n == WSI_TOKEN_POST_URI && - wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI]) { - lwsl_warn("Duplicated POST\n"); - return -1; - } - if (n == WSI_TOKEN_OPTIONS_URI && - wsi->u.hdr.ah->frag_index[WSI_TOKEN_OPTIONS_URI]) { - lwsl_warn("Duplicated OPTIONS\n"); - return -1; - } - - /* - * WSORIGIN is protocol equiv to ORIGIN, - * JWebSocket likes to send it, map to ORIGIN - */ - if (n == WSI_TOKEN_SWORIGIN) - n = WSI_TOKEN_ORIGIN; - - wsi->u.hdr.parser_state = (enum lws_token_indexes) - (WSI_TOKEN_GET_URI + n); - - if (context->token_limits) - wsi->u.hdr.current_token_limit = - context->token_limits->token_limit[wsi->u.hdr.parser_state]; - else - wsi->u.hdr.current_token_limit = sizeof(wsi->u.hdr.ah->data); - - if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - - goto start_fragment; - } - break; - -start_fragment: - wsi->u.hdr.ah->next_frag_index++; - if (wsi->u.hdr.ah->next_frag_index == - sizeof(wsi->u.hdr.ah->frags) / - sizeof(wsi->u.hdr.ah->frags[0])) { - lwsl_warn("More hdr frags than we can deal with\n"); - return -1; - } - - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].next_frag_index = 0; - - n = wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state]; - if (!n) { /* first fragment */ - wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state] = - wsi->u.hdr.ah->next_frag_index; - break; - } - /* continuation */ - while (wsi->u.hdr.ah->frags[n].next_frag_index) - n = wsi->u.hdr.ah->frags[n].next_frag_index; - wsi->u.hdr.ah->frags[n].next_frag_index = - wsi->u.hdr.ah->next_frag_index; - - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_warn("excessive header content\n"); - return -1; - } - - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = ' '; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; - break; - - /* skipping arg part of a name we didn't recognize */ - case WSI_TOKEN_SKIPPING: - lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c); - - if (c == '\x0d') - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - break; - - case WSI_TOKEN_SKIPPING_SAW_CR: - lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c); - if (c == '\x0a') { - wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; - wsi->u.hdr.lextable_pos = 0; - } else - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - break; - /* we're done, ignore anything else */ - - case WSI_PARSING_COMPLETE: - lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c); - break; - } - - return 0; - -set_parsing_complete: - - if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) { - if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION)) - wsi->ietf_spec_revision = - atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION)); - - lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision); - } - wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE; - wsi->hdr_parsing_completed = 1; - - return 0; -} - - -/** - * lws_frame_is_binary: true if the current frame was sent in binary mode - * - * @wsi: the connection we are inquiring about - * - * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if - * it's interested to see if the frame it's dealing with was sent in binary - * mode. - */ - -LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi) -{ - return wsi->u.ws.frame_is_binary; -} - -int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) -{ - int n; - struct lws_tokens eff_buf; - int ret = 0; - - switch (wsi->lws_rx_parse_state) { - case LWS_RXPS_NEW: - - switch (wsi->ietf_spec_revision) { - case 13: - /* - * no prepended frame key any more - */ - wsi->u.ws.all_zero_nonce = 1; - goto handle_first; - - default: - lwsl_warn("lws_rx_sm: unknown spec version %d\n", - wsi->ietf_spec_revision); - break; - } - break; - case LWS_RXPS_04_MASK_NONCE_1: - wsi->u.ws.frame_masking_nonce_04[1] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2; - break; - case LWS_RXPS_04_MASK_NONCE_2: - wsi->u.ws.frame_masking_nonce_04[2] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3; - break; - case LWS_RXPS_04_MASK_NONCE_3: - wsi->u.ws.frame_masking_nonce_04[3] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - - /* - * start from the zero'th byte in the XOR key buffer since - * this is the start of a frame with a new key - */ - - wsi->u.ws.frame_mask_index = 0; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1; - break; - - /* - * 04 logical framing from the spec (all this is masked when incoming - * and has to be unmasked) - * - * We ignore the possibility of extension data because we don't - * negotiate any extensions at the moment. - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-------+-+-------------+-------------------------------+ - * |F|R|R|R| opcode|R| Payload len | Extended payload length | - * |I|S|S|S| (4) |S| (7) | (16/63) | - * |N|V|V|V| |V| | (if payload len==126/127) | - * | |1|2|3| |4| | | - * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - * | Extended payload length continued, if payload len == 127 | - * + - - - - - - - - - - - - - - - +-------------------------------+ - * | | Extension data | - * +-------------------------------+ - - - - - - - - - - - - - - - + - * : : - * +---------------------------------------------------------------+ - * : Application data : - * +---------------------------------------------------------------+ - * - * We pass payload through to userland as soon as we get it, ignoring - * FIN. It's up to userland to buffer it up if it wants to see a - * whole unfragmented block of the original size (which may be up to - * 2^63 long!) - */ - - case LWS_RXPS_04_FRAME_HDR_1: -handle_first: - - wsi->u.ws.opcode = c & 0xf; - wsi->u.ws.rsv = c & 0x70; - wsi->u.ws.final = !!((c >> 7) & 1); - - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - wsi->u.ws.frame_is_binary = - wsi->u.ws.opcode == LWS_WS_OPCODE_07__BINARY_FRAME; - break; - } - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN: - - wsi->u.ws.this_frame_masked = !!(c & 0x80); - - switch (c & 0x7f) { - case 126: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; - break; - case 127: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; - break; - default: - wsi->u.ws.rx_packet_length = c & 0x7f; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - if (wsi->u.ws.rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->u.ws.rx_packet_length = c << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->u.ws.rx_packet_length |= c; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_8: - if (c & 0x80) { - lwsl_warn("b63 of length must be zero\n"); - /* kill the connection */ - return -1; - } -#if defined __LP64__ - wsi->u.ws.rx_packet_length = ((size_t)c) << 56; -#else - wsi->u.ws.rx_packet_length = 0; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_7: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 48; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_6: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 40; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_5: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 32; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 24; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 16; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->u.ws.rx_packet_length |= ((size_t)c); - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->u.ws.frame_masking_nonce_04[0] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->u.ws.frame_masking_nonce_04[1] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->u.ws.frame_masking_nonce_04[2] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->u.ws.frame_masking_nonce_04[3] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - wsi->u.ws.frame_mask_index = 0; - if (wsi->u.ws.rx_packet_length == 0) { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - - - case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - - if (!wsi->u.ws.rx_user_buffer) { - lwsl_err("NULL user buffer...\n"); - return 1; - } - - if (wsi->u.ws.all_zero_nonce) - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = c; - else - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = - c ^ wsi->u.ws.frame_masking_nonce_04[ - (wsi->u.ws.frame_mask_index++) & 3]; - - if (--wsi->u.ws.rx_packet_length == 0) { - /* spill because we have the whole frame */ - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - - /* - * if there's no protocol max frame size given, we are - * supposed to default to LWS_MAX_SOCKET_IO_BUF - */ - - if (!wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - LWS_MAX_SOCKET_IO_BUF) - break; - else - if (wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - wsi->protocol->rx_buffer_size) - break; - - /* spill because we filled our rx buffer */ -spill: - /* - * is this frame a control packet we should take care of at this - * layer? If so service it and hide it from the user callback - */ - - lwsl_parser("spill on %s\n", wsi->protocol->name); - - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__CLOSE: - /* is this an acknowledgement of our close? */ - if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) { - /* - * fine he has told us he is closing too, let's - * finish our close - */ - lwsl_parser("seen client close ack\n"); - return -1; - } - lwsl_parser("server sees client close packet\n"); - /* parrot the close packet payload back */ - n = libwebsocket_write(wsi, (unsigned char *) - &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head, - LWS_WRITE_CLOSE); - if (n < 0) - lwsl_info("write of close ack failed %d\n", n); - wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY; - /* close the connection */ - return -1; - - case LWS_WS_OPCODE_07__PING: - lwsl_info("received %d byte ping, sending pong\n", - wsi->u.ws.rx_user_buffer_head); - - if (wsi->u.ws.ping_payload_len) { - /* - * there is already a pending ping payload - * we should just log and drop - */ - lwsl_parser("DROP PING since one pending\n"); - goto ping_drop; - } - - /* control packets can only be < 128 bytes long */ - if (wsi->u.ws.ping_payload_len > 128 - 4) { - lwsl_parser("DROP PING payload too large\n"); - goto ping_drop; - } - - /* if existing buffer is too small, drop it */ - if (wsi->u.ws.ping_payload_buf && - wsi->u.ws.ping_payload_alloc < wsi->u.ws.rx_user_buffer_head) { - lws_free2(wsi->u.ws.ping_payload_buf); - } - - /* if no buffer, allocate it */ - if (!wsi->u.ws.ping_payload_buf) { - wsi->u.ws.ping_payload_buf = lws_malloc(wsi->u.ws.rx_user_buffer_head - + LWS_SEND_BUFFER_PRE_PADDING); - wsi->u.ws.ping_payload_alloc = wsi->u.ws.rx_user_buffer_head; - } - - /* stash the pong payload */ - memcpy(wsi->u.ws.ping_payload_buf + LWS_SEND_BUFFER_PRE_PADDING, - &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head); - - wsi->u.ws.ping_payload_len = wsi->u.ws.rx_user_buffer_head; - - /* get it sent as soon as possible */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); -ping_drop: - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - - case LWS_WS_OPCODE_07__PONG: - /* ... then just drop it */ - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - case LWS_WS_OPCODE_07__CONTINUATION: - break; - - default: - lwsl_parser("passing opc %x up to exts\n", - wsi->u.ws.opcode); - /* - * It's something special we can't understand here. - * Pass the payload up to the extension's parsing - * state machine. - */ - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - &eff_buf, 0) <= 0) /* not handle or fail */ - lwsl_ext("ext opc opcode 0x%x unknown\n", - wsi->u.ws.opcode); - - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - } - - /* - * No it's real payload, pass it up to the user callback. - * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using libwebsocket_write - */ - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_RX, &eff_buf, 0) < 0) - return -1; - - if (eff_buf.token_len > 0) { - eff_buf.token[eff_buf.token_len] = '\0'; - - if (wsi->protocol->callback) - ret = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi->protocol->owning_server, - wsi, LWS_CALLBACK_RECEIVE, - wsi->user_space, - eff_buf.token, - eff_buf.token_len); - else - lwsl_err("No callback on payload spill!\n"); - } - - wsi->u.ws.rx_user_buffer_head = 0; - break; - } - - return ret; - -illegal_ctl_length: - - lwsl_warn("Control frame with xtended length is illegal\n"); - /* kill the connection */ - return -1; -} - - -/** - * libwebsockets_remaining_packet_payload() - Bytes to come before "overall" - * rx packet is complete - * @wsi: Websocket instance (available from user callback) - * - * This function is intended to be called from the callback if the - * user code is interested in "complete packets" from the client. - * libwebsockets just passes through payload as it comes and issues a buffer - * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE - * callback handler can use this API to find out if the buffer it has just - * been given is the last piece of a "complete packet" from the client -- - * when that is the case libwebsockets_remaining_packet_payload() will return - * 0. - * - * Many protocols won't care becuse their packets are always small. - */ - -LWS_VISIBLE size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi) -{ - return wsi->u.ws.rx_packet_length; -} diff --git a/src/engine/external/libwebsockets/pollfd.c b/src/engine/external/libwebsockets/pollfd.c deleted file mode 100644 index b09127e08..000000000 --- a/src/engine/external/libwebsockets/pollfd.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; - - if (context->fds_count >= context->max_fds) { - lwsl_err("Too many fds (%d)\n", context->max_fds); - return 1; - } - - if (wsi->sock >= context->max_fds) { - lwsl_err("Socket fd %d is too high (%d)\n", - wsi->sock, context->max_fds); - return 1; - } - - assert(wsi); - assert(wsi->sock >= 0); - - lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n", - wsi, wsi->sock, context->fds_count); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0); - - context->lws_lookup[wsi->sock] = wsi; - wsi->position_in_fds_table = context->fds_count; - context->fds[context->fds_count].fd = wsi->sock; - context->fds[context->fds_count].events = LWS_POLLIN; - - lws_plat_insert_socket_into_fds(context, wsi); - - /* external POLL support via protocol 0 */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_ADD_POLL_FD, - wsi->user_space, (void *) &pa, 0); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *)&pa, 0); - - return 0; -} - -int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - int m; - struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 }; - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE); - - if (!--context->fds_count) { - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0); - goto do_ext; - } - - if (wsi->sock > context->max_fds) { - lwsl_err("Socket fd %d too high (%d)\n", - wsi->sock, context->max_fds); - return 1; - } - - lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__, - wsi, wsi->sock, wsi->position_in_fds_table); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *)&pa, 0); - - m = wsi->position_in_fds_table; /* replace the contents for this */ - - /* have the last guy take up the vacant slot */ - context->fds[m] = context->fds[context->fds_count]; - - lws_plat_delete_socket_from_fds(context, wsi, m); - - /* - * end guy's fds_lookup entry remains unchanged - * (still same fd pointing to same wsi) - */ - /* end guy's "position in fds table" changed */ - context->lws_lookup[context->fds[context->fds_count].fd]-> - position_in_fds_table = m; - /* deletion guy's lws_lookup entry needs nuking */ - context->lws_lookup[wsi->sock] = NULL; - /* removed wsi has no position any more */ - wsi->position_in_fds_table = -1; - -do_ext: - /* remove also from external POLL support via protocol 0 */ - if (wsi->sock) { - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_DEL_POLL_FD, wsi->user_space, - (void *) &pa, 0); - } - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 0); - return 0; -} - -int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) -{ - struct libwebsocket_context *context; - int tid; - int sampled_tid; - struct libwebsocket_pollfd *pfd; - struct libwebsocket_pollargs pa; - - if (!wsi || !wsi->protocol || wsi->position_in_fds_table < 0) - return 1; - - context = wsi->protocol->owning_server; - if (!context) - return 1; - - pfd = &context->fds[wsi->position_in_fds_table]; - pa.fd = wsi->sock; - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0); - - pa.prev_events = pfd->events; - pa.events = pfd->events = (pfd->events & ~_and) | _or; - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - wsi->user_space, (void *) &pa, 0); - - /* - * if we changed something in this pollfd... - * ... and we're running in a different thread context - * than the service thread... - * ... and the service thread is waiting ... - * then cancel it to force a restart with our changed events - */ - if (pa.prev_events != pa.events) { - - if (lws_plat_change_pollfd(context, wsi, pfd)) { - lwsl_info("%s failed\n", __func__); - return 1; - } - - sampled_tid = context->service_tid; - if (sampled_tid) { - tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - if (tid != sampled_tid) - libwebsocket_cancel_service(context); - } - } - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0); - - return 0; -} - - -/** - * libwebsocket_callback_on_writable() - Request a callback when this socket - * becomes able to be written to without - * blocking - * - * @context: libwebsockets context - * @wsi: Websocket connection instance to get callback for - */ - -LWS_VISIBLE int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ -#ifdef LWS_USE_HTTP2 - struct libwebsocket *network_wsi, *wsi2; - int already; - - lwsl_info("%s: %p\n", __func__, wsi); - - if (wsi->mode != LWS_CONNMODE_HTTP2_SERVING) - goto network_sock; - - if (wsi->u.http2.requested_POLLOUT) { - lwsl_info("already pending writable\n"); - return 1; - } - - if (wsi->u.http2.tx_credit <= 0) { - /* - * other side is not able to cope with us sending - * anything so no matter if we have POLLOUT on our side. - * - * Delay waiting for our POLLOUT until peer indicates he has - * space for more using tx window command in http2 layer - */ - lwsl_info("%s: %p: waiting_tx_credit (%d)\n", __func__, wsi, wsi->u.http2.tx_credit); - wsi->u.http2.waiting_tx_credit = 1; - return 0; - } - - network_wsi = lws_http2_get_network_wsi(wsi); - already = network_wsi->u.http2.requested_POLLOUT; - - /* mark everybody above him as requesting pollout */ - - wsi2 = wsi; - while (wsi2) { - wsi2->u.http2.requested_POLLOUT = 1; - lwsl_info("mark %p pending writable\n", wsi2); - wsi2 = wsi2->u.http2.parent_wsi; - } - - /* for network action, act only on the network wsi */ - - wsi = network_wsi; - if (already) - return 1; -network_sock: -#endif - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, NULL, 0)) - return 1; - - if (wsi->position_in_fds_table < 0) { - lwsl_err("%s: failed to find socket %d\n", __func__, wsi->sock); - return -1; - } - - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) - return -1; - - lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_WRITE); - - return 1; -} - -/** - * libwebsocket_callback_on_writable_all_protocol() - Request a callback for - * all connections using the given protocol when it - * becomes possible to write to each socket without - * blocking in turn. - * - * @protocol: Protocol whose connections will get callbacks - */ - -LWS_VISIBLE int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - libwebsocket_callback_on_writable(context, wsi); - } - - return 0; -} diff --git a/src/engine/external/libwebsockets/private-libwebsockets.h b/src/engine/external/libwebsockets/private-libwebsockets.h deleted file mode 100644 index de43ec423..000000000 --- a/src/engine/external/libwebsockets/private-libwebsockets.h +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -/* System introspection configs */ -#ifdef CMAKE_BUILD -#include "lws_config.h" -#else -#if defined(WIN32) || defined(_WIN32) -#define inline __inline -#else /* not WIN32 */ -#include "config.h" - -#endif /* not WIN32 */ -#endif /* not CMAKE */ - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#if defined(WIN32) || defined(_WIN32) -#define LWS_NO_DAEMONIZE -#define LWS_ERRNO WSAGetLastError() -#define LWS_EAGAIN WSAEWOULDBLOCK -#define LWS_EALREADY WSAEALREADY -#define LWS_EINPROGRESS WSAEINPROGRESS -#define LWS_EINTR WSAEINTR -#define LWS_EISCONN WSAEISCONN -#define LWS_EWOULDBLOCK WSAEWOULDBLOCK -#define LWS_POLLHUP (FD_CLOSE) -#define LWS_POLLIN (FD_READ | FD_ACCEPT) -#define LWS_POLLOUT (FD_WRITE) -#define MSG_NOSIGNAL 0 -#define SHUT_RDWR SD_BOTH -#define SOL_TCP IPPROTO_TCP - -#define compatible_close(fd) closesocket(fd) -#define compatible_file_close(fd) CloseHandle(fd) -#define compatible_file_seek_cur(fd, offset) SetFilePointer(fd, offset, NULL, FILE_CURRENT) -#define compatible_file_read(amount, fd, buf, len) {\ - DWORD _amount; \ - if (!ReadFile(fd, buf, len, &_amount, NULL)) \ - amount = -1; \ - else \ - amount = _amount; \ - } -#define lws_set_blocking_send(wsi) wsi->sock_send_blocking = TRUE -#include -#include -#include -#ifdef HAVE_IN6ADDR_H -#include -#endif -#include - -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif - -#ifdef _WIN32_WCE -#define vsnprintf _vsnprintf -#endif - -#define LWS_INVALID_FILE INVALID_HANDLE_VALUE -#else /* not windows --> */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef LWS_BUILTIN_GETIFADDRS - #include -#else - #include -#endif -#if defined (__ANDROID__) -#include -#else -#include -#endif -#include -#include -#include -#ifndef LWS_NO_FORK -#ifdef HAVE_SYS_PRCTL_H -#include -#endif -#endif -#include -#include -#include -#include -#ifdef LWS_USE_LIBEV -#include -#endif /* LWS_USE_LIBEV */ - -#include -#include - -#define LWS_ERRNO errno -#define LWS_EAGAIN EAGAIN -#define LWS_EALREADY EALREADY -#define LWS_EINPROGRESS EINPROGRESS -#define LWS_EINTR EINTR -#define LWS_EISCONN EISCONN -#define LWS_EWOULDBLOCK EWOULDBLOCK -#define LWS_INVALID_FILE -1 -#define LWS_POLLHUP (POLLHUP|POLLERR) -#define LWS_POLLIN (POLLIN) -#define LWS_POLLOUT (POLLOUT) -#define compatible_close(fd) close(fd) -#define compatible_file_close(fd) close(fd) -#define compatible_file_seek_cur(fd, offset) lseek(fd, offset, SEEK_CUR) -#define compatible_file_read(amount, fd, buf, len) \ - amount = read(fd, buf, len); -#define lws_set_blocking_send(wsi) -#endif - -#ifndef HAVE_BZERO -#ifndef bzero -#define bzero(b, len) (memset((b), '\0', (len)), (void) 0) -#endif -#endif - -#ifndef HAVE_STRERROR -#define strerror(x) "" -#endif - -#ifdef LWS_OPENSSL_SUPPORT -#ifdef USE_CYASSL -#include -#include -#else -#include -#include -#include -#include -#include -#endif /* not USE_CYASSL */ -#endif - -#include "libwebsockets.h" - -#if defined(WIN32) || defined(_WIN32) - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */ -#endif -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif -typedef unsigned __int64 u_int64_t; - -#undef __P -#ifndef __P -#if __STDC__ -#define __P(protos) protos -#else -#define __P(protos) () -#endif -#endif - -#else - -#include -#include -#include - -#if defined(__APPLE__) -#include -#elif defined(__FreeBSD__) -#include -#elif defined(__linux__) -#include -#endif - -#include - -#ifndef container_of -#define container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M))) -#endif - -#if defined(__QNX__) - #include - #if defined(__LITTLEENDIAN__) - #define BYTE_ORDER __LITTLEENDIAN__ - #define LITTLE_ENDIAN __LITTLEENDIAN__ - #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc); for suppres warning that BIG_ENDIAN is not defined. */ - #endif - #if defined(__BIGENDIAN__) - #define BYTE_ORDER __BIGENDIAN__ - #define LITTLE_ENDIAN 1234 /* to show byte order (taken from gcc); for suppres warning that LITTLE_ENDIAN is not defined. */ - #define BIG_ENDIAN __BIGENDIAN__ - #endif -#endif - -#if !defined(BYTE_ORDER) -# define BYTE_ORDER __BYTE_ORDER -#endif -#if !defined(LITTLE_ENDIAN) -# define LITTLE_ENDIAN __LITTLE_ENDIAN -#endif -#if !defined(BIG_ENDIAN) -# define BIG_ENDIAN __BIG_ENDIAN -#endif - -#endif - -/* - * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag, - * but happily have something equivalent in the SO_NOSIGPIPE flag. - */ -#ifdef __APPLE__ -#define MSG_NOSIGNAL SO_NOSIGPIPE -#endif - -#ifndef LWS_MAX_HEADER_LEN -#define LWS_MAX_HEADER_LEN 1024 -#endif -#ifndef LWS_MAX_PROTOCOLS -#define LWS_MAX_PROTOCOLS 5 -#endif -#ifndef LWS_MAX_EXTENSIONS_ACTIVE -#define LWS_MAX_EXTENSIONS_ACTIVE 3 -#endif -#ifndef SPEC_LATEST_SUPPORTED -#define SPEC_LATEST_SUPPORTED 13 -#endif -#ifndef AWAITING_TIMEOUT -#define AWAITING_TIMEOUT 5 -#endif -#ifndef CIPHERS_LIST_STRING -#define CIPHERS_LIST_STRING "DEFAULT" -#endif -#ifndef LWS_SOMAXCONN -#define LWS_SOMAXCONN SOMAXCONN -#endif - -#define MAX_WEBSOCKET_04_KEY_LEN 128 -#define LWS_MAX_SOCKET_IO_BUF 4096 - -#ifndef SYSTEM_RANDOM_FILEPATH -#define SYSTEM_RANDOM_FILEPATH "/dev/urandom" -#endif -#ifndef LWS_MAX_ZLIB_CONN_BUFFER -#define LWS_MAX_ZLIB_CONN_BUFFER (64 * 1024) -#endif - -/* - * if not in a connection storm, check for incoming - * connections this many normal connection services - */ -#define LWS_LISTEN_SERVICE_MODULO 10 - -enum lws_websocket_opcodes_07 { - LWS_WS_OPCODE_07__CONTINUATION = 0, - LWS_WS_OPCODE_07__TEXT_FRAME = 1, - LWS_WS_OPCODE_07__BINARY_FRAME = 2, - - LWS_WS_OPCODE_07__NOSPEC__MUX = 7, - - /* control extensions 8+ */ - - LWS_WS_OPCODE_07__CLOSE = 8, - LWS_WS_OPCODE_07__PING = 9, - LWS_WS_OPCODE_07__PONG = 0xa, -}; - - -enum lws_connection_states { - WSI_STATE_HTTP, - WSI_STATE_HTTP_ISSUING_FILE, - WSI_STATE_HTTP_HEADERS, - WSI_STATE_HTTP_BODY, - WSI_STATE_DEAD_SOCKET, - WSI_STATE_ESTABLISHED, - WSI_STATE_CLIENT_UNCONNECTED, - WSI_STATE_RETURNED_CLOSE_ALREADY, - WSI_STATE_AWAITING_CLOSE_ACK, - WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE, - - WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE, - WSI_STATE_HTTP2_ESTABLISHED_PRE_SETTINGS, - WSI_STATE_HTTP2_ESTABLISHED, -}; - -enum http_version { - HTTP_VERSION_1_0, - HTTP_VERSION_1_1, -}; - -enum http_connection_type { - HTTP_CONNECTION_CLOSE, - HTTP_CONNECTION_KEEP_ALIVE -}; - -enum lws_pending_protocol_send { - LWS_PPS_NONE, - LWS_PPS_HTTP2_MY_SETTINGS, - LWS_PPS_HTTP2_ACK_SETTINGS, - LWS_PPS_HTTP2_PONG, -}; - -enum lws_rx_parse_state { - LWS_RXPS_NEW, - - LWS_RXPS_04_MASK_NONCE_1, - LWS_RXPS_04_MASK_NONCE_2, - LWS_RXPS_04_MASK_NONCE_3, - - LWS_RXPS_04_FRAME_HDR_1, - LWS_RXPS_04_FRAME_HDR_LEN, - LWS_RXPS_04_FRAME_HDR_LEN16_2, - LWS_RXPS_04_FRAME_HDR_LEN16_1, - LWS_RXPS_04_FRAME_HDR_LEN64_8, - LWS_RXPS_04_FRAME_HDR_LEN64_7, - LWS_RXPS_04_FRAME_HDR_LEN64_6, - LWS_RXPS_04_FRAME_HDR_LEN64_5, - LWS_RXPS_04_FRAME_HDR_LEN64_4, - LWS_RXPS_04_FRAME_HDR_LEN64_3, - LWS_RXPS_04_FRAME_HDR_LEN64_2, - LWS_RXPS_04_FRAME_HDR_LEN64_1, - - LWS_RXPS_07_COLLECT_FRAME_KEY_1, - LWS_RXPS_07_COLLECT_FRAME_KEY_2, - LWS_RXPS_07_COLLECT_FRAME_KEY_3, - LWS_RXPS_07_COLLECT_FRAME_KEY_4, - - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED -}; - - -enum connection_mode { - LWS_CONNMODE_HTTP_SERVING, - LWS_CONNMODE_HTTP_SERVING_ACCEPTED, /* actual HTTP service going on */ - LWS_CONNMODE_PRE_WS_SERVING_ACCEPT, - - LWS_CONNMODE_WS_SERVING, - LWS_CONNMODE_WS_CLIENT, - - LWS_CONNMODE_HTTP2_SERVING, - - /* transient, ssl delay hiding */ - LWS_CONNMODE_SSL_ACK_PENDING, - - /* transient modes */ - LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT, - LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY, - LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE, - LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2, - LWS_CONNMODE_WS_CLIENT_WAITING_SSL, - LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY, - LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT, - LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD, - - /* special internal types */ - LWS_CONNMODE_SERVER_LISTENER, -}; - -enum { - LWS_RXFLOW_ALLOW = (1 << 0), - LWS_RXFLOW_PENDING_CHANGE = (1 << 1), -}; - -struct libwebsocket_protocols; -struct libwebsocket; - -#ifdef LWS_USE_LIBEV -struct lws_io_watcher { - struct ev_io watcher; - struct libwebsocket_context* context; -}; - -struct lws_signal_watcher { - struct ev_signal watcher; - struct libwebsocket_context* context; -}; -#endif /* LWS_USE_LIBEV */ - -struct libwebsocket_context { -#ifdef _WIN32 - WSAEVENT *events; -#endif - struct libwebsocket_pollfd *fds; - struct libwebsocket **lws_lookup; /* fd to wsi */ - int fds_count; -#ifdef LWS_USE_LIBEV - struct ev_loop* io_loop; - struct lws_io_watcher w_accept; - struct lws_signal_watcher w_sigint; -#endif /* LWS_USE_LIBEV */ - int max_fds; - int listen_port; - const char *iface; - char http_proxy_address[128]; - char canonical_hostname[128]; - unsigned int http_proxy_port; - unsigned int options; - time_t last_timeout_check_s; - - /* - * usable by anything in the service code, but only if the scope - * does not last longer than the service action (since next service - * of any socket can likewise use it and overwrite) - */ - unsigned char service_buffer[LWS_MAX_SOCKET_IO_BUF]; - - int started_with_parent; - - int fd_random; - int listen_service_modulo; - int listen_service_count; - int listen_service_fd; - int listen_service_extraseen; - - /* - * set to the Thread ID that's doing the service loop just before entry - * to poll indicates service thread likely idling in poll() - * volatile because other threads may check it as part of processing - * for pollfd event change. - */ - volatile int service_tid; -#ifndef _WIN32 - int dummy_pipe_fds[2]; -#endif - - int ka_time; - int ka_probes; - int ka_interval; - -#ifdef LWS_LATENCY - unsigned long worst_latency; - char worst_latency_info[256]; -#endif - -#ifdef LWS_OPENSSL_SUPPORT - int use_ssl; - int allow_non_ssl_on_ssl_port; - unsigned int user_supplied_ssl_ctx:1; - SSL_CTX *ssl_ctx; - SSL_CTX *ssl_client_ctx; - unsigned int ssl_flag_buffered_reads:1; -#endif - struct libwebsocket_protocols *protocols; - int count_protocols; -#ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension *extensions; -#endif - struct lws_token_limits *token_limits; - void *user_space; -}; - -enum { - LWS_EV_READ = (1 << 0), - LWS_EV_WRITE = (1 << 1), - LWS_EV_START = (1 << 2), - LWS_EV_STOP = (1 << 3), -}; - -#ifdef LWS_USE_LIBEV -#define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV) -LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info); -LWS_EXTERN void -lws_libev_accept(struct libwebsocket_context *context, - struct libwebsocket *new_wsi, int accept_fd); -LWS_EXTERN void -lws_libev_io(struct libwebsocket_context *context, - struct libwebsocket *wsi, int flags); -LWS_EXTERN int -lws_libev_init_fd_table(struct libwebsocket_context *context); -LWS_EXTERN void -lws_libev_run(struct libwebsocket_context *context); -#else -#define LWS_LIBEV_ENABLED(context) (0) -#define lws_feature_status_libev(_a) \ - lwsl_notice("libev support not compiled in\n") -#define lws_libev_accept(_a, _b, _c) ((void) 0) -#define lws_libev_io(_a, _b, _c) ((void) 0) -#define lws_libev_init_fd_table(_a) (0) -#define lws_libev_run(_a) ((void) 0) -#endif - -#ifdef LWS_USE_IPV6 -#define LWS_IPV6_ENABLED(context) (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6)) -#else -#define LWS_IPV6_ENABLED(context) (0) -#endif - -enum uri_path_states { - URIPS_IDLE, - URIPS_SEEN_SLASH, - URIPS_SEEN_SLASH_DOT, - URIPS_SEEN_SLASH_DOT_DOT, - URIPS_ARGUMENTS, -}; - -enum uri_esc_states { - URIES_IDLE, - URIES_SEEN_PERCENT, - URIES_SEEN_PERCENT_H1, -}; - -/* - * This is totally opaque to code using the library. It's exported as a - * forward-reference pointer-only declaration; the user can use the pointer with - * other APIs to get information out of it. - */ - -struct lws_fragments { - unsigned short offset; - unsigned short len; - unsigned char next_frag_index; -}; - -/* notice that these union members: - * - * hdr - * http - * http2 - * - * all have a pointer to allocated_headers struct as their first member. - * - * It means for allocated_headers access, the three union paths can all be - * used interchangably to access the same data - */ - -struct allocated_headers { - unsigned short next_frag_index; - unsigned short pos; - unsigned char frag_index[WSI_TOKEN_COUNT]; - struct lws_fragments frags[WSI_TOKEN_COUNT * 2]; - char data[LWS_MAX_HEADER_LEN]; -#ifndef LWS_NO_CLIENT - char initial_handshake_hash_base64[30]; - unsigned short c_port; -#endif -}; - -struct _lws_http_mode_related { - /* MUST be first in struct */ - struct allocated_headers *ah; /* mirroring _lws_header_related */ -#if defined(WIN32) || defined(_WIN32) - HANDLE fd; -#else - int fd; -#endif - unsigned long filepos; - unsigned long filelen; - - enum http_version request_version; - enum http_connection_type connection_type; - int content_length; - int content_remain; -}; - - -#ifdef LWS_USE_HTTP2 - -enum lws_http2_settings { - LWS_HTTP2_SETTINGS__HEADER_TABLE_SIZE = 1, - LWS_HTTP2_SETTINGS__ENABLE_PUSH, - LWS_HTTP2_SETTINGS__MAX_CONCURRENT_STREAMS, - LWS_HTTP2_SETTINGS__INITIAL_WINDOW_SIZE, - LWS_HTTP2_SETTINGS__MAX_FRAME_SIZE, - LWS_HTTP2_SETTINGS__MAX_HEADER_LIST_SIZE, - - LWS_HTTP2_SETTINGS__COUNT /* always last */ -}; - -enum lws_http2_wellknown_frame_types { - LWS_HTTP2_FRAME_TYPE_DATA, - LWS_HTTP2_FRAME_TYPE_HEADERS, - LWS_HTTP2_FRAME_TYPE_PRIORITY, - LWS_HTTP2_FRAME_TYPE_RST_STREAM, - LWS_HTTP2_FRAME_TYPE_SETTINGS, - LWS_HTTP2_FRAME_TYPE_PUSH_PROMISE, - LWS_HTTP2_FRAME_TYPE_PING, - LWS_HTTP2_FRAME_TYPE_GOAWAY, - LWS_HTTP2_FRAME_TYPE_WINDOW_UPDATE, - LWS_HTTP2_FRAME_TYPE_CONTINUATION, - - LWS_HTTP2_FRAME_TYPE_COUNT /* always last */ -}; - -enum lws_http2_flags { - LWS_HTTP2_FLAG_END_STREAM = 1, - LWS_HTTP2_FLAG_END_HEADERS = 4, - LWS_HTTP2_FLAG_PADDED = 8, - LWS_HTTP2_FLAG_PRIORITY = 0x20, - - LWS_HTTP2_FLAG_SETTINGS_ACK = 1, -}; - -#define LWS_HTTP2_STREAM_ID_MASTER 0 -#define LWS_HTTP2_FRAME_HEADER_LENGTH 9 -#define LWS_HTTP2_SETTINGS_LENGTH 6 - -struct http2_settings { - unsigned int setting[LWS_HTTP2_SETTINGS__COUNT]; -}; - -enum http2_hpack_state { - - /* optional before first header block */ - HPKS_OPT_PADDING, - HKPS_OPT_E_DEPENDENCY, - HKPS_OPT_WEIGHT, - - /* header block */ - HPKS_TYPE, - - HPKS_IDX_EXT, - - HPKS_HLEN, - HPKS_HLEN_EXT, - - HPKS_DATA, - - /* optional after last header block */ - HKPS_OPT_DISCARD_PADDING, -}; - -enum http2_hpack_type { - HPKT_INDEXED_HDR_7, - HPKT_INDEXED_HDR_6_VALUE_INCR, - HPKT_LITERAL_HDR_VALUE_INCR, - HPKT_INDEXED_HDR_4_VALUE, - HPKT_LITERAL_HDR_VALUE, - HPKT_SIZE_5 -}; - -struct hpack_dt_entry { - int token; /* additions that don't map to a token are ignored */ - int arg_offset; - int arg_len; -}; - -struct hpack_dynamic_table { - struct hpack_dt_entry *entries; - char *args; - int pos; - int next; - int num_entries; - int args_length; -}; - -struct _lws_http2_related { - /* - * having this first lets us also re-use all HTTP union code - * and in turn, http_mode_related has allocated headers in right - * place so we can use the header apis on the wsi directly still - */ - struct _lws_http_mode_related http; /* MUST BE FIRST IN STRUCT */ - - struct http2_settings my_settings; - struct http2_settings peer_settings; - - struct libwebsocket *parent_wsi; - struct libwebsocket *next_child_wsi; - - struct hpack_dynamic_table *hpack_dyn_table; - - unsigned int count; - - /* frame */ - unsigned int length; - unsigned int stream_id; - struct libwebsocket *stream_wsi; - unsigned char type; - unsigned char flags; - unsigned char frame_state; - unsigned char padding; - - unsigned char ping_payload[8]; - - unsigned short round_robin_POLLOUT; - unsigned short count_POLLOUT_children; - - unsigned int END_STREAM:1; - unsigned int END_HEADERS:1; - unsigned int send_END_STREAM:1; - unsigned int GOING_AWAY; - unsigned int requested_POLLOUT:1; - unsigned int waiting_tx_credit:1; - - /* hpack */ - enum http2_hpack_state hpack; - enum http2_hpack_type hpack_type; - unsigned int header_index; - unsigned int hpack_len; - unsigned short hpack_pos; - unsigned char hpack_m; - unsigned int hpack_e_dep; - unsigned int huff:1; - unsigned int value:1; - - /* negative credit is mandated by the spec */ - int tx_credit; - unsigned int my_stream_id; - unsigned int child_count; - int my_priority; - unsigned char initialized; - unsigned char one_setting[LWS_HTTP2_SETTINGS_LENGTH]; -}; - -#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->u.http2.parent_wsi) - -#endif - -struct _lws_header_related { - /* MUST be first in struct */ - struct allocated_headers *ah; - short lextable_pos; - unsigned short current_token_limit; - unsigned char parser_state; /* enum lws_token_indexes */ - enum uri_path_states ups; - enum uri_esc_states ues; - char esc_stash; -}; - -struct _lws_websocket_related { - char *rx_user_buffer; - int rx_user_buffer_head; - unsigned char frame_masking_nonce_04[4]; - unsigned char frame_mask_index; - size_t rx_packet_length; - unsigned char opcode; - unsigned int final:1; - unsigned char rsv; - unsigned int frame_is_binary:1; - unsigned int all_zero_nonce:1; - short close_reason; /* enum lws_close_status */ - - unsigned int this_frame_masked:1; - unsigned int inside_frame:1; /* next write will be more of frame */ - unsigned int clean_buffer:1; /* buffer not rewritten by extension */ - - unsigned char *ping_payload_buf; /* non-NULL if malloc'd */ - unsigned int ping_payload_alloc; /* length malloc'd */ - unsigned int ping_payload_len; /* nonzero if PONG pending */ -}; - -struct libwebsocket { - - /* lifetime members */ - -#ifdef LWS_USE_LIBEV - struct lws_io_watcher w_read; - struct lws_io_watcher w_write; -#endif /* LWS_USE_LIBEV */ - const struct libwebsocket_protocols *protocol; -#ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension * - active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; - void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE]; - unsigned char count_active_extensions; - unsigned int extension_data_pending:1; -#endif - unsigned char ietf_spec_revision; - enum lws_pending_protocol_send pps; - - char mode; /* enum connection_mode */ - char state; /* enum lws_connection_states */ - char lws_rx_parse_state; /* enum lws_rx_parse_state */ - char rx_frame_type; /* enum libwebsocket_write_protocol */ - - unsigned int hdr_parsing_completed:1; - unsigned int user_space_externally_allocated:1; - unsigned int socket_is_permanently_unusable:1; - - char pending_timeout; /* enum pending_timeout */ - time_t pending_timeout_limit; - - int sock; - int position_in_fds_table; -#ifdef LWS_LATENCY - unsigned long action_start; - unsigned long latency_start; -#endif - /* rxflow handling */ - unsigned char *rxflow_buffer; - int rxflow_len; - int rxflow_pos; - unsigned int rxflow_change_to:2; - - /* truncated send handling */ - unsigned char *truncated_send_malloc; /* non-NULL means buffering in progress */ - unsigned int truncated_send_allocation; /* size of malloc */ - unsigned int truncated_send_offset; /* where we are in terms of spilling */ - unsigned int truncated_send_len; /* how much is buffered */ - - void *user_space; - - /* members with mutually exclusive lifetimes are unionized */ - - union u { - struct _lws_http_mode_related http; -#ifdef LWS_USE_HTTP2 - struct _lws_http2_related http2; -#endif - struct _lws_header_related hdr; - struct _lws_websocket_related ws; - } u; - -#ifdef LWS_OPENSSL_SUPPORT - SSL *ssl; - BIO *client_bio; - unsigned int use_ssl:2; - unsigned int buffered_reads_pending:1; - unsigned int upgraded:1; -#endif - -#ifdef _WIN32 - BOOL sock_send_blocking; -#endif -}; - -LWS_EXTERN int log_level; - -LWS_EXTERN void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status); - -LWS_EXTERN int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); -LWS_EXTERN int -lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int len); - -#ifndef LWS_LATENCY -static inline void lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion) { do { } while (0); } -static inline void lws_latency_pre(struct libwebsocket_context *context, - struct libwebsocket *wsi) { do { } while (0); } -#else -#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0) -extern void -lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion); -#endif - -LWS_EXTERN void lws_set_protocol_write_pending(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_pending_protocol_send pend); -LWS_EXTERN int -libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -libwebsocket_parse(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -lws_http_action(struct libwebsocket_context *context, struct libwebsocket *wsi); - -LWS_EXTERN int -lws_b64_selftest(void); - -LWS_EXTERN struct libwebsocket * -wsi_from_fd(struct libwebsocket_context *context, int fd); - -LWS_EXTERN int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN int -lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len); - - -LWS_EXTERN int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec); - -LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_2(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context); - -LWS_EXTERN char * -libwebsockets_generate_client_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char *pkt); - -LWS_EXTERN int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); - -/* - * EXTENSIONS - */ - -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE void -lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -LWS_EXTERN int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, - void *v, size_t len); - -LWS_EXTERN int -lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, - void *buf, int len); -LWS_EXTERN int -lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, - int reason, void *arg, int len); -#else -#define lws_any_extension_handled(_a, _b, _c, _d, _e) (0) -#define lws_ext_callback_for_each_active(_a, _b, _c, _d) (0) -#define lws_ext_callback_for_each_extension_type(_a, _b, _c, _d, _e) (0) -#define lws_issue_raw_ext_access lws_issue_raw -#define lws_context_init_extensions(_a, _b) -#endif - -LWS_EXTERN int -lws_client_interpret_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -lws_issue_raw_ext_access(struct libwebsocket *wsi, - unsigned char *buf, size_t len); - -LWS_EXTERN int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi); - -LWS_EXTERN void -lws_union_transition(struct libwebsocket *wsi, enum connection_mode mode); - -LWS_EXTERN int -user_callback_handle_rxflow(callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); -#ifdef LWS_USE_HTTP2 -LWS_EXTERN struct libwebsocket *lws_http2_get_network_wsi(struct libwebsocket *wsi); -struct libwebsocket * lws_http2_get_nth_child(struct libwebsocket *wsi, int n); -LWS_EXTERN int -lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned char *buf, int len); -LWS_EXTERN void lws_http2_init(struct http2_settings *settings); -LWS_EXTERN int -lws_http2_parser(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char c); -LWS_EXTERN int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsocket *wsi); -LWS_EXTERN int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf); -LWS_EXTERN struct libwebsocket * -lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid); -LWS_EXTERN int lws_hpack_interpret(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char c); -LWS_EXTERN int -lws_add_http2_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, - const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); -LWS_EXTERN int -lws_add_http2_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end); -LWS_EXTERN int -lws_add_http2_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, - unsigned char *end); -LWS_EXTERN -void lws_http2_configure_if_upgraded(struct libwebsocket *wsi); -#else -#define lws_http2_configure_if_upgraded(x) -#endif - -LWS_EXTERN int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd); - -LWS_EXTERN int -lws_allocate_header_table(struct libwebsocket *wsi); - -LWS_EXTERN int -lws_free_header_table(struct libwebsocket *wsi); - -LWS_EXTERN char * -lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h); - -LWS_EXTERN int -lws_hdr_simple_create(struct libwebsocket *wsi, - enum lws_token_indexes h, const char *s); - -LWS_EXTERN int -libwebsocket_ensure_user_space(struct libwebsocket *wsi); - -LWS_EXTERN int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or); - -#ifndef LWS_NO_SERVER -int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -LWS_EXTERN int handshake_0405(struct libwebsocket_context *context, - struct libwebsocket *wsi); -LWS_EXTERN int -libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len); -LWS_EXTERN void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info); -#else -#define lws_context_init_server(_a, _b) (0) -#define libwebsocket_interpret_incoming_packet(_a, _b, _c) (0) -#define lws_server_get_canonical_hostname(_a, _b) -#endif - -#ifndef LWS_NO_DAEMONIZE -LWS_EXTERN int get_daemonize_pid(); -#else -#define get_daemonize_pid() (0) -#endif - -LWS_EXTERN int interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen); - -LWS_EXTERN void lwsl_emit_stderr(int level, const char *line); - -#ifdef _WIN32 -LWS_EXTERN HANDLE lws_plat_open_file(const char* filename, unsigned long* filelen); -#else -LWS_EXTERN int lws_plat_open_file(const char* filename, unsigned long* filelen); -#endif - -enum lws_ssl_capable_status { - LWS_SSL_CAPABLE_ERROR = -1, - LWS_SSL_CAPABLE_MORE_SERVICE = -2, -}; - -#ifndef LWS_OPENSSL_SUPPORT -#define LWS_SSL_ENABLED(context) (0) -#define lws_context_init_server_ssl(_a, _b) (0) -#define lws_ssl_destroy(_a) -#define lws_context_init_http2_ssl(_a) -#define lws_ssl_capable_read lws_ssl_capable_read_no_ssl -#define lws_ssl_capable_write lws_ssl_capable_write_no_ssl -#define lws_server_socket_service_ssl(_a, _b, _c, _d, _e) (0) -#define lws_ssl_close(_a) (0) -#define lws_ssl_context_destroy(_a) -#else -#define LWS_SSL_ENABLED(context) (context->use_ssl) -LWS_EXTERN int openssl_websocket_private_data_index; -LWS_EXTERN int -lws_ssl_capable_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len); - -LWS_EXTERN int -lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len); -LWS_EXTERN int -lws_server_socket_service_ssl(struct libwebsocket_context *context, - struct libwebsocket **wsi, struct libwebsocket *new_wsi, - int accept_fd, struct libwebsocket_pollfd *pollfd); -LWS_EXTERN int -lws_ssl_close(struct libwebsocket *wsi); -LWS_EXTERN void -lws_ssl_context_destroy(struct libwebsocket_context *context); -#ifndef LWS_NO_SERVER -LWS_EXTERN int -lws_context_init_server_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -#else -#define lws_context_init_server_ssl(_a, _b) (0) -#endif -LWS_EXTERN void -lws_ssl_destroy(struct libwebsocket_context *context); - -/* HTTP2-related */ - -#ifdef LWS_USE_HTTP2 -LWS_EXTERN void -lws_context_init_http2_ssl(struct libwebsocket_context *context); -#else -#define lws_context_init_http2_ssl(_a) -#endif -#endif - -LWS_EXTERN int -lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, int len); - -LWS_EXTERN int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len); - -#ifndef LWS_NO_CLIENT - LWS_EXTERN int lws_client_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); -#ifdef LWS_OPENSSL_SUPPORT - LWS_EXTERN int lws_context_init_client_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -#else - #define lws_context_init_client_ssl(_a, _b) (0) -#endif - LWS_EXTERN int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len); - LWS_EXTERN void - libwebsockets_decode_ssl_error(void); -#else -#define lws_context_init_client_ssl(_a, _b) (0) -#define lws_handshake_client(_a, _b, _c) (0) -#endif -#ifndef LWS_NO_SERVER - LWS_EXTERN int lws_server_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); - LWS_EXTERN int _libwebsocket_rx_flow_control(struct libwebsocket *wsi); - LWS_EXTERN int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len); -#else -#define lws_server_socket_service(_a, _b, _c) (0) -#define _libwebsocket_rx_flow_control(_a) (0) -#define lws_handshake_server(_a, _b, _c, _d) (0) -#endif - -/* - * custom allocator - */ -LWS_EXTERN void* -lws_realloc(void *ptr, size_t size); - -LWS_EXTERN void* -lws_zalloc(size_t size); - -#define lws_malloc(S) lws_realloc(NULL, S) -#define lws_free(P) lws_realloc(P, 0) -#define lws_free2(P) do { lws_realloc(P, 0); (P) = NULL; } while(0) - -/* - * lws_plat_ - */ -LWS_EXTERN void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m); -LWS_EXTERN void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); -LWS_EXTERN void -lws_plat_service_periodic(struct libwebsocket_context *context); - -LWS_EXTERN int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd); -LWS_EXTERN int -lws_plat_context_early_init(void); -LWS_EXTERN void -lws_plat_context_early_destroy(struct libwebsocket_context *context); -LWS_EXTERN void -lws_plat_context_late_destroy(struct libwebsocket_context *context); -LWS_EXTERN int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd); -LWS_EXTERN int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms); -LWS_EXTERN int -lws_plat_init_fd_tables(struct libwebsocket_context *context); -LWS_EXTERN void -lws_plat_drop_app_privileges(struct lws_context_creation_info *info); -LWS_EXTERN unsigned long long -time_in_microseconds(void); -LWS_EXTERN const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt); diff --git a/src/engine/external/libwebsockets/server-handshake.c b/src/engine/external/libwebsockets/server-handshake.c deleted file mode 100644 index b4641d1b9..000000000 --- a/src/engine/external/libwebsockets/server-handshake.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); } -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE int -lws_extension_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char **p) -{ - int n; - char *c; - char ext_name[128]; - struct libwebsocket_extension *ext; - int ext_count = 0; - int more = 1; - - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list - */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) - return 0; - - /* - * break down the list of client extensions - * and go through them - */ - - if (lws_hdr_copy(wsi, (char *)context->service_buffer, - sizeof(context->service_buffer), - WSI_TOKEN_EXTENSIONS) < 0) - return 1; - - c = (char *)context->service_buffer; - lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c); - wsi->count_active_extensions = 0; - n = 0; - while (more) { - - if (*c && (*c != ',' && *c != ' ' && *c != '\t')) { - ext_name[n] = *c++; - if (n < sizeof(ext_name) - 1) - n++; - continue; - } - ext_name[n] = '\0'; - if (!*c) - more = 0; - else { - c++; - if (!n) - continue; - } - - /* check a client's extension against our support */ - - ext = wsi->protocol->owning_server->extensions; - - while (ext && ext->callback) { - - if (strcmp(ext_name, ext->name)) { - ext++; - continue; - } - - /* - * oh, we do support this one he - * asked for... but let's ask user - * code if it's OK to apply it on this - * particular connection + protocol - */ - - n = wsi->protocol->owning_server-> - protocols[0].callback( - wsi->protocol->owning_server, - wsi, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - wsi->user_space, ext_name, 0); - - /* - * zero return from callback means - * go ahead and allow the extension, - * it's what we get if the callback is - * unhandled - */ - - if (n) { - ext++; - continue; - } - - /* apply it */ - - if (ext_count) - *(*p)++ = ','; - else - LWS_CPYAPP(*p, - "\x0d\x0aSec-WebSocket-Extensions: "); - *p += sprintf(*p, "%s", ext_name); - ext_count++; - - /* instantiate the extension on this conn */ - - wsi->active_extensions_user[ - wsi->count_active_extensions] = - lws_zalloc(ext->per_session_data_size); - if (wsi->active_extensions_user[ - wsi->count_active_extensions] == NULL) { - lwsl_err("Out of mem\n"); - return 1; - } - - wsi->active_extensions[ - wsi->count_active_extensions] = ext; - - /* allow him to construct his context */ - - ext->callback(wsi->protocol->owning_server, - ext, wsi, - LWS_EXT_CALLBACK_CONSTRUCT, - wsi->active_extensions_user[ - wsi->count_active_extensions], NULL, 0); - - wsi->count_active_extensions++; - lwsl_parser("count_active_extensions <- %d\n", - wsi->count_active_extensions); - - ext++; - } - - n = 0; - } - - return 0; -} -#endif -int -handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) -{ - unsigned char hash[20]; - int n; - char *response; - char *p; - int accept_len; - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) || - !lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) { - lwsl_parser("handshake_04 missing pieces\n"); - /* completed header processing, but missing some bits */ - goto bail; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >= - MAX_WEBSOCKET_04_KEY_LEN) { - lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN); - goto bail; - } - - /* - * since key length is restricted above (currently 128), cannot - * overflow - */ - n = sprintf((char *)context->service_buffer, - "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY)); - - libwebsockets_SHA1(context->service_buffer, n, hash); - - accept_len = lws_b64_encode_string((char *)hash, 20, - (char *)context->service_buffer, - sizeof(context->service_buffer)); - if (accept_len < 0) { - lwsl_warn("Base64 encoded hash too long\n"); - goto bail; - } - - /* allocate the per-connection user memory (if any) */ - if (libwebsocket_ensure_user_space(wsi)) - goto bail; - - /* create the response packet */ - - /* make a buffer big enough for everything */ - - response = (char *)context->service_buffer + MAX_WEBSOCKET_04_KEY_LEN + LWS_SEND_BUFFER_PRE_PADDING; - p = response; - LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a" - "Upgrade: WebSocket\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Sec-WebSocket-Accept: "); - strcpy(p, (char *)context->service_buffer); - p += accept_len; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) { - LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: "); - n = lws_hdr_copy(wsi, p, 128, WSI_TOKEN_PROTOCOL); - if (n < 0) - goto bail; - p += n; - } - -#ifndef LWS_NO_EXTENSIONS - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list - */ - if (lws_extension_server_handshake(context, wsi, &p)) - goto bail; -#endif - /* end of response packet */ - - LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a"); - - if (!lws_any_extension_handled(context, wsi, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - response, p - response)) { - - /* okay send the handshake response accepting the connection */ - - lwsl_parser("issuing resp pkt %d len\n", (int)(p - response)); -#ifdef DEBUG - fwrite(response, 1, p - response, stderr); -#endif - n = libwebsocket_write(wsi, (unsigned char *)response, - p - response, LWS_WRITE_HTTP_HEADERS); - if (n != (p - response)) { - lwsl_debug("handshake_0405: ERROR writing to socket\n"); - goto bail; - } - - } - - /* alright clean up and set ourselves into established state */ - - wsi->state = WSI_STATE_ESTABLISHED; - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - - /* notify user code that we're ready to roll */ - - if (wsi->protocol->callback) - wsi->protocol->callback(wsi->protocol->owning_server, - wsi, LWS_CALLBACK_ESTABLISHED, - wsi->user_space, NULL, 0); - - return 0; - - -bail: - /* free up his parsing allocations */ - lws_free_header_table(wsi); - return -1; -} - diff --git a/src/engine/external/libwebsockets/server.c b/src/engine/external/libwebsockets/server.c deleted file mode 100644 index ed5c47b2a..000000000 --- a/src/engine/external/libwebsockets/server.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - - -#include "private-libwebsockets.h" - -int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context) -{ - int n; - int sockfd; - struct sockaddr_in sin; - socklen_t len = sizeof(sin); - int opt = 1; - struct libwebsocket *wsi; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 serv_addr6; -#endif - struct sockaddr_in serv_addr4; - struct sockaddr *v; - - /* set up our external listening socket we serve on */ - - if (info->port == CONTEXT_PORT_NO_LISTEN) - return 0; - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) - sockfd = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - sockfd = socket(AF_INET, SOCK_STREAM, 0); - - if (sockfd < 0) { - lwsl_err("ERROR opening socket\n"); - return 1; - } - - /* - * allow us to restart even if old sockets in TIME_WAIT - */ - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&opt, sizeof(opt)) < 0) { - compatible_close(sockfd); - return 1; - } - - lws_plat_set_socket_options(context, sockfd); - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&serv_addr6; - n = sizeof(struct sockaddr_in6); - bzero((char *) &serv_addr6, sizeof(serv_addr6)); - serv_addr6.sin6_addr = in6addr_any; - serv_addr6.sin6_family = AF_INET6; - serv_addr6.sin6_port = htons(info->port); - } else -#endif - { - v = (struct sockaddr *)&serv_addr4; - n = sizeof(serv_addr4); - bzero((char *) &serv_addr4, sizeof(serv_addr4)); - serv_addr4.sin_addr.s_addr = INADDR_ANY; - serv_addr4.sin_family = AF_INET; - - if (info->iface) { - if (interface_to_sa(context, info->iface, - (struct sockaddr_in *)v, n) < 0) { - lwsl_err("Unable to find interface %s\n", - info->iface); - compatible_close(sockfd); - return 1; - } - } - - serv_addr4.sin_port = htons(info->port); - } /* ipv4 */ - - n = bind(sockfd, v, n); - if (n < 0) { - lwsl_err("ERROR on binding to port %d (%d %d)\n", - info->port, n, LWS_ERRNO); - compatible_close(sockfd); - return 1; - } - - if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1) - lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); - else - info->port = ntohs(sin.sin_port); - - context->listen_port = info->port; - - wsi = lws_zalloc(sizeof(struct libwebsocket)); - if (wsi == NULL) { - lwsl_err("Out of mem\n"); - compatible_close(sockfd); - return 1; - } - wsi->sock = sockfd; - wsi->mode = LWS_CONNMODE_SERVER_LISTENER; - - insert_wsi_socket_into_fds(context, wsi); - - context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO; - context->listen_service_count = 0; - context->listen_service_fd = sockfd; - - listen(sockfd, LWS_SOMAXCONN); - lwsl_notice(" Listening on port %d\n", info->port); - - return 0; -} - -int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi) -{ - struct libwebsocket_context *context = wsi->protocol->owning_server; - - /* there is no pending change */ - if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE)) - return 0; - - /* stuff is still buffered, not ready to really accept new input */ - if (wsi->rxflow_buffer) { - /* get ourselves called back to deal with stashed buffer */ - libwebsocket_callback_on_writable(context, wsi); - return 0; - } - - /* pending is cleared, we can change rxflow state */ - - wsi->rxflow_change_to &= ~LWS_RXFLOW_PENDING_CHANGE; - - lwsl_info("rxflow: wsi %p change_to %d\n", wsi, - wsi->rxflow_change_to & LWS_RXFLOW_ALLOW); - - /* adjust the pollfd for this wsi */ - - if (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW) { - if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { - lwsl_info("%s: fail\n", __func__); - return -1; - } - } else - if (lws_change_pollfd(wsi, LWS_POLLIN, 0)) - return -1; - - return 0; -} - -int lws_http_action(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - char *uri_ptr = NULL; - int uri_len = 0; - enum http_version request_version; - enum http_connection_type connection_type; - int http_version_len; - char content_length_str[32]; - char http_version_str[10]; - char http_conn_str[20]; - int n; - - /* it's not websocket.... shall we accept it as http? */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) && - !lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) && -#ifdef LWS_USE_HTTP2 - !lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH) && -#endif - !lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) { - lwsl_warn("Missing URI in HTTP request\n"); - goto bail_nuke_ah; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) && - lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - lwsl_warn("GET and POST methods?\n"); - goto bail_nuke_ah; - } - - if (libwebsocket_ensure_user_space(wsi)) - goto bail_nuke_ah; - -#ifdef LWS_USE_HTTP2 - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH)) { - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH); - lwsl_info("HTTP2 request for '%s'\n", uri_ptr); - goto got_uri; - } -#endif - if (lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) { - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_OPTIONS_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI); - lwsl_info("HTTP OPTIONS request for '%s'\n", uri_ptr); - goto got_uri; - } - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI); - lwsl_info("HTTP POST request for '%s'\n", uri_ptr); - goto got_uri; - } - if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) { - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI); - lwsl_info("HTTP GET request for '%s'\n", uri_ptr); - } - -got_uri: - /* HTTP header had a content length? */ - - wsi->u.http.content_length = 0; - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) - wsi->u.http.content_length = 100 * 1024 * 1024; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - lws_hdr_copy(wsi, content_length_str, - sizeof(content_length_str) - 1, - WSI_TOKEN_HTTP_CONTENT_LENGTH); - wsi->u.http.content_length = atoi(content_length_str); - } - - /* http_version? Default to 1.0, override with token: */ - request_version = HTTP_VERSION_1_0; - - /* Works for single digit HTTP versions. : */ - http_version_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP); - if (http_version_len > 7) { - lws_hdr_copy(wsi, http_version_str, - sizeof(http_version_str) - 1, WSI_TOKEN_HTTP); - if (http_version_str[5] == '1' && http_version_str[7] == '1') - request_version = HTTP_VERSION_1_1; - } - wsi->u.http.request_version = request_version; - - /* HTTP/1.1 defaults to "keep-alive", 1.0 to "close" */ - if (request_version == HTTP_VERSION_1_1) - connection_type = HTTP_CONNECTION_KEEP_ALIVE; - else - connection_type = HTTP_CONNECTION_CLOSE; - - /* Override default if http "Connection:" header: */ - if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) { - lws_hdr_copy(wsi, http_conn_str, sizeof(http_conn_str) - 1, - WSI_TOKEN_CONNECTION); - http_conn_str[sizeof(http_conn_str) - 1] = '\0'; - if (!strcasecmp(http_conn_str, "keep-alive")) - connection_type = HTTP_CONNECTION_KEEP_ALIVE; - else - if (strcasecmp(http_conn_str, "close")) - connection_type = HTTP_CONNECTION_CLOSE; - } - wsi->u.http.connection_type = connection_type; - - n = 0; - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - wsi->user_space, uri_ptr, uri_len); - - if (!n) { - /* - * if there is content supposed to be coming, - * put a timeout on it having arrived - */ - libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, - AWAITING_TIMEOUT); - - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_HTTP, - wsi->user_space, uri_ptr, uri_len); - } - - /* now drop the header info we kept a pointer to */ - lws_free2(wsi->u.http.ah); - - if (n) { - lwsl_info("LWS_CALLBACK_HTTP closing\n"); - return 1; /* struct ah ptr already nuked */ } - - /* - * If we're not issuing a file, check for content_length or - * HTTP keep-alive. No keep-alive header allocation for - * ISSUING_FILE, as this uses HTTP/1.0. - * - * In any case, return 0 and let libwebsocket_read decide how to - * proceed based on state - */ - if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) - /* Prepare to read body if we have a content length: */ - if (wsi->u.http.content_length > 0) - wsi->state = WSI_STATE_HTTP_BODY; - - return 0; - -bail_nuke_ah: - /* drop the header info */ - lws_free2(wsi->u.hdr.ah); - - return 1; -} - - -int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len) -{ - struct allocated_headers *ah; - int protocol_len; - char protocol_list[128]; - char protocol_name[32]; - char *p; - int n, hit; - - /* LWS_CONNMODE_WS_SERVING */ - - while (len--) { - if (libwebsocket_parse(context, wsi, *(*buf)++)) { - lwsl_info("libwebsocket_parse failed\n"); - goto bail_nuke_ah; - } - - if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) - continue; - - lwsl_parser("libwebsocket_parse sees parsing complete\n"); - - wsi->mode = LWS_CONNMODE_PRE_WS_SERVING_ACCEPT; - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* is this websocket protocol or normal http 1.0? */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) || - !lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) { - - ah = wsi->u.hdr.ah; - - lws_union_transition(wsi, LWS_CONNMODE_HTTP_SERVING_ACCEPTED); - wsi->state = WSI_STATE_HTTP; - wsi->u.http.fd = LWS_INVALID_FILE; - - /* expose it at the same offset as u.hdr */ - wsi->u.http.ah = ah; - - n = lws_http_action(context, wsi); - - return n; - } - - if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE), - "websocket")) - goto upgrade_ws; -#ifdef LWS_USE_HTTP2 - if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE), - "h2c-14")) - goto upgrade_h2c; -#endif - /* dunno what he wanted to upgrade to */ - goto bail_nuke_ah; - -#ifdef LWS_USE_HTTP2 -upgrade_h2c: - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP2_SETTINGS)) { - lwsl_err("missing http2_settings\n"); - goto bail_nuke_ah; - } - - lwsl_err("h2c upgrade...\n"); - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS); - /* convert the peer's HTTP-Settings */ - n = lws_b64_decode_string(p, protocol_list, sizeof(protocol_list)); - if (n < 0) { - lwsl_parser("HTTP2_SETTINGS too long\n"); - return 1; - } - - /* adopt the header info */ - - ah = wsi->u.hdr.ah; - - lws_union_transition(wsi, LWS_CONNMODE_HTTP2_SERVING); - - /* http2 union member has http union struct at start */ - wsi->u.http.ah = ah; - - lws_http2_init(&wsi->u.http2.peer_settings); - lws_http2_init(&wsi->u.http2.my_settings); - - /* HTTP2 union */ - - lws_http2_interpret_settings_payload(&wsi->u.http2.peer_settings, (unsigned char *)protocol_list, n); - - strcpy(protocol_list, - "HTTP/1.1 101 Switching Protocols\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Upgrade: h2c\x0d\x0a\x0d\x0a"); - n = lws_issue_raw(wsi, (unsigned char *)protocol_list, - strlen(protocol_list)); - if (n != strlen(protocol_list)) { - lwsl_debug("http2 switch: ERROR writing to socket\n"); - return 1; - } - - wsi->state = WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE; - - return 0; -#endif - -upgrade_ws: - if (!wsi->protocol) - lwsl_err("NULL protocol at libwebsocket_read\n"); - - /* - * It's websocket - * - * Select the first protocol we support from the list - * the client sent us. - * - * Copy it to remove header fragmentation - */ - - if (lws_hdr_copy(wsi, protocol_list, sizeof(protocol_list) - 1, - WSI_TOKEN_PROTOCOL) < 0) { - lwsl_err("protocol list too long"); - goto bail_nuke_ah; - } - - protocol_len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL); - protocol_list[protocol_len] = '\0'; - p = protocol_list; - hit = 0; - - while (*p && !hit) { - n = 0; - while (n < sizeof(protocol_name) - 1 && *p && *p !=',') - protocol_name[n++] = *p++; - protocol_name[n] = '\0'; - if (*p) - p++; - - lwsl_info("checking %s\n", protocol_name); - - n = 0; - while (wsi->protocol && context->protocols[n].callback) { - if (!wsi->protocol->name) { - n++; - continue; - } - if (!strcmp(context->protocols[n].name, - protocol_name)) { - lwsl_info("prot match %d\n", n); - wsi->protocol = &context->protocols[n]; - hit = 1; - break; - } - - n++; - } - } - - /* we didn't find a protocol he wanted? */ - - if (!hit) { - if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL) == - NULL) { - /* - * some clients only have one protocol and - * do not sent the protocol list header... - * allow it and match to protocol 0 - */ - lwsl_info("defaulting to prot 0 handler\n"); - wsi->protocol = &context->protocols[0]; - } else { - lwsl_err("No protocol from list \"%s\" supported\n", - protocol_list); - goto bail_nuke_ah; - } - } - - /* allocate wsi->user storage */ - if (libwebsocket_ensure_user_space(wsi)) - goto bail_nuke_ah; - - /* - * Give the user code a chance to study the request and - * have the opportunity to deny it - */ - - if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - wsi->user_space, - lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) { - lwsl_warn("User code denied connection\n"); - goto bail_nuke_ah; - } - - - /* - * Perform the handshake according to the protocol version the - * client announced - */ - - switch (wsi->ietf_spec_revision) { - case 13: - lwsl_parser("lws_parse calling handshake_04\n"); - if (handshake_0405(context, wsi)) { - lwsl_info("hs0405 has failed the connection\n"); - goto bail_nuke_ah; - } - break; - - default: - lwsl_warn("Unknown client spec version %d\n", - wsi->ietf_spec_revision); - goto bail_nuke_ah; - } - - /* drop the header info -- no bail_nuke_ah after this */ - lws_free_header_table(wsi); - - lws_union_transition(wsi, LWS_CONNMODE_WS_SERVING); - - /* - * create the frame buffer for this connection according to the - * size mentioned in the protocol definition. If 0 there, use - * a big default for compatibility - */ - - n = wsi->protocol->rx_buffer_size; - if (!n) - n = LWS_MAX_SOCKET_IO_BUF; - n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING; - wsi->u.ws.rx_user_buffer = lws_malloc(n); - if (!wsi->u.ws.rx_user_buffer) { - lwsl_err("Out of Mem allocating rx buffer %d\n", n); - return 1; - } - lwsl_info("Allocating RX buffer %d\n", n); - - if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { - lwsl_warn("Failed to set SNDBUF to %d", n); - return 1; - } - - lwsl_parser("accepted v%02d connection\n", - wsi->ietf_spec_revision); - } /* while all chars are handled */ - - return 0; - -bail_nuke_ah: - /* drop the header info */ - lws_free_header_table(wsi); - return 1; -} - -struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) -{ - struct libwebsocket *new_wsi; - - new_wsi = lws_zalloc(sizeof(struct libwebsocket)); - if (new_wsi == NULL) { - lwsl_err("Out of memory for new connection\n"); - return NULL; - } - - new_wsi->pending_timeout = NO_PENDING_TIMEOUT; - new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* intialize the instance struct */ - - new_wsi->state = WSI_STATE_HTTP; - new_wsi->mode = LWS_CONNMODE_HTTP_SERVING; - new_wsi->hdr_parsing_completed = 0; - - if (lws_allocate_header_table(new_wsi)) { - lws_free(new_wsi); - return NULL; - } - - /* - * these can only be set once the protocol is known - * we set an unestablished connection's protocol pointer - * to the start of the supported list, so it can look - * for matching ones during the handshake - */ - new_wsi->protocol = context->protocols; - new_wsi->user_space = NULL; - new_wsi->ietf_spec_revision = 0; - - /* - * outermost create notification for wsi - * no user_space because no protocol selection - */ - context->protocols[0].callback(context, new_wsi, - LWS_CALLBACK_WSI_CREATE, NULL, NULL, 0); - - return new_wsi; -} - -/** - * lws_http_transaction_completed() - wait for new http transaction or close - * @wsi: websocket connection - * - * Returns 1 if the HTTP connection must close now - * Returns 0 and resets connection to wait for new HTTP header / - * transaction if possible - */ - -LWS_VISIBLE -int lws_http_transaction_completed(struct libwebsocket *wsi) -{ - /* if we can't go back to accept new headers, drop the connection */ - if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { - lwsl_info("%s: close connection\n", __func__); - return 1; - } - - /* otherwise set ourselves up ready to go again */ - wsi->state = WSI_STATE_HTTP; - - lwsl_info("%s: await new transaction\n", __func__); - - return 0; -} - -int lws_server_socket_service(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) -{ - struct libwebsocket *new_wsi = NULL; - int accept_fd = 0; - socklen_t clilen; - struct sockaddr_in cli_addr; - int n; - int len; - - switch (wsi->mode) { - - case LWS_CONNMODE_HTTP_SERVING: - case LWS_CONNMODE_HTTP_SERVING_ACCEPTED: - case LWS_CONNMODE_HTTP2_SERVING: - - /* handle http headers coming in */ - - /* pending truncated sends have uber priority */ - - if (wsi->truncated_send_len) { - if (pollfd->revents & LWS_POLLOUT) - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from socket service\n"); - return -1; - } - /* - * we can't afford to allow input processing send - * something new, so spin around he event loop until - * he doesn't have any partials - */ - break; - } - - /* any incoming data ready? */ - - if (pollfd->revents & LWS_POLLIN) { - len = lws_ssl_capable_read(context, wsi, - context->service_buffer, - sizeof(context->service_buffer)); - switch (len) { - case 0: - lwsl_info("lws_server_skt_srv: read 0 len\n"); - /* lwsl_info(" state=%d\n", wsi->state); */ - if (!wsi->hdr_parsing_completed) - lws_free_header_table(wsi); - /* fallthru */ - case LWS_SSL_CAPABLE_ERROR: - libwebsocket_close_and_free_session( - context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; - case LWS_SSL_CAPABLE_MORE_SERVICE: - goto try_pollout; - } - - /* just ignore incoming if waiting for close */ - if (wsi->state != WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - - /* hm this may want to send (via HTTP callback for example) */ - n = libwebsocket_read(context, wsi, - context->service_buffer, len); - if (n < 0) - /* we closed wsi */ - return 0; - - /* hum he may have used up the writability above */ - break; - } - } - -try_pollout: - /* this handles POLLOUT for http serving fragments */ - - if (!(pollfd->revents & LWS_POLLOUT)) - break; - - /* one shot */ - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) - goto fail; - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE); - - if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) { - n = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi->protocol->owning_server, - wsi, LWS_CALLBACK_HTTP_WRITEABLE, - wsi->user_space, - NULL, - 0); - if (n < 0) - goto fail; - break; - } - - /* >0 == completion, <0 == error */ - n = libwebsockets_serve_http_file_fragment(context, wsi); - if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi))) - goto fail; - break; - - case LWS_CONNMODE_SERVER_LISTENER: - - /* pollin means a client has connected to us then */ - - if (!(pollfd->revents & LWS_POLLIN)) - break; - - /* listen socket got an unencrypted connection... */ - - clilen = sizeof(cli_addr); - lws_latency_pre(context, wsi); - accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr, - &clilen); - lws_latency(context, wsi, - "unencrypted accept LWS_CONNMODE_SERVER_LISTENER", - accept_fd, accept_fd >= 0); - if (accept_fd < 0) { - if (LWS_ERRNO == LWS_EAGAIN || LWS_ERRNO == LWS_EWOULDBLOCK) { - lwsl_debug("accept asks to try again\n"); - break; - } - lwsl_warn("ERROR on accept: %s\n", strerror(LWS_ERRNO)); - break; - } - - lws_plat_set_socket_options(context, accept_fd); - - /* - * look at who we connected to and give user code a chance - * to reject based on client IP. There's no protocol selected - * yet so we issue this to protocols[0] - */ - - if ((context->protocols[0].callback)(context, wsi, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - NULL, (void *)(long)accept_fd, 0)) { - lwsl_debug("Callback denied network connection\n"); - compatible_close(accept_fd); - break; - } - - new_wsi = libwebsocket_create_new_server_wsi(context); - if (new_wsi == NULL) { - compatible_close(accept_fd); - break; - } - - new_wsi->sock = accept_fd; - - /* the transport is accepted... give him time to negotiate */ - libwebsocket_set_timeout(new_wsi, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - AWAITING_TIMEOUT); - - /* - * A new connection was accepted. Give the user a chance to - * set properties of the newly created wsi. There's no protocol - * selected yet so we issue this to protocols[0] - */ - - (context->protocols[0].callback)(context, new_wsi, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0); - - lws_libev_accept(context, new_wsi, accept_fd); - - if (!LWS_SSL_ENABLED(context)) { - lwsl_debug("accepted new conn port %u on fd=%d\n", - ntohs(cli_addr.sin_port), accept_fd); - - insert_wsi_socket_into_fds(context, new_wsi); - } - break; - - default: - break; - } - - if (lws_server_socket_service_ssl(context, &wsi, new_wsi, - accept_fd, pollfd)) - goto fail; - - return 0; - -fail: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 1; -} - -#include "lextable-strings.h" - -const unsigned char *lws_token_to_string(enum lws_token_indexes token) -{ - if ((unsigned int)token >= ARRAY_SIZE(set)) - return NULL; - - return (unsigned char *)set[token]; -} - -int lws_add_http_header_by_name(struct libwebsocket_context *context, - struct libwebsocket *wsi, - const unsigned char *name, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) -{ -#ifdef LWS_USE_HTTP2 - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) - return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end); -#endif - if (name) { - while (*p < end && *name) - *((*p)++) = *name++; - - if (*p == end) - return 1; - - *((*p)++) = ' '; - } - if (*p + length + 3 >= end) - return 1; - - memcpy(*p, value, length); - *p += length; - - *((*p)++) = '\x0d'; - *((*p)++) = '\x0a'; - - return 0; -} - -int lws_finalize_http_header(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char **p, - unsigned char *end) -{ -#ifdef LWS_USE_HTTP2 - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) - return 0; -#endif - - if ((long)(end - *p) < 3) - return 1; - - *((*p)++) = '\x0d'; - *((*p)++) = '\x0a'; - - return 0; -} - -int lws_add_http_header_by_token(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum lws_token_indexes token, - const unsigned char *value, - int length, - unsigned char **p, - unsigned char *end) -{ - const unsigned char *name; -#ifdef LWS_USE_HTTP2 - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) - return lws_add_http2_header_by_token(context, wsi, token, value, length, p, end); -#endif - name = lws_token_to_string(token); - if (!name) - return 1; - - return lws_add_http_header_by_name(context, wsi, name, value, length, p, end); -} - -int lws_add_http_header_content_length(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned long content_length, - unsigned char **p, - unsigned char *end) -{ - char b[24]; - int n; - - n = sprintf(b, "%lu", content_length); - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, (unsigned char *)b, n, p, end)) - return 1; - wsi->u.http.content_length = content_length; - wsi->u.http.content_remain = content_length; - - return 0; -} - -static const char *err400[] = { - "Bad Request", - "Unauthorized", - "Payment Required", - "Forbidden", - "Not Found", - "Method Not Allowed", - "Not Acceptable", - "Proxy Auth Required", - "Request Timeout", - "Conflict", - "Gone", - "Length Required", - "Precondition Failed", - "Request Entity Too Large", - "Request URI too Long", - "Unsupported Media Type", - "Requested Range Not Satisfiable", - "Expectation Failed" -}; - -static const char *err500[] = { - "Internal Server Error", - "Not Implemented", - "Bad Gateway", - "Service Unavailable", - "Gateway Timeout", - "HTTP Version Not Supported" -}; - -int lws_add_http_header_status(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned int code, - unsigned char **p, - unsigned char *end) -{ - unsigned char code_and_desc[60]; - const char *description = ""; - int n; - -#ifdef LWS_USE_HTTP2 - if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) - return lws_add_http2_header_status(context, wsi, code, p, end); -#endif - if (code >= 400 && code < (400 + ARRAY_SIZE(err400))) - description = err400[code - 400]; - if (code >= 500 && code < (500 + ARRAY_SIZE(err500))) - description = err500[code - 500]; - - n = sprintf((char *)code_and_desc, "HTTP/1.0 %u %s", code, description); - - return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, n, p, end); -} - -/** - * libwebsockets_return_http_status() - Return simple http status - * @context: libwebsockets context - * @wsi: Websocket instance (available from user callback) - * @code: Status index, eg, 404 - * @html_body: User-readable HTML description < 1KB, or NULL - * - * Helper to report HTTP errors back to the client cleanly and - * consistently - */ -LWS_VISIBLE int libwebsockets_return_http_status( - struct libwebsocket_context *context, struct libwebsocket *wsi, - unsigned int code, const char *html_body) -{ - int n, m; - - unsigned char *p = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING; - unsigned char *start = p; - unsigned char *end = p + sizeof(context->service_buffer) - - LWS_SEND_BUFFER_PRE_PADDING; - - if (!html_body) - html_body = ""; - - if (lws_add_http_header_status(context, wsi, code, &p, end)) - return 1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end)) - return 1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"text/html", 9, &p, end)) - return 1; - if (lws_finalize_http_header(context, wsi, &p, end)) - return 1; - - m = libwebsocket_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS); - if (m != (int)(p - start)) - return 1; - - n = sprintf((char *)start, "

%u

%s", code, html_body); - m = libwebsocket_write(wsi, start, n, LWS_WRITE_HTTP); - - return m != n; -} - -/** - * libwebsockets_serve_http_file() - Send a file back to the client using http - * @context: libwebsockets context - * @wsi: Websocket instance (available from user callback) - * @file: The file to issue over http - * @content_type: The http content type, eg, text/html - * @other_headers: NULL or pointer to \0-terminated other header string - * - * This function is intended to be called from the callback in response - * to http requests from the client. It allows the callback to issue - * local files down the http link in a single step. - * - * Returning <0 indicates error and the wsi should be closed. Returning - * >0 indicates the file was completely sent and - * lws_http_transaction_completed() called on the wsi (and close if != 0) - * ==0 indicates the file transfer is started and needs more service later, - * the wsi should be left alone. - */ - -LWS_VISIBLE int libwebsockets_serve_http_file( - struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers, - int other_headers_len) -{ - unsigned char *response = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING; - unsigned char *p = response; - unsigned char *end = p + sizeof(context->service_buffer) - - LWS_SEND_BUFFER_PRE_PADDING; - int ret = 0; - - wsi->u.http.fd = lws_plat_open_file(file, &wsi->u.http.filelen); - - if (wsi->u.http.fd == LWS_INVALID_FILE) { - lwsl_err("Unable to open '%s'\n", file); - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_NOT_FOUND, NULL); - return -1; - } - - if (lws_add_http_header_status(context, wsi, 200, &p, end)) - return -1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end)) - return -1; - if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)content_type, strlen(content_type), &p, end)) - return -1; - if (lws_add_http_header_content_length(context, wsi, wsi->u.http.filelen, &p, end)) - return -1; - - if (other_headers) { - if ((end - p) < other_headers_len) - return -1; - memcpy(p, other_headers, other_headers_len); - p += other_headers_len; - } - - if (lws_finalize_http_header(context, wsi, &p, end)) - return -1; - - ret = libwebsocket_write(wsi, response, - p - response, LWS_WRITE_HTTP_HEADERS); - if (ret != (p - response)) { - lwsl_err("_write returned %d from %d\n", ret, (p - response)); - return -1; - } - - wsi->u.http.filepos = 0; - wsi->state = WSI_STATE_HTTP_ISSUING_FILE; - - return libwebsockets_serve_http_file_fragment(context, wsi); -} - - -int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len) -{ - size_t n = 0; - int m; - -#if 0 - lwsl_parser("received %d byte packet\n", (int)len); - lwsl_hexdump(buf, len); -#endif - - /* let the rx protocol state machine have as much as it needs */ - - while (n < len) { - /* - * we were accepting input but now we stopped doing so - */ - if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) { - lws_rxflow_cache(wsi, buf, n, len); - - return 1; - } - - /* account for what we're using in rxflow buffer */ - if (wsi->rxflow_buffer) - wsi->rxflow_pos++; - - /* process the byte */ - m = libwebsocket_rx_sm(wsi, buf[n++]); - if (m < 0) - return -1; - } - - return 0; -} - -LWS_VISIBLE void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info) -{ - if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) - return; - - /* find canonical hostname */ - gethostname((char *)context->canonical_hostname, - sizeof(context->canonical_hostname) - 1); - - lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname); -} diff --git a/src/engine/external/libwebsockets/service.c b/src/engine/external/libwebsockets/service.c deleted file mode 100644 index f905a6051..000000000 --- a/src/engine/external/libwebsockets/service.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * 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: - * version 2.1 of the License. - * - * 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 - */ - -#include "private-libwebsockets.h" - -static int -lws_calllback_as_writeable(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - int n; - - switch (wsi->mode) { - case LWS_CONNMODE_WS_CLIENT: - n = LWS_CALLBACK_CLIENT_WRITEABLE; - break; - case LWS_CONNMODE_WS_SERVING: - n = LWS_CALLBACK_SERVER_WRITEABLE; - break; - default: - n = LWS_CALLBACK_HTTP_WRITEABLE; - break; - } - lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space); - return user_callback_handle_rxflow(wsi->protocol->callback, context, - wsi, (enum libwebsocket_callback_reasons) n, - wsi->user_space, NULL, 0); -} - -int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) -{ - int n; - struct lws_tokens eff_buf; -#ifdef LWS_USE_HTTP2 - struct libwebsocket *wsi2; -#endif - int ret; - int m; - - /* pending truncated sends have uber priority */ - - if (wsi->truncated_send_len) { - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("lws_handle_POLLOUT_event signalling to close\n"); - return -1; - } - /* leave POLLOUT active either way */ - return 0; - } else - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - lwsl_info("***** %x signalling to close in POLLOUT handler\n", wsi); - return -1; /* retry closing now */ - } -#ifdef LWS_USE_HTTP2 - /* protocol packets are next */ - if (wsi->pps) { - lwsl_info("servicing pps %d\n", wsi->pps); - switch (wsi->pps) { - case LWS_PPS_HTTP2_MY_SETTINGS: - case LWS_PPS_HTTP2_ACK_SETTINGS: - lws_http2_do_pps_send(context, wsi); - break; - default: - break; - } - wsi->pps = LWS_PPS_NONE; - libwebsocket_rx_flow_control(wsi, 1); - - return 0; /* leave POLLOUT active */ - } -#endif - /* pending control packets have next priority */ - - if (wsi->state == WSI_STATE_ESTABLISHED && wsi->u.ws.ping_payload_len) { - n = libwebsocket_write(wsi, - &wsi->u.ws.ping_payload_buf[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.ping_payload_len, - LWS_WRITE_PONG); - if (n < 0) - return -1; - /* well he is sent, mark him done */ - wsi->u.ws.ping_payload_len = 0; - /* leave POLLOUT active either way */ - return 0; - } - - /* if nothing critical, user can get the callback */ - - m = lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_IS_WRITEABLE, - NULL, 0); -#ifndef LWS_NO_EXTENSIONS - if (!wsi->extension_data_pending) - goto user_service; -#endif - /* - * check in on the active extensions, see if they - * had pending stuff to spill... they need to get the - * first look-in otherwise sequence will be disordered - * - * NULL, zero-length eff_buf means just spill pending - */ - - ret = 1; - while (ret == 1) { - - /* default to nobody has more to spill */ - - ret = 0; - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* give every extension a chance to spill */ - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - &eff_buf, 0); - if (m < 0) { - lwsl_err("ext reports fatal error\n"); - return -1; - } - if (m) - /* - * at least one extension told us he has more - * to spill, so we will go around again after - */ - ret = 1; - - /* assuming they gave us something to send, send it */ - - if (eff_buf.token_len) { - n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - lwsl_info("closing from POLLOUT spill\n"); - return -1; - } - /* - * Keep amount spilled small to minimize chance of this - */ - if (n != eff_buf.token_len) { - lwsl_err("Unable to spill ext %d vs %s\n", - eff_buf.token_len, n); - return -1; - } - } else - continue; - - /* no extension has more to spill */ - - if (!ret) - continue; - - /* - * There's more to spill from an extension, but we just sent - * something... did that leave the pipe choked? - */ - - if (!lws_send_pipe_choked(wsi)) - /* no we could add more */ - continue; - - lwsl_info("choked in POLLOUT service\n"); - - /* - * Yes, he's choked. Leave the POLLOUT masked on so we will - * come back here when he is unchoked. Don't call the user - * callback to enforce ordering of spilling, he'll get called - * when we come back here and there's nothing more to spill. - */ - - return 0; - } -#ifndef LWS_NO_EXTENSIONS - wsi->extension_data_pending = 0; - -user_service: -#endif - /* one shot */ - - if (pollfd) { - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_info("failled at set pollfd\n"); - return 1; - } - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE); - } - -#ifdef LWS_USE_HTTP2 - /* - * we are the 'network wsi' for potentially many muxed child wsi with - * no network connection of their own, who have to use us for all their - * network actions. So we use a round-robin scheme to share out the - * POLLOUT notifications to our children. - * - * But because any child could exhaust the socket's ability to take - * writes, we can only let one child get notified each time. - * - * In addition children may be closed / deleted / added between POLLOUT - * notifications, so we can't hold pointers - */ - - if (wsi->mode != LWS_CONNMODE_HTTP2_SERVING) { - lwsl_info("%s: non http2\n", __func__); - goto notify; - } - - wsi->u.http2.requested_POLLOUT = 0; - if (!wsi->u.http2.initialized) { - lwsl_info("pollout on uninitialized http2 conn\n"); - return 0; - } - - lwsl_info("%s: doing children\n", __func__); - - wsi2 = wsi; - do { - wsi2 = wsi2->u.http2.next_child_wsi; - lwsl_info("%s: child %p\n", __func__, wsi2); - if (!wsi2) - continue; - if (!wsi2->u.http2.requested_POLLOUT) - continue; - wsi2->u.http2.requested_POLLOUT = 0; - if (lws_calllback_as_writeable(context, wsi2)) { - lwsl_debug("Closing POLLOUT child\n"); - libwebsocket_close_and_free_session(context, wsi2, - LWS_CLOSE_STATUS_NOSTATUS); - } - wsi2 = wsi; - } while (wsi2 != NULL && !lws_send_pipe_choked(wsi)); - - lwsl_info("%s: completed\n", __func__); - - return 0; -notify: -#endif - return lws_calllback_as_writeable(context, wsi); -} - - - -int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec) -{ - /* - * if extensions want in on it (eg, we are a mux parent) - * give them a chance to service child timeouts - */ - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_1HZ, NULL, sec) < 0) - return 0; - - if (!wsi->pending_timeout) - return 0; - - /* - * if we went beyond the allowed time, kill the - * connection - */ - if (sec > wsi->pending_timeout_limit) { - lwsl_info("TIMEDOUT WAITING on %d\n", wsi->pending_timeout); - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS); - return 1; - } - - return 0; -} - -int lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int len) -{ - /* his RX is flowcontrolled, don't send remaining now */ - if (wsi->rxflow_buffer) { - /* rxflow while we were spilling prev rxflow */ - lwsl_info("stalling in existing rxflow buf\n"); - return 1; - } - - /* a new rxflow, buffer it and warn caller */ - lwsl_info("new rxflow input buffer len %d\n", len - n); - wsi->rxflow_buffer = lws_malloc(len - n); - wsi->rxflow_len = len - n; - wsi->rxflow_pos = 0; - memcpy(wsi->rxflow_buffer, buf + n, len - n); - - return 0; -} - -/** - * libwebsocket_service_fd() - Service polled socket with something waiting - * @context: Websocket context - * @pollfd: The pollfd entry describing the socket fd and which events - * happened. - * - * This function takes a pollfd that has POLLIN or POLLOUT activity and - * services it according to the state of the associated - * struct libwebsocket. - * - * The one call deals with all "service" that might happen on a socket - * including listen accepts, http files as well as websocket protocol. - * - * If a pollfd says it has something, you can just pass it to - * libwebsocket_serice_fd() whether it is a socket handled by lws or not. - * If it sees it is a lws socket, the traffic will be handled and - * pollfd->revents will be zeroed now. - * - * If the socket is foreign to lws, it leaves revents alone. So you can - * see if you should service yourself by checking the pollfd revents - * after letting lws try to service it. - */ - -LWS_VISIBLE int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd) -{ - struct libwebsocket *wsi; - int n; - int m; - int listen_socket_fds_index = 0; - time_t now; - int timed_out = 0; - int our_fd = 0; - char draining_flow = 0; - int more; - struct lws_tokens eff_buf; - - if (context->listen_service_fd) - listen_socket_fds_index = context->lws_lookup[ - context->listen_service_fd]->position_in_fds_table; - - /* - * you can call us with pollfd = NULL to just allow the once-per-second - * global timeout checks; if less than a second since the last check - * it returns immediately then. - */ - - time(&now); - - /* TODO: if using libev, we should probably use timeout watchers... */ - if (context->last_timeout_check_s != now) { - context->last_timeout_check_s = now; - - lws_plat_service_periodic(context); - - /* global timeout check once per second */ - - if (pollfd) - our_fd = pollfd->fd; - - for (n = 0; n < context->fds_count; n++) { - m = context->fds[n].fd; - wsi = context->lws_lookup[m]; - if (!wsi) - continue; - - if (libwebsocket_service_timeout_check(context, wsi, now)) - /* he did time out... */ - if (m == our_fd) { - /* it was the guy we came to service! */ - timed_out = 1; - /* mark as handled */ - if (pollfd) - pollfd->revents = 0; - } - } - } - - /* the socket we came to service timed out, nothing to do */ - if (timed_out) - return 0; - - /* just here for timeout management? */ - if (pollfd == NULL) - return 0; - - /* no, here to service a socket descriptor */ - wsi = context->lws_lookup[pollfd->fd]; - if (wsi == NULL) - /* not lws connection ... leave revents alone and return */ - return 0; - - /* - * so that caller can tell we handled, past here we need to - * zero down pollfd->revents after handling - */ - - /* - * deal with listen service piggybacking - * every listen_service_modulo services of other fds, we - * sneak one in to service the listen socket if there's anything waiting - * - * To handle connection storms, as found in ab, if we previously saw a - * pending connection here, it causes us to check again next time. - */ - - if (context->listen_service_fd && pollfd != - &context->fds[listen_socket_fds_index]) { - context->listen_service_count++; - if (context->listen_service_extraseen || - context->listen_service_count == - context->listen_service_modulo) { - context->listen_service_count = 0; - m = 1; - if (context->listen_service_extraseen > 5) - m = 2; - while (m--) { - /* - * even with extpoll, we prepared this - * internal fds for listen - */ - n = lws_poll_listen_fd(&context->fds[listen_socket_fds_index]); - if (n > 0) { /* there's a conn waiting for us */ - libwebsocket_service_fd(context, - &context-> - fds[listen_socket_fds_index]); - context->listen_service_extraseen++; - } else { - if (context->listen_service_extraseen) - context-> - listen_service_extraseen--; - break; - } - } - } - - } - - /* handle session socket closed */ - - if ((!(pollfd->revents & LWS_POLLIN)) && - (pollfd->revents & LWS_POLLHUP)) { - - lwsl_debug("Session Socket %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - goto close_and_handled; - } - - /* okay, what we came here to do... */ - - switch (wsi->mode) { - case LWS_CONNMODE_HTTP_SERVING: - case LWS_CONNMODE_HTTP_SERVING_ACCEPTED: - case LWS_CONNMODE_SERVER_LISTENER: - case LWS_CONNMODE_SSL_ACK_PENDING: - n = lws_server_socket_service(context, wsi, pollfd); - if (n < 0) - goto close_and_handled; - goto handled; - - case LWS_CONNMODE_WS_SERVING: - case LWS_CONNMODE_WS_CLIENT: - case LWS_CONNMODE_HTTP2_SERVING: - - /* the guy requested a callback when it was OK to write */ - - if ((pollfd->revents & LWS_POLLOUT) && - (wsi->state == WSI_STATE_ESTABLISHED || wsi->state == WSI_STATE_HTTP2_ESTABLISHED || wsi->state == WSI_STATE_HTTP2_ESTABLISHED_PRE_SETTINGS || - wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) && - lws_handle_POLLOUT_event(context, wsi, pollfd)) { - lwsl_info("libwebsocket_service_fd: closing\n"); - goto close_and_handled; - } - - if (wsi->rxflow_buffer && - (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) { - lwsl_info("draining rxflow\n"); - /* well, drain it */ - eff_buf.token = (char *)wsi->rxflow_buffer + - wsi->rxflow_pos; - eff_buf.token_len = wsi->rxflow_len - wsi->rxflow_pos; - draining_flow = 1; - goto drain; - } - - /* any incoming data ready? */ - - if (!(pollfd->revents & LWS_POLLIN)) - break; - - eff_buf.token_len = lws_ssl_capable_read(context, wsi, - context->service_buffer, - sizeof(context->service_buffer)); - switch (eff_buf.token_len) { - case 0: - lwsl_info("service_fd: closing due to 0 length read\n"); - goto close_and_handled; - case LWS_SSL_CAPABLE_MORE_SERVICE: - lwsl_info("SSL Capable more service\n"); - n = 0; - goto handled; - case LWS_SSL_CAPABLE_ERROR: - lwsl_info("Closing when error\n"); - goto close_and_handled; - } - - /* - * give any active extensions a chance to munge the buffer - * before parse. We pass in a pointer to an lws_tokens struct - * prepared with the default buffer and content length that's in - * there. Rather than rewrite the default buffer, extensions - * that expect to grow the buffer can adapt .token to - * point to their own per-connection buffer in the extension - * user allocation. By default with no extensions or no - * extension callback handling, just the normal input buffer is - * used then so it is efficient. - */ - - eff_buf.token = (char *)context->service_buffer; -drain: - - do { - - more = 0; - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, &eff_buf, 0); - if (m < 0) - goto close_and_handled; - if (m) - more = 1; - - /* service incoming data */ - - if (eff_buf.token_len) { - n = libwebsocket_read(context, wsi, - (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - /* we closed wsi */ - n = 0; - goto handled; - } - } - - eff_buf.token = NULL; - eff_buf.token_len = 0; - } while (more); - - if (draining_flow && wsi->rxflow_buffer && - wsi->rxflow_pos == wsi->rxflow_len) { - lwsl_info("flow buffer: drained\n"); - lws_free2(wsi->rxflow_buffer); - /* having drained the rxflow buffer, can rearm POLLIN */ -#ifdef LWS_NO_SERVER - n = -#endif - _libwebsocket_rx_flow_control(wsi); /* n ignored, needed for NO_SERVER case */ - } - - break; - - default: -#ifdef LWS_NO_CLIENT - break; -#else - n = lws_client_socket_service(context, wsi, pollfd); - goto handled; -#endif - } - - n = 0; - goto handled; - -close_and_handled: - lwsl_debug("Close and handled\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - n = 1; - -handled: - pollfd->revents = 0; - return n; -} - -/** - * libwebsocket_service() - Service any pending websocket activity - * @context: Websocket context - * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed - * service otherwise block and service immediately, returning - * after the timeout if nothing needed service. - * - * This function deals with any pending websocket traffic, for three - * kinds of event. It handles these events on both server and client - * types of connection the same. - * - * 1) Accept new connections to our context's server - * - * 2) Call the receive callback for incoming frame data received by - * server or client connections. - * - * You need to call this service function periodically to all the above - * functions to happen; if your application is single-threaded you can - * just call it in your main event loop. - * - * Alternatively you can fork a new process that asynchronously handles - * calling this service in a loop. In that case you are happy if this - * call blocks your thread until it needs to take care of something and - * would call it with a large nonzero timeout. Your loop then takes no - * CPU while there is nothing happening. - * - * If you are calling it in a single-threaded app, you don't want it to - * wait around blocking other things in your loop from happening, so you - * would call it with a timeout_ms of 0, so it returns immediately if - * nothing is pending, or as soon as it services whatever was pending. - */ - -LWS_VISIBLE int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms) -{ - return lws_plat_service(context, timeout_ms); -} - diff --git a/src/engine/external/libwebsockets/sha-1.c b/src/engine/external/libwebsockets/sha-1.c deleted file mode 100644 index e68ee38d6..000000000 --- a/src/engine/external/libwebsockets/sha-1.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://csrc.nist.gov/fips/fip180-1.txt - * implemented by Jun-ichiro itojun Itoh - */ - -#include "private-libwebsockets.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -struct sha1_ctxt { - union { - unsigned char b8[20]; - unsigned int b32[5]; - } h; - union { - unsigned char b8[8]; - u_int64_t b64[1]; - } c; - union { - unsigned char b8[64]; - unsigned int b32[16]; - } m; - unsigned char count; -}; - -/* sanity check */ -#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) -# define unsupported 1 -#elif BYTE_ORDER != BIG_ENDIAN -# if BYTE_ORDER != LITTLE_ENDIAN -# define unsupported 1 -# endif -#endif - -#ifndef unsupported - -/* constant table */ -static const unsigned int _K[] = - { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTBYTE(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - -#define PUTPAD(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - -static void sha1_step __P((struct sha1_ctxt *)); - -static void -sha1_step(struct sha1_ctxt *ctxt) -{ - unsigned int a, b, c, d, e, tmp; - size_t t, s; - -#if BYTE_ORDER == LITTLE_ENDIAN - struct sha1_ctxt tctxt; - - memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); - - for (t = 0; t < 20; t++) { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 20; t < 40; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 40; t < 60; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 60; t < 80; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - bzero(&ctxt->m.b8[0], 64); -} - -/*------------------------------------------------------------*/ - -static void -sha1_init(struct sha1_ctxt *ctxt) -{ - bzero(ctxt, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt *ctxt) -{ - size_t padlen; /*pad length in bytes*/ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) { - bzero(&ctxt->m.b8[padstart], padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - bzero(&ctxt->m.b8[padstart], padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; -#if BYTE_ORDER == BIG_ENDIAN - PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) -{ - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - off = 0; - - while (off < len) { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt *ctxt, void *digest0) -{ - unsigned char *digest; - - digest = (unsigned char *)digest0; - sha1_pad(ctxt); -#if BYTE_ORDER == BIG_ENDIAN - memcpy(digest, &ctxt->h.b8[0], 20); -#else - digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; -#endif -} - -/* - * This should look and work like the libcrypto implementation - */ - -LWS_VISIBLE unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md) -{ - struct sha1_ctxt ctx; - - sha1_init(&ctx); - sha1_loop(&ctx, d, n); - sha1_result(&ctx, (void *)md); - - return md; -} - -#endif /*unsupported*/