diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d079b235..a41e1dbc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Install Dependencies - run: sudo apt install lua-check + run: sudo apt-get -y update && sudo apt-get -y install lua-check - name: Install example site run: ln -s ./docs/site-example ./site - name: Lint Lua code @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Install Dependencies - run: sudo apt install shellcheck + run: sudo apt-get -y update && sudo apt-get -y install shellcheck - name: Install example site run: ln -s ./docs/site-example ./site - name: Lint shell code diff --git a/Makefile b/Makefile index 4ff9f0c6..76aa9cb2 100644 --- a/Makefile +++ b/Makefile @@ -19,8 +19,9 @@ escape = '$(subst ','\'',$(1))' GLUON_SITEDIR ?= site $(eval $(call mkabspath,GLUON_SITEDIR)) -$(GLUON_SITEDIR)/site.mk: - $(error No site configuration was found. Please check out a site configuration to $(GLUON_SITEDIR)) +ifeq ($(realpath $(GLUON_SITEDIR)/site.mk),) +$(error No site configuration was found. Please check out a site configuration to $(GLUON_SITEDIR)) +endif include $(GLUON_SITEDIR)/site.mk diff --git a/docs/user/site.rst b/docs/user/site.rst index 408cf455..31fb2653 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -478,7 +478,7 @@ config_mode \: optional *openlayers_url* allows to override the base URL of the *build/ol.js* and *css/ol.css* files (the default is - ``https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.2.0``). + ``https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@35ffe7626ce16c372143f3c903950750075e7068/en/v5.3.0``). It is also possible to replace the default tile layer (which is OpenStreetMap) with a custom one using the *tile_layer* section. Only XYZ layers are supported at this point. diff --git a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/model/gluon-config-mode/wizard.lua b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/model/gluon-config-mode/wizard.lua index dfc4ab4c..edfe0bc3 100644 --- a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/model/gluon-config-mode/wizard.lua +++ b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/model/gluon-config-mode/wizard.lua @@ -22,7 +22,7 @@ function f:write() uci:set("gluon-setup-mode", uci:get_first("gluon-setup-mode", "setup_mode"), "configured", true) uci:save("gluon-setup-mode") - os.execute('gluon-reconfigure') + os.execute('exec gluon-reconfigure >/dev/null') f.template = "wizard/reboot" f.package = "gluon-config-mode-core" diff --git a/package/gluon-neighbour-info/src/gluon-neighbour-info.c b/package/gluon-neighbour-info/src/gluon-neighbour-info.c index 6470508c..119aaddc 100644 --- a/package/gluon-neighbour-info/src/gluon-neighbour-info.c +++ b/package/gluon-neighbour-info/src/gluon-neighbour-info.c @@ -69,8 +69,23 @@ void tv_subtract (struct timeval *r, const struct timeval *a, const struct timev } } -ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, const struct timeval *timeout) { +void resize_recvbuffer(char **recvbuffer, size_t *recvbuffer_len, size_t recvlen) +{ + free(*recvbuffer); + *recvbuffer = malloc(recvlen); + + if (!(*recvbuffer)) { + perror("Could not resize recvbuffer"); + exit(EXIT_FAILURE); + } + + *recvbuffer_len = recvlen; +} + +ssize_t recvtimeout(int socket, char **recvbuffer, size_t *recvbuffer_len, + const struct timeval *timeout) { struct timeval now, timeout_left; + ssize_t recvlen; getclock(&now); tv_subtract(&timeout_left, timeout, &now); @@ -79,18 +94,28 @@ ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, const st return -1; setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout_left, sizeof(timeout_left)); - return recv(socket, buffer, length, flags); + + recvlen = recv(socket, NULL, 0, MSG_PEEK | MSG_TRUNC); + if (recvlen < 0) + return recvlen; + + if (recvlen > *recvbuffer_len) + resize_recvbuffer(recvbuffer, recvbuffer_len, recvlen); + + return recv(socket, *recvbuffer, *recvbuffer_len, 0); } -int request(const int sock, const struct sockaddr_in6 *client_addr, const char *request, const char *sse, double timeout, unsigned int max_count) { +int request(const int sock, char **recvbuffer, size_t *recvbuffer_len, + const struct sockaddr_in6 *client_addr, const char *request, + const char *sse, double timeout, unsigned int max_count) { ssize_t ret; - char buffer[8192]; unsigned int count = 0; ret = sendto(sock, request, strlen(request), 0, (struct sockaddr *)client_addr, sizeof(struct sockaddr_in6)); if (ret < 0) { perror("Error in sendto()"); + free(*recvbuffer); exit(EXIT_FAILURE); } @@ -105,7 +130,7 @@ int request(const int sock, const struct sockaddr_in6 *client_addr, const char * } do { - ret = recvtimeout(sock, buffer, sizeof(buffer), 0, &tv_timeout); + ret = recvtimeout(sock, recvbuffer, recvbuffer_len, &tv_timeout); if (ret < 0) break; @@ -116,7 +141,7 @@ int request(const int sock, const struct sockaddr_in6 *client_addr, const char * fputs("data: ", stdout); } - fwrite(buffer, sizeof(char), ret, stdout); + fwrite(*recvbuffer, sizeof(char), ret, stdout); if (sse) fputs("\n\n", stdout); @@ -137,6 +162,8 @@ int main(int argc, char **argv) { int sock; struct sockaddr_in6 client_addr = {}; char *request_string = NULL; + char *recvbuffer = NULL; + size_t recvbuffer_len = 0; sock = socket(PF_INET6, SOCK_DGRAM, 0); @@ -243,11 +270,13 @@ int main(int argc, char **argv) { } do { - ret = request(sock, &client_addr, request_string, sse, timeout, max_count); + ret = request(sock, &recvbuffer, &recvbuffer_len, &client_addr, + request_string, sse, timeout, max_count); } while(loop); if (sse) fputs("event: eot\ndata: null\n\n", stdout); + free(recvbuffer); return ret; } diff --git a/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html b/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html index 861c13a4..6957599f 100644 --- a/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html +++ b/package/gluon-status-page/files/lib/gluon/status-page/view/status-page.html @@ -1,7 +1,11 @@ <%- + local iwinfo = require 'iwinfo' local ubus = require 'ubus' local unistd = require 'posix.unistd' local util = require 'gluon.util' + local wireless = require 'gluon.wireless' + + local uci = require('simple-uci').cursor() local translations = {} local site_i18n = i18n 'gluon-site' @@ -29,17 +33,31 @@ local mesh = get_mesh() - local function get_interfaces() - local uconn = ubus.connect() - if not uconn then - error('failed to connect to ubus') - end + local function get_interfaces(uconn) local interfaces = util.get_mesh_devices(uconn) - ubus.close(uconn) table.sort(interfaces) return interfaces end + local function get_radios() + local ret = {} + + wireless.foreach_radio(uci, function(radio) + local channel = iwinfo.nl80211.channel(wireless.find_phy(radio)) + if channel then + table.insert(ret, { + name = radio['.name'], + channel = channel, + }) + end + end) + table.sort(ret, function(a, b) + return a.name < b.name + end) + + return ret + end + local function is_wireless(iface) while true do local pattern = '/sys/class/net/' .. iface .. '/lower_*' @@ -52,7 +70,16 @@ return unistd.access('/sys/class/net/' .. iface .. '/wireless') ~= nil end - local interfaces = get_interfaces() + local uconn = ubus.connect() + if not uconn then + error('failed to connect to ubus') + end + + local interfaces = get_interfaces(uconn) + + ubus.close(uconn) + + local radios = get_radios() local function sorted(t) t = {unpack(t)} @@ -66,12 +93,17 @@ local function formatBits(bits) local units = {[0]='', 'k', 'M', 'G'} + local unit = 0 - local pow = math.floor(math.log(math.max(math.abs(bits), 1)) / math.log(1000)) - local known_pow = math.min(pow, #units) + for i = 1, #units do + if math.abs(bits) < 1000 then + break + end + unit = i + bits = bits / 1000 + end - local significand = bits/(1000^known_pow) - return string.format('%g %sbit', significand, units[known_pow]) + return string.format('%g %sbit', bits, units[unit]) end local function statistics(key, format) @@ -135,11 +167,11 @@ <% if nodeinfo.network.mesh_vpn.bandwidth_limit.enabled then -%>
<%:Bandwidth limit%>
- <% if nodeinfo.network.mesh_vpn.bandwidth_limit.egress then -%> - ▲ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.egress*1000) %>/s <%:upstream%>
- <%- end %> <% if nodeinfo.network.mesh_vpn.bandwidth_limit.ingress then -%> - ▼ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.ingress*1000) %>/s <%:downstream%> + ▼ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.ingress*1000) %>/s <%:downstream%>
+ <%- end %> + <% if nodeinfo.network.mesh_vpn.bandwidth_limit.egress then -%> + ▲ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.egress*1000) %>/s <%:upstream%> <%- end %>
<%- end %> @@ -190,11 +222,17 @@ <%:Wireless 2.4 GHz%><%= statistics('clients/wifi24') %> <%:Wireless 5 GHz%><%= statistics('clients/wifi5') %> - + <%- end %>

