From c0228cdf4954704106ceb61bab55593c4b8d6eeb Mon Sep 17 00:00:00 2001 From: 7m9 Date: Thu, 9 Sep 2021 02:35:15 +0200 Subject: [PATCH] Added gzip compression --- Makefile | 2 +- README.md | 2 +- docker/firmware/Dockerfile | 2 +- firmware/.gitignore | 4 +- firmware/Makefile | 11 +- firmware/fsdata/fs/404.html | 22 ---- firmware/fsdata/makefsdata | 114 ------------------ firmware/mkwebfs.py | 112 +++++++++++++++++ firmware/webdir/404.html | 22 ++++ .../{fsdata/fs => webdir}/css/picnic.min.css | 0 firmware/{fsdata/fs => webdir}/css/style.css | 24 ++-- firmware/{fsdata/fs => webdir}/index.html | 0 .../{fsdata/fs => webdir}/js/smoothie_min.js | 0 13 files changed, 159 insertions(+), 156 deletions(-) delete mode 100644 firmware/fsdata/fs/404.html delete mode 100755 firmware/fsdata/makefsdata create mode 100755 firmware/mkwebfs.py create mode 100644 firmware/webdir/404.html rename firmware/{fsdata/fs => webdir}/css/picnic.min.css (100%) rename firmware/{fsdata/fs => webdir}/css/style.css (71%) rename firmware/{fsdata/fs => webdir}/index.html (100%) rename firmware/{fsdata/fs => webdir}/js/smoothie_min.js (100%) diff --git a/Makefile b/Makefile index 8fafbe1..0518768 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ clean: firmware_docker: sh -c "docker build -t fiatlux_firmware_env docker/firmware" - sh -c "docker run --volume "$$(pwd)"/firmware:/app/firmware fiatlux_firmware_env make -C firmware all" + sh -c "docker run --volume "$$(pwd)"/firmware:/app/firmware fiatlux_firmware_env make -C firmware html all" pcb_docker: sh -c "docker build -t fiatlux_pcb_env docker/pcb" diff --git a/README.md b/README.md index 6ff897e..ecb33c2 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ git submodule update --init --recursive ### Build Requirements - make - - bash gawk perl + - bash gawk - g++ gcc - libc6-dev - flex bison diff --git a/docker/firmware/Dockerfile b/docker/firmware/Dockerfile index 582fe2f..d278775 100644 --- a/docker/firmware/Dockerfile +++ b/docker/firmware/Dockerfile @@ -6,7 +6,7 @@ RUN cd app; git clone --recursive https://github.com/SuperHouse/esp-open-rtos.gi RUN cd app; sed -i 's/GNU bash, version (3\\\.\[1-9\]|4)/GNU bash, version (3.[1-9]|4|5)/g' modules/sdk/crosstool-NG/configure.ac; mkdir -p modules/sdk/crosstool-NG/.build/tarballs; wget https://github.com/libexpat/libexpat/releases/download/R_2_1_0/expat-2.1.0.tar.gz -O modules/sdk/crosstool-NG/.build/tarballs/expat-2.1.0.tar.gz RUN cd app/modules/sdk; export CT_EXPERIMENTAL=y; export CT_ALLOW_BUILD_AS_ROOT=y; export CT_ALLOW_BUILD_AS_ROOT_SURE=y; make standalone=y -j$(nproc); wget -N https://raw.githubusercontent.com/espressif/esptool/master/esptool.py -O xtensa-lx106-elf/bin/esptool.py USER 0 -RUN apt remove --purge -y python2 && apt autoremove --purge -y && apt install -y python3 python3-serial perl +RUN apt remove --purge -y python2 && apt autoremove --purge -y && apt install -y python3 python3-serial RUN apt install -y --reinstall python-is-python3 USER 1000 WORKDIR /app diff --git a/firmware/.gitignore b/firmware/.gitignore index c67e8c9..14041d9 100644 --- a/firmware/.gitignore +++ b/firmware/.gitignore @@ -142,5 +142,5 @@ dkms.conf *.remove firmware/ -fsdata/fsdata.c -compile_commands.json \ No newline at end of file +build/ +compile_commands.json diff --git a/firmware/Makefile b/firmware/Makefile index bc8dc8b..e0a7ccb 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,6 +1,6 @@ PROGRAM=fiatlux -EXTRA_CFLAGS=-O3 -Ifsdata +EXTRA_CFLAGS=-O3 -Ibuild/gen EXTRA_COMPONENTS=extras/i2s_dma extras/ws2812_i2s extras/dhcpserver extras/rboot-ota extras/mbedtls extras/httpd extras/sntp extras/cpp_support @@ -10,11 +10,12 @@ FLASH_MODE = dio include ../modules/rtos/common.mk -html: fsdata/fsdata.c +html: build/gen/fsdata.c -fsdata/fsdata.c: fsdata/fs/index.html fsdata/fs/404.html fsdata/fs/css/picnic.min.css fsdata/fs/css/style.css fsdata/fs/js/smoothie_min.js +build/gen/fsdata.c: webdir/index.html webdir/404.html webdir/css/picnic.min.css webdir/css/style.css webdir/js/smoothie_min.js @echo "Generating fsdata.." - cd fsdata && ./makefsdata + @mkdir -p $(dir $@) + @./mkwebfs.py --gzip -o $@ $^ test: unittest systest @@ -24,4 +25,4 @@ unittest: systest: true -.NOTPARALLEL: html all \ No newline at end of file +.NOTPARALLEL: html all diff --git a/firmware/fsdata/fs/404.html b/firmware/fsdata/fs/404.html deleted file mode 100644 index da81a20..0000000 --- a/firmware/fsdata/fs/404.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - HTTP Server - - - - -
-

