diff --git a/code/components/jomjol_fileserver_ota/server_help.cpp b/code/components/jomjol_fileserver_ota/server_help.cpp index c878aa91..ecf838e7 100644 --- a/code/components/jomjol_fileserver_ota/server_help.cpp +++ b/code/components/jomjol_fileserver_ota/server_help.cpp @@ -16,77 +16,101 @@ extern "C" { #include "esp_err.h" #include "esp_log.h" - #include "Helper.h" - #include "esp_http_server.h" - #include "../../include/defines.h" - static const char *TAG = "SERVER HELP"; char scratch[SERVER_HELPER_SCRATCH_BUFSIZE]; - -bool endsWith(std::string const &str, std::string const &suffix) { +bool endsWith(std::string const &str, std::string const &suffix) +{ if (str.length() < suffix.length()) { return false; } return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0; } - esp_err_t send_file(httpd_req_t *req, std::string filename) { + std::string _filename_old = filename; + struct stat file_stat; + bool _gz_file_exists = false; + + ESP_LOGD(TAG, "old filename: %s", filename.c_str()); + std::string _filename_temp = std::string(filename) + ".gz"; + + // Checks whether the file is available as .gz + if (stat(_filename_temp.c_str(), &file_stat) == 0) { + filename = _filename_temp; + + ESP_LOGD(TAG, "new filename: %s", filename.c_str()); + _gz_file_exists = true; + } + FILE *fd = fopen(filename.c_str(), "r"); - if (!fd) { + if (!fd) { ESP_LOGE(TAG, "Failed to read file: %s", filename.c_str()); + /* Respond with 404 Error */ httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404()); return ESP_FAIL; } ESP_LOGD(TAG, "Sending file: %s ...", filename.c_str()); -// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - /* For all files with the following file extention tell - the webbrowser to cache them for 24h */ + /* For all files with the following file extention tell the webbrowser to cache them for 12h */ if (endsWith(filename, ".html") || endsWith(filename, ".htm") || + endsWith(filename, ".xml") || endsWith(filename, ".css") || endsWith(filename, ".js") || endsWith(filename, ".map") || endsWith(filename, ".jpg") || endsWith(filename, ".jpeg") || endsWith(filename, ".ico") || - endsWith(filename, ".png")) { - - if (filename == "/sdcard/html/setup.html") { + endsWith(filename, ".png") || + endsWith(filename, ".gif") || + // endsWith(filename, ".zip") || + endsWith(filename, ".gz")) { + if (filename == "/sdcard/html/setup.html") { httpd_resp_set_hdr(req, "Clear-Site-Data", "\"*\""); + set_content_type_from_file(req, filename.c_str()); + } + else if (_gz_file_exists) { + httpd_resp_set_hdr(req, "Cache-Control", "max-age=43200"); + httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); + set_content_type_from_file(req, _filename_old.c_str()); } else { - httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400"); + httpd_resp_set_hdr(req, "Cache-Control", "max-age=43200"); + set_content_type_from_file(req, filename.c_str()); } } - - set_content_type_from_file(req, filename.c_str()); + else { + set_content_type_from_file(req, filename.c_str()); + } /* Retrieve the pointer to scratch buffer for temporary storage */ char *chunk = scratch; size_t chunksize; - do { + + do { /* Read file in chunks into the scratch buffer */ chunksize = fread(chunk, 1, SERVER_HELPER_SCRATCH_BUFSIZE, fd); /* Send the buffer contents as HTTP response chunk */ - if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) { + if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) { fclose(fd); ESP_LOGE(TAG, "File sending failed!"); + /* Abort sending file */ httpd_resp_sendstr_chunk(req, NULL); + /* Respond with 500 Internal Server Error */ httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file"); + return ESP_FAIL; } @@ -95,13 +119,11 @@ esp_err_t send_file(httpd_req_t *req, std::string filename) /* Close file after sending complete */ fclose(fd); - ESP_LOGD(TAG, "File sending complete"); + ESP_LOGD(TAG, "File sending complete"); + return ESP_OK; } - - - /* Copies the full path into destination buffer and returns * pointer to path (skipping the preceding base path) */ const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize) @@ -131,25 +153,49 @@ const char* get_path_from_uri(char *dest, const char *base_path, const char *uri return dest + base_pathlen; } - /* Set HTTP response content type according to file extension */ esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename) { if (IS_FILE_EXT(filename, ".pdf")) { - return httpd_resp_set_type(req, "application/pdf"); - } else if (IS_FILE_EXT(filename, ".html")) { + return httpd_resp_set_type(req, "application/x-pdf"); + } + else if (IS_FILE_EXT(filename, ".htm")) { return httpd_resp_set_type(req, "text/html"); - } else if (IS_FILE_EXT(filename, ".jpeg")) { + } + else if (IS_FILE_EXT(filename, ".html")) { + return httpd_resp_set_type(req, "text/html"); + } + else if (IS_FILE_EXT(filename, ".jpeg")) { return httpd_resp_set_type(req, "image/jpeg"); - } else if (IS_FILE_EXT(filename, ".jpg")) { + } + else if (IS_FILE_EXT(filename, ".jpg")) { return httpd_resp_set_type(req, "image/jpeg"); - } else if (IS_FILE_EXT(filename, ".ico")) { + } + else if (IS_FILE_EXT(filename, ".gif")) { + return httpd_resp_set_type(req, "image/gif"); + } + else if (IS_FILE_EXT(filename, ".png")) { + return httpd_resp_set_type(req, "image/png"); + } + else if (IS_FILE_EXT(filename, ".ico")) { return httpd_resp_set_type(req, "image/x-icon"); - } else if (IS_FILE_EXT(filename, ".js")) { - return httpd_resp_set_type(req, "text/javascript"); - } else if (IS_FILE_EXT(filename, ".css")) { + } + else if (IS_FILE_EXT(filename, ".js")) { + return httpd_resp_set_type(req, "application/javascript"); + } + else if (IS_FILE_EXT(filename, ".css")) { return httpd_resp_set_type(req, "text/css"); } + else if (IS_FILE_EXT(filename, ".xml")) { + return httpd_resp_set_type(req, "text/xml"); + } + else if (IS_FILE_EXT(filename, ".zip")) { + return httpd_resp_set_type(req, "application/x-zip"); + } + else if (IS_FILE_EXT(filename, ".gz")) { + return httpd_resp_set_type(req, "application/x-gzip"); + } + /* This is a limited set only */ /* For any other type always set as plain text */ return httpd_resp_set_type(req, "text/plain"); diff --git a/sd-card/html/FileSaver.min.js.gz b/sd-card/html/FileSaver.min.js.gz new file mode 100644 index 00000000..356b9734 Binary files /dev/null and b/sd-card/html/FileSaver.min.js.gz differ diff --git a/sd-card/html/FileSaver.min.js.map.gz b/sd-card/html/FileSaver.min.js.map.gz new file mode 100644 index 00000000..44b613c1 Binary files /dev/null and b/sd-card/html/FileSaver.min.js.map.gz differ diff --git a/sd-card/html/Flowstate_initialization.jpg.gz b/sd-card/html/Flowstate_initialization.jpg.gz new file mode 100644 index 00000000..86e98a99 Binary files /dev/null and b/sd-card/html/Flowstate_initialization.jpg.gz differ diff --git a/sd-card/html/Flowstate_initialization_delayed.jpg.gz b/sd-card/html/Flowstate_initialization_delayed.jpg.gz new file mode 100644 index 00000000..b20323dc Binary files /dev/null and b/sd-card/html/Flowstate_initialization_delayed.jpg.gz differ diff --git a/sd-card/html/Flowstate_take_image.jpg.gz b/sd-card/html/Flowstate_take_image.jpg.gz new file mode 100644 index 00000000..dceec352 Binary files /dev/null and b/sd-card/html/Flowstate_take_image.jpg.gz differ diff --git a/sd-card/html/close.png.gz b/sd-card/html/close.png.gz new file mode 100644 index 00000000..cb189346 Binary files /dev/null and b/sd-card/html/close.png.gz differ diff --git a/sd-card/html/cnn_images.jpg.gz b/sd-card/html/cnn_images.jpg.gz new file mode 100644 index 00000000..40d1c2d2 Binary files /dev/null and b/sd-card/html/cnn_images.jpg.gz differ diff --git a/sd-card/html/favicon.ico.gz b/sd-card/html/favicon.ico.gz new file mode 100644 index 00000000..4a027859 Binary files /dev/null and b/sd-card/html/favicon.ico.gz differ diff --git a/sd-card/html/flow_overview.jpg.gz b/sd-card/html/flow_overview.jpg.gz new file mode 100644 index 00000000..9776328b Binary files /dev/null and b/sd-card/html/flow_overview.jpg.gz differ diff --git a/sd-card/html/github.min.css.gz b/sd-card/html/github.min.css.gz new file mode 100644 index 00000000..dd2f00c6 Binary files /dev/null and b/sd-card/html/github.min.css.gz differ diff --git a/sd-card/html/help.png.gz b/sd-card/html/help.png.gz new file mode 100644 index 00000000..51b49619 Binary files /dev/null and b/sd-card/html/help.png.gz differ diff --git a/sd-card/html/img/ChangeRateThreshold.png.gz b/sd-card/html/img/ChangeRateThreshold.png.gz new file mode 100644 index 00000000..7aa05c2a Binary files /dev/null and b/sd-card/html/img/ChangeRateThreshold.png.gz differ diff --git a/sd-card/html/img/flipImageSize.png.gz b/sd-card/html/img/flipImageSize.png.gz new file mode 100644 index 00000000..0ce73b0e Binary files /dev/null and b/sd-card/html/img/flipImageSize.png.gz differ diff --git a/sd-card/html/ipInput.min.css b/sd-card/html/ipInput.min.css new file mode 100644 index 00000000..3b5811e8 --- /dev/null +++ b/sd-card/html/ipInput.min.css @@ -0,0 +1,26 @@ +.ip-input-container { + display:inline-block; + font-size:0; + border:1px solid #ccc; + padding:1px 0; +} + +.ip-input-container .ip-input-item { + border:none; + outline:0; + margin:0; + width:40px; + text-align:center; + vertical-align:bottom; + font-size:16px; +} + +.ip-input-container .ip-input-dot { + display:inline-block; + width:2px; + height:2px; + margin-bottom:1px; + background-color:#333; + border-radius:50%; + vertical-align:bottom; +} diff --git a/sd-card/html/ipInput.min.css.gz b/sd-card/html/ipInput.min.css.gz new file mode 100644 index 00000000..72b695b7 Binary files /dev/null and b/sd-card/html/ipInput.min.css.gz differ diff --git a/sd-card/html/ipInput.min.js b/sd-card/html/ipInput.min.js new file mode 100644 index 00000000..6b9b84c6 --- /dev/null +++ b/sd-card/html/ipInput.min.js @@ -0,0 +1 @@ +!function(t,i,e){function n(t,i,e){if(t.setSelectionRange)t.setSelectionRange(i,e);else if(t.createTextRange){var n=t.createTextRange();n.moveEnd("character",e),n.moveStart("character",i),n.select()}}function l(t,i,e){var n=i?/\d+/.test(i.replace(".","")):"",l=i?i.split("."):"";this.ipArr=4==l.length&&n?l:"",this.el=t,e&&this._init()}l.prototype={_init:function(){this.el.html('
'),this._initEvent()},_initEvent:function(){var i;this.el.on("focus","input",function(){i=t(this).val()}).on("input","input",function(e){var l=t(this),r=l.val();if("."!=r||""==i){var a=r.charAt(r.length-1);if(3==(r=r.replace(/[^\d]/g,"")).length&&"."!=a){var s=l.nextAll("input").eq(0);s[0]&&(s.focus(),n(s[0],0,s.val().length))}parseInt(r)>255&&(r=r.substr(0,r.length-1)),l.val(r)}else l.val(i)}).on("keyup","input",function(e){var l=t(this),r=e.keyCode;if(190==r&&l.val().trim().length>0){var a=l.nextAll("input").eq(0);a[0]&&(a.focus(),n(a[0],0,a.val().length))}if(8==r){if(0==l.val().trim().length&&""==i){var s=l.prevAll("input").eq(0);if(s[0]){s.focus();var u=s.val();s.val(u.slice(0,u.length-1)),n(s[0],s.val().length,s.val().length)}}i=""==l.val()?"":i.slice(0,i.length-1)}8!=r&&190!=r&&(i=l.val())})},getIp:function(){for(var t=this.el.find("input"),i=[],e=0,n=t.length;e