From 12829bdedc8e43e32a10f8343f23c5cb03330cb1 Mon Sep 17 00:00:00 2001 From: Jakob Lechner Date: Thu, 6 Jan 2022 20:04:13 +0000 Subject: [PATCH] raven/laserkutter: use nginx as reverse proxy We need to set the `Access-Control-Allow-Origin` header in order to upload gcode with XHR --- machines/raven/services/default.nix | 1 + machines/raven/services/dnsmasq.nix | 2 +- machines/raven/services/laserkutter.nix | 31 ++++++ pkgs/fablab/default.nix | 1 + pkgs/fablab/laser-upload/default.nix | 18 ++++ pkgs/fablab/laser-upload/src/index.html | 21 +++++ pkgs/fablab/laser-upload/src/index.js | 119 ++++++++++++++++++++++++ pkgs/fablab/laser-upload/src/style.css | 6 ++ 8 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 machines/raven/services/laserkutter.nix create mode 100644 pkgs/fablab/laser-upload/default.nix create mode 100644 pkgs/fablab/laser-upload/src/index.html create mode 100644 pkgs/fablab/laser-upload/src/index.js create mode 100644 pkgs/fablab/laser-upload/src/style.css diff --git a/machines/raven/services/default.nix b/machines/raven/services/default.nix index 420c68a..80e1a37 100644 --- a/machines/raven/services/default.nix +++ b/machines/raven/services/default.nix @@ -4,6 +4,7 @@ ./dnsmasq.nix ./dyndns.nix ./labsync + ./laserkutter.nix ./unifi-controller.nix ]; } diff --git a/machines/raven/services/dnsmasq.nix b/machines/raven/services/dnsmasq.nix index 0eb666a..86e9e0c 100644 --- a/machines/raven/services/dnsmasq.nix +++ b/machines/raven/services/dnsmasq.nix @@ -22,7 +22,7 @@ no-hosts addn-hosts=${pkgs.writeText "hosts.dnsmasq" '' - 192.168.94.1 raven labsync unifi + 192.168.94.1 raven labsync unifi upload.laserkutter.lab.fablab-nea.de proxy.laserkutter.lab.fablab-nea.de 192.168.94.2 switch ''} ''; diff --git a/machines/raven/services/laserkutter.nix b/machines/raven/services/laserkutter.nix new file mode 100644 index 0000000..ef7a7b2 --- /dev/null +++ b/machines/raven/services/laserkutter.nix @@ -0,0 +1,31 @@ +{ pkgs, ... }: + +{ + services.nginx.virtualHosts."upload.laserkutter.lab.fablab-nea.de" = { + root = pkgs.fablab.laser-upload; + }; + services.nginx.virtualHosts."proxy.laserkutter.lab.fablab-nea.de" = { + # "/rr_upload" + #basicAuthFile = + # Basic Auth password file for a vhost. Can be created via: htpasswd -c . WARNING: The generate file contains the users' passwords in a non-cryptographically-securely hashed way. + extraConfig = '' + set $duet_web "laserkutter.lab.fablab-nea.de"; + allow 192.168.94.0/24; + deny all; + location / { + if ($request_method = OPTIONS ) { + add_header 'Access-Control-Allow-Origin' 'http://upload.laserkutter.lab.fablab-nea.de'; + add_header 'Access-Control-Allow-Methods' 'POST'; + add_header 'Access-Control-Allow-Headers' 'Content-Type'; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + break; + } + add_header 'Access-Control-Allow-Origin' 'http://upload.laserkutter.lab.fablab-nea.de'; + proxy_set_header Origin "http://$duet_web"; + proxy_pass "http://$duet_web"; + } + ''; + }; +} diff --git a/pkgs/fablab/default.nix b/pkgs/fablab/default.nix index d32b0b0..a2d2d6b 100644 --- a/pkgs/fablab/default.nix +++ b/pkgs/fablab/default.nix @@ -2,4 +2,5 @@ { mitgliedsantrag = callPackage ./mitgliedsantrag { }; + laser-upload = callPackage ./laser-upload { }; } diff --git a/pkgs/fablab/laser-upload/default.nix b/pkgs/fablab/laser-upload/default.nix new file mode 100644 index 0000000..db635d1 --- /dev/null +++ b/pkgs/fablab/laser-upload/default.nix @@ -0,0 +1,18 @@ +{ lib, stdenvNoCC }: + +stdenvNoCC.mkDerivation { + name = "laser-upload"; + + src = ./src; + + dontBuild = true; + installPhase = '' + mkdir $out + cp * $out + ''; + + meta = with lib; { + license = licenses.mit; + platforms = platforms.all; + }; +} diff --git a/pkgs/fablab/laser-upload/src/index.html b/pkgs/fablab/laser-upload/src/index.html new file mode 100644 index 0000000..8dff71a --- /dev/null +++ b/pkgs/fablab/laser-upload/src/index.html @@ -0,0 +1,21 @@ + + + + + + + LaserKutter Job Control + + + + +
+
+

Drag & Drop files here

+
+ + + + + + diff --git a/pkgs/fablab/laser-upload/src/index.js b/pkgs/fablab/laser-upload/src/index.js new file mode 100644 index 0000000..fd17d55 --- /dev/null +++ b/pkgs/fablab/laser-upload/src/index.js @@ -0,0 +1,119 @@ +var lasercutter = "http://proxy.laserkutter.lab.fablab-nea.de"; + +// https://gist.github.com/azat/2762138 +var crc32 = function(str) { + for(var i=256, tbl=[], crc, j; i--; tbl[i]=crc>>>0){ + j=8;for(crc=i;j--;)crc=crc&1?crc>>>1^0xEDB88320:crc>>>1; + } + return function(str) { + for(var n=0, crc=-1; n>>8; + return crc^-1; + } +}(); + +function signedToUnsigned(number, bits){ + let msb=1 <<(bits - 1); + + let mask=~((~0) <<(bits - 1)); + if (number & msb) { + return (number & mask) + msb * Math.sign(msb); + } + else { + return number; + } +} + +function crc32_hex(data) { + return signedToUnsigned(crc32(data), 32).toString(16); +} + + +function connect(fn) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", `${lasercutter}/rr_connect?password=`); + xhr.addEventListener('load', fn()); + xhr.send(content); +}; + +function uploadFile(file) { + connect(function() { + var uploadName=`0:/gcodes/${file.name}`; + const reader = new FileReader(); + reader.addEventListener('load', function() { + var content = this.result; + + var invalid = /^M5$/gm; + var content = content.replace(invalid, ""); + + var content = content.replace(/^M8$/gm, "M106 P1 S255 ; Air-assist on"); + var content = content.replace(/^M9$/gm, "M106 P1 S0 ; Air-assist off"); + + console.log(content); + + var checksum = crc32_hex(content); + var now = new Date().toISOString(); + + var url = `${lasercutter}/rr_upload?name=${uploadName}&time=${now}&crc32=${checksum}`; + + var xhr = new XMLHttpRequest(); + xhr.open("POST", url); + + xhr.setRequestHeader("Content-Type", "application/json"); + + xhr.addEventListener('loadend', function() { + console.log(xhr.responseText); + }); + + xhr.addEventListener('load', function() { + if (document.querySelector('#autostart').checked) { + startGcode(uploadName); + } + }); + + xhr.send(content); + }); + reader.readAsText(file); + }); +}; + +function startGcode(name) { + connect(function() { + var url = `${lasercutter}/rr_gcode?gcode=M32 "${name}"`; + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + console.log(xhr.responseText); + } + }; + xhr.send(); + }); +}; + + +function dropHandler(ev) { + ev.preventDefault(); + + if (!ev.dataTransfer.items) { + return; + } + + for (var i = 0; i < ev.dataTransfer.items.length; i++) { + if (ev.dataTransfer.items[i].kind !== 'file') { + continue; + } + var file = ev.dataTransfer.items[i].getAsFile(); + uploadFile(file); + } +}; + +function fileUploadChanged(ev) { + for (var i = 0; i < ev.target.files.length; i++) { + var file = ev.target.files[i]; + uploadFile(file); + } + ev.target.value = null; +}; + diff --git a/pkgs/fablab/laser-upload/src/style.css b/pkgs/fablab/laser-upload/src/style.css new file mode 100644 index 0000000..e66e2e1 --- /dev/null +++ b/pkgs/fablab/laser-upload/src/style.css @@ -0,0 +1,6 @@ +.drop-zone { + border: 5px solid blue; + width: 600px; + height: 337px; +} +