Compare commits

...

33 Commits

Author SHA1 Message Date
6cf15dc7b8 Changes for esp-idf 2021-05-31 19:33:08 +02:00
a14b6b73b4 bump version to 2.3.6 2021-03-08 17:22:23 +01:00
ed685e551f fix _fingerprint is set checks for ESP32
see #633 and #632
2021-03-07 13:46:37 +01:00
7c3b1b7408 install libgtk-3-0 2021-03-06 08:59:21 +01:00
738e43fda4 install libgtk-3-0 2021-03-06 08:56:08 +01:00
f55bf8d4ed bump version to 2.3.5 2021-02-09 18:26:21 +01:00
a484da47ed Merge branch 'eio_4_ping_handling' 2021-01-31 20:32:25 +01:00
4355199120 bump version 2.3.4 2021-01-31 20:31:52 +01:00
0a4fcd44c2 EIO=4 ping handling #611 2021-01-31 20:27:56 +01:00
3a2b757155 EIO=4 ping handling #611 2021-01-31 10:28:15 +01:00
900d81e534 make WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); public 2021-01-19 16:59:03 +01:00
0ecef8c552 Fixing WebSocket Close see #610 2021-01-19 16:58:37 +01:00
410489f7c5 bump version to 2.3.3 2021-01-07 10:27:42 +01:00
ec22d67c12 version.py can now create WebSocketsVersion.h 2021-01-07 10:24:23 +01:00
39e6a8e709 print version in DEBUG mode 2021-01-07 10:14:30 +01:00
784b7f9cb8 no python3.9 on github actions 2021-01-07 10:05:30 +01:00
fd83d6ad45 add WebSocketsVersion.h and some build checks 2021-01-07 09:59:49 +01:00
0e729cd896 cleanup clone_library 2021-01-06 09:39:19 +01:00
2f21590e55 no need for a full clone 2021-01-06 09:18:27 +01:00
c98baafda7 jobs steps array 2021-01-05 21:54:58 +01:00
983b9801fb Merge branch 'master' of github.com:Links2004/arduinoWebSockets 2021-01-05 21:50:56 +01:00
e70262dab9 add done job 2021-01-05 21:50:40 +01:00
4a05eab627 Update README.md
use github actions as Build Status
2021-01-05 21:30:28 +01:00
822618f606 code style fix 2021-01-05 21:18:30 +01:00
1b4f186fa6 use github actions for build 2021-01-05 21:17:09 +01:00
c68e015322 github actions test3 2021-01-05 18:32:11 +01:00
dc30a2b7bf github actions test2 2021-01-05 18:28:59 +01:00
6bee53a8bd github actions test 2021-01-05 18:11:48 +01:00
ebb87cdc8a + constructors for scalars 2020-11-26 19:33:18 +01:00
e7ab913693 fix clearing _Client[] 2020-11-26 19:33:18 +01:00
52547ec47c fix clients init logic 2020-11-26 19:33:18 +01:00
74411bf729 use native contructor and destructor to initialize WSclient_t 2020-11-26 19:33:18 +01:00
f0cc36dede bump version to 2.3.2 2020-11-21 18:13:22 +01:00
17 changed files with 711 additions and 190 deletions

188
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,188 @@
name: CI
on:
schedule:
- cron: '0 0 * * 5'
push:
branches: [ master ]
pull_request:
branches: [ master ]
release:
types: [ published, created, edited ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
check_version_files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: check version
run: |
$GITHUB_WORKSPACE/travis/version.py --check
prepare_example_json:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: generate examples
id: set-matrix
run: |
source $GITHUB_WORKSPACE/travis/common.sh
cd $GITHUB_WORKSPACE
echo -en "::set-output name=matrix::"
echo -en "["
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.13 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.13 espressif:esp32:esp32:FlashFreq=80
echo -en "]"
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
prepare_ide:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
IDE_VERSION: [1.8.13, 1.6.13]
env:
IDE_VERSION: ${{ matrix.IDE_VERSION }}
steps:
- uses: actions/checkout@v2
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
shell: bash
- uses: actions/cache@v2
id: cache_all
with:
path: |
/home/runner/arduino_ide
/home/runner/Arduino
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }}
- name: download IDE
if: steps.cache_all.outputs.cache-hit != 'true'
run: |
wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz -q
tar xf arduino-$IDE_VERSION-linux64.tar.xz
mv arduino-$IDE_VERSION $HOME/arduino_ide
- name: download ArduinoJson
if: steps.cache_all.outputs.cache-hit != 'true'
run: |
mkdir -p $HOME/Arduino/libraries
wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip -q
unzip 6.x.zip
mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson
- name: download esp8266
if: steps.cache_all.outputs.cache-hit != 'true'
run: |
source $GITHUB_WORKSPACE/travis/common.sh
get_core esp8266
- name: download esp32
if: steps.cache_all.outputs.cache-hit != 'true' && matrix.IDE_VERSION != '1.6.13'
run: |
source $GITHUB_WORKSPACE/travis/common.sh
get_core esp32
build:
needs: [prepare_ide, prepare_example_json]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.prepare_example_json.outputs.matrix) }}
env:
CPU: ${{ matrix.cpu }}
BOARD: ${{ matrix.board }}
IDE_VERSION: ${{ matrix.ideversion }}
SKETCH: ${{ matrix.sketch }}
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2
- name: install libgtk2.0-0
run: |
sudo apt-get install -y libgtk2.0-0
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
shell: bash
- uses: actions/cache@v2
id: cache_all
with:
path: |
/home/runner/arduino_ide
/home/runner/Arduino
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }}
- name: install python serial
if: matrix.cpu == 'esp32'
run: |
sudo pip3 install pyserial
sudo pip install pyserial
# sudo apt install python-is-python3
- name: start DISPLAY
run: |
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
export DISPLAY=:1.0
sleep 3
- name: test IDE
run: |
export PATH="$HOME/arduino_ide:$PATH"
which arduino
- name: copy code
run: |
mkdir -p $HOME/Arduino/libraries/
cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets
- name: config IDE
run: |
export DISPLAY=:1.0
export PATH="$HOME/arduino_ide:$PATH"
arduino --board $BOARD --save-prefs
arduino --get-pref sketchbook.path
arduino --pref update.check=false
- name: build example
timeout-minutes: 20
run: |
export DISPLAY=:1.0
export PATH="$HOME/arduino_ide:$PATH"
source $GITHUB_WORKSPACE/travis/common.sh
cd $GITHUB_WORKSPACE
build_sketch arduino $SKETCH
done:
needs: [prepare_ide, prepare_example_json, build, check_version_files]
runs-on: ubuntu-latest
steps:
- name: Done
run: |
echo DONE

