* commit '6d27b5d321978586ea1601f757ead73dfba03da7':
Add 2 arguments to websockify.WSRequestHandler
As of now, only implemented the first command; see #83 for details.
Unit test data will now go to a temporary dir that will be deleted
once the test completes. The unit tests also setup a logger which
will persist so that it can be inspected once tests complete.
Also fixes a bug where instance var is missing from decode_hybi()
Co-authored-by: natsume.takashi@lab.ntt.co.jp
To run the unit tests just run tox from the top
level directory which will try to run unit tests
for most versions of python. Requires tox to be
installed. To run tox for a specifice env, run
tox -e<env> e.g. for python 2.7 run 'tox -epy27'.
Co-authored-by: natsume.takashi@lab.ntt.co.jp
This commit should fix#101 by enabling a special SIGCHLD
handler for when multiprocessing is in use. The handler
simply calls `multiprocessing.active_children()` (which in
turn calls `_cleanup()`) upon receiving a SIGCHLD. Now,
the `fallback_SIGCHLD` is only called when `multiprocessing`
is not in use. See also #95.
TCP_KEEPALIVE is now enabled by default. Settings for
KEEPCNT, KEEPINTVL and KEEPIDLE can be supplied when
creating WebSocketServer and KEEPALIVE can also be
disabled if required.
Also adds new unit test for testing.
Co-authored-by: natsume.takashi@lab.ntt.co.jp
WebSocketServer is a library module, as such, it cannot assume it can
write output to process stdout.
Python logging module is designed in order to allow subscribers to
handle the output out of modules. It is simple and generic mechanism to
separate between data producer and data handling.
Python logging API also has the nature of log level, so the verbose
parameter can probably be obsoleted in favor of logging level. And of
course the logging API has built in support for exception tracebacks, no
need for manual format.
Per upstream request a wrapper is created around python logging to
enable shorter statements and optional replacement.
Add --traffic parameter for traffic specific debug, this is required as
it uses direct unformatted stdout output.
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
WebSocketServer is a library module, as such it should not exit process
but return from a method, allowing the caller to execute process show
down.
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
WebSocketServer is a library module, as such it should try to restore state
after processing, to allow caller to resume normal operation.
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
This patch adds 2 arguments to websockify.WSRequestHandler for security:
* file_only: returns 404 response if non-file contents are requested.
Required to disable directory listing.
* no_parent: returns 403 response if contents out of the web root are
requested. Required to disable directory traversal.
TypeError: exceptions must be old-style classes or derived from
BaseException, not str
Thus, we are not allowed to raise a string. Raise Exception instead.
refactoring. Basically, we are dividing WebSocketServer into two
classes: One request handler following the SocketServer Requesthandler
API, and one optional server engine. The standard Python SocketServer
engine can also be used.
websocketproxy.py has been updated to match the API change. I've also
added a new option --libserver in order to use the Python built in
server instead.
I've done a lot of testing with the new code. This includes: verbose,
daemon, run-once, timeout, idle-timeout, ssl, web, libserver. I've
tested both Python 2 and 3. I've also tested websocket.py in another
external service.
Code details follows:
* The new request handler class is called WebSocketRequestHandler,
inheriting SimpleHTTPRequestHandler.
* The service engine is called WebSocketServer, just like before.
* do_websocket_handshake: Using send_header() etc, instead of manually
sending HTTP response.
* A new method called handle_websocket() upgrades the connection to
WebSocket, if requested. Otherwise, it returns False. A typical
application use is:
def do_GET(self):
if not self.handle_websocket():
# handle normal requests
* new_client has been renamed to new_websocket_client, in order to
have a better name in the SocketServer/HTTPServer request handler
hierarchy.
* Note that in the request handler, configuration variables must be
provided by the "server" object, ie self.server.target_host.
Move around functions and methods, so that connection-related and
server-related stuff are close together.
This patch just moves things around - it does not change anything at
all. This can be verified with:
git diff websocket.py | grep ^- | cut -c 2- | sort > removed
git diff websocket.py | grep ^+ | cut -c 2- | sort > added
diff -u removed added
If WebSocketServer is used as a library with run_once or timeout, then
cleanup the socket listener socket so that when start_server returns
(due to run_once or timeout) then port is freed up.
Fix recording so that it records the actual payload bytes sent to the
client. This means that if the client and server and using base64
encoding then the captured data will still be base64 encoded. However,
data received from the client is unmasked when recorded. Note that
this is not done efficiently; when recording, client data is unmasked
twice (once for sending on to the target and once for recording). This
could be made more efficient but that would require a refactor of how
frame reception and unmasking works and recording is not considered
a performance sensitive mode.
Make websockify subdirectory and move websocket.py ->
websockify/websocket.py and websockify ->
websockify/websocketproxy.py. Create a ./run script that launches
websockify as before (unfortunately can't have a websockify script at
the same level since this is now a directory). Make websockify.py
a symlink to ./run. Once the package is installed, the main launch
script will be /usr/bin/websockify.
This makes it easier to package up websockify as a python module.
setup.py should now properly install websockify as a module.
Note that to include the base websocket module/class you will now do:
import websockify.websocket
#OR
from websockify.websocket import WebSocketServer
To import the full websocket proxy functionality:
import websockify.websocketproxy
#OR
from websockify.websocket import WebSocketProxy
This will also help with startup speed slightly because the code in
websocketproxy will now be byte compiled since it is no longer in the
main invocation script.