mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge pull request #1036 from heinrich5991/pr_ddnet_cmake_websockets
Try to find `libwebsockets` on the host system
This commit is contained in:
commit
9ec8e16ec6
|
@ -282,6 +282,13 @@ find_package(PythonInterp)
|
||||||
find_package(SDL2)
|
find_package(SDL2)
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
find_package(Wavpack)
|
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")
|
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
|
||||||
find_program(DMG dmg)
|
find_program(DMG dmg)
|
||||||
|
@ -338,6 +345,9 @@ show_dependency_status("PythonInterp" PYTHONINTERP)
|
||||||
show_dependency_status("SDL2" SDL2)
|
show_dependency_status("SDL2" SDL2)
|
||||||
show_dependency_status("Wavpack" WAVPACK)
|
show_dependency_status("Wavpack" WAVPACK)
|
||||||
show_dependency_status("Zlib" ZLIB)
|
show_dependency_status("Zlib" ZLIB)
|
||||||
|
if(WEBSOCKETS)
|
||||||
|
show_dependency_status("Websockets" WEBSOCKETS)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT(PYTHONINTERP_FOUND))
|
if(NOT(PYTHONINTERP_FOUND))
|
||||||
message(SEND_ERROR "You must install Python to compile DDNet")
|
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")
|
message(SEND_ERROR "You must install MySQL to compile the DDNet server with MySQL support")
|
||||||
endif()
|
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))
|
if(CLIENT AND NOT(CURL_FOUND))
|
||||||
message(SEND_ERROR "You must install Curl to compile the DDNet client")
|
message(SEND_ERROR "You must install Curl to compile the DDNet client")
|
||||||
endif()
|
endif()
|
||||||
|
@ -664,45 +678,10 @@ add_library(md5 EXCLUDE_FROM_ALL OBJECT ${DEP_MD5_SRC})
|
||||||
set(DEP_MD5 $<TARGET_OBJECTS:md5>)
|
set(DEP_MD5 $<TARGET_OBJECTS:md5>)
|
||||||
list(APPEND TARGETS_DEP md5)
|
list(APPEND TARGETS_DEP md5)
|
||||||
|
|
||||||
if(WEBSOCKETS)
|
set(DEPS ${DEP_MD5} ${ZLIB_DEP})
|
||||||
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 $<TARGET_OBJECTS:websockets>)
|
|
||||||
else()
|
|
||||||
set(DEP_WEBSOCKETS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(DEPS ${DEP_MD5} ${DEP_WEBSOCKETS} ${ZLIB_DEP})
|
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
set(LIBS ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES} ${PLATFORM_LIBS})
|
set(LIBS ${CMAKE_THREAD_LIBS_INIT} ${WEBSOCKETS_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_LIBS})
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
add_library(engine-shared EXCLUDE_FROM_ALL OBJECT ${ENGINE_INTERFACE} ${ENGINE_SHARED} ${ENGINE_GENERATED_SHARED} ${BASE})
|
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)
|
target_compile_definitions(${target} PRIVATE GLEW_STATIC)
|
||||||
if(WEBSOCKETS)
|
if(WEBSOCKETS)
|
||||||
target_compile_definitions(${target} PRIVATE CONF_WEBSOCKETS)
|
target_compile_definitions(${target} PRIVATE CONF_WEBSOCKETS)
|
||||||
|
target_include_directories(${target} PRIVATE ${WEBSOCKETS_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
if(MYSQL)
|
if(MYSQL)
|
||||||
target_compile_definitions(${target} PRIVATE CONF_SQL)
|
target_compile_definitions(${target} PRIVATE CONF_SQL)
|
||||||
|
|
31
cmake/FindWebsockets.cmake
Normal file
31
cmake/FindWebsockets.cmake
Normal file
|
@ -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()
|
526
src/engine/external/libwebsockets/LICENSE
vendored
526
src/engine/external/libwebsockets/LICENSE
vendored
|
@ -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.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
30
src/engine/external/libwebsockets/alloc.c
vendored
30
src/engine/external/libwebsockets/alloc.c
vendored
|
@ -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;
|
|
||||||
}
|
|
185
src/engine/external/libwebsockets/base64-decode.c
vendored
185
src/engine/external/libwebsockets/base64-decode.c
vendored
|
@ -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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
174
src/engine/external/libwebsockets/config.h
vendored
174
src/engine/external/libwebsockets/config.h
vendored
|
@ -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 <dlfcn.h> header file. */
|
|
||||||
#define HAVE_DLFCN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> 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 <in6addr.h> header file. */
|
|
||||||
/* #undef HAVE_IN6ADDR_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> 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 <memory.h> 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 <netinet/in.h> 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 <stdint.h> header file. */
|
|
||||||
#define HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
|
|
||||||
#define HAVE_STRINGS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#define HAVE_STRING_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
|
||||||
/* #undef HAVE_SYS_PRCTL_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
|
||||||
#define HAVE_SYS_SOCKET_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#define HAVE_SYS_STAT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#define HAVE_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> 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 <vfork.h> 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 <zlib.h> 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 <sys/types.h> does not define. */
|
|
||||||
/* #undef pid_t */
|
|
||||||
|
|
||||||
/* Define to rpl_realloc if the replacement function should be used. */
|
|
||||||
/* #undef realloc */
|
|
||||||
|
|
||||||
/* Define to `unsigned int' if <sys/types.h> 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 */
|
|
337
src/engine/external/libwebsockets/context.c
vendored
337
src/engine/external/libwebsockets/context.c
vendored
|
@ -1,337 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,288 +0,0 @@
|
||||||
#include "private-libwebsockets.h"
|
|
||||||
#include "extension-deflate-frame.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#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);
|
|
|
@ -1,166 +0,0 @@
|
||||||
#include "private-libwebsockets.h"
|
|
||||||
#include "extension-deflate-stream.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#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);
|
|
208
src/engine/external/libwebsockets/extension.c
vendored
208
src/engine/external/libwebsockets/extension.c
vendored
|
@ -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;
|
|
||||||
}
|
|
76
src/engine/external/libwebsockets/getifaddrs.h
vendored
76
src/engine/external/libwebsockets/getifaddrs.h
vendored
|
@ -1,76 +0,0 @@
|
||||||
#if HAVE_GETIFADDRS
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2000 Kungliga Tekniska H<EFBFBD>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
|
|
232
src/engine/external/libwebsockets/handshake.c
vendored
232
src/engine/external/libwebsockets/handshake.c
vendored
|
@ -1,232 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
530
src/engine/external/libwebsockets/huftable.h
vendored
530
src/engine/external/libwebsockets/huftable.h
vendored
|
@ -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
|
|
|
@ -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 */
|
|
||||||
|
|
||||||
};
|
|
745
src/engine/external/libwebsockets/lextable.h
vendored
745
src/engine/external/libwebsockets/lextable.h
vendored
|
@ -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 */
|
|
850
src/engine/external/libwebsockets/libwebsockets.c
vendored
850
src/engine/external/libwebsockets/libwebsockets.c
vendored
|
@ -1,850 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
1371
src/engine/external/libwebsockets/libwebsockets.h
vendored
1371
src/engine/external/libwebsockets/libwebsockets.h
vendored
File diff suppressed because it is too large
Load diff
442
src/engine/external/libwebsockets/lws-plat-unix.c
vendored
442
src/engine/external/libwebsockets/lws-plat-unix.c
vendored
|
@ -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
|
|
606
src/engine/external/libwebsockets/output.c
vendored
606
src/engine/external/libwebsockets/output.c
vendored
|
@ -1,606 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
1015
src/engine/external/libwebsockets/parsers.c
vendored
1015
src/engine/external/libwebsockets/parsers.c
vendored
File diff suppressed because it is too large
Load diff
293
src/engine/external/libwebsockets/pollfd.c
vendored
293
src/engine/external/libwebsockets/pollfd.c
vendored
|
@ -1,293 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
274
src/engine/external/libwebsockets/server-handshake.c
vendored
274
src/engine/external/libwebsockets/server-handshake.c
vendored
|
@ -1,274 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
1162
src/engine/external/libwebsockets/server.c
vendored
1162
src/engine/external/libwebsockets/server.c
vendored
File diff suppressed because it is too large
Load diff
636
src/engine/external/libwebsockets/service.c
vendored
636
src/engine/external/libwebsockets/service.c
vendored
|
@ -1,636 +0,0 @@
|
||||||
/*
|
|
||||||
* libwebsockets - small server side websockets and web server implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
301
src/engine/external/libwebsockets/sha-1.c
vendored
301
src/engine/external/libwebsockets/sha-1.c
vendored
|
@ -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 <itojun@itojun.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "private-libwebsockets.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#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*/
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "engine/external/libwebsockets/libwebsockets.h"
|
#include <libwebsockets.h>
|
||||||
#include "base/system.h"
|
#include "base/system.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
@ -31,7 +31,7 @@ typedef struct
|
||||||
|
|
||||||
struct per_session_data
|
struct per_session_data
|
||||||
{
|
{
|
||||||
struct libwebsocket *wsi;
|
struct lws *wsi;
|
||||||
int port;
|
int port;
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
TSendBuffer send_buffer;
|
TSendBuffer send_buffer;
|
||||||
|
@ -39,7 +39,7 @@ struct per_session_data
|
||||||
|
|
||||||
struct context_data
|
struct context_data
|
||||||
{
|
{
|
||||||
libwebsocket_context *context;
|
lws_context *context;
|
||||||
per_session_data *port_map[WS_CLIENTS];
|
per_session_data *port_map[WS_CLIENTS];
|
||||||
TRecvBuffer recv_buffer;
|
TRecvBuffer recv_buffer;
|
||||||
int last_used_port;
|
int last_used_port;
|
||||||
|
@ -57,10 +57,11 @@ static int receive_chunk(context_data *ctx_data, struct per_session_data *pss, v
|
||||||
return 0;
|
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;
|
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)
|
switch(reason)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +86,7 @@ static int websocket_callback(struct libwebsocket_context *context, struct libwe
|
||||||
}
|
}
|
||||||
ctx_data->last_used_port = port;
|
ctx_data->last_used_port = port;
|
||||||
pss->wsi = wsi;
|
pss->wsi = wsi;
|
||||||
int fd = libwebsocket_get_socket_fd(wsi);
|
int fd = lws_get_socket_fd(wsi);
|
||||||
socklen_t addr_size = sizeof(pss->addr);
|
socklen_t addr_size = sizeof(pss->addr);
|
||||||
getpeername(fd, (struct sockaddr *)&pss->addr, &addr_size);
|
getpeername(fd, (struct sockaddr *)&pss->addr, &addr_size);
|
||||||
int orig_port = ntohs(pss->addr.sin_port);
|
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)
|
if(chunk == NULL)
|
||||||
break;
|
break;
|
||||||
int len = chunk->size - chunk->read;
|
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)
|
if(n < 0)
|
||||||
return 1;
|
return 1;
|
||||||
if(n < len)
|
if(n < len)
|
||||||
{
|
{
|
||||||
chunk->read += n;
|
chunk->read += n;
|
||||||
libwebsocket_callback_on_writable(context, wsi);
|
lws_callback_on_writable(wsi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pss->send_buffer.PopFirst();
|
pss->send_buffer.PopFirst();
|
||||||
libwebsocket_callback_on_writable(context, wsi);
|
lws_callback_on_writable(wsi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ static int websocket_callback(struct libwebsocket_context *context, struct libwe
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct libwebsocket_protocols protocols[] = { {
|
static struct lws_protocols protocols[] = { {
|
||||||
"binary", /* name */
|
"binary", /* name */
|
||||||
websocket_callback, /* callback */
|
websocket_callback, /* callback */
|
||||||
sizeof(struct per_session_data) /* per_session_data_size */
|
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];
|
context_data *ctx_data = &contexts[first_free];
|
||||||
info.user = (void *)ctx_data;
|
info.user = (void *)ctx_data;
|
||||||
|
|
||||||
ctx_data->context = libwebsocket_create_context(&info);
|
ctx_data->context = lws_create_context(&info);
|
||||||
if(ctx_data->context == NULL)
|
if(ctx_data->context == NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -195,23 +196,23 @@ int websocket_create(const char *addr, int port)
|
||||||
|
|
||||||
int websocket_destroy(int socket)
|
int websocket_destroy(int socket)
|
||||||
{
|
{
|
||||||
libwebsocket_context *context = contexts[socket].context;
|
lws_context *context = contexts[socket].context;
|
||||||
if(context == NULL)
|
if(context == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
libwebsocket_context_destroy(context);
|
lws_context_destroy(context);
|
||||||
contexts[socket].context = NULL;
|
contexts[socket].context = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int websocket_recv(int socket, unsigned char *data, size_t maxsize, struct sockaddr_in *sockaddrbuf, size_t fromLen)
|
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)
|
if(context == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
int n = libwebsocket_service(context, 0);
|
int n = lws_service(context, 0);
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
return n;
|
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();
|
websocket_chunk *chunk = (websocket_chunk *)ctx_data->recv_buffer.First();
|
||||||
if(chunk == 0)
|
if(chunk == 0)
|
||||||
return 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)
|
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)
|
if(context == NULL)
|
||||||
return -1;
|
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];
|
struct per_session_data *pss = ctx_data->port_map[port];
|
||||||
if(pss == NULL)
|
if(pss == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -248,23 +249,23 @@ int websocket_send(int socket, const unsigned char *data, size_t size, int port)
|
||||||
chunk->read = 0;
|
chunk->read = 0;
|
||||||
memcpy(&chunk->addr, &pss->addr, sizeof(sockaddr_in));
|
memcpy(&chunk->addr, &pss->addr, sizeof(sockaddr_in));
|
||||||
memcpy(&chunk->data[LWS_SEND_BUFFER_PRE_PADDING], data, size);
|
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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int websocket_fd_set(int socket, fd_set *set)
|
int websocket_fd_set(int socket, fd_set *set)
|
||||||
{
|
{
|
||||||
libwebsocket_context *context = contexts[socket].context;
|
lws_context *context = contexts[socket].context;
|
||||||
if(context == NULL)
|
if(context == NULL)
|
||||||
return -1;
|
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;
|
int max = 0;
|
||||||
for(int i = 0; i < WS_CLIENTS; i++)
|
for(int i = 0; i < WS_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
per_session_data *pss = ctx_data->port_map[i];
|
per_session_data *pss = ctx_data->port_map[i];
|
||||||
if(pss == NULL)
|
if(pss == NULL)
|
||||||
continue;
|
continue;
|
||||||
int fd = libwebsocket_get_socket_fd(pss->wsi);
|
int fd = lws_get_socket_fd(pss->wsi);
|
||||||
if(fd > max)
|
if(fd > max)
|
||||||
max = fd;
|
max = fd;
|
||||||
FD_SET(fd, set);
|
FD_SET(fd, set);
|
||||||
|
|
Loading…
Reference in a new issue