Skip to content

Commit 8db4dce

Browse files
authored
WifiClient::write refactoring (second attempt) (#2177)
* WiFiClient: use DataSource for writes * ESP8266WebServer: delegate writing to WiFiClient * ESP8266WebServer: set write timeout before sending content
1 parent 5e3df08 commit 8db4dce

File tree

7 files changed

+527
-377
lines changed

7 files changed

+527
-377
lines changed

libraries/ESP8266WebServer/src/ESP8266WebServer.cpp

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ void ESP8266WebServer::handleClient() {
193193
_currentStatus = HC_NONE;
194194
return;
195195
}
196-
196+
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT);
197197
_contentLength = CONTENT_LENGTH_NOT_SET;
198198
_handleRequest();
199199

@@ -241,6 +241,9 @@ void ESP8266WebServer::sendHeader(const String& name, const String& value, bool
241241
}
242242
}
243243

244+
void ESP8266WebServer::setContentLength(size_t contentLength) {
245+
_contentLength = contentLength;
246+
}
244247

245248
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
246249
response = "HTTP/1.1 ";
@@ -270,7 +273,6 @@ void ESP8266WebServer::send(int code, const char* content_type, const String& co
270273
String header;
271274
_prepareHeader(header, code, content_type, content.length());
272275
sendContent(header);
273-
274276
sendContent(content);
275277
}
276278

@@ -307,67 +309,15 @@ void ESP8266WebServer::send(int code, const String& content_type, const String&
307309
}
308310

309311
void ESP8266WebServer::sendContent(const String& content) {
310-
const size_t unit_size = HTTP_DOWNLOAD_UNIT_SIZE;
311-
size_t size_to_send = content.length();
312-
const char* send_start = content.c_str();
313-
314-
while (size_to_send) {
315-
size_t will_send = (size_to_send < unit_size) ? size_to_send : unit_size;
316-
size_t sent = _currentClient.write(send_start, will_send);
317-
if (sent == 0) {
318-
break;
319-
}
320-
size_to_send -= sent;
321-
send_start += sent;
322-
}
312+
_currentClient.write(content.c_str(), content.length());
323313
}
324314

325315
void ESP8266WebServer::sendContent_P(PGM_P content) {
326-
char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1];
327-
328-
contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0';
329-
330-
while (content != NULL) {
331-
size_t contentUnitLen;
332-
PGM_P contentNext;
333-
334-
// due to the memccpy signature, lots of casts are needed
335-
contentNext = (PGM_P)memccpy_P((void*)contentUnit, (PGM_VOID_P)content, 0, HTTP_DOWNLOAD_UNIT_SIZE);
336-
337-
if (contentNext == NULL) {
338-
// no terminator, more data available
339-
content += HTTP_DOWNLOAD_UNIT_SIZE;
340-
contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE;
341-
}
342-
else {
343-
// reached terminator. Do not send the terminator
344-
contentUnitLen = contentNext - contentUnit - 1;
345-
content = NULL;
346-
}
347-
348-
// write is so overloaded, had to use the cast to get it pick the right one
349-
_currentClient.write((const char*)contentUnit, contentUnitLen);
350-
}
316+
_currentClient.write_P(content, strlen_P(content));
351317
}
352318

353319
void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) {
354-
char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1];
355-
contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0';
356-
size_t remaining_size = size;
357-
358-
while (content != NULL && remaining_size > 0) {
359-
size_t contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE;
360-
361-
if (remaining_size < HTTP_DOWNLOAD_UNIT_SIZE) contentUnitLen = remaining_size;
362-
// due to the memcpy signature, lots of casts are needed
363-
memcpy_P((void*)contentUnit, (PGM_VOID_P)content, contentUnitLen);
364-
365-
content += contentUnitLen;
366-
remaining_size -= contentUnitLen;
367-
368-
// write is so overloaded, had to use the cast to get it pick the right one
369-
_currentClient.write((const char*)contentUnit, contentUnitLen);
370-
}
320+
_currentClient.write_P(content, size);
371321
}
372322

373323

libraries/ESP8266WebServer/src/ESP8266WebServer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
3636
#define HTTP_UPLOAD_BUFLEN 2048
3737
#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
3838
#define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
39+
#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
3940
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
4041

4142
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
@@ -113,7 +114,7 @@ class ESP8266WebServer
113114
void send_P(int code, PGM_P content_type, PGM_P content);
114115
void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);
115116

116-
void setContentLength(size_t contentLength) { _contentLength = contentLength; }
117+
void setContentLength(size_t contentLength);
117118
void sendHeader(const String& name, const String& value, bool first = false);
118119
void sendContent(const String& content);
119120
void sendContent_P(PGM_P content);
@@ -129,7 +130,7 @@ template<typename T> size_t streamFile(T &file, const String& contentType){
129130
sendHeader("Content-Encoding", "gzip");
130131
}
131132
send(200, contentType, "");
132-
return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE);
133+
return _currentClient.write(file);
133134
}
134135

135136
protected:

libraries/ESP8266WiFi/src/WiFiClient.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -172,35 +172,30 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
172172
{
173173
return 0;
174174
}
175+
return _client->write(buf, size);
176+
}
175177

176-
return _client->write(reinterpret_cast<const char*>(buf), size);
178+
size_t WiFiClient::write(Stream& stream, size_t unused)
179+
{
180+
return WiFiClient::write(stream);
177181
}
178182

179-
size_t WiFiClient::write_P(PGM_P buf, size_t size)
183+
size_t WiFiClient::write(Stream& stream)
180184
{
181-
if (!_client || !size)
185+
if (!_client || !stream.available())
182186
{
183187
return 0;
184188
}
189+
return _client->write(stream);
190+
}
185191

186-
char chunkUnit[WIFICLIENT_MAX_PACKET_SIZE + 1];
187-
chunkUnit[WIFICLIENT_MAX_PACKET_SIZE] = '\0';
188-
size_t remaining_size = size;
189-
190-
while (buf != NULL && remaining_size > 0) {
191-
size_t chunkUnitLen = WIFICLIENT_MAX_PACKET_SIZE;
192-
193-
if (remaining_size < WIFICLIENT_MAX_PACKET_SIZE) chunkUnitLen = remaining_size;
194-
// due to the memcpy signature, lots of casts are needed
195-
memcpy_P((void*)chunkUnit, (PGM_VOID_P)buf, chunkUnitLen);
196-
197-
buf += chunkUnitLen;
198-
remaining_size -= chunkUnitLen;
199-
200-
// write is so overloaded, had to use the cast to get it pick the right one
201-
_client->write((const char*)chunkUnit, chunkUnitLen);
192+
size_t WiFiClient::write_P(PGM_P buf, size_t size)
193+
{
194+
if (!_client || !size)
195+
{
196+
return 0;
202197
}
203-
return size;
198+
return _client->write_P(buf, size);
204199
}
205200

206201
int WiFiClient::available()

libraries/ESP8266WiFi/src/WiFiClient.h

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ class WiFiClient : public Client, public SList<WiFiClient> {
4949
virtual size_t write(uint8_t);
5050
virtual size_t write(const uint8_t *buf, size_t size);
5151
size_t write_P(PGM_P buf, size_t size);
52-
template <typename T>
53-
size_t write(T& source, size_t unitSize);
52+
size_t write(Stream& stream);
53+
54+
// This one is deprecated, use write(Stream& instead)
55+
size_t write(Stream& stream, size_t unitSize) __attribute__ ((deprecated));
5456

5557
virtual int available();
5658
virtual int read();
@@ -73,28 +75,6 @@ class WiFiClient : public Client, public SList<WiFiClient> {
7375
void setNoDelay(bool nodelay);
7476
static void setLocalPortStart(uint16_t port) { _localPort = port; }
7577

76-
template<typename T> size_t write(T &src){
77-
uint8_t obuf[WIFICLIENT_MAX_PACKET_SIZE];
78-
size_t doneLen = 0;
79-
size_t sentLen;
80-
int i;
81-
82-
while (src.available() > WIFICLIENT_MAX_PACKET_SIZE){
83-
src.read(obuf, WIFICLIENT_MAX_PACKET_SIZE);
84-
sentLen = write(obuf, WIFICLIENT_MAX_PACKET_SIZE);
85-
doneLen = doneLen + sentLen;
86-
if(sentLen != WIFICLIENT_MAX_PACKET_SIZE){
87-
return doneLen;
88-
}
89-
}
90-
91-
uint16_t leftLen = src.available();
92-
src.read(obuf, leftLen);
93-
sentLen = write(obuf, leftLen);
94-
doneLen = doneLen + sentLen;
95-
return doneLen;
96-
}
97-
9878
friend class WiFiServer;
9979

10080
using Print::write;
@@ -114,24 +94,4 @@ class WiFiClient : public Client, public SList<WiFiClient> {
11494
static uint16_t _localPort;
11595
};
11696

117-
118-
template <typename T>
119-
inline size_t WiFiClient::write(T& source, size_t unitSize) {
120-
std::unique_ptr<uint8_t[]> buffer(new uint8_t[unitSize]);
121-
size_t size_sent = 0;
122-
while(true) {
123-
size_t left = source.available();
124-
if (!left)
125-
break;
126-
size_t will_send = (left < unitSize) ? left : unitSize;
127-
source.read(buffer.get(), will_send);
128-
size_t cb = write(buffer.get(), will_send);
129-
size_sent += cb;
130-
if (cb != will_send) {
131-
break;
132-
}
133-
}
134-
return size_sent;
135-
}
136-
13797
#endif

libraries/ESP8266WiFi/src/WiFiClientSecure.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,8 @@ extern "C" int ax_port_write(int fd, uint8_t* buffer, size_t count) {
557557
errno = EIO;
558558
return -1;
559559
}
560-
size_t cb = _client->write((const char*) buffer, count);
560+
561+
size_t cb = _client->write(buffer, count);
561562
if (cb != count) {
562563
errno = EAGAIN;
563564
}

0 commit comments

Comments
 (0)