From 9651f3823d26189480969b640127354f42ba50f2 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Fri, 10 Jan 2020 18:32:34 -0800 Subject: [PATCH] (apple ssl) model write method after the OpenSSL one for consistency More test code for #140. --- docs/CHANGELOG.md | 4 +++ ixwebsocket/IXSocketAppleSSL.cpp | 28 +++++++++---------- ixwebsocket/IXWebSocketVersion.h | 2 +- .../python/websockets/Dockerfile | 14 +++++++--- .../python/websockets/echo_server_ssl.py | 26 +++++++++++++++++ .../python/websockets/entrypoint.sh | 10 +++++++ .../python/websockets/localhost.pem | 1 + test/compatibility/python/websockets/makefile | 5 +++- .../python/websockets/trusted-server-crt.pem | 19 +++++++++++++ .../python/websockets/trusted-server-key.pem | 27 ++++++++++++++++++ ws/ws_send.cpp | 11 ++++++-- 11 files changed, 124 insertions(+), 23 deletions(-) create mode 100644 test/compatibility/python/websockets/echo_server_ssl.py create mode 100644 test/compatibility/python/websockets/entrypoint.sh create mode 120000 test/compatibility/python/websockets/localhost.pem create mode 100644 test/compatibility/python/websockets/trusted-server-crt.pem create mode 100644 test/compatibility/python/websockets/trusted-server-key.pem diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 13115d34..0304ff84 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All changes to this project will be documented in this file. +## [7.9.3] - 2020-01-10 + +(apple ssl) model write method after the OpenSSL one for consistency + ## [7.9.2] - 2020-01-06 (apple ssl) unify read and write ssl utility code diff --git a/ixwebsocket/IXSocketAppleSSL.cpp b/ixwebsocket/IXSocketAppleSSL.cpp index 3dbad319..91f62acd 100644 --- a/ixwebsocket/IXSocketAppleSSL.cpp +++ b/ixwebsocket/IXSocketAppleSSL.cpp @@ -238,31 +238,31 @@ namespace ix ssize_t SocketAppleSSL::send(char* buf, size_t nbyte) { - OSStatus status = errSSLWouldBlock; - while (status == errSSLWouldBlock) + ssize_t sent = 0; + + while (nbyte > 0) { - size_t processed = 0; std::lock_guard lock(_mutex); - status = SSLWrite(_sslContext, buf, nbyte, &processed); - if (processed > 0) return (ssize_t) processed; + size_t processed = 0; + OSStatus status = SSLWrite(_sslContext, buf + sent, nbyte, &processed); - // The connection was reset, inform the caller that this - // Socket should close - if (status == errSSLClosedGraceful || status == errSSLClosedNoNotify || - status == errSSLClosedAbort) + if (status == noErr) { - errno = ECONNRESET; - return -1; + nbyte -= processed; + sent += processed; } - - if (status == errSSLWouldBlock) + else if (status == errSSLWouldBlock) { errno = EWOULDBLOCK; return -1; } + else + { + return -1; + } } - return -1; + return sent; } ssize_t SocketAppleSSL::send(const std::string& buffer) diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index 927d9f12..843736fb 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "7.9.2" +#define IX_WEBSOCKET_VERSION "7.9.3" diff --git a/test/compatibility/python/websockets/Dockerfile b/test/compatibility/python/websockets/Dockerfile index 016e3f23..a2564400 100644 --- a/test/compatibility/python/websockets/Dockerfile +++ b/test/compatibility/python/websockets/Dockerfile @@ -1,8 +1,14 @@ FROM python:3.8.0-alpine3.10 RUN pip install websockets -COPY ws_proxy.py /usr/bin -RUN chmod +x /usr/bin/ws_proxy.py +COPY *.py /usr/bin/ +COPY entrypoint.sh /usr/bin/ +RUN chmod +x /usr/bin/*.py -EXPOSE 8765 -CMD ["python", "/usr/bin/ws_proxy.py"] +RUN mkdir /certs +COPY *.pem /certs/ + +WORKDIR /certs + +EXPOSE 8765 8766 +CMD ["sh", "/usr/bin/entrypoint.sh"] diff --git a/test/compatibility/python/websockets/echo_server_ssl.py b/test/compatibility/python/websockets/echo_server_ssl.py new file mode 100644 index 00000000..54f1dd39 --- /dev/null +++ b/test/compatibility/python/websockets/echo_server_ssl.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +# WS server example + +import asyncio +import os +import pathlib +import ssl +import websockets + + +async def echo(websocket, path): + msg = await websocket.recv() + print(f'Received {len(msg)} bytes') + await websocket.send(msg) + +ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) +ssl_context.load_cert_chain('trusted-server-crt.pem', + 'trusted-server-key.pem') + +print('Serving on localhost:8766') +host = os.getenv('BIND_HOST', 'localhost') +start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30, ssl=ssl_context) + +asyncio.get_event_loop().run_until_complete(start_server) +asyncio.get_event_loop().run_forever() diff --git a/test/compatibility/python/websockets/entrypoint.sh b/test/compatibility/python/websockets/entrypoint.sh new file mode 100644 index 00000000..50f7298e --- /dev/null +++ b/test/compatibility/python/websockets/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +case $MODE in + echo_server) + ./echo_server.py + ;; + ssl) + python /usr/bin/echo_server_ssl.py + ;; +esac diff --git a/test/compatibility/python/websockets/localhost.pem b/test/compatibility/python/websockets/localhost.pem new file mode 120000 index 00000000..03737260 --- /dev/null +++ b/test/compatibility/python/websockets/localhost.pem @@ -0,0 +1 @@ +trusted-client-crt.pem \ No newline at end of file diff --git a/test/compatibility/python/websockets/makefile b/test/compatibility/python/websockets/makefile index 381c9bdc..8f7962e0 100644 --- a/test/compatibility/python/websockets/makefile +++ b/test/compatibility/python/websockets/makefile @@ -3,7 +3,7 @@ all: .PHONY: docker -NAME := bsergean/ws_proxy +NAME := bsergean/echo_server TAG := $(shell cat DOCKER_VERSION) IMG := ${NAME}:${TAG} LATEST := ${NAME}:latest @@ -21,3 +21,6 @@ docker_push: docker tag ${IMG} ${LATEST} docker push ${LATEST} docker push ${IMG} + +ssl_server: + docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=ssl -it --rm bsergean/echo_server:build diff --git a/test/compatibility/python/websockets/trusted-server-crt.pem b/test/compatibility/python/websockets/trusted-server-crt.pem new file mode 100644 index 00000000..54bbaf31 --- /dev/null +++ b/test/compatibility/python/websockets/trusted-server-crt.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIJALyEpMxNH62fMA0GCSqGSIb3DQEBCwUAMEExFDASBgNV +BAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDETMBEGA1UEAwwK +dHJ1c3RlZC1jYTAeFw0xOTEyMjQwMDM3MzVaFw0yMDEyMjMwMDM3MzVaMEUxFDAS +BgNVBAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDEXMBUGA1UE +AwwOdHJ1c3RlZC1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCv0T68TZZ7nab+UWPhssGLrInE0egzWn1AF20RkJv1ePIyU0rQbDxuuP+HQbXD +FzF6vo2j+5p+VxxvUOfko9V6xad3cB4T3AoFrT5sYI8gQX1uby6pjqVX16TK5t+c +i56aNhUXdmcWhuUzlIMIauvueohd+pNj6E6weWqCf8QFD6KYPgK3wWCR4VfWA5QY +RJUhv2aI9HrC9P4Mg0mut8LYURRQvGxOhtbAw76FJ6IgBujpgI5GLHgVK5Q1GlXK +8W7RlNKNmxX+mzK2D6nHixCUGvrFk9nZgZiaHI/h5x0IGXu0sbwlTPjqQ4Axpofw +G1FDi/er4FaGCzU4CKmc7rxRAgMBAAGjIzAhMB8GA1UdEQQYMBaCCWxvY2FsaG9z +dIIJMTI3LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4IBAQBkUB6smmApnBfr2eDwKJew +GQUMUAa7TlyANYlwQ6EjbAH7H6oNf7Sm63Go2Y72JjZPw3OvZl3QcvvS14QxYJ71 +kRdvJ1mhEbIaA2QkdZCuDmcQGLfVEyo0j5q03amQKt9QtSv9MsX1Ok2HqGL17Tf1 +QiUqlkzGCqMIsU20X8QzqwYCGzYZeTFtwLYi75za15Uo/6tE2KwzU7oUhuIebOaS +Sa+s2Y1TjpbWyw9usnuQWQ0k1FJR78F1mKJGghmPBoySBHJdLkLYOMhE1u2shgk5 +N0muMcDRTeHLxm1aBPLHtkRbW3QscEQB6GkT2Dt4U66qNV2CY7Gk0F5xxOrGBC/9 +-----END CERTIFICATE----- diff --git a/test/compatibility/python/websockets/trusted-server-key.pem b/test/compatibility/python/websockets/trusted-server-key.pem new file mode 100644 index 00000000..29ae8bc3 --- /dev/null +++ b/test/compatibility/python/websockets/trusted-server-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr9E+vE2We52m/lFj4bLBi6yJxNHoM1p9QBdtEZCb9XjyMlNK +0Gw8brj/h0G1wxcxer6No/uaflccb1Dn5KPVesWnd3AeE9wKBa0+bGCPIEF9bm8u +qY6lV9ekyubfnIuemjYVF3ZnFoblM5SDCGrr7nqIXfqTY+hOsHlqgn/EBQ+imD4C +t8FgkeFX1gOUGESVIb9miPR6wvT+DINJrrfC2FEUULxsTobWwMO+hSeiIAbo6YCO +Rix4FSuUNRpVyvFu0ZTSjZsV/psytg+px4sQlBr6xZPZ2YGYmhyP4ecdCBl7tLG8 +JUz46kOAMaaH8BtRQ4v3q+BWhgs1OAipnO68UQIDAQABAoIBAG/bIR2uAyJMT7UX +VQN/tbFGKTRmE2Owm2UOQl7dcMvAkd5AraViZyROYIvN23TuKZWc7AI7DbR5eWa8 +w3vsW+JLI9tSImCiKmIoMUHEQOrVn5aF99r6HOmBEZ/hOLyg+1vDMrIFq1pioimp +v5+4XrgPjvizddgnMQEHjiLOZIiOtin+alixN/W41Ij0jOtRycM5wq3Xr/0RAs5A +ziNeQvWdvDwqa6L9upHZpFfYqP/+KflJPlHLfEkBHZtZQF3uy5tQ1VusfVMO3Xvb +Ljk6RBnD9dKayreD9NVzotr36zYEy/V1oGJcP/8AD1xmDA0/2Kb+bfm+WQHG5wp6 +o09zsZECgYEA5Y3d79Nrfi6InVaZ0r5Y+XXqSZFTsgFnxRseVEbuK4jvrh7eC9jW +pWoaXDh8W6RoT59BPSCKtbQ9mjdECh+aJ6MOeCzCiGSppJboOhC1iVFqFuQLDRO7 +w+2NgkhOvNnJJJYmdTwfokTLmaRUiNqwWAtBm+h7py9e5eXujzqt4+UCgYEAxBKL +OO8CWRb0yGlwKoCwYgGCsVauvbZHaELOAKJUB6H+YhZ+SJqd915u8aYs5nbcMyne +5kuewzd+32WpkykI0Fz4SrGvDETKB5/Yynblp9m69LNdgYoVWgQqQocXVw0nD/nA +KQdFSBZZRExXC/aUAa55txFJitMC4FjgTENgR/0CgYAS/OonxVg15sl8Ika1DPO1 +JtDLZw8CQWWBA1494GQhC8GvqHP7jOMsaZtml3GJ7w6Fz4mI8eEnaJJT6FBjefu5 +XZ57yFALEjCKIcVx0CIECsz4ucJEQaadbU/wP+TrcCRYN2dU+TUwqfohaltnupct +oTi7Gb7otF1oLN3P0S3DFQKBgEnVjdXPszunOGBrzBBFS6ZsWTG8qarJBFTPq1Fz +z17ccrWvMLjYeJnZVr/qyseyhLNDlit02IE82ar4VoYTEr2b9Ofzxy5AjS+X0wRT +B6JQjGVvUcvhGq8+GEfbJT/jtQ0ACIuqsD04JT9h2/mmTg/gCveUK/R6B4BCF5zA +VnZlAoGBANOG5T7KsOH+Hbb//dEmfZYMQmkO/+1Pac9eP4uDFNAVF00M6XHf5LrR +gRp5t46drDtLgxdufN0oUItp8y74EuMa9FHlBQVZRaSqYF4bCgf2PieGApbKWG2n +QhnxYfZqf9S2oVK95EHiJxmtumOFBL7YI9NdzNEeoJExS5Bw6kUn +-----END RSA PRIVATE KEY----- diff --git a/ws/ws_send.cpp b/ws/ws_send.cpp index 4e3bc9ff..5f0bd00e 100644 --- a/ws/ws_send.cpp +++ b/ws/ws_send.cpp @@ -241,7 +241,7 @@ namespace ix { std::vector content; { - Bench bench("load file from disk"); + Bench bench("ws_send: load file from disk"); content = load(filename); } @@ -257,9 +257,12 @@ namespace ix MsgPack msg(pdu); - Bench bench("Sending file through websocket"); + auto serializedMsg = msg.dump(); + spdlog::info("ws_send: sending {} bytes", serializedMsg.size()); + + Bench bench("ws_send: Sending file through websocket"); auto result = - _webSocket.sendBinary(msg.dump(), [this, throttle](int current, int total) -> bool { + _webSocket.sendBinary(serializedMsg, [this, throttle](int current, int total) -> bool { spdlog::info("ws_send: Step {} out of {}", current + 1, total); if (throttle) @@ -283,6 +286,8 @@ namespace ix return false; } + spdlog::info("ws_send: sent {} bytes", serializedMsg.size()); + do { size_t bufferedAmount = _webSocket.bufferedAmount();