From 8fdb824e11d4d74100f3f43bd5cecb42b8894da4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 22 May 2015 17:57:30 +0300 Subject: [PATCH] Add setContentLength method to web server, update examples related to #304 --- .../examples/FSWebServer/FSWebServer.ino | 65 ++++++++++++------- .../examples/SDWebServer/SDWebServer.ino | 13 +--- .../ESP8266WebServer/src/ESP8266WebServer.cpp | 9 ++- .../ESP8266WebServer/src/ESP8266WebServer.h | 33 ++++------ 4 files changed, 62 insertions(+), 58 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/FSWebServer/FSWebServer.ino b/libraries/ESP8266WebServer/examples/FSWebServer/FSWebServer.ino index fccf2b3eb..12d7a20c2 100644 --- a/libraries/ESP8266WebServer/examples/FSWebServer/FSWebServer.ino +++ b/libraries/ESP8266WebServer/examples/FSWebServer/FSWebServer.ino @@ -106,36 +106,54 @@ void handleFileUpdate(){ } void handleFileDelete(){ - if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS"); + if(server.args() == 0) { + server.send(500, "text/plain", "BAD ARGS"); + return; + } String path = server.arg(0); - if(path == "/") - return server.send(500, "text/plain", "BAD PATH"); - if(!FS.exists((char *)(path.c_str()))) - return server.send(404, "text/plain", "FileNotFound"); + if(path == "/") { + server.send(500, "text/plain", "BAD PATH"); + return; + } + if(!FS.exists((char *)(path.c_str()))) { + server.send(404, "text/plain", "FileNotFound"); + return; + } FS.remove((char *)path.c_str()); server.send(200, "text/plain", ""); path = String(); } void handleFileCreate(){ - if(server.args() == 0) - return server.send(500, "text/plain", "BAD ARGS"); + if(server.args() == 0) { + server.send(500, "text/plain", "BAD ARGS"); + return; + } String path = server.arg(0); - if(path == "/") - return server.send(500, "text/plain", "BAD PATH"); - if(FS.exists((char *)path.c_str())) - return server.send(500, "text/plain", "FILE EXISTS"); + if(path == "/") { + server.send(500, "text/plain", "BAD PATH"); + return; + } + if(FS.exists((char *)path.c_str())) { + server.send(500, "text/plain", "FILE EXISTS"); + return; + } FSFile file = FS.open((char *)path.c_str(), FSFILE_OVERWRITE); if(file) file.close(); - else - return server.send(500, "text/plain", "CREATE FAILED"); + else { + server.send(500, "text/plain", "CREATE FAILED"); + return; + } server.send(200, "text/plain", ""); path = String(); } void handleFileList() { - if(!server.hasArg("dir")) return server.send(500, "text/plain", "BAD ARGS"); + if(!server.hasArg("dir")) { + server.send(500, "text/plain", "BAD ARGS"); + return; + } String path = server.arg("dir"); FSFile entry; @@ -148,19 +166,21 @@ void handleFileList() { } dir.rewindDirectory(); - WiFiClient client = server.client(); - client.print("HTTP/1.1 200 OK\r\nContent-Type: text/json\r\nConnection: close\r\n\r\n"); String output = "["; while(true){ entry = dir.openNextFile(); - if (!entry) break; + if (!entry) + break; + if(!FS.exists(entry.name())){ os_printf("Entry[%s] Not Exists!\n", entry.name()); entry.remove(); entry.close(); continue; } - if(output != "[") output += ','; + + if(output != "[") + output += ','; output += "{\"type\":\""; output += (entry.isDirectory())?"dir":"file"; output += "\",\"name\":\""; @@ -169,14 +189,9 @@ void handleFileList() { entry.close(); } dir.close(); - + output += "]"; - client.write(output.c_str(), output.length()); - output = String(); - uint16_t maxWait = HTTP_MAX_CLOSE_WAIT; - while(client.connected() && maxWait--) { - delay(1); - } + server.send(200, "text/json", output); } void setup(void){ diff --git a/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino b/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino index d0e4e1d35..557b0788b 100644 --- a/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino +++ b/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino @@ -85,16 +85,9 @@ bool loadFromSdCard(String path){ if (!dataFile) return false; - if(server.hasArg("download")) dataType = "application/octet-stream"; + if (server.hasArg("download")) dataType = "application/octet-stream"; - server.sendHeader("Content-Length", String(dataFile.size())); - server.sendHeader("Connection", "close"); - server.sendHeader("Access-Control-Allow-Origin", "*"); - server.send(200, dataType.c_str(), ""); - - WiFiClient client = server.client(); - size_t totalSize = dataFile.size(); - if (client.write(dataFile, HTTP_DOWNLOAD_UNIT_SIZE) != totalSize) { + if (server.streamFile(dataFile, dataType) != dataFile.size()) { DBG_OUTPUT_PORT.println("Sent less data than expected!"); } @@ -187,7 +180,7 @@ void printDirectory() { return returnFail("NOT DIR"); } dir.rewindDirectory(); - + server.setContentSize(CONTENT_SIZE_UNKNOWN); server.send(200, "text/json", ""); WiFiClient client = server.client(); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index c851a7cfb..5c94ee818 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -111,6 +111,7 @@ void ESP8266WebServer::handleClient() } _currentClient = client; + _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); } @@ -138,9 +139,13 @@ void ESP8266WebServer::send(int code, const char* content_type, String content) if (!content_type) content_type = "text/html"; - String len(content.length()); sendHeader("Content-Type", content_type, true); - sendHeader("Content-Length", len.c_str()); + if (_contentLength != CONTENT_LENGTH_UNKNOWN) { + size_t length = (_contentLength == CONTENT_LENGTH_NOT_SET) ? + content.length() : _contentLength; + String lengthStr(length); + sendHeader("Content-Length", lengthStr.c_str()); + } sendHeader("Connection", "close"); sendHeader("Access-Control-Allow-Origin", "*"); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 0b553b518..d787e4e3f 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -34,6 +34,9 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END }; #define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request #define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection +#define CONTENT_LENGTH_UNKNOWN ((size_t) -1) +#define CONTENT_LENGTH_NOT_SET ((size_t) -2) + typedef struct { HTTPUploadStatus status; String filename; @@ -78,32 +81,19 @@ public: void send(int code, char* content_type, String content); void send(int code, String content_type, String content); + void setContentLength(size_t contentLength) { _contentLength = contentLength; } void sendHeader(String name, String value, bool first = false); void sendContent(String content); template size_t streamFile(T &file, String contentType){ - String head = "HTTP/1.1 200 OK\r\nContent-Type: "; - head += contentType; - head += "\r\nContent-Length: "; - head += file.size(); - head += "\r\nConnection: close"; - head += "\r\nAccess-Control-Allow-Origin: *"; - if( - String(file.name()).endsWith(".gz") && - contentType != "application/x-gzip" && - contentType != "application/octet-stream" - ){ - head += "\r\nContent-Encoding: gzip"; + setContentLength(file.size()); + if (String(file.name()).endsWith(".gz") && + contentType != "application/x-gzip" && + contentType != "application/octet-stream"){ + sendHeader("Content-Encoding", "gzip"); } - head += "\r\n\r\n"; - _currentClient.print(head); - head = String(); - size_t res = _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE); - uint16_t maxWait = HTTP_MAX_CLOSE_WAIT; - while(_currentClient.connected() && maxWait--) { - delay(1); - } - return res; + send(200, contentType, ""); + return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE); } protected: @@ -131,6 +121,7 @@ protected: RequestArgument* _currentArgs; HTTPUpload _currentUpload; + size_t _contentLength; String _responseHeaders; RequestHandler* _firstHandler;