mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
Chunked encoding (#2199)
* 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 }); ``` * update examples, keep setContentLength and add bool _chunked * fix wrong session id * set _chunked to false earlier for cases where users use only sendContent
This commit is contained in:
parent
6d3109e8c7
commit
6390cf6bd6
@ -33,14 +33,18 @@ void handleLogin(){
|
|||||||
}
|
}
|
||||||
if (server.hasArg("DISCONNECT")){
|
if (server.hasArg("DISCONNECT")){
|
||||||
Serial.println("Disconnection");
|
Serial.println("Disconnection");
|
||||||
String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=0\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
|
server.sendHeader("Location","/login");
|
||||||
server.sendContent(header);
|
server.sendHeader("Cache-Control","no-cache");
|
||||||
|
server.sendHeader("Set-Cookie","ESPSESSIONID=0");
|
||||||
|
server.send(301);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
|
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
|
||||||
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin" ){
|
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin" ){
|
||||||
String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=1\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n";
|
server.sendHeader("Location","/");
|
||||||
server.sendContent(header);
|
server.sendHeader("Cache-Control","no-cache");
|
||||||
|
server.sendHeader("Set-Cookie","ESPSESSIONID=1");
|
||||||
|
server.send(301);
|
||||||
Serial.println("Log in Successful");
|
Serial.println("Log in Successful");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -60,8 +64,9 @@ void handleRoot(){
|
|||||||
Serial.println("Enter handleRoot");
|
Serial.println("Enter handleRoot");
|
||||||
String header;
|
String header;
|
||||||
if (!is_authentified()){
|
if (!is_authentified()){
|
||||||
String header = "HTTP/1.1 301 OK\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
|
server.sendHeader("Location","/login");
|
||||||
server.sendContent(header);
|
server.sendHeader("Cache-Control","no-cache");
|
||||||
|
server.send(301);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String content = "<html><body><H2>hello, you successfully connected to esp8266!</H2><br>";
|
String content = "<html><body><H2>hello, you successfully connected to esp8266!</H2><br>";
|
||||||
|
@ -24,12 +24,10 @@ void setup(void){
|
|||||||
MDNS.begin(host);
|
MDNS.begin(host);
|
||||||
server.on("/", HTTP_GET, [](){
|
server.on("/", HTTP_GET, [](){
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "text/html", serverIndex);
|
server.send(200, "text/html", serverIndex);
|
||||||
});
|
});
|
||||||
server.on("/update", HTTP_POST, [](){
|
server.on("/update", HTTP_POST, [](){
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
|
server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
},[](){
|
},[](){
|
||||||
|
@ -41,6 +41,7 @@ const char * AUTHORIZATION_HEADER = "Authorization";
|
|||||||
ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
|
ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
|
||||||
: _server(addr, port)
|
: _server(addr, port)
|
||||||
, _currentMethod(HTTP_ANY)
|
, _currentMethod(HTTP_ANY)
|
||||||
|
, _currentVersion(0)
|
||||||
, _currentHandler(0)
|
, _currentHandler(0)
|
||||||
, _firstHandler(0)
|
, _firstHandler(0)
|
||||||
, _lastHandler(0)
|
, _lastHandler(0)
|
||||||
@ -49,12 +50,14 @@ ESP8266WebServer::ESP8266WebServer(IPAddress addr, int port)
|
|||||||
, _headerKeysCount(0)
|
, _headerKeysCount(0)
|
||||||
, _currentHeaders(0)
|
, _currentHeaders(0)
|
||||||
, _contentLength(0)
|
, _contentLength(0)
|
||||||
|
, _chunked(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP8266WebServer::ESP8266WebServer(int port)
|
ESP8266WebServer::ESP8266WebServer(int port)
|
||||||
: _server(port)
|
: _server(port)
|
||||||
, _currentMethod(HTTP_ANY)
|
, _currentMethod(HTTP_ANY)
|
||||||
|
, _currentVersion(0)
|
||||||
, _currentHandler(0)
|
, _currentHandler(0)
|
||||||
, _firstHandler(0)
|
, _firstHandler(0)
|
||||||
, _lastHandler(0)
|
, _lastHandler(0)
|
||||||
@ -63,6 +66,7 @@ ESP8266WebServer::ESP8266WebServer(int port)
|
|||||||
, _headerKeysCount(0)
|
, _headerKeysCount(0)
|
||||||
, _currentHeaders(0)
|
, _currentHeaders(0)
|
||||||
, _contentLength(0)
|
, _contentLength(0)
|
||||||
|
, _chunked(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +250,7 @@ void ESP8266WebServer::setContentLength(size_t contentLength) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
|
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
|
||||||
response = "HTTP/1.1 ";
|
response = "HTTP/1."+String(_currentVersion)+" ";
|
||||||
response += String(code);
|
response += String(code);
|
||||||
response += " ";
|
response += " ";
|
||||||
response += _responseCodeToString(code);
|
response += _responseCodeToString(code);
|
||||||
@ -260,9 +264,13 @@ void ESP8266WebServer::_prepareHeader(String& response, int code, const char* co
|
|||||||
sendHeader("Content-Length", String(contentLength));
|
sendHeader("Content-Length", String(contentLength));
|
||||||
} else if (_contentLength != CONTENT_LENGTH_UNKNOWN) {
|
} else if (_contentLength != CONTENT_LENGTH_UNKNOWN) {
|
||||||
sendHeader("Content-Length", String(_contentLength));
|
sendHeader("Content-Length", String(_contentLength));
|
||||||
|
} else if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){ //HTTP/1.1 or above client
|
||||||
|
//let's do chunked
|
||||||
|
_chunked = true;
|
||||||
|
sendHeader("Accept-Ranges","none");
|
||||||
|
sendHeader("Transfer-Encoding","chunked");
|
||||||
}
|
}
|
||||||
sendHeader("Connection", "close");
|
sendHeader("Connection", "close");
|
||||||
sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
response += _responseHeaders;
|
response += _responseHeaders;
|
||||||
response += "\r\n";
|
response += "\r\n";
|
||||||
@ -271,8 +279,12 @@ void ESP8266WebServer::_prepareHeader(String& response, int code, const char* co
|
|||||||
|
|
||||||
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
|
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
|
||||||
String header;
|
String header;
|
||||||
|
// Can we asume the following?
|
||||||
|
//if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET)
|
||||||
|
// _contentLength = CONTENT_LENGTH_UNKNOWN;
|
||||||
_prepareHeader(header, code, content_type, content.length());
|
_prepareHeader(header, code, content_type, content.length());
|
||||||
sendContent(header);
|
_currentClient.write(header.c_str(), header.length());
|
||||||
|
if(content.length())
|
||||||
sendContent(content);
|
sendContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +299,7 @@ void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
|
|||||||
char type[64];
|
char type[64];
|
||||||
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
|
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
|
||||||
_prepareHeader(header, code, (const char* )type, contentLength);
|
_prepareHeader(header, code, (const char* )type, contentLength);
|
||||||
sendContent(header);
|
_currentClient.write(header.c_str(), header.length());
|
||||||
sendContent_P(content);
|
sendContent_P(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,15 +321,40 @@ void ESP8266WebServer::send(int code, const String& content_type, const String&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::sendContent(const String& content) {
|
void ESP8266WebServer::sendContent(const String& content) {
|
||||||
_currentClient.write(content.c_str(), content.length());
|
const char * footer = "\r\n";
|
||||||
|
size_t len = content.length();
|
||||||
|
if(_chunked) {
|
||||||
|
char * chunkSize = (char *)malloc(11);
|
||||||
|
if(chunkSize){
|
||||||
|
sprintf(chunkSize, "%x%s", len, footer);
|
||||||
|
_currentClient.write(chunkSize, strlen(chunkSize));
|
||||||
|
free(chunkSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_currentClient.write(content.c_str(), len);
|
||||||
|
if(_chunked){
|
||||||
|
_currentClient.write(footer, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::sendContent_P(PGM_P content) {
|
void ESP8266WebServer::sendContent_P(PGM_P content) {
|
||||||
_currentClient.write_P(content, strlen_P(content));
|
sendContent_P(content, strlen_P(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) {
|
void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) {
|
||||||
|
const char * footer = "\r\n";
|
||||||
|
if(_chunked) {
|
||||||
|
char * chunkSize = (char *)malloc(11);
|
||||||
|
if(chunkSize){
|
||||||
|
sprintf(chunkSize, "%x%s", size, footer);
|
||||||
|
_currentClient.write(chunkSize, strlen(chunkSize));
|
||||||
|
free(chunkSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
_currentClient.write_P(content, size);
|
_currentClient.write_P(content, size);
|
||||||
|
if(_chunked){
|
||||||
|
_currentClient.write(footer, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ protected:
|
|||||||
WiFiClient _currentClient;
|
WiFiClient _currentClient;
|
||||||
HTTPMethod _currentMethod;
|
HTTPMethod _currentMethod;
|
||||||
String _currentUri;
|
String _currentUri;
|
||||||
|
uint8_t _currentVersion;
|
||||||
HTTPClientStatus _currentStatus;
|
HTTPClientStatus _currentStatus;
|
||||||
unsigned long _statusChange;
|
unsigned long _statusChange;
|
||||||
|
|
||||||
@ -175,6 +176,7 @@ protected:
|
|||||||
String _responseHeaders;
|
String _responseHeaders;
|
||||||
|
|
||||||
String _hostHeader;
|
String _hostHeader;
|
||||||
|
bool _chunked;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,6 +86,8 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
|||||||
|
|
||||||
String methodStr = req.substring(0, addr_start);
|
String methodStr = req.substring(0, addr_start);
|
||||||
String url = req.substring(addr_start + 1, addr_end);
|
String url = req.substring(addr_start + 1, addr_end);
|
||||||
|
String versionEnd = req.substring(addr_end + 8);
|
||||||
|
_currentVersion = atoi(versionEnd.c_str());
|
||||||
String searchStr = "";
|
String searchStr = "";
|
||||||
int hasSearch = url.indexOf('?');
|
int hasSearch = url.indexOf('?');
|
||||||
if (hasSearch != -1){
|
if (hasSearch != -1){
|
||||||
@ -93,6 +95,7 @@ bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
|
|||||||
url = url.substring(0, hasSearch);
|
url = url.substring(0, hasSearch);
|
||||||
}
|
}
|
||||||
_currentUri = url;
|
_currentUri = url;
|
||||||
|
_chunked = false;
|
||||||
|
|
||||||
HTTPMethod method = HTTP_GET;
|
HTTPMethod method = HTTP_GET;
|
||||||
if (methodStr == "POST") {
|
if (methodStr == "POST") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user