mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
json is always chunked
This commit is contained in:
195
lib/PsychicHttp/src_old/PsychicStaticFileHander.cpp
Normal file
195
lib/PsychicHttp/src_old/PsychicStaticFileHander.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "PsychicStaticFileHandler.h"
|
||||
|
||||
/*************************************/
|
||||
/* PsychicStaticFileHandler */
|
||||
/*************************************/
|
||||
|
||||
PsychicStaticFileHandler::PsychicStaticFileHandler(const char * uri, FS & fs, const char * path, const char * cache_control)
|
||||
: _fs(fs)
|
||||
, _uri(uri)
|
||||
, _path(path)
|
||||
, _default_file("index.html")
|
||||
, _cache_control(cache_control)
|
||||
, _last_modified("") {
|
||||
// Ensure leading '/'
|
||||
if (_uri.length() == 0 || _uri[0] != '/')
|
||||
_uri = "/" + _uri;
|
||||
if (_path.length() == 0 || _path[0] != '/')
|
||||
_path = "/" + _path;
|
||||
|
||||
// If path ends with '/' we assume a hint that this is a directory to improve performance.
|
||||
// However - if it does not end with '/' we, can't assume a file, path can still be a directory.
|
||||
_isDir = _path[_path.length() - 1] == '/';
|
||||
|
||||
// Remove the trailing '/' so we can handle default file
|
||||
// Notice that root will be "" not "/"
|
||||
if (_uri[_uri.length() - 1] == '/')
|
||||
_uri = _uri.substring(0, _uri.length() - 1);
|
||||
if (_path[_path.length() - 1] == '/')
|
||||
_path = _path.substring(0, _path.length() - 1);
|
||||
|
||||
// Reset stats
|
||||
_gzipFirst = false;
|
||||
_gzipStats = 0xF8;
|
||||
}
|
||||
|
||||
PsychicStaticFileHandler & PsychicStaticFileHandler::setIsDir(bool isDir) {
|
||||
_isDir = isDir;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PsychicStaticFileHandler & PsychicStaticFileHandler::setDefaultFile(const char * filename) {
|
||||
_default_file = String(filename);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PsychicStaticFileHandler & PsychicStaticFileHandler::setCacheControl(const char * cache_control) {
|
||||
_cache_control = String(cache_control);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PsychicStaticFileHandler & PsychicStaticFileHandler::setLastModified(const char * last_modified) {
|
||||
_last_modified = String(last_modified);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PsychicStaticFileHandler & PsychicStaticFileHandler::setLastModified(struct tm * last_modified) {
|
||||
char result[30];
|
||||
strftime(result, 30, "%a, %d %b %Y %H:%M:%S %Z", last_modified);
|
||||
return setLastModified((const char *)result);
|
||||
}
|
||||
|
||||
bool PsychicStaticFileHandler::canHandle(PsychicRequest * request) {
|
||||
if (request->method() != HTTP_GET || !request->uri().startsWith(_uri))
|
||||
return false;
|
||||
|
||||
if (_getFile(request))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PsychicStaticFileHandler::_getFile(PsychicRequest * request) {
|
||||
// Remove the found uri
|
||||
String path = request->uri().substring(_uri.length());
|
||||
|
||||
// We can skip the file check and look for default if request is to the root of a directory or that request path ends with '/'
|
||||
bool canSkipFileCheck = (_isDir && path.length() == 0) || (path.length() && path[path.length() - 1] == '/');
|
||||
|
||||
path = _path + path;
|
||||
|
||||
// Do we have a file or .gz file
|
||||
if (!canSkipFileCheck && _fileExists(path))
|
||||
return true;
|
||||
|
||||
// Can't handle if not default file
|
||||
if (_default_file.length() == 0)
|
||||
return false;
|
||||
|
||||
// Try to add default file, ensure there is a trailing '/' ot the path.
|
||||
if (path.length() == 0 || path[path.length() - 1] != '/')
|
||||
path += "/";
|
||||
path += _default_file;
|
||||
|
||||
return _fileExists(path);
|
||||
}
|
||||
|
||||
#define FILE_IS_REAL(f) (f == true && !f.isDirectory())
|
||||
|
||||
bool PsychicStaticFileHandler::_fileExists(const String & path) {
|
||||
bool fileFound = false;
|
||||
bool gzipFound = false;
|
||||
|
||||
String gzip = path + ".gz";
|
||||
|
||||
if (_gzipFirst) {
|
||||
_file = _fs.open(gzip, "r");
|
||||
gzipFound = FILE_IS_REAL(_file);
|
||||
if (!gzipFound) {
|
||||
_file = _fs.open(path, "r");
|
||||
fileFound = FILE_IS_REAL(_file);
|
||||
}
|
||||
} else {
|
||||
_file = _fs.open(path, "r");
|
||||
fileFound = FILE_IS_REAL(_file);
|
||||
if (!fileFound) {
|
||||
_file = _fs.open(gzip, "r");
|
||||
gzipFound = FILE_IS_REAL(_file);
|
||||
}
|
||||
}
|
||||
|
||||
bool found = fileFound || gzipFound;
|
||||
|
||||
if (found) {
|
||||
_filename = path;
|
||||
|
||||
// Calculate gzip statistic
|
||||
_gzipStats = (_gzipStats << 1) + (gzipFound ? 1 : 0);
|
||||
if (_gzipStats == 0x00)
|
||||
_gzipFirst = false; // All files are not gzip
|
||||
else if (_gzipStats == 0xFF)
|
||||
_gzipFirst = true; // All files are gzip
|
||||
else
|
||||
_gzipFirst = _countBits(_gzipStats) > 4; // IF we have more gzip files - try gzip first
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
uint8_t PsychicStaticFileHandler::_countBits(const uint8_t value) const {
|
||||
uint8_t w = value;
|
||||
uint8_t n;
|
||||
for (n = 0; w != 0; n++)
|
||||
w &= w - 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
esp_err_t PsychicStaticFileHandler::handleRequest(PsychicRequest * request) {
|
||||
if (_file == true) {
|
||||
DUMP(_filename);
|
||||
|
||||
//is it not modified?
|
||||
String etag = String(_file.size());
|
||||
if (_last_modified.length() && _last_modified == request->header("If-Modified-Since")) {
|
||||
DUMP("Last Modified Hit");
|
||||
TRACE();
|
||||
_file.close();
|
||||
request->reply(304); // Not modified
|
||||
}
|
||||
//does our Etag match?
|
||||
else if (_cache_control.length() && request->hasHeader("If-None-Match") && request->header("If-None-Match").equals(etag)) {
|
||||
DUMP("Etag Hit");
|
||||
DUMP(etag);
|
||||
DUMP(_cache_control);
|
||||
|
||||
_file.close();
|
||||
|
||||
PsychicResponse response(request);
|
||||
response.addHeader("Cache-Control", _cache_control.c_str());
|
||||
response.addHeader("ETag", etag.c_str());
|
||||
response.setCode(304);
|
||||
response.send();
|
||||
}
|
||||
//nope, send them the full file.
|
||||
else {
|
||||
DUMP("No cache hit");
|
||||
DUMP(_last_modified);
|
||||
DUMP(_cache_control);
|
||||
|
||||
PsychicFileResponse response(request, _fs, _filename);
|
||||
|
||||
if (_last_modified.length())
|
||||
response.addHeader("Last-Modified", _last_modified.c_str());
|
||||
if (_cache_control.length()) {
|
||||
response.addHeader("Cache-Control", _cache_control.c_str());
|
||||
response.addHeader("ETag", etag.c_str());
|
||||
}
|
||||
|
||||
return response.send();
|
||||
}
|
||||
} else {
|
||||
return request->reply(404);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user