PsychichHTTP v2-dev
This commit is contained in:
@@ -1,97 +1,116 @@
|
||||
#include "PsychicFileResponse.h"
|
||||
#include "PsychicResponse.h"
|
||||
#include "PsychicRequest.h"
|
||||
#include "PsychicResponse.h"
|
||||
|
||||
|
||||
PsychicFileResponse::PsychicFileResponse(PsychicRequest *request, FS &fs, const String& path, const String& contentType, bool download)
|
||||
: PsychicResponse(request) {
|
||||
PsychicFileResponse::PsychicFileResponse(PsychicResponse* response, FS& fs, const String& path, const String& contentType, bool download) : PsychicResponseDelegate(response)
|
||||
{
|
||||
//_code = 200;
|
||||
String _path(path);
|
||||
|
||||
if(!download && !fs.exists(_path) && fs.exists(_path+".gz")){
|
||||
_path = _path+".gz";
|
||||
if (!download && !fs.exists(_path) && fs.exists(_path + ".gz")) {
|
||||
_path = _path + ".gz";
|
||||
addHeader("Content-Encoding", "gzip");
|
||||
}
|
||||
|
||||
_content = fs.open(_path, "r");
|
||||
_contentLength = _content.size();
|
||||
setContentLength(_content.size());
|
||||
|
||||
if(contentType == "")
|
||||
_setContentType(path);
|
||||
if (contentType == "")
|
||||
_setContentTypeFromPath(path);
|
||||
else
|
||||
setContentType(contentType.c_str());
|
||||
|
||||
int filenameStart = path.lastIndexOf('/') + 1;
|
||||
char buf[26+path.length()-filenameStart];
|
||||
char buf[26 + path.length() - filenameStart];
|
||||
char* filename = (char*)path.c_str() + filenameStart;
|
||||
|
||||
if(download) {
|
||||
if (download) {
|
||||
// set filename and force download
|
||||
snprintf(buf, sizeof (buf), "attachment; filename=\"%s\"", filename);
|
||||
snprintf(buf, sizeof(buf), "attachment; filename=\"%s\"", filename);
|
||||
} else {
|
||||
// set filename and force rendering
|
||||
snprintf(buf, sizeof (buf), "inline; filename=\"%s\"", filename);
|
||||
snprintf(buf, sizeof(buf), "inline; filename=\"%s\"", filename);
|
||||
}
|
||||
addHeader("Content-Disposition", buf);
|
||||
}
|
||||
|
||||
PsychicFileResponse::PsychicFileResponse(PsychicRequest *request, File content, const String& path, const String& contentType, bool download)
|
||||
: PsychicResponse(request) {
|
||||
PsychicFileResponse::PsychicFileResponse(PsychicResponse* response, File content, const String& path, const String& contentType, bool download) : PsychicResponseDelegate(response)
|
||||
{
|
||||
String _path(path);
|
||||
|
||||
if(!download && String(content.name()).endsWith(".gz") && !path.endsWith(".gz")){
|
||||
if (!download && String(content.name()).endsWith(".gz") && !path.endsWith(".gz")) {
|
||||
addHeader("Content-Encoding", "gzip");
|
||||
}
|
||||
|
||||
_content = content;
|
||||
_contentLength = _content.size();
|
||||
setContentLength(_content.size());
|
||||
|
||||
if(contentType == "")
|
||||
_setContentType(path);
|
||||
if (contentType == "")
|
||||
_setContentTypeFromPath(path);
|
||||
else
|
||||
setContentType(contentType.c_str());
|
||||
|
||||
int filenameStart = path.lastIndexOf('/') + 1;
|
||||
char buf[26+path.length()-filenameStart];
|
||||
char buf[26 + path.length() - filenameStart];
|
||||
char* filename = (char*)path.c_str() + filenameStart;
|
||||
|
||||
if(download) {
|
||||
snprintf(buf, sizeof (buf), "attachment; filename=\"%s\"", filename);
|
||||
if (download) {
|
||||
snprintf(buf, sizeof(buf), "attachment; filename=\"%s\"", filename);
|
||||
} else {
|
||||
snprintf(buf, sizeof (buf), "inline; filename=\"%s\"", filename);
|
||||
snprintf(buf, sizeof(buf), "inline; filename=\"%s\"", filename);
|
||||
}
|
||||
addHeader("Content-Disposition", buf);
|
||||
}
|
||||
|
||||
PsychicFileResponse::~PsychicFileResponse()
|
||||
{
|
||||
if(_content)
|
||||
if (_content)
|
||||
_content.close();
|
||||
}
|
||||
|
||||
void PsychicFileResponse::_setContentType(const String& path){
|
||||
const char *_contentType;
|
||||
|
||||
if (path.endsWith(".html")) _contentType = "text/html";
|
||||
else if (path.endsWith(".htm")) _contentType = "text/html";
|
||||
else if (path.endsWith(".css")) _contentType = "text/css";
|
||||
else if (path.endsWith(".json")) _contentType = "application/json";
|
||||
else if (path.endsWith(".js")) _contentType = "application/javascript";
|
||||
else if (path.endsWith(".png")) _contentType = "image/png";
|
||||
else if (path.endsWith(".gif")) _contentType = "image/gif";
|
||||
else if (path.endsWith(".jpg")) _contentType = "image/jpeg";
|
||||
else if (path.endsWith(".ico")) _contentType = "image/x-icon";
|
||||
else if (path.endsWith(".svg")) _contentType = "image/svg+xml";
|
||||
else if (path.endsWith(".eot")) _contentType = "font/eot";
|
||||
else if (path.endsWith(".woff")) _contentType = "font/woff";
|
||||
else if (path.endsWith(".woff2")) _contentType = "font/woff2";
|
||||
else if (path.endsWith(".ttf")) _contentType = "font/ttf";
|
||||
else if (path.endsWith(".xml")) _contentType = "text/xml";
|
||||
else if (path.endsWith(".pdf")) _contentType = "application/pdf";
|
||||
else if (path.endsWith(".zip")) _contentType = "application/zip";
|
||||
else if(path.endsWith(".gz")) _contentType = "application/x-gzip";
|
||||
else _contentType = "text/plain";
|
||||
|
||||
void PsychicFileResponse::_setContentTypeFromPath(const String& path)
|
||||
{
|
||||
const char* _contentType;
|
||||
|
||||
if (path.endsWith(".html"))
|
||||
_contentType = "text/html";
|
||||
else if (path.endsWith(".htm"))
|
||||
_contentType = "text/html";
|
||||
else if (path.endsWith(".css"))
|
||||
_contentType = "text/css";
|
||||
else if (path.endsWith(".json"))
|
||||
_contentType = "application/json";
|
||||
else if (path.endsWith(".js"))
|
||||
_contentType = "application/javascript";
|
||||
else if (path.endsWith(".png"))
|
||||
_contentType = "image/png";
|
||||
else if (path.endsWith(".gif"))
|
||||
_contentType = "image/gif";
|
||||
else if (path.endsWith(".jpg"))
|
||||
_contentType = "image/jpeg";
|
||||
else if (path.endsWith(".ico"))
|
||||
_contentType = "image/x-icon";
|
||||
else if (path.endsWith(".svg"))
|
||||
_contentType = "image/svg+xml";
|
||||
else if (path.endsWith(".eot"))
|
||||
_contentType = "font/eot";
|
||||
else if (path.endsWith(".woff"))
|
||||
_contentType = "font/woff";
|
||||
else if (path.endsWith(".woff2"))
|
||||
_contentType = "font/woff2";
|
||||
else if (path.endsWith(".ttf"))
|
||||
_contentType = "font/ttf";
|
||||
else if (path.endsWith(".xml"))
|
||||
_contentType = "text/xml";
|
||||
else if (path.endsWith(".pdf"))
|
||||
_contentType = "application/pdf";
|
||||
else if (path.endsWith(".zip"))
|
||||
_contentType = "application/zip";
|
||||
else if (path.endsWith(".gz"))
|
||||
_contentType = "application/x-gzip";
|
||||
else
|
||||
_contentType = "text/plain";
|
||||
|
||||
setContentType(_contentType);
|
||||
}
|
||||
|
||||
@@ -99,59 +118,52 @@ esp_err_t PsychicFileResponse::send()
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
//just send small files directly
|
||||
// just send small files directly
|
||||
size_t size = getContentLength();
|
||||
if (size < FILE_CHUNK_SIZE)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)malloc(size);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(this->_request->request(), HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to allocate memory.");
|
||||
if (size < FILE_CHUNK_SIZE) {
|
||||
uint8_t* buffer = (uint8_t*)malloc(size);
|
||||
if (buffer == NULL) {
|
||||
ESP_LOGE(PH_TAG, "Unable to allocate %" PRIu32 " bytes to send chunk", size);
|
||||
httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to allocate memory.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
size_t readSize = _content.readBytes((char *)buffer, size);
|
||||
size_t readSize = _content.readBytes((char*)buffer, size);
|
||||
|
||||
setContent(buffer, readSize);
|
||||
err = _response->send();
|
||||
|
||||
this->setContent(buffer, readSize);
|
||||
err = PsychicResponse::send();
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
char *chunk = (char *)malloc(FILE_CHUNK_SIZE);
|
||||
if (chunk == NULL)
|
||||
{
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(this->_request->request(), HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to allocate memory.");
|
||||
char* chunk = (char*)malloc(FILE_CHUNK_SIZE);
|
||||
if (chunk == NULL) {
|
||||
ESP_LOGE(PH_TAG, "Unable to allocate %" PRIu32 " bytes to send chunk", FILE_CHUNK_SIZE);
|
||||
httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to allocate memory.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
this->sendHeaders();
|
||||
sendHeaders();
|
||||
|
||||
size_t chunksize;
|
||||
do {
|
||||
/* Read file in chunks into the scratch buffer */
|
||||
chunksize = _content.readBytes(chunk, FILE_CHUNK_SIZE);
|
||||
if (chunksize > 0)
|
||||
{
|
||||
err = this->sendChunk((uint8_t *)chunk, chunksize);
|
||||
if (err != ESP_OK)
|
||||
break;
|
||||
}
|
||||
/* Read file in chunks into the scratch buffer */
|
||||
chunksize = _content.readBytes(chunk, FILE_CHUNK_SIZE);
|
||||
if (chunksize > 0) {
|
||||
err = sendChunk((uint8_t*)chunk, chunksize);
|
||||
if (err != ESP_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Keep looping till the whole file is sent */
|
||||
/* Keep looping till the whole file is sent */
|
||||
} while (chunksize != 0);
|
||||
|
||||
//keep track of our memory
|
||||
// keep track of our memory
|
||||
free(chunk);
|
||||
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGD(PH_TAG, "File sending complete");
|
||||
this->finishChunking();
|
||||
finishChunking();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user