openvibers/openvibe.events Commits
openvibe.events: POST /release-metrics reaches the app (open tabs' release reports were refused 403 by the GET/HEAD catch-all) (#99)
Changes
@@@ -106,6 +106,9 @@ server {location = /api/ready { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }location = /release.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }location = /limits.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }++ # Open tabs report "a newer release took over" here (openvibe-shared release-watch, POST text/plain); the catch-all++ # below refuses every POST, so each report was a 403 (2026-10-17).++ location = /release-metrics { limit_except POST { deny all; } client_max_body_size 4k; proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }# Metrics are for host-local scrapers only (http://127.0.0.1:4300/metrics).location ~* ^/metrics(/|$) { return 404; }@@@ -185,7 +185,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no rediassert.ok(!conf.includes('$proxy_add_x_forwarded_for'), 'the client address is never appended to');// The product surface (plan expansion II) and everything the API host proxies (plan T7).for (const loc of ['location = / {', 'location ^~ /shared/ {', 'location = /robots.txt {', 'location = /sitemap.xml {', 'location = /llms.txt {', 'location = /llms-full.txt {',-- 'location = /realtime/stream {', 'location = /api/health', 'location = /api/ready', 'location = /release.json', 'location = /limits.json']) {++ 'location = /realtime/stream {', 'location = /api/health', 'location = /api/ready', 'location = /release.json', 'location = /limits.json', 'location = /release-metrics']) {assert.ok(conf.includes(loc), `${loc} is proxied`);}assert.ok(conf.includes('location ~ ^/api/v1/(events|subscriptions|checkpoints)(/|$)'), 'the token-guarded API block');@@@ -200,6 +200,8 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no rediassert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');++ // Open tabs' release reports are POSTs: their own location, POST only, small bodies.++ assert.match(conf, /location = \/release-metrics \{ limit_except POST \{ deny all; \} client_max_body_size 4k; proxy_pass http:\/\/127\.0\.0\.1:4300;/);assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf')), 'the retired events.openvibe.network vhost is gone (plan T7)');assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');});
@@ -106,6 +106,9 @@ server {
@@ -106,6 +106,9 @@ server {
location = /api/ready { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
location = /api/ready { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
location = /release.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
location = /release.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
location = /limits.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
location = /limits.json { proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
+ # Open tabs report "a newer release took over" here (openvibe-shared release-watch, POST text/plain); the catch-all
+ # below refuses every POST, so each report was a 403 (2026-10-17).
+ location = /release-metrics { limit_except POST { deny all; } client_max_body_size 4k; proxy_pass http://127.0.0.1:4300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header CF-Connecting-IP $remote_addr; }
# Metrics are for host-local scrapers only (http://127.0.0.1:4300/metrics).
# Metrics are for host-local scrapers only (http://127.0.0.1:4300/metrics).
location ~* ^/metrics(/|$) { return 404; }
location ~* ^/metrics(/|$) { return 404; }
@@ -185,7 +185,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
@@ -185,7 +185,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
assert.ok(!conf.includes('$proxy_add_x_forwarded_for'), 'the client address is never appended to');
assert.ok(!conf.includes('$proxy_add_x_forwarded_for'), 'the client address is never appended to');
// The product surface (plan expansion II) and everything the API host proxies (plan T7).
// The product surface (plan expansion II) and everything the API host proxies (plan T7).
for (const loc of ['location = / {', 'location ^~ /shared/ {', 'location = /robots.txt {', 'location = /sitemap.xml {', 'location = /llms.txt {', 'location = /llms-full.txt {',
for (const loc of ['location = / {', 'location ^~ /shared/ {', 'location = /robots.txt {', 'location = /sitemap.xml {', 'location = /llms.txt {', 'location = /llms-full.txt {',
- 'location = /realtime/stream {', 'location = /api/health', 'location = /api/ready', 'location = /release.json', 'location = /limits.json']) {
+ 'location = /realtime/stream {', 'location = /api/health', 'location = /api/ready', 'location = /release.json', 'location = /limits.json', 'location = /release-metrics']) {
assert.ok(conf.includes(loc), `${loc} is proxied`);
assert.ok(conf.includes(loc), `${loc} is proxied`);
}
}
assert.ok(conf.includes('location ~ ^/api/v1/(events|subscriptions|checkpoints)(/|$)'), 'the token-guarded API block');
assert.ok(conf.includes('location ~ ^/api/v1/(events|subscriptions|checkpoints)(/|$)'), 'the token-guarded API block');
@@ -200,6 +200,8 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
@@ -200,6 +200,8 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
assert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');
assert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');
assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');
assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');
assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');
assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');
+ // Open tabs' release reports are POSTs: their own location, POST only, small bodies.
+ assert.match(conf, /location = \/release-metrics \{ limit_except POST \{ deny all; \} client_max_body_size 4k; proxy_pass http:\/\/127\.0\.0\.1:4300;/);
assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf')), 'the retired events.openvibe.network vhost is gone (plan T7)');
assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf')), 'the retired events.openvibe.network vhost is gone (plan T7)');
assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');
assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');
});
});