<%:Traffic%>

diff --git a/package/gluon-status-page/files/lib/gluon/status-page/www/static/status-page.js b/package/gluon-status-page/files/lib/gluon/status-page/www/static/status-page.js index 3fe35c37..21c3c692 100644 --- a/package/gluon-status-page/files/lib/gluon/status-page/www/static/status-page.js +++ b/package/gluon-status-page/files/lib/gluon/status-page/www/static/status-page.js @@ -1 +1 @@ -"use strict";!function(){var r=JSON.parse(document.body.getAttribute("data-translations"));function i(t,e){return t.toFixed(e).replace(/\./,r["."])}function o(t,e){e--;for(var n=t;10<=n&&0Channel "+(2484===(t=t.frequency)?14:2412<=t&&t<=2472?(t-2407)/5:5160<=t&&t<=5885?(t-5e3)/5:"unknown"),e.appendChild(n),i.appendChild(e)})}else e.style.display="none"}var n=document.querySelectorAll("[data-statistics]");d("/cgi-bin/dyn/statistics",function(o,a){var c=o.uptime-a.uptime;n.forEach(function(t){var e=t.getAttribute("data-statistics"),n=t.getAttribute("data-format"),i=l(a,e),e=l(o,e);try{var r=s[n](e,i,c);void 0!==r&&(t.textContent=r)}catch(t){console.error(t)}});try{t(o.mesh_vpn)}catch(t){console.error(t)}try{e(o.wireless)}catch(t){console.error(t)}});var c={};function A(n){var i=document.createElement("canvas"),r=i.getContext("2d"),o=null;return{canvas:i,highlight:!1,resize:function(t,e){try{r.getImageData(0,0,t,e)}catch(t){}i.width=t,i.height=e},draw:function(t,e){e=e(o);r.clearRect(t,0,5,i.height),e&&(t=t,e=e,r.beginPath(),r.fillStyle=n,r.arc(t,e,1.2,0,2*Math.PI,!1),r.closePath(),r.fill())},set:function(t){o=t}}}function h(){var c=-100,s=0,n=0,i=[],l=document.createElement("canvas");l.className="signalgraph",l.height=200;var u=l.getContext("2d");function t(){l.width=l.clientWidth,i.forEach(function(t){t.resize(l.width,l.height)})}function r(){var e;0!==l.clientWidth&&(l.width!==l.clientWidth&&t(),u.clearRect(0,0,l.width,l.height),e=!1,i.forEach(function(t){t.highlight&&(e=!0)}),u.save(),i.forEach(function(t){e&&(u.globalAlpha=.2),t.highlight&&(u.globalAlpha=1),t.draw(n,function(t){return e=t,n=c,i=s,t=l.height,(1-(e-n)/(i-n))*t;var e,n,i}),u.drawImage(t.canvas,0,0)}),u.restore(),u.save(),u.beginPath(),u.strokeStyle="rgba(255, 180, 0, 0.15)",u.lineWidth=5,u.moveTo(n+2.5,0),u.lineTo(n+2.5,l.height),u.stroke(),function(){var t=Math.floor(l.height/40);u.save(),u.lineWidth=.5,u.strokeStyle="rgba(0, 0, 0, 0.25)",u.fillStyle="rgba(0, 0, 0, 0.5)",u.textAlign="end",u.textBaseline="bottom",u.beginPath();for(var e,n,i,r=0;re[0]||t[1]e[1]?1:0});t=t[0][2];return t&&!/^fe80:/i.test(t)?t:void 0}}return t.wireless&&((g=a.insertCell()).textContent="-",g.setAttribute("data-label",o.children[Object.keys(l).length+1].textContent),(v=a.insertCell()).textContent="-",v.setAttribute("data-label",o.children[Object.keys(l).length+2].textContent),(m=a.insertCell()).textContent="-",m.setAttribute("data-label",o.children[Object.keys(l).length+3].textContent),p=A(n),t.signalgraph.addSignal(p)),a.onmouseenter=function(){a.classList.add("highlight"),p&&(p.highlight=!0)},a.onmouseleave=function(){a.classList.remove("highlight"),p&&(p.highlight=!1)},C(),{get_hostname:function(){return s.textContent},update_nodeinfo:function(t){var e,n,i,r,o=w(t.network.addresses);o&&("span"===s.nodeName.toLowerCase()&&(r=s,s=document.createElement("a"),r.parentNode.replaceChild(s,r)),s.href="http://["+o+"]/"),s.textContent=t.hostname,x&&t.location&&(e=x.latitude,n=x.longitude,i=t.location.latitude,r=t.location.longitude,o=Math.PI/180,t=(i*=o)-(e*=o),n=(r*=o)-(n*=o),i=Math.sin(t/2)*Math.sin(t/2)+Math.sin(n/2)*Math.sin(n/2)*Math.cos(e)*Math.cos(i),i=6372.8*(2*Math.asin(Math.sqrt(i))),v.textContent=Math.round(1e3*i)+" m"),C()},update_mesh:function(n){Object.keys(l).forEach(function(t){var e=l[t];e.td.textContent=n[t]+e.suffix}),C()},update_wifi:function(t){g.textContent=t.signal,m.textContent=Math.round(t.inactive/1e3)+" s",a.classList.toggle("inactive",200e[0]||t[1]e[1]?1:0});t=t[0][2];return t&&!/^fe80:/i.test(t)?t:void 0}}return t.wireless&&((g=a.insertCell()).textContent="-",g.setAttribute("data-label",i.children[Object.keys(s).length+1].textContent),(v=a.insertCell()).textContent="-",v.setAttribute("data-label",i.children[Object.keys(s).length+2].textContent),(p=a.insertCell()).textContent="-",p.setAttribute("data-label",i.children[Object.keys(s).length+3].textContent),m=A(e),t.signalgraph.addSignal(m)),a.onmouseenter=function(){a.classList.add("highlight"),m&&(m.highlight=!0)},a.onmouseleave=function(){a.classList.remove("highlight"),m&&(m.highlight=!1)},y(),{get_hostname:function(){return u.textContent},get_addr:function(){return o},update_nodeinfo:function(t){var e,n,r,i,a;(o=E(t.network.addresses))&&("span"===u.nodeName.toLowerCase()&&(a=u,u=document.createElement("a"),a.parentNode.replaceChild(u,a)),u.href="http://["+o+"]/"),u.textContent=t.hostname,x&&t.location&&(e=x.latitude,n=x.longitude,r=t.location.latitude,i=t.location.longitude,a=Math.PI/180,t=(r*=a)-(e*=a),n=(i*=a)-(n*=a),r=Math.sin(t/2)*Math.sin(t/2)+Math.sin(n/2)*Math.sin(n/2)*Math.cos(e)*Math.cos(r),r=6372.8*(2*Math.asin(Math.sqrt(r))),v.textContent=Math.round(1e3*r)+" m"),y()},update_mesh:function(n){Object.keys(s).forEach(function(t){var e=s[t];e.td.textContent=n[t]+e.suffix}),y()},update_wifi:function(t){g.textContent=t.signal,p.textContent=Math.round(t.inactive/1e3)+" s",a.classList.toggle("inactive",200Channel " + channel(radio.frequency); - tr.appendChild(td); - - table.appendChild(tr); - }); - } - var statisticsElems = document.querySelectorAll('[data-statistics]'); add_event_source('/cgi-bin/dyn/statistics', function(data, dataPrev) { @@ -264,9 +228,16 @@ var valuePrev = resolve_key(dataPrev, stat); var value = resolve_key(data, stat); try { - var text = formats[format](value, valuePrev, diff); - if (text !== undefined) - elem.textContent = text; + var format_result = formats[format](value, valuePrev, diff); + switch (typeof format_result) { + case "object": + if (elem.lastChild) + elem.removeChild(elem.lastChild); + elem.appendChild(format_result); + break; + default: + elem.textContent = format_result; + } } catch (e) { console.error(e); } @@ -277,11 +248,6 @@ } catch (e) { console.error(e); } - try { - update_radios(data.wireless); - } catch (e) { - console.error(e); - } }) function haversine(lat1, lon1, lat2, lon2) { @@ -319,7 +285,7 @@ 'resize': function(w, h) { var lastImage; try { - ctx.getImageData(0, 0, w, h); + lastImage = ctx.getImageData(0, 0, w, h); } catch (e) {} canvas.width = w; canvas.height = h; @@ -492,6 +458,7 @@ } var hostname = document.createElement("span"); + var addr; hostname.textContent = addr; tdHostname.appendChild(hostname); @@ -552,13 +519,13 @@ el.classList.add("highlight"); if (signal) signal.highlight = true; - } + }; el.onmouseleave = function () { - el.classList.remove("highlight") + el.classList.remove("highlight"); if (signal) signal.highlight = false; - } + }; var timeout; @@ -586,7 +553,8 @@ var n = parts.length; var groups = []; - parts.forEach(function(part, i) { + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; if (part === '') { while (n++ <= 8) groups.push(0); @@ -596,7 +564,7 @@ groups.push(parseInt(part, 16)); } - }); + }; return groups; } @@ -664,8 +632,11 @@ 'get_hostname': function() { return hostname.textContent; }, + 'get_addr': function() { + return addr; + }, 'update_nodeinfo': function(nodeinfo) { - var addr = choose_address(nodeinfo.network.addresses); + addr = choose_address(nodeinfo.network.addresses); if (addr) { if (hostname.nodeName.toLowerCase() === 'span') { var oldHostname = hostname; diff --git a/package/gluon-status-page/luasrc/lib/gluon/status-page/controller/status-page.lua b/package/gluon-status-page/luasrc/lib/gluon/status-page/controller/status-page.lua index ceb5d855..80c5e50a 100644 --- a/package/gluon-status-page/luasrc/lib/gluon/status-page/controller/status-page.lua +++ b/package/gluon-status-page/luasrc/lib/gluon/status-page/controller/status-page.lua @@ -61,7 +61,7 @@ local function match(a, b, n) end entry({}, call(function(http, renderer) - local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 1 -c 1 -r nodeinfo')) + local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 3 -c 1 -r nodeinfo')) local node_ip = parse_ip(http:getenv('SERVER_ADDR')) if node_ip and ( diff --git a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html index 31555f16..7778be4a 100644 --- a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html +++ b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade.html @@ -44,7 +44,6 @@ $Id$
-
diff --git a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade_confirm.html b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade_confirm.html index 92c25a63..9733132f 100644 --- a/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade_confirm.html +++ b/package/gluon-web-admin/files/lib/gluon/config-mode/view/admin/upgrade_confirm.html @@ -49,13 +49,11 @@ You may obtain a copy of the License at
" /> -
" /> - diff --git a/package/gluon-web-model/files/lib/gluon/web/view/model/form.html b/package/gluon-web-model/files/lib/gluon/web/view/model/form.html index 06270be3..d222dde2 100644 --- a/package/gluon-web-model/files/lib/gluon/web/view/model/form.html +++ b/package/gluon-web-model/files/lib/gluon/web/view/model/form.html @@ -1,5 +1,4 @@
-
diff --git a/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html b/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html index 2caa3f37..a2822cd4 100644 --- a/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html +++ b/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html @@ -1,6 +1,7 @@ diff --git a/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua b/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua index ec18a003..294caddf 100644 --- a/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua +++ b/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua @@ -4,7 +4,8 @@ local util = require "gluon.web.util" local class = util.class -local DEFAULT_URL = 'https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.2.0' +local DEFAULT_URL = + 'https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@35ffe7626ce16c372143f3c903950750075e7068/en/v5.3.0' local M = {} diff --git a/package/gluon-web/luasrc/usr/lib/lua/gluon/web/dispatcher.lua b/package/gluon-web/luasrc/usr/lib/lua/gluon/web/dispatcher.lua index 2d727776..3aca99dc 100644 --- a/package/gluon-web/luasrc/usr/lib/lua/gluon/web/dispatcher.lua +++ b/package/gluon-web/luasrc/usr/lib/lua/gluon/web/dispatcher.lua @@ -184,9 +184,15 @@ local function dispatch(config, http, request) return end - http:parse_input(node.filehandler) + local ok, err = pcall(http.parse_input, http, node.filehandler) + if not ok then + http:status(400, "Bad request") + http:prepare_content("text/plain") + http:write(err .. "\r\n") + return + end - local ok, err = pcall(node.target) + ok, err = pcall(node.target) if not ok then http:status(500, "Internal Server Error") renderer.render_layout("error/500", { @@ -208,6 +214,6 @@ return function(config, http) if not ok then http:status(500, "Internal Server Error") http:prepare_content("text/plain") - http:write(err) + http:write(err .. "\r\n") end end diff --git a/package/gluon-web/luasrc/usr/lib/lua/gluon/web/http/protocol.lua b/package/gluon-web/luasrc/usr/lib/lua/gluon/web/http/protocol.lua index 8d070d95..5f56fa1b 100644 --- a/package/gluon-web/luasrc/usr/lib/lua/gluon/web/http/protocol.lua +++ b/package/gluon-web/luasrc/usr/lib/lua/gluon/web/http/protocol.lua @@ -108,16 +108,11 @@ end -- o String value containing a chunk of the file data -- o Boolean which indicates whether the current chunk is the last one (eof) local function mimedecode_message_body(src, msg, filecb) - - if msg and msg.env.CONTENT_TYPE then - msg.mime_boundary = msg.env.CONTENT_TYPE:match("^multipart/form%-data; boundary=(.+)$") + local mime_boundary = (msg.env.CONTENT_TYPE or ''):match("^multipart/form%-data; boundary=(.+)$") + if not mime_boundary then + error("Invalid Content-Type found") end - if not msg.mime_boundary then - return nil, "Invalid Content-Type found" - end - - local tlen = 0 local inhdr = false local field = nil @@ -188,10 +183,10 @@ local function mimedecode_message_body(src, msg, filecb) local spos, epos, found repeat - spos, epos = data:find("\r\n--" .. msg.mime_boundary .. "\r\n", 1, true) + spos, epos = data:find("\r\n--" .. mime_boundary .. "\r\n", 1, true) if not spos then - spos, epos = data:find("\r\n--" .. msg.mime_boundary .. "--\r\n", 1, true) + spos, epos = data:find("\r\n--" .. mime_boundary .. "--\r\n", 1, true) end @@ -250,20 +245,61 @@ local function mimedecode_message_body(src, msg, filecb) return true end - return pump(src, snk) + assert(pump(src, snk)) +end + +local function check_post_origin(msg) + local default_port = '80' + local request_scheme = 'http' + if msg.env.HTTPS then + default_port = '443' + request_scheme = 'https' + end + + local request_host = msg.env.HTTP_HOST + if not request_host then + error('POST request without Host header') + end + if not request_host:match(':[0-9]+$') then + request_host = request_host .. ':' .. default_port + end + + local origin = msg.env.HTTP_ORIGIN + if not origin then + error('POST request without Origin header') + end + local origin_scheme, origin_host = origin:match('^([^:]*)://(.*)$') + if not origin_host then + error('POST request with invalid Origin header') + end + if not origin_host:match(':[0-9]+$') then + local origin_port + if origin_scheme == 'http' then + origin_port = '80' + elseif origin_scheme == 'https' then + origin_port = '443' + else + error('POST request with invalid Origin header') + end + origin_host = origin_host .. ':' .. origin_port + end + + if request_scheme ~= origin_scheme or request_host ~= origin_host then + error('Invalid cross-origin POST') + end end -- This function will examine the Content-Type within the given message object -- to select the appropriate content decoder. -- Currently only the multipart/form-data mime type is supported. function M.parse_message_body(src, msg, filecb) - if not (msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE) then + if msg.env.REQUEST_METHOD ~= "POST" then return end - if msg.env.CONTENT_TYPE:match("^multipart/form%-data") then - return mimedecode_message_body(src, msg, filecb) - end + check_post_origin(msg) + + mimedecode_message_body(src, msg, filecb) end return M diff --git a/patches/packages/packages/0003-perl-don-t-build-in-parallel-and-bump-release.patch b/patches/packages/packages/0003-perl-don-t-build-in-parallel-and-bump-release.patch new file mode 100644 index 00000000..b8fe11d2 --- /dev/null +++ b/patches/packages/packages/0003-perl-don-t-build-in-parallel-and-bump-release.patch @@ -0,0 +1,24 @@ +From: Martin Weinelt +Date: Tue, 8 Feb 2022 21:09:20 +0100 +Subject: perl: don't build in parallel and bump release + +Parallel builds cause spurious build failures with high core counts. + +https://github.com/openwrt/packages/issues/8238 +https://github.com/openwrt/packages/pull/17274 + +diff --git a/lang/perl/Makefile b/lang/perl/Makefile +index 84d256d2d8c682f18670a4cbae0a48e3333fb222..c2e5cf8e703af675dd296704597934aa9b5f7446 100644 +--- a/lang/perl/Makefile ++++ b/lang/perl/Makefile +@@ -34,8 +34,8 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/perl/$(PKG_NAME)-$(PKG_VERSION) + HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/perl/$(PKG_NAME)-$(PKG_VERSION) + PKG_INSTALL:=1 + PKG_BUILD_DEPENDS:=perl/host +-PKG_BUILD_PARALLEL:=1 +-HOST_BUILD_PARALLEL:=1 ++PKG_BUILD_PARALLEL:=0 ++HOST_BUILD_PARALLEL:=0 + + # Variables used during configuration/build + HOST_PERL_PREFIX:=$(STAGING_DIR_HOSTPKG)/usr