Merge pull request #2390 from freifunk-gluon/v2021.1.x-backports
Backports for v2021.1.x
This commit is contained in:
commit
e51836ecf1
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@ -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
|
||||
|
5
Makefile
5
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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 -%>
|
||||
<dt><%:Bandwidth limit%></dt>
|
||||
<dd>
|
||||
<% if nodeinfo.network.mesh_vpn.bandwidth_limit.egress then -%>
|
||||
▲ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.egress*1000) %>/s <%:upstream%><br />
|
||||
<%- 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%><br />
|
||||
<%- end %>
|
||||
<% if nodeinfo.network.mesh_vpn.bandwidth_limit.egress then -%>
|
||||
▲ <%| formatBits(nodeinfo.network.mesh_vpn.bandwidth_limit.egress*1000) %>/s <%:upstream%>
|
||||
<%- end %>
|
||||
</dd>
|
||||
<%- end %>
|
||||
@ -190,11 +222,17 @@
|
||||
<tr><th><%:Wireless 2.4 GHz%></th><td><%= statistics('clients/wifi24') %></td></tr>
|
||||
<tr><th><%:Wireless 5 GHz%></th><td><%= statistics('clients/wifi5') %></td></tr>
|
||||
</table>
|
||||
<div id="radios" style="display: none">
|
||||
<% if radios[1] then -%>
|
||||
<h3><%:Radios%></h3>
|
||||
<table id="radio-devices">
|
||||
<table>
|
||||
<% for _, radio in ipairs(radios) do -%>
|
||||
<tr>
|
||||
<th><%| radio.name %></th>
|
||||
<td><%| translatef('Channel %u', radio.channel) %></td>
|
||||
</tr>
|
||||
<%- end %>
|
||||
</table>
|
||||
</div>
|
||||
<%- end %>
|
||||
|
||||
<h3><%:Traffic%></h3>
|
||||
<table>
|
||||
|
File diff suppressed because one or more lines are too long
@ -31,8 +31,8 @@ msgstr "Automatische Updates"
|
||||
msgid "Bandwidth limit"
|
||||
msgstr "Bandbreitenlimit"
|
||||
|
||||
msgid "Channel"
|
||||
msgstr "Kanal"
|
||||
msgid "Channel %u"
|
||||
msgstr "Kanal %u"
|
||||
|
||||
msgid "Clients"
|
||||
msgstr "Clients"
|
||||
|
@ -22,7 +22,7 @@ msgstr ""
|
||||
msgid "Bandwidth limit"
|
||||
msgstr ""
|
||||
|
||||
msgid "Channel"
|
||||
msgid "Channel %u"
|
||||
msgstr ""
|
||||
|
||||
msgid "Clients"
|
||||
|
@ -121,7 +121,15 @@
|
||||
var neigh = iface.lookup_neigh(addr);
|
||||
if (!neigh)
|
||||
continue;
|
||||
return 'via ' + neigh.get_hostname() + ' (' + i + ')';
|
||||
|
||||
var span = document.createElement('span');
|
||||
span.appendChild(document.createTextNode('via '));
|
||||
var a = document.createElement('a');
|
||||
a.href = 'http://[' + neigh.get_addr() + ']/';
|
||||
a.textContent = neigh.get_hostname();
|
||||
span.appendChild(a);
|
||||
span.appendChild(document.createTextNode(' (' + i + ')'));
|
||||
return span;
|
||||
}
|
||||
|
||||
return 'via ' + addr + ' (unknown iface)';
|
||||
@ -208,50 +216,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
function update_radios(wireless) {
|
||||
function channel(frequency) {
|
||||
if (frequency===2484)
|
||||
return 14
|
||||
|
||||
if (2412<=frequency && frequency<=2472)
|
||||
return (frequency-2407)/5
|
||||
|
||||
if (5160<=frequency && frequency<=5885)
|
||||
return (frequency-5000)/5
|
||||
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
var div = document.getElementById('radios');
|
||||
if (!wireless) {
|
||||
div.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
div.style.display = '';
|
||||
|
||||
var table = document.getElementById('radio-devices');
|
||||
while (table.lastChild)
|
||||
table.removeChild(table.lastChild);
|
||||
|
||||
wireless.sort(function (a, b) {
|
||||
return a.phy - b.phy;
|
||||
});
|
||||
|
||||
wireless.forEach(function (radio) {
|
||||
var tr = document.createElement('tr');
|
||||
|
||||
var th = document.createElement('th');
|
||||
th.textContent = "phy" + radio.phy;
|
||||
tr.appendChild(th);
|
||||
|
||||
var td = document.createElement('td');
|
||||
td.innerHTML = radio.frequency + " MHz<br />Channel " + 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;
|
||||
|
@ -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 (
|
||||
|
@ -44,7 +44,6 @@ $Id$
|
||||
|
||||
<div class="gluon-page-actions">
|
||||
<input type="hidden" name="step" value="2" />
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>" />
|
||||
</div>
|
||||
</form>
|
||||
|
@ -49,13 +49,11 @@ You may obtain a copy of the License at
|
||||
<form method="post" enctype="multipart/form-data" action="<%|url(request)%>" style="display:inline">
|
||||
<input type="hidden" name="step" value="3" />
|
||||
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" />
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Continue%>" />
|
||||
</form>
|
||||
<form method="post" enctype="multipart/form-data" action="<%|url(request)%>" style="display:inline">
|
||||
<input type="hidden" name="step" value="1" />
|
||||
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" />
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input class="gluon-button gluon-button-reset" type="submit" value="<%:Cancel%>" />
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<form method="post" enctype="multipart/form-data" action="<%|url(request)%>" data-update="reset">
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input type="hidden" name="<%=id%>" value="1" />
|
||||
|
||||
<div class="gluon-form" id="form-<%=id%>">
|
||||
|
@ -1,6 +1,7 @@
|
||||
<div id="<%=id%>" class="gluon-osm-map" style="display: none"></div>
|
||||
<script type="text/javascript" src="/static/gluon-web-osm.js"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function() {
|
||||
var elMap = document.getElementById(<%=json(id)%>);
|
||||
var wrapper = elMap.parentNode;
|
||||
@ -41,4 +42,5 @@
|
||||
});
|
||||
});
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
|
@ -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 = {}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,24 @@
|
||||
From: Martin Weinelt <martin@darmstadt.freifunk.net>
|
||||
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
|
Loading…
Reference in New Issue
Block a user