404 - Page not found

-
Sorry, the page you are requesting was not found on this server.
-
- - - diff --git a/firmware/fsdata/makefsdata b/firmware/fsdata/makefsdata deleted file mode 100755 index 5361370..0000000 --- a/firmware/fsdata/makefsdata +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl - -$incHttpHeader = 1; - -open(OUTPUT, "> fsdata.c"); -print(OUTPUT "#include \"httpd/fsdata.h\"\n\n"); - -chdir("fs"); -open(FILES, "find . -type f |"); - -while($file = ) { - - # Do not include files in CVS directories nor backup files. - if($file =~ /(CVS|~)/) { - next; - } - - chop($file); - - if($incHttpHeader == 1) { - open(HEADER, "> /tmp/header") || die $!; - if($file =~ /404/) { - print(HEADER "HTTP/1.0 404 File not found\r\n"); - } else { - print(HEADER "HTTP/1.0 200 OK\r\n"); - } - print(HEADER "lwIP/1.4.1 (http://savannah.nongnu.org/projects/lwip)\r\n"); - if($file =~ /\.html$/ || $file =~ /\.htm$/ || $file =~ /\.shtml$/ || $file =~ /\.shtm$/ || $file =~ /\.ssi$/) { - print(HEADER "Content-type: text/html\r\n"); - } elsif($file =~ /\.js$/) { - print(HEADER "Content-type: application/x-javascript\r\n\r\n"); - } elsif($file =~ /\.css$/) { - print(HEADER "Content-type: text/css\r\n\r\n"); - } elsif($file =~ /\.ico$/) { - print(HEADER "Content-type: image/x-icon\r\n\r\n"); - } elsif($file =~ /\.gif$/) { - print(HEADER "Content-type: image/gif\r\n"); - } elsif($file =~ /\.png$/) { - print(HEADER "Content-type: image/png\r\n"); - } elsif($file =~ /\.jpg$/) { - print(HEADER "Content-type: image/jpeg\r\n"); - } elsif($file =~ /\.bmp$/) { - print(HEADER "Content-type: image/bmp\r\n\r\n"); - } elsif($file =~ /\.class$/) { - print(HEADER "Content-type: application/octet-stream\r\n"); - } elsif($file =~ /\.ram$/) { - print(HEADER "Content-type: audio/x-pn-realaudio\r\n"); - } else { - print(HEADER "Content-type: text/plain\r\n"); - } - print(HEADER "\r\n"); - close(HEADER); - - unless($file =~ /\.plain$/ || $file =~ /cgi/) { - system("cat /tmp/header $file > /tmp/file"); - } else { - system("cp $file /tmp/file"); - } - } else { - system("cp $file /tmp/file"); - } - - open(FILE, "/tmp/file"); - unlink("/tmp/file"); - unlink("/tmp/header"); - - $file =~ s/\.//; - $fvar = $file; - $fvar =~ s-/-_-g; - $fvar =~ s-\.-_-g; - - print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); - print(OUTPUT "\t/* $file */\n\t"); - for($j = 0; $j < length($file); $j++) { - printf(OUTPUT "0x%02X, ", unpack("C", substr($file, $j, 1))); - } - printf(OUTPUT "0,\n"); - - - $i = 0; - while(read(FILE, $data, 1)) { - if($i == 0) { - print(OUTPUT "\t"); - } - printf(OUTPUT "0x%02X, ", unpack("C", $data)); - $i++; - if($i == 10) { - print(OUTPUT "\n"); - $i = 0; - } - } - print(OUTPUT "};\n\n"); - close(FILE); - push(@fvars, $fvar); - push(@files, $file); -} - -for($i = 0; $i < @fvars; $i++) { - $file = $files[$i]; - $fvar = $fvars[$i]; - - if($i == 0) { - $prevfile = "NULL"; - } else { - $prevfile = "file" . $fvars[$i - 1]; - } - print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{\n$prevfile,\ndata$fvar, "); - print(OUTPUT "data$fvar + ". (length($file) + 1) .",\n"); - print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) .",\n"); - print(OUTPUT $incHttpHeader."\n}};\n\n"); -} - -print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); -print(OUTPUT "#define FS_NUMFILES $i\n"); diff --git a/firmware/mkwebfs.py b/firmware/mkwebfs.py new file mode 100755 index 0000000..667af23 --- /dev/null +++ b/firmware/mkwebfs.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +import os +import gzip +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-o', '--output', help='Output file name', default='stdout') +parser.add_argument('-W', '--webroot', help='Output file name', default='webdir/') +parser.add_argument('--gzip', dest='gzip', action='store_true') +parser.add_argument('--no-gzip', dest='gzip', action='store_false') +parser.set_defaults(gzip=False) +parser.add_argument('--header', dest='header', action='store_true') +parser.add_argument('--no-header', dest='header', action='store_false') +parser.set_defaults(header=True) +parser.add_argument('input', nargs='+', default=os.getcwd()) +args = parser.parse_args() + + +def dumpBin2CHex(f, b): + oStr = "\t" + n = 0 + for val in b: + oStr += hex(val) + ", " + n += 1 + if n % 8 == 0: + oStr += "\n\t" + oStr += "\n" + f.write(oStr) + + +f_fsdata_c = open(args.output, 'w') +f_fsdata_c.write('#include "httpd/fsdata.h"\n\n') + +httpFiles = [file for file in args.input if (args.webroot in file)] + +lastFileStruct = "NULL" + +for file in httpFiles: + response = b'' + + webPath = ("/" + file.removeprefix(args.webroot)).replace("//", "/") + print("{} > {}".format(file, webPath)) + + if args.header: + if ("404" in file): + response = b'HTTP/1.0 404 File not found\r\n' + else: + response = b'HTTP/1.0 200 OK\r\n' + response += b"lwIP/1.4.1 (http://savannah.nongnu.org/projects/lwip)\r\n" + fext = file.split('.')[-1] + ctype = b'Content-type: text/plain\r\n' + if (fext.endswith("html") or fext.endswith("htm") or fext.endswith("shtml") or fext.endswith( + "shtm") or fext.endswith("ssi")): + ctype = b'Content-type: text/html\r\n' + if (fext.endswith("js")): + ctype = b'Content-type: application/x-javascript\r\n' + if (fext.endswith("css")): + ctype = b'Content-type: text/css\r\n' + if (fext.endswith("ico")): + ctype = b'Content-type: image/x-icon\r\n' + if (fext.endswith("gif")): + ctype = b'Content-type: image/gif\r\n' + if (fext.endswith("png")): + ctype = b'Content-type: image/png\r\n' + if(fext.endswith("jpg")): + ctype = b'Content-type: image/jpeg\r\n' + if(fext.endswith("bmp")): + ctype = b'Content-type: image/bmp\r\n' + if(fext.endswith("class")): + ctype = b'Content-type: application/octet-stream\r\n' + if(fext.endswith("ram")): + ctype = b'Content-type: audio/x-pn-realaudio\r\n' + response += ctype + + binFile = open(file, 'rb') + binData = binFile.read() + compEff = False + if args.gzip: + compData = gzip.compress(binData, 9) + if len(compData) < len(binData): + compEff = True + print("- Compressed from {} to {}".format(len(binData), len(compData))) + binData = compData + else: + print("- Compression skipped Orig: {} Comp: {}".format(len(binData), len(compData))) + binFile.close() + + if compEff: + response += b'Content-Encoding: gzip\r\n' + response += b"\r\n" + response += binData + binFile.close() + escFile = file.replace("/", "_").replace(".", "_") + escFileData = "data_" + escFile + escFileFile = "file_" + escFile + + f_fsdata_c.write('static const unsigned char {}[] = {{\n'.format(escFileData)) + f_fsdata_c.write('\t/* LOCAL:{} */\n'.format(file)) + f_fsdata_c.write('\t/* WEB: {} */\n'.format(webPath)) + fnameBin = webPath.encode("ascii") + b'\0' + dumpBin2CHex(f_fsdata_c, fnameBin) + dumpBin2CHex(f_fsdata_c, response) + f_fsdata_c.write("};\n\n") + + f_fsdata_c.write("const struct fsdata_file {}[] = {{{{\n {},\n {}, {} + {}, sizeof({}) - {}, 1 }}}};\n\n" + .format(escFileFile, lastFileStruct, escFileData, escFileData, len(fnameBin), escFileData, len(fnameBin))) + # TODO: The last value is 1 if args.header == True + lastFileStruct = escFileFile + +f_fsdata_c.write("\n") +f_fsdata_c.write("#define FS_ROOT {}\n\n".format(lastFileStruct)) +f_fsdata_c.write("#define FS_NUMFILES {}\n\n".format(len(httpFiles))) diff --git a/firmware/webdir/404.html b/firmware/webdir/404.html new file mode 100644 index 0000000..ebea9c6 --- /dev/null +++ b/firmware/webdir/404.html @@ -0,0 +1,22 @@ + + + + + + + HTTP Server + + + + +
+

404 - Page not found

+
Sorry, the page you are requesting was not found on this server.
+
+ + + diff --git a/firmware/fsdata/fs/css/picnic.min.css b/firmware/webdir/css/picnic.min.css similarity index 100% rename from firmware/fsdata/fs/css/picnic.min.css rename to firmware/webdir/css/picnic.min.css diff --git a/firmware/fsdata/fs/css/style.css b/firmware/webdir/css/style.css similarity index 71% rename from firmware/fsdata/fs/css/style.css rename to firmware/webdir/css/style.css index 0e0e33a..136393e 100644 --- a/firmware/fsdata/fs/css/style.css +++ b/firmware/webdir/css/style.css @@ -6,15 +6,15 @@ main { margin-right: auto; } -canvas{ +canvas { width: 100%; } -main section:target ~ section, main section#io, main section#wifi, main section#ota { +main section:target ~ section, main section#io, main section#wifi, main section#ota { display: none; } -main section:target{ +main section:target { display: block !important; } @@ -22,30 +22,34 @@ main section:target{ width: 100%; display: table; } -.table>.row{ + +.table > .row { display: table-row; } -.table>.row:nth-child(2n) { - background: rgba(17,17,17,0.05); + +.table > .row:nth-child(2n) { + background: rgba(17, 17, 17, 0.05); } -.table>.row>*{ + +.table > .row > * { display: table-cell; padding: .3em 2.4em .3em .6em; } -.table>header.row>*{ + +.table > header.row > * { text-align: left; font-weight: 900; color: #fff; background-color: #0074d9; } -.table>.row>input{ +.table > .row > input { border: none; background: none; font-weight: 900; } -.plain{ +.plain { opacity: initial; width: initial; } \ No newline at end of file diff --git a/firmware/fsdata/fs/index.html b/firmware/webdir/index.html similarity index 100% rename from firmware/fsdata/fs/index.html rename to firmware/webdir/index.html diff --git a/firmware/fsdata/fs/js/smoothie_min.js b/firmware/webdir/js/smoothie_min.js similarity index 100% rename from firmware/fsdata/fs/js/smoothie_min.js rename to firmware/webdir/js/smoothie_min.js