diff --git a/cores/esp8266/StreamDev.h b/cores/esp8266/StreamDev.h index 1112ce73b..b61a0df55 100644 --- a/cores/esp8266/StreamDev.h +++ b/cores/esp8266/StreamDev.h @@ -179,12 +179,14 @@ public: virtual int read() override { - return _peekPointer < _size ? _buffer[_peekPointer++] : -1; + // valid with dram, iram and flash + return _peekPointer < _size ? pgm_read_byte(&_buffer[_peekPointer++]) : -1; } virtual int peek() override { - return _peekPointer < _size ? _buffer[_peekPointer] : -1; + // valid with dram, iram and flash + return _peekPointer < _size ? pgm_read_byte(&_buffer[_peekPointer]) : -1; } virtual size_t readBytes(char* buffer, size_t len) override diff --git a/doc/reference.rst b/doc/reference.rst index 236d4ff73..5cf150f9e 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -441,7 +441,7 @@ Stream extensions Two additional classes are provided. - - ``StreamPtr::`` is designed to hold a constant buffer (in ram or flash). + - ``StreamConstPtr::`` is designed to hold a constant buffer (in ram or flash). With this class, a ``Stream::`` can be made from ``const char*``, ``F("some words in flash")`` or ``PROGMEM`` strings. This class makes @@ -451,7 +451,7 @@ Stream extensions .. code:: cpp - StreamPtr css(F("my long css data")); // CSS data not copied to RAM + StreamConstPtr css(F("my long css data")); // CSS data not copied to RAM server.sendAll(css); - ``S2Stream::`` is designed to make a ``Stream::`` out of a ``String::`` without copy. diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index f72451d69..9064377c9 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -263,6 +263,27 @@ uint8_t WiFiClientSecureCtx::connected() { return false; } +int WiFiClientSecureCtx::availableForWrite () { + // code taken from ::_write() + if (!connected() || !_handshake_done) { + return 0; + } + // Get BearSSL to a state where we can send + if (_run_until(BR_SSL_SENDAPP) < 0) { + return 0; + } + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { + size_t sendapp_len; + (void)br_ssl_engine_sendapp_buf(_eng, &sendapp_len); + // We want to call br_ssl_engine_sendapp_ack(0) but 0 is forbidden (bssl doc). + // After checking br_ssl_engine_sendapp_buf() src code, + // it seems that it is OK to not call ack when the buffer is left untouched. + //forbidden: br_ssl_engine_sendapp_ack(_eng, 0); + return (int)sendapp_len; + } + return 0; +} + size_t WiFiClientSecureCtx::_write(const uint8_t *buf, size_t size, bool pmem) { size_t sent_bytes = 0; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 602e75450..8ed5edcd9 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -58,6 +58,8 @@ class WiFiClientSecureCtx : public WiFiClient { void flush() override { (void)flush(0); } void stop() override { (void)stop(0); } + int availableForWrite() override; + // Allow sessions to be saved/restored automatically to a memory area void setSession(Session *session) { _session = session; } @@ -249,6 +251,7 @@ class WiFiClientSecure : public WiFiClient { size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } int available() override { return _ctx->available(); } + int availableForWrite() override { return _ctx->availableForWrite(); } int read() override { return _ctx->read(); } int peek() override { return _ctx->peek(); } size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); }