47
CMakeLists.txt Normal file
View File

@ -0,0 +1,47 @@
set(headers
src/SocketIOclient.h
src/WebSockets.h
src/WebSockets4WebServer.h
src/WebSocketsClient.h
src/WebSocketsServer.h
src/WebSocketsVersion.h
src/libb64/cdecode_inc.h
src/libb64/cencode_inc.h
src/libsha1/libsha1.h
)
set(sources
src/SocketIOclient.cpp
src/WebSockets.cpp
src/WebSocketsClient.cpp
src/WebSocketsServer.cpp
src/libb64/cdecode.c
src/libb64/cencode.c
src/libsha1/libsha1.c
)
set(dependencies
)
idf_component_register(
INCLUDE_DIRS
src
SRCS
${headers}
${sources}
REQUIRES
${dependencies}
)
target_compile_options(${COMPONENT_TARGET}
PUBLIC
-DESP32
-DWEBSOCKETS_NETWORK_TYPE=NETWORK_ESP32
PRIVATE
-fstack-reuse=all
-fstack-protector-all
-Wno-unused-function
-Wno-deprecated-declarations
-Wno-missing-field-initializers
-Wno-parentheses
)

View File

@ -1,4 +1,4 @@
WebSocket Server and Client for Arduino [![Build Status](https://travis-ci.com/Links2004/arduinoWebSockets.svg?branch=master)](https://travis-ci.com/Links2004/arduinoWebSockets)
WebSocket Server and Client for Arduino [![Build Status](https://github.com/Links2004/arduinoWebSockets/workflows/CI/badge.svg?branch=master)](https://github.com/Links2004/arduinoWebSockets/actions?query=workflow%3ACI+branch%3Amaster)
===========================================
a WebSocket Server and Client for Arduino based on RFC6455.

View File

@ -1,25 +1,25 @@
{
"name": "WebSockets",
"description": "WebSocket Server and Client for Arduino based on RFC6455",
"keywords": "wifi, http, web, server, client, websocket",
"authors": [
{
"maintainer": true,
"name": "Markus Sattler",
"url": "https://github.com/Links2004",
"maintainer": true
"url": "https://github.com/Links2004"
}
],
"repository": {
"type": "git",
"url": "https://github.com/Links2004/arduinoWebSockets.git"
},
"version": "2.3.1",
"license": "LGPL-2.1",
"description": "WebSocket Server and Client for Arduino based on RFC6455",
"export": {
"exclude": [
"tests"
]
},
"frameworks": "arduino",
"platforms": "atmelavr, espressif8266, espressif32"
}
"keywords": "wifi, http, web, server, client, websocket",
"license": "LGPL-2.1",
"name": "WebSockets",
"platforms": "atmelavr, espressif8266, espressif32",
"repository": {
"type": "git",
"url": "https://github.com/Links2004/arduinoWebSockets.git"
},
"version": "2.3.6"
}

View File

@ -1,5 +1,5 @@
name=WebSockets
version=2.3.1
version=2.3.6
author=Markus Sattler
maintainer=Markus Sattler
sentence=WebSockets for Arduino (Server + Client)

View File

@ -5,9 +5,12 @@
* Author: links
*/
#include "SocketIOclient.h"
#include <string>
#include "WebSockets.h"
#include "WebSocketsClient.h"
#include "SocketIOclient.h"
SocketIOclient::SocketIOclient() {
}
@ -18,31 +21,37 @@ SocketIOclient::~SocketIOclient() {
void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) {
WebSocketsClient::beginSocketIO(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) {
void SocketIOclient::begin(std::string host, uint16_t port, std::string url, std::string protocol) {
WebSocketsClient::beginSocketIO(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
#if defined(HAS_SSL)
void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) {
WebSocketsClient::beginSocketIOSSL(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) {
void SocketIOclient::beginSSL(std::string host, uint16_t port, std::string url, std::string protocol) {
WebSocketsClient::beginSocketIOSSL(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
#if !defined(SSL_AXTLS)
#if defined(SSL_BARESSL)
void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) {
WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
}
void SocketIOclient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) {
@ -55,6 +64,18 @@ void SocketIOclient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL
#endif
#endif
void SocketIOclient::configureEIOping(bool disableHeartbeat) {
_disableHeartbeat = disableHeartbeat;
}
void SocketIOclient::initClient(void) {
if(_client.cUrl.indexOf("EIO=4") != -1) {
DEBUG_WEBSOCKETS("[wsIOc] found EIO=4 disable EIO ping on client\n");
configureEIOping(true);
}
}
/**
* set callback function
* @param cbEvent SocketIOclientEvent
@ -113,7 +134,7 @@ bool SocketIOclient::send(socketIOmessageType_t type, const char * payload, size
return send(type, (uint8_t *)payload, length);
}
bool SocketIOclient::send(socketIOmessageType_t type, String & payload) {
bool SocketIOclient::send(socketIOmessageType_t type, std::string & payload) {
return send(type, (uint8_t *)payload.c_str(), payload.length());
}
@ -141,15 +162,15 @@ bool SocketIOclient::sendEVENT(const char * payload, size_t length) {
return sendEVENT((uint8_t *)payload, length);
}
bool SocketIOclient::sendEVENT(String & payload) {
bool SocketIOclient::sendEVENT(std::string & payload) {
return sendEVENT((uint8_t *)payload.c_str(), payload.length());
}
void SocketIOclient::loop(void) {
WebSocketsClient::loop();
unsigned long t = millis();
if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) {
_lastConnectionFail = t;
if(!_disableHeartbeat && (t - _lastHeartbeat) > EIO_HEARTBEAT_INTERVAL) {
_lastHeartbeat = t;
DEBUG_WEBSOCKETS("[wsIOc] send ping\n");
WebSocketsClient::sendTXT(eIOtype_PING);
}

View File

@ -8,6 +8,8 @@
#ifndef SOCKETIOCLIENT_H_
#define SOCKETIOCLIENT_H_
#include <string>
#include "WebSockets.h"
#define EIO_HEARTBEAT_INTERVAL 20000
@ -47,11 +49,11 @@ class SocketIOclient : protected WebSocketsClient {
virtual ~SocketIOclient(void);
void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void begin(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#ifdef HAS_SSL
void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSSL(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#ifndef SSL_AXTLS
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
@ -67,17 +69,20 @@ class SocketIOclient : protected WebSocketsClient {
bool sendEVENT(const uint8_t * payload, size_t length = 0);
bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false);
bool sendEVENT(const char * payload, size_t length = 0);
bool sendEVENT(String & payload);
bool sendEVENT(std::string & payload);
bool send(socketIOmessageType_t type, uint8_t * payload, size_t length = 0, bool headerToPayload = false);
bool send(socketIOmessageType_t type, const uint8_t * payload, size_t length = 0);
bool send(socketIOmessageType_t type, char * payload, size_t length = 0, bool headerToPayload = false);
bool send(socketIOmessageType_t type, const char * payload, size_t length = 0);
bool send(socketIOmessageType_t type, String & payload);
bool send(socketIOmessageType_t type, std::string & payload);
void loop(void);
void configureEIOping(bool disableHeartbeat = false);
protected:
bool _disableHeartbeat = false;
uint64_t _lastHeartbeat = 0;
SocketIOclientEvent _cbEvent;
virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
@ -86,6 +91,8 @@ class SocketIOclient : protected WebSocketsClient {
}
}
void initClient(void);
// Handeling events from websocket layer
virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) {
handleCbEvent(type, payload, length);

View File

@ -24,6 +24,8 @@
#include "WebSockets.h"
#include <string>
#ifdef ESP8266
#include <core_esp8266_features.h>
#endif
@ -535,15 +537,15 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t
/**
* generate the key for Sec-WebSocket-Accept
* @param clientKey String
* @return String Accept Key
* @param clientKey std::string
* @return std::string Accept Key
*/
String WebSockets::acceptKey(String & clientKey) {
std::string WebSockets::acceptKey(std::string & clientKey) {
uint8_t sha1HashBin[20] = { 0 };
#ifdef ESP8266
sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
#elif defined(ESP32)
String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
std::string data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
esp_sha(SHA1, (unsigned char *)data.c_str(), data.length(), &sha1HashBin[0]);
#else
clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@ -553,7 +555,7 @@ String WebSockets::acceptKey(String & clientKey) {
SHA1Final(&sha1HashBin[0], &ctx);
#endif
String key = base64_encode(sha1HashBin, 20);
std::string key = base64_encode(sha1HashBin, 20);
key.trim();
return key;
@ -563,9 +565,9 @@ String WebSockets::acceptKey(String & clientKey) {
* base64_encode
* @param data uint8_t *
* @param length size_t
* @return base64 encoded String
* @return base64 encoded std::string
*/
String WebSockets::base64_encode(uint8_t * data, size_t length) {
std::string WebSockets::base64_encode(uint8_t * data, size_t length) {
size_t size = ((length * 1.6f) + 1);
char * buffer = (char *)malloc(size);
if(buffer) {
@ -574,11 +576,11 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) {
int len = base64_encode_block((const char *)&data[0], length, &buffer[0], &_state);
len = base64_encode_blockend((buffer + len), &_state);
String base64 = String(buffer);
std::string base64 = std::string(buffer);
free(buffer);
return base64;
}
return String("-FAIL-");
return std::string("-FAIL-");
}
/**

View File

@ -25,12 +25,14 @@
#ifndef WEBSOCKETS_H_
#define WEBSOCKETS_H_
#include <string>
#ifdef STM32_DEVICE
#include <application.h>
#define bit(b) (1UL << (b)) // Taken directly from Arduino.h
#else
#include <Arduino.h>
#include <IPAddress.h>
//#include <Arduino.h>
//#include <IPAddress.h>
#endif
#ifdef ARDUINO_ARCH_AVR
@ -40,6 +42,8 @@
#include <functional>
#endif
#include "WebSocketsVersion.h"
#ifndef NODEBUG_WEBSOCKETS
#ifdef DEBUG_ESP_PORT
#define DEBUG_WEBSOCKETS(...) \
@ -184,8 +188,8 @@
#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
#include <WiFi.h>
#include <WiFiClientSecure.h>
//#include <WiFi.h>
//#include <WiFiClientSecure.h>
#define SSL_AXTLS
#define WEBSOCKETS_NETWORK_CLASS WiFiClient
#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure
@ -259,54 +263,64 @@ typedef struct {
} WSMessageHeader_t;
typedef struct {
uint8_t num; ///< connection number
void init(uint8_t num,
uint32_t pingInterval,
uint32_t pongTimeout,
uint8_t disconnectTimeoutCount) {
this->num = num;
this->pingInterval = pingInterval;
this->pongTimeout = pongTimeout;
this->disconnectTimeoutCount = disconnectTimeoutCount;
}
WSclientsStatus_t status;
uint8_t num = 0; ///< connection number
WEBSOCKETS_NETWORK_CLASS * tcp;
WSclientsStatus_t status = WSC_NOT_CONNECTED;
bool isSocketIO; ///< client for socket.io server
WEBSOCKETS_NETWORK_CLASS * tcp = nullptr;
bool isSocketIO = false; ///< client for socket.io server
#if defined(HAS_SSL)
bool isSSL; ///< run in ssl mode
bool isSSL = false; ///< run in ssl mode
WEBSOCKETS_NETWORK_SSL_CLASS * ssl;
#endif
String cUrl; ///< http url
uint16_t cCode; ///< http code
std::string cUrl; ///< http url
uint16_t cCode = 0; ///< http code
bool cIsClient = false; ///< will be used for masking
bool cIsUpgrade; ///< Connection == Upgrade
bool cIsWebsocket; ///< Upgrade == websocket
bool cIsClient = false; ///< will be used for masking
bool cIsUpgrade = false; ///< Connection == Upgrade
bool cIsWebsocket = false; ///< Upgrade == websocket
String cSessionId; ///< client Set-Cookie (session id)
String cKey; ///< client Sec-WebSocket-Key
String cAccept; ///< client Sec-WebSocket-Accept
String cProtocol; ///< client Sec-WebSocket-Protocol
String cExtensions; ///< client Sec-WebSocket-Extensions
uint16_t cVersion; ///< client Sec-WebSocket-Version
std::string cSessionId; ///< client Set-Cookie (session id)
std::string cKey; ///< client Sec-WebSocket-Key
std::string cAccept; ///< client Sec-WebSocket-Accept
std::string cProtocol; ///< client Sec-WebSocket-Protocol
std::string cExtensions; ///< client Sec-WebSocket-Extensions
uint16_t cVersion = 0; ///< client Sec-WebSocket-Version
uint8_t cWsRXsize; ///< State of the RX
uint8_t cWsRXsize = 0; ///< State of the RX
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
WSMessageHeader_t cWsHeaderDecode;
String base64Authorization; ///< Base64 encoded Auth request
String plainAuthorization; ///< Base64 encoded Auth request
std::string base64Authorization; ///< Base64 encoded Auth request
std::string plainAuthorization; ///< Base64 encoded Auth request
String extraHeaders;
std::string extraHeaders;
bool cHttpHeadersValid; ///< non-websocket http header validity indicator
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count
bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count
bool pongReceived;
uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active"
uint32_t lastPing; // millis when last pong has been received
uint32_t pongTimeout; // interval in millis after which pong is considered to timeout
uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect"
uint8_t pongTimeoutCount; // current pong timeout count
bool pongReceived = false;
uint32_t pingInterval = 0; // how often ping will be sent, 0 means "heartbeat is not active"
uint32_t lastPing = 0; // millis when last pong has been received
uint32_t pongTimeout = 0; // interval in millis after which pong is considered to timeout
uint8_t disconnectTimeoutCount = 0; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect"
uint8_t pongTimeoutCount = 0; // current pong timeout count
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
String cHttpLine; ///< HTTP header lines
std::string cHttpLine; ///< HTTP header lines
#endif
} WSclient_t;
@ -338,8 +352,8 @@ class WebSockets {
void handleWebsocketCb(WSclient_t * client);
void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload);
String acceptKey(String & clientKey);
String base64_encode(uint8_t * data, size_t length);
std::string acceptKey(std::string & clientKey);
std::string base64_encode(uint8_t * data, size_t length);
bool readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb);
virtual size_t write(WSclient_t * client, uint8_t * out, size_t n);

View File

@ -25,6 +25,8 @@
#ifndef __WEBSOCKETS4WEBSERVER_H
#define __WEBSOCKETS4WEBSERVER_H
#include <string>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
@ -32,15 +34,17 @@
class WebSockets4WebServer : public WebSocketsServerCore {
public:
WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino")
WebSockets4WebServer(const std::string & origin = "", const std::string & protocol = "arduino")
: WebSocketsServerCore(origin, protocol) {
begin();
}
ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) {
ESP8266WebServer::HookFunction hookForWebserver(const std::string & wsRootDir, WebSocketServerEvent event) {
onEvent(event);
return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) {
return [&, wsRootDir](const std::string & method, const std::string & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) {
(void)contentType;
if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) {
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
}
@ -53,7 +57,7 @@ class WebSockets4WebServer : public WebSocketsServerCore {
if(client) {
// give "GET <url>"
String headerLine;
std::string headerLine;
headerLine.reserve(url.length() + 5);
headerLine = "GET ";
headerLine += url;

View File

@ -22,9 +22,12 @@
*
*/
#include "WebSockets.h"
#include "WebSocketsClient.h"
#include <string>
#include "WebSockets.h"
WebSocketsClient::WebSocketsClient() {
_cbEvent = NULL;
_client.num = 0;
@ -86,9 +89,11 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url,
_lastConnectionFail = 0;
_lastHeaderSent = 0;
DEBUG_WEBSOCKETS("[WS-Client] Websocket Version: " WEBSOCKETS_VERSION "\n");
}
void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::begin(std::string host, uint16_t port, std::string url, std::string protocol) {
begin(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -105,7 +110,7 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u
_CA_cert = NULL;
}
void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) {
void WebSocketsClient::beginSSL(std::string host, uint16_t port, std::string url, std::string fingerprint, std::string protocol) {
beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), protocol.c_str());
}
@ -151,7 +156,7 @@ void WebSocketsClient::beginSocketIO(const char * host, uint16_t port, const cha
_client.isSocketIO = true;
}
void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::beginSocketIO(std::string host, uint16_t port, std::string url, std::string protocol) {
beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -163,7 +168,7 @@ void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const
_fingerprint = SSL_FINGERPRINT_NULL;
}
void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::beginSocketIOSSL(std::string host, uint16_t port, std::string url, std::string protocol) {
beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -227,8 +232,11 @@ void WebSocketsClient::loop(void) {
#else
#error setCACert not implemented
#endif
#if defined(SSL_BARESSL)
} else if(_fingerprint) {
#if defined(ESP32)
} else if(!SSL_FINGERPRINT_IS_SET) {
_client.ssl->setInsecure();
#elif defined(SSL_BARESSL)
} else if(SSL_FINGERPRINT_IS_SET) {
_client.ssl->setFingerprint(_fingerprint);
} else {
_client.ssl->setInsecure();
@ -315,7 +323,7 @@ bool WebSocketsClient::sendTXT(const char * payload, size_t length) {
return sendTXT((uint8_t *)payload, length);
}
bool WebSocketsClient::sendTXT(String & payload) {
bool WebSocketsClient::sendTXT(std::string & payload) {
return sendTXT((uint8_t *)payload.c_str(), payload.length());
}
@ -360,7 +368,7 @@ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) {
return false;
}
bool WebSocketsClient::sendPing(String & payload) {
bool WebSocketsClient::sendPing(std::string & payload) {
return sendPing((uint8_t *)payload.c_str(), payload.length());
}
@ -381,7 +389,7 @@ void WebSocketsClient::disconnect(void) {
*/
void WebSocketsClient::setAuthorization(const char * user, const char * password) {
if(user && password) {
String auth = user;
std::string auth = user;
auth += ":";
auth += password;
_client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
@ -560,13 +568,13 @@ void WebSocketsClient::handleClientData(void) {
if(len > 0) {
switch(_client.status) {
case WSC_HEADER: {
String headerLine = _client.tcp->readStringUntil('\n');
std::string headerLine = _client.tcp->readStringUntil('\n');
handleHeader(&_client, &headerLine);
} break;
case WSC_BODY: {
char buf[256] = { 0 };
_client.tcp->readBytes(&buf[0], std::min((size_t)len, sizeof(buf)));
String bodyLine = buf;
std::string bodyLine = buf;
handleHeader(&_client, &bodyLine);
} break;
case WSC_CONNECTED:
@ -602,9 +610,9 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
unsigned long start = micros();
#endif
String handshake;
std::string handshake;
bool ws_header = true;
String url = client->cUrl;
std::string url = client->cUrl;
if(client->isSocketIO) {
if(client->cSessionId.length() == 0) {
@ -677,13 +685,13 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
* handle the WebSocket header reading
* @param client WSclient_t * ptr to the client struct
*/
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
void WebSocketsClient::handleHeader(WSclient_t * client, std::string * headerLine) {
headerLine->trim(); // remove \r
// this code handels the http body for Socket.IO V3 requests
if(headerLine->length() > 0 && client->isSocketIO && client->status == WSC_BODY && client->cSessionId.length() == 0) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] socket.io json: %s\n", headerLine->c_str());
String sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
std::string sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
if(headerLine->indexOf(sid_begin) > -1) {
int start = headerLine->indexOf(sid_begin) + sid_begin.length();
int end = headerLine->indexOf('"', start);
@ -703,8 +711,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
// "HTTP/1.1 101 Switching Protocols"
client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
} else if(headerLine->indexOf(':') >= 0) {
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
std::string headerName = headerLine->substring(0, headerLine->indexOf(':'));
std::string headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
// remove space in the beginning (RFC2616)
if(headerValue[0] == ' ') {
@ -795,7 +803,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
ok = false;
} else {
// generate Sec-WebSocket-Accept key for check
String sKey = acceptKey(client->cKey);
std::string sKey = acceptKey(client->cKey);
if(sKey != client->cAccept) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Sec-WebSocket-Accept is wrong\n");
ok = false;
@ -863,14 +871,14 @@ void WebSocketsClient::connectedCb() {
#if defined(HAS_SSL)
#if defined(SSL_AXTLS) || defined(ESP32)
if(_client.isSSL && _fingerprint.length()) {
if(_client.isSSL && SSL_FINGERPRINT_IS_SET) {
if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) {
DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n");
WebSockets::clientDisconnect(&_client, 1000);
return;
}
#else
if(_client.isSSL && _fingerprint) {
if(_client.isSSL && SSL_FINGERPRINT_IS_SET) {
#endif
} else if(_client.isSSL && !_CA_cert) {
#if defined(SSL_BARESSL)
@ -943,6 +951,9 @@ void WebSocketsClient::handleHBPing() {
if(sendPing()) {
_client.lastPing = millis();
_client.pongReceived = false;
} else {
DEBUG_WEBSOCKETS("[WS-Client] sending HB ping failed\n");
WebSockets::clientDisconnect(&_client, 1000);
}
}
}

View File

@ -25,6 +25,8 @@
#ifndef WEBSOCKETSCLIENT_H_
#define WEBSOCKETSCLIENT_H_
#include <string>
#include "WebSockets.h"
class WebSocketsClient : protected WebSockets {
@ -39,13 +41,13 @@ class WebSocketsClient : protected WebSockets {
virtual ~WebSocketsClient(void);
void begin(const char * host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
void begin(String host, uint16_t port, String url = "/", String protocol = "arduino");
void begin(std::string host, uint16_t port, std::string url = "/", std::string protocol = "arduino");
void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
#if defined(HAS_SSL)
#ifdef SSL_AXTLS
void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * fingerprint = "", const char * protocol = "arduino");
void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino");
void beginSSL(std::string host, uint16_t port, std::string url = "/", std::string fingerprint = "", std::string protocol = "arduino");
#else
void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino");
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
@ -56,11 +58,11 @@ class WebSocketsClient : protected WebSockets {
#endif
void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSocketIO(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#if defined(HAS_SSL)
void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSocketIOSSL(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
#if defined(SSL_BARESSL)
@ -81,14 +83,14 @@ class WebSocketsClient : protected WebSockets {
bool sendTXT(const uint8_t * payload, size_t length = 0);
bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false);
bool sendTXT(const char * payload, size_t length = 0);
bool sendTXT(String & payload);
bool sendTXT(std::string & payload);
bool sendTXT(char payload);
bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
bool sendBIN(const uint8_t * payload, size_t length);
bool sendPing(uint8_t * payload = NULL, size_t length = 0);
bool sendPing(String & payload);
bool sendPing(std::string & payload);
void disconnect(void);
@ -105,19 +107,21 @@ class WebSocketsClient : protected WebSockets {
bool isConnected(void);
protected:
String _host;
std::string _host;
uint16_t _port;
#if defined(HAS_SSL)
#ifdef SSL_AXTLS
String _fingerprint;
std::string _fingerprint;
const char * _CA_cert;
#define SSL_FINGERPRINT_IS_SET (_fingerprint.length())
#define SSL_FINGERPRINT_NULL ""
#else
const uint8_t * _fingerprint;
BearSSL::X509List * _CA_cert;
BearSSL::X509List * _client_cert;
BearSSL::PrivateKey * _client_key;
#define SSL_FINGERPRINT_IS_SET (_fingerprint != NULL)
#define SSL_FINGERPRINT_NULL NULL
#endif
@ -140,7 +144,7 @@ class WebSocketsClient : protected WebSockets {
#endif
void sendHeader(WSclient_t * client);
void handleHeader(WSclient_t * client, String * headerLine);
void handleHeader(WSclient_t * client, std::string * headerLine);
void connectedCb();
void connectFailedCb();

View File

@ -22,10 +22,13 @@
*
*/
#include "WebSockets.h"
#include "WebSocketsServer.h"
WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) {
#include <string>
#include "WebSockets.h"
WebSocketsServerCore::WebSocketsServerCore(const std::string & origin, const std::string & protocol) {
_origin = origin;
_protocol = protocol;
_runnning = false;
@ -38,11 +41,9 @@ WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String &
_httpHeaderValidationFunc = NULL;
_mandatoryHttpHeaders = NULL;
_mandatoryHttpHeaderCount = 0;
memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX));
}
WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const String & protocol)
WebSocketsServer::WebSocketsServer(uint16_t port, const std::string & origin, const std::string & protocol)
: WebSocketsServerCore(origin, protocol) {
_port = port;
@ -73,47 +74,13 @@ WebSocketsServer::~WebSocketsServer() {
* called to initialize the Websocket server
*/
void WebSocketsServerCore::begin(void) {
WSclient_t * client;
// init client storage
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
client = &_clients[i];
client->num = i;
client->status = WSC_NOT_CONNECTED;
client->tcp = NULL;
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
client->isSSL = false;
client->ssl = NULL;
#endif
client->cUrl = "";
client->cCode = 0;
client->cIsClient = false;
client->cIsUpgrade = false;
client->cIsWebsocket = false;
client->cSessionId = "";
client->cKey = "";
client->cAccept = "";
client->cProtocol = "";
client->cExtensions = "";
client->cVersion = 0;
client->cWsRXsize = 0;
client->base64Authorization = "";
client->plainAuthorization = "";
client->extraHeaders = "";
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->cHttpLine = "";
#endif
client->pingInterval = _pingInterval;
client->pongTimeout = _pongTimeout;
client->disconnectTimeoutCount = _disconnectTimeoutCount;
// adjust clients storage:
// _clients[i]'s constructor are already called,
// all its members are initialized to their default value,
// except the ones explicitly detailed in WSclient_t() constructor.
// Then we need to initialize some members to non-trivial values:
for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
_clients[i].init(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount);
}
#ifdef ESP8266
@ -127,11 +94,19 @@ void WebSocketsServerCore::begin(void) {
#endif
_runnning = true;
DEBUG_WEBSOCKETS("[WS-Server] Websocket Version: " WEBSOCKETS_VERSION "\n");
}
void WebSocketsServerCore::close(void) {
_runnning = false;
disconnect();
// restore _clients[] to their initial state
// before next call to ::begin()
for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
_clients[i] = WSclient_t();
}
}
/**
@ -158,7 +133,7 @@ void WebSocketsServerCore::onValidateHttpHeader(
delete[] _mandatoryHttpHeaders;
_mandatoryHttpHeaderCount = mandatoryHttpHeaderCount;
_mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount];
_mandatoryHttpHeaders = new std::string[_mandatoryHttpHeaderCount];
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
_mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i];
@ -199,7 +174,7 @@ bool WebSocketsServerCore::sendTXT(uint8_t num, const char * payload, size_t len
return sendTXT(num, (uint8_t *)payload, length);
}
bool WebSocketsServerCore::sendTXT(uint8_t num, String & payload) {
bool WebSocketsServerCore::sendTXT(uint8_t num, std::string & payload) {
return sendTXT(num, (uint8_t *)payload.c_str(), payload.length());
}
@ -241,7 +216,7 @@ bool WebSocketsServerCore::broadcastTXT(const char * payload, size_t length) {
return broadcastTXT((uint8_t *)payload, length);
}
bool WebSocketsServerCore::broadcastTXT(String & payload) {
bool WebSocketsServerCore::broadcastTXT(std::string & payload) {
return broadcastTXT((uint8_t *)payload.c_str(), payload.length());
}
@ -312,7 +287,7 @@ bool WebSocketsServerCore::sendPing(uint8_t num, uint8_t * payload, size_t lengt
return false;
}
bool WebSocketsServerCore::sendPing(uint8_t num, String & payload) {
bool WebSocketsServerCore::sendPing(uint8_t num, std::string & payload) {
return sendPing(num, (uint8_t *)payload.c_str(), payload.length());
}
@ -337,7 +312,7 @@ bool WebSocketsServerCore::broadcastPing(uint8_t * payload, size_t length) {
return ret;
}
bool WebSocketsServerCore::broadcastPing(String & payload) {
bool WebSocketsServerCore::broadcastPing(std::string & payload) {
return broadcastPing((uint8_t *)payload.c_str(), payload.length());
}
@ -375,7 +350,7 @@ void WebSocketsServerCore::disconnect(uint8_t num) {
*/
void WebSocketsServerCore::setAuthorization(const char * user, const char * password) {
if(user && password) {
String auth = user;
std::string auth = user;
auth += ":";
auth += password;
_base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
@ -690,7 +665,7 @@ void WebSocketsServerCore::handleClientData(void) {
//DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len);
switch(client->status) {
case WSC_HEADER: {
String headerLine = client->tcp->readStringUntil('\n');
std::string headerLine = client->tcp->readStringUntil('\n');
handleHeader(client, &headerLine);
} break;
case WSC_CONNECTED:
@ -713,9 +688,9 @@ void WebSocketsServerCore::handleClientData(void) {
/*
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
* @param headerName String ///< the name of the header being checked
* @param headerName std::string ///< the name of the header being checked
*/
bool WebSocketsServerCore::hasMandatoryHeader(String headerName) {
bool WebSocketsServerCore::hasMandatoryHeader(std::string headerName) {
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName))
return true;
@ -726,9 +701,9 @@ bool WebSocketsServerCore::hasMandatoryHeader(String headerName) {
/**
* handles http header reading for WebSocket upgrade
* @param client WSclient_t * ///< pointer to the client struct
* @param headerLine String ///< the header being read / processed
* @param headerLine std::string ///< the header being read / processed
*/
void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine) {
void WebSocketsServerCore::handleHeader(WSclient_t * client, std::string * headerLine) {
static const char * NEW_LINE = "\r\n";
headerLine->trim(); // remove \r
@ -746,8 +721,8 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
client->cMandatoryHeadersCount = 0;
} else if(headerLine->indexOf(':') >= 0) {
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
std::string headerName = headerLine->substring(0, headerLine->indexOf(':'));
std::string headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
// remove space in the beginning (RFC2616)
if(headerValue[0] == ' ') {
@ -823,7 +798,7 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
}
if(_base64Authorization.length() > 0) {
String auth = WEBSOCKETS_STRING("Basic ");
std::string auth = WEBSOCKETS_STRING("Basic ");
auth += _base64Authorization;
if(auth != client->base64Authorization) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num);
@ -836,13 +811,13 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num);
// generate Sec-WebSocket-Accept key
String sKey = acceptKey(client->cKey);
std::string sKey = acceptKey(client->cKey);
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, sKey.c_str());
client->status = WSC_CONNECTED;
String handshake = WEBSOCKETS_STRING(
std::string handshake = WEBSOCKETS_STRING(
"HTTP/1.1 101 Switching Protocols\r\n"
"Server: arduino-WebSocketsServer\r\n"
"Upgrade: websocket\r\n"
@ -942,7 +917,7 @@ void WebSocketsServer::begin(void) {
}
void WebSocketsServer::close(void) {
WebSocketsServer::close();
WebSocketsServerCore::close();
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
_server->close();
#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)

View File

@ -25,6 +25,8 @@
#ifndef WEBSOCKETSSERVER_H_
#define WEBSOCKETSSERVER_H_
#include <string>
#include "WebSockets.h"
#ifndef WEBSOCKETS_SERVER_CLIENT_MAX
@ -33,7 +35,7 @@
class WebSocketsServerCore : protected WebSockets {
public:
WebSocketsServerCore(const String & origin = "", const String & protocol = "arduino");
WebSocketsServerCore(const std::string & origin = "", const std::string & protocol = "arduino");
virtual ~WebSocketsServerCore(void);
void begin(void);
@ -41,10 +43,10 @@ class WebSocketsServerCore : protected WebSockets {
#ifdef __AVR__
typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue);
typedef bool (*WebSocketServerHttpHeaderValFunc)(std::string headerName, std::string headerValue);
#else
typedef std::function<void(uint8_t num, WStype_t type, uint8_t * payload, size_t length)> WebSocketServerEvent;
typedef std::function<bool(String headerName, String headerValue)> WebSocketServerHttpHeaderValFunc;
typedef std::function<bool(std::string headerName, std::string headerValue)> WebSocketServerHttpHeaderValFunc;
#endif
void onEvent(WebSocketServerEvent cbEvent);
@ -57,13 +59,13 @@ class WebSocketsServerCore : protected WebSockets {
bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false);
bool sendTXT(uint8_t num, const char * payload, size_t length = 0);
bool sendTXT(uint8_t num, String & payload);
bool sendTXT(uint8_t num, std::string & payload);
bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
bool broadcastTXT(const uint8_t * payload, size_t length = 0);
bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false);
bool broadcastTXT(const char * payload, size_t length = 0);
bool broadcastTXT(String & payload);
bool broadcastTXT(std::string & payload);
bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false);
bool sendBIN(uint8_t num, const uint8_t * payload, size_t length);
@ -72,10 +74,10 @@ class WebSocketsServerCore : protected WebSockets {
bool broadcastBIN(const uint8_t * payload, size_t length);
bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0);
bool sendPing(uint8_t num, String & payload);
bool sendPing(uint8_t num, std::string & payload);
bool broadcastPing(uint8_t * payload = NULL, size_t length = 0);
bool broadcastPing(String & payload);
bool broadcastPing(std::string & payload);
void disconnect(void);
void disconnect(uint8_t num);
@ -98,11 +100,13 @@ class WebSocketsServerCore : protected WebSockets {
void loop(void); // handle client data only
#endif
WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
protected:
String _origin;
String _protocol;
String _base64Authorization; ///< Base64 encoded Auth request
String * _mandatoryHttpHeaders;
std::string _origin;
std::string _protocol;
std::string _base64Authorization; ///< Base64 encoded Auth request
std::string * _mandatoryHttpHeaders;
size_t _mandatoryHttpHeaderCount;
WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
@ -116,8 +120,6 @@ class WebSocketsServerCore : protected WebSockets {
uint32_t _pongTimeout;
uint8_t _disconnectTimeoutCount;
WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
void clientDisconnect(WSclient_t * client);
@ -127,7 +129,7 @@ class WebSocketsServerCore : protected WebSockets {
void handleClientData(void);
#endif
void handleHeader(WSclient_t * client, String * headerLine);
void handleHeader(WSclient_t * client, std::string * headerLine);
void handleHBPing(WSclient_t * client); // send ping in specified intervals
@ -190,7 +192,7 @@ class WebSocketsServerCore : protected WebSockets {
* This mechanism can be used to enable custom authentication schemes e.g. test the value
* of a session cookie to determine if a user is logged on / authenticated
*/
virtual bool execHttpHeaderValidation(String headerName, String headerValue) {
virtual bool execHttpHeaderValidation(std::string headerName, std::string headerValue) {
if(_httpHeaderValidationFunc) {
//return the value of the custom http header validation function
return _httpHeaderValidationFunc(headerName, headerValue);
@ -211,14 +213,14 @@ class WebSocketsServerCore : protected WebSockets {
private:
/*
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
* @param headerName String ///< the name of the header being checked
* @param headerName std::string ///< the name of the header being checked
*/
bool hasMandatoryHeader(String headerName);
bool hasMandatoryHeader(std::string headerName);
};
class WebSocketsServer : public WebSocketsServerCore {
public:
WebSocketsServer(uint16_t port, const String & origin = "", const String & protocol = "arduino");
WebSocketsServer(uint16_t port, const std::string & origin = "", const std::string & protocol = "arduino");
virtual ~WebSocketsServer(void);
void begin(void);

36
src/WebSocketsVersion.h Normal file
View File

@ -0,0 +1,36 @@
/**
* @file WebSocketsVersion.h
* @date 08.03.2021
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the WebSockets for Arduino.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef WEBSOCKETSVERSION_H_
#define WEBSOCKETSVERSION_H_
#define WEBSOCKETS_VERSION "2.3.6"
#define WEBSOCKETS_VERSION_MAJOR 2
#define WEBSOCKETS_VERSION_MINOR 3
#define WEBSOCKETS_VERSION_PATCH 6
#define WEBSOCKETS_VERSION_INT 2003006
#endif /* WEBSOCKETSVERSION_H_ */

View File

@ -27,6 +27,64 @@ function build_sketches()
done
}
function build_sketch()
{
local arduino=$1
local sketch=$2
$arduino --verify $sketch;
local result=$?
if [ $result -ne 0 ]; then
echo "Build failed ($sketch) build verbose..."
$arduino --verify --verbose --preserve-temp-files $sketch
result=$?
fi
if [ $result -ne 0 ]; then
echo "Build failed ($1) $sketch"
return $result
fi
}
function get_sketches_json()
{
local arduino=$1
local srcpath=$2
local platform=$3
local sketches=($(find $srcpath -name *.ino))
echo -en "["
for sketch in "${sketches[@]}" ; do
local sketchdir=$(dirname $sketch)
if [[ -f "$sketchdir/.$platform.skip" ]]; then
continue
fi
echo -en "\"$sketch\""
if [[ $sketch != ${sketches[-1]} ]] ; then
echo -en ","
fi
done
echo -en "]"
}
function get_sketches_json_matrix()
{
local arduino=$1
local srcpath=$2
local platform=$3
local ideversion=$4
local board=$5
local sketches=($(find $srcpath -name *.ino))
for sketch in "${sketches[@]}" ; do
local sketchdir=$(dirname $sketch)
local sketchname=$(basename $sketch)
if [[ -f "$sketchdir/.$platform.skip" ]]; then
continue
fi
echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"ideversion\":\"$ideversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}"
if [[ $sketch != ${sketches[-1]} ]] ; then
echo -en ","
fi
done
}
function get_core()
{
@ -37,17 +95,37 @@ function get_core()
if [ "$1" = "esp8266" ] ; then
mkdir esp8266com
cd esp8266com
git clone https://github.com/esp8266/Arduino.git esp8266
cd esp8266/tools
git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266
cd esp8266/
rm -rf .git
cd tools
python get.py
fi
if [ "$1" = "esp32" ] ; then
mkdir espressif
cd espressif
git clone https://github.com/espressif/arduino-esp32.git esp32
cd esp32/tools
git clone --depth 1 https://github.com/espressif/arduino-esp32.git esp32
cd esp32/
rm -rf .git
cd tools
python get.py
fi
}
function clone_library() {
local url=$1
echo clone $(basename $url)
mkdir -p $HOME/Arduino/libraries
cd $HOME/Arduino/libraries
git clone --depth 1 $url
rm -rf */.git
rm -rf */.github
rm -rf */examples
}
function hash_library_names() {
cd $HOME/Arduino/libraries
ls | sha1sum -z | cut -c1-5
}

132
travis/version.py Executable file
View File

@ -0,0 +1,132 @@
#!/usr/bin/python3
import json
import configparser
import argparse
import re
import os
import datetime
travis_dir = os.path.dirname(os.path.abspath(__file__))
base_dir = os.path.abspath(travis_dir + "/../")
def write_header_file(version):
hvs = version.split('.')
intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2])
now = datetime.datetime.now()
text = f'''/**
* @file WebSocketsVersion.h
* @date {now.strftime("%d.%m.%Y")}
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the WebSockets for Arduino.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef WEBSOCKETSVERSION_H_
#define WEBSOCKETSVERSION_H_
#define WEBSOCKETS_VERSION "{version}"
#define WEBSOCKETS_VERSION_MAJOR {hvs[0]}
#define WEBSOCKETS_VERSION_MINOR {hvs[1]}
#define WEBSOCKETS_VERSION_PATCH {hvs[2]}
#define WEBSOCKETS_VERSION_INT {intversion}
#endif /* WEBSOCKETSVERSION_H_ */
'''
with open(f'{base_dir}/src/WebSocketsVersion.h', 'w') as f:
f.write(text)
def get_library_properties_version():
library_properties = {}
with open(f'{base_dir}/library.properties', 'r') as f:
library_properties = configparser.ConfigParser()
library_properties.read_string('[root]\n' + f.read())
return library_properties['root']['version']
def get_library_json_version():
library_json = {}
with open(f'{base_dir}/library.json', 'r') as f:
library_json = json.load(f)
return library_json['version']
def get_header_versions():
data = {}
define = re.compile('^#define WEBSOCKETS_VERSION_?(.*) "?([0-9\.]*)"?$')
with open(f'{base_dir}/src/WebSocketsVersion.h', 'r') as f:
for line in f:
m = define.match(line)
if m:
name = m[1]
if name == "":
name = "VERSION"
data[name] = m[2]
return data
parser = argparse.ArgumentParser(description='Checks and update Version files')
parser.add_argument(
'--update', action='store_true', default=False)
parser.add_argument(
'--check', action='store_true', default=True)
args = parser.parse_args()
if args.update:
library_properties_version = get_library_properties_version()
with open(f'{base_dir}/library.json', 'r') as f:
library_json = json.load(f)
library_json['version'] = library_properties_version
with open(f'{base_dir}/library.json', 'w') as f:
json.dump(library_json, f, indent=4, sort_keys=True)
write_header_file(library_properties_version)
library_json_version = get_library_json_version()
library_properties_version = get_library_properties_version()
header_version = get_header_versions()
print("WebSocketsVersion.h", header_version)
print(f"library.json: {library_json_version}")
print(f"library.properties: {library_properties_version}")
if args.check:
if library_json_version != library_properties_version or header_version['VERSION'] != library_properties_version:
raise Exception('versions did not match!')
hvs = header_version['VERSION'].split('.')
if header_version['MAJOR'] != hvs[0]:
raise Exception('header MAJOR version wrong!')
if header_version['MINOR'] != hvs[1]:
raise Exception('header MINOR version wrong!')
if header_version['PATCH'] != hvs[2]:
raise Exception('header PATCH version wrong!')
intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2])
if int(header_version['INT']) != intversion:
raise Exception('header INT version wrong!')