1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-18 23:03:34 +03:00

fixes for WiFiClient::write(Stream) (#7987)

fixes for WiFiClient::write(Stream) and Stream transfers
- remove deprecated WiFiClient::write(Stream,size)
- fix and deprecate WiFiClient::write(Stream) to use Stream::sendAll instead of ::sendAvailable
- update ESP8266WebServer::streamFile to use file.sendAll(client) instead of client.write(file)
- remove stream dependence in ClientContext
- Stream::send(): honor timeout in all case, avoid short transfer when output is temporarily full
- example WiFiEcho: show sendAll and sendAvailable
This commit is contained in:
david gauchard
2021-04-27 16:02:19 +02:00
committed by GitHub
parent 457692101a
commit f4178e58dc
7 changed files with 46 additions and 91 deletions

View File

@ -213,28 +213,19 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
return 0;
}
_client->setTimeout(_timeout);
StreamConstPtr ptr(buf, size);
return _client->write(ptr);
}
size_t WiFiClient::write(Stream& stream, size_t unused)
{
(void) unused;
return WiFiClient::write(stream);
return _client->write((const char*)buf, size);
}
size_t WiFiClient::write(Stream& stream)
{
// (this method is deprecated)
if (!_client || !stream.available())
{
return 0;
}
if (stream.hasPeekBufferAPI())
{
_client->setTimeout(_timeout);
return _client->write(stream);
}
return stream.sendAvailable(this);
// core up to 2.7.4 was equivalent to this
return stream.sendAll(this);
}
size_t WiFiClient::write_P(PGM_P buf, size_t size)

View File

@ -59,10 +59,7 @@ public:
virtual size_t write(uint8_t) override;
virtual size_t write(const uint8_t *buf, size_t size) override;
virtual size_t write_P(PGM_P buf, size_t size);
size_t write(Stream& stream);
// This one is deprecated, use write(Stream& instead)
size_t write(Stream& stream, size_t unitSize) __attribute__ ((deprecated));
size_t write(Stream& stream) [[ deprecated("use stream.sendHow(client...)") ]];
virtual int available() override;
virtual int read() override;

View File

@ -30,7 +30,6 @@ extern "C" void esp_yield();
extern "C" void esp_schedule();
#include <assert.h>
#include <StreamDev.h>
#include <esp_priv.h>
bool getDefaultPrivateGlobalSyncValue ();
@ -376,13 +375,12 @@ public:
return _pcb->state;
}
size_t write(Stream& stream)
size_t write(const char* ds, const size_t dl)
{
if (!_pcb) {
return 0;
}
assert(stream.hasPeekBufferAPI());
return _write_from_source(&stream);
return _write_from_source(ds, dl);
}
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
@ -466,11 +464,12 @@ protected:
}
}
size_t _write_from_source(Stream* ds)
size_t _write_from_source(const char* ds, const size_t dl)
{
assert(_datasource == nullptr);
assert(!_send_waiting);
_datasource = ds;
_datalen = dl;
_written = 0;
_op_start_time = millis();
do {
@ -478,11 +477,12 @@ protected:
_op_start_time = millis();
}
if (!_datasource->available() || _is_timeout() || state() == CLOSED) {
if (_written == _datalen || _is_timeout() || state() == CLOSED) {
if (_is_timeout()) {
DEBUGV(":wtmo\r\n");
}
_datasource = nullptr;
_datalen = 0;
break;
}
@ -507,20 +507,21 @@ protected:
return false;
}
DEBUGV(":wr %d %d\r\n", _datasource->peekAvailable(), _written);
DEBUGV(":wr %d %d\r\n", _datalen - _written, _written);
bool has_written = false;
while (_datasource) {
while (_written < _datalen) {
if (state() == CLOSED)
return false;
size_t next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), _datasource->peekAvailable());
const auto remaining = _datalen - _written;
size_t next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), remaining);
if (!next_chunk_size)
break;
const char* buf = _datasource->peekBuffer();
const char* buf = _datasource + _written;
uint8_t flags = 0;
if (next_chunk_size < _datasource->peekAvailable())
if (next_chunk_size < remaining)
// PUSH is meant for peer, telling to give data to user app as soon as received
// PUSH "may be set" when sender has finished sending a "meaningful" data block
// PUSH does not break Nagle
@ -534,10 +535,9 @@ protected:
err_t err = tcp_write(_pcb, buf, next_chunk_size, flags);
DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, _datasource->peekAvailable(), (int)err);
DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, remaining, (int)err);
if (err == ERR_OK) {
_datasource->peekConsume(next_chunk_size);
_written += next_chunk_size;
has_written = true;
} else {
@ -695,7 +695,8 @@ private:
discard_cb_t _discard_cb;
void* _discard_cb_arg;
Stream* _datasource = nullptr;
const char* _datasource = nullptr;
size_t _datalen = 0;
size_t _written = 0;
uint32_t _timeout_ms = 5000;
uint32_t _op_start_time = 0;