Skip to content

Commit f607b6a

Browse files
author
Me No Dev
committed
Add chunked encoding
example: ```cpp server.on("/chunked", HTTP_GET, [](){ server.send(200, "text/html", String()); server.sendContent("<!DOCTYPE html><html><head><title>Chunked Test</title></head><body>"); server.sendContent("<p>Chunk 1</p>"); server.sendContent("<p>Chunk 2</p>"); server.sendContent("<p>Chunk 3</p>"); server.sendContent("<p>Chunk 4</p>"); server.sendContent("<p>Chunk 5</p>"); server.sendContent("<p>Chunk 6</p>"); server.sendContent("</html>"); server.sendContent("");//end of chunked }); ```
1 parent 7158fea commit f607b6a

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

libraries/ESP8266WebServer/src/ESP8266WebServer.cpp

+40-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const char * AUTHORIZATION_HEADER = "Authorization";
4141
ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
4242
: _server(addr, port)
4343
, _currentMethod(HTTP_ANY)
44+
, _currentVersion(0)
4445
, _currentHandler(0)
4546
, _firstHandler(0)
4647
, _lastHandler(0)
@@ -55,6 +56,7 @@ ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
5556
ESP8266WebServer::ESP8266WebServer(int port)
5657
: _server(port)
5758
, _currentMethod(HTTP_ANY)
59+
, _currentVersion(0)
5860
, _currentHandler(0)
5961
, _firstHandler(0)
6062
, _lastHandler(0)
@@ -246,7 +248,7 @@ void ESP8266WebServer::setContentLength(size_t contentLength) {
246248
}
247249

248250
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
249-
response = "HTTP/1.1 ";
251+
response = "HTTP/1."+String(_currentVersion)+" ";
250252
response += String(code);
251253
response += " ";
252254
response += _responseCodeToString(code);
@@ -260,9 +262,12 @@ void ESP8266WebServer::_prepareHeader(String& response, int code, const char* co
260262
sendHeader("Content-Length", String(contentLength));
261263
} else if (_contentLength != CONTENT_LENGTH_UNKNOWN) {
262264
sendHeader("Content-Length", String(_contentLength));
265+
} else if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){ //HTTP/1.1 or above client
266+
//let's do chunked
267+
sendHeader("Accept-Ranges","none");
268+
sendHeader("Transfer-Encoding","chunked");
263269
}
264270
sendHeader("Connection", "close");
265-
sendHeader("Access-Control-Allow-Origin", "*");
266271

267272
response += _responseHeaders;
268273
response += "\r\n";
@@ -271,9 +276,12 @@ void ESP8266WebServer::_prepareHeader(String& response, int code, const char* co
271276

272277
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
273278
String header;
279+
if(content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET)
280+
_contentLength = CONTENT_LENGTH_UNKNOWN;
274281
_prepareHeader(header, code, content_type, content.length());
275-
sendContent(header);
276-
sendContent(content);
282+
_currentClient.write(header.c_str(), header.length());
283+
if(content.length())
284+
sendContent(content);
277285
}
278286

279287
void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
@@ -287,7 +295,7 @@ void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
287295
char type[64];
288296
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
289297
_prepareHeader(header, code, (const char* )type, contentLength);
290-
sendContent(header);
298+
_currentClient.write(header.c_str(), header.length());
291299
sendContent_P(content);
292300
}
293301

@@ -309,15 +317,40 @@ void ESP8266WebServer::send(int code, const String& content_type, const String&
309317
}
310318

311319
void ESP8266WebServer::sendContent(const String& content) {
312-
_currentClient.write(content.c_str(), content.length());
320+
const char * footer = "\r\n";
321+
size_t len = content.length();
322+
if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion) {
323+
char * chunkSize = (char *)malloc(11);
324+
if(chunkSize){
325+
sprintf(chunkSize, "%x%s", len, footer);
326+
_currentClient.write(chunkSize, strlen(chunkSize));
327+
free(chunkSize);
328+
}
329+
}
330+
_currentClient.write(content.c_str(), len);
331+
if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){
332+
_currentClient.write(footer, 2);
333+
}
313334
}
314335

315336
void ESP8266WebServer::sendContent_P(PGM_P content) {
316-
_currentClient.write_P(content, strlen_P(content));
337+
sendContent_P(content, strlen_P(content));
317338
}
318339

319340
void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) {
341+
const char * footer = "\r\n";
342+
if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion) {
343+
char * chunkSize = (char *)malloc(11);
344+
if(chunkSize){
345+
sprintf(chunkSize, "%x%s", size, footer);
346+
_currentClient.write(chunkSize, strlen(chunkSize));
347+
free(chunkSize);
348+
}
349+
}
320350
_currentClient.write_P(content, size);
351+
if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){
352+
_currentClient.write(footer, 2);
353+
}
321354
}
322355

323356

libraries/ESP8266WebServer/src/ESP8266WebServer.h

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ template<typename T> size_t streamFile(T &file, const String& contentType){
156156
WiFiClient _currentClient;
157157
HTTPMethod _currentMethod;
158158
String _currentUri;
159+
uint8_t _currentVersion;
159160
HTTPClientStatus _currentStatus;
160161
unsigned long _statusChange;
161162

libraries/ESP8266WebServer/src/Parsing.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
8686

8787
String methodStr = req.substring(0, addr_start);
8888
String url = req.substring(addr_start + 1, addr_end);
89+
String versionEnd = req.substring(addr_end + 8);
90+
_currentVersion = atoi(versionEnd.c_str());
8991
String searchStr = "";
9092
int hasSearch = url.indexOf('?');
9193
if (hasSearch != -1){

0 commit comments

Comments
 (0)