feat: publish av-tools 0.1.0
This commit is contained in:
25
deployment/caddy.example
Normal file
25
deployment/caddy.example
Normal file
@@ -0,0 +1,25 @@
|
||||
tools.example.test {
|
||||
header {
|
||||
X-Content-Type-Options "nosniff"
|
||||
Referrer-Policy "no-referrer"
|
||||
X-Frame-Options "DENY"
|
||||
Cross-Origin-Opener-Policy "same-origin"
|
||||
Cross-Origin-Embedder-Policy "require-corp"
|
||||
Cross-Origin-Resource-Policy "same-origin"
|
||||
Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()"
|
||||
Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' blob: data:; media-src 'self' blob:; font-src 'self'; style-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'"
|
||||
Cache-Control "no-cache"
|
||||
}
|
||||
|
||||
@wasm path_regexp wasm \.wasm$
|
||||
header @wasm Content-Type "application/wasm"
|
||||
|
||||
@immutable path_regexp immutable ^/av/(?:vendor/ffmpeg/0\.12\.10/(?:st|mt)/ffmpeg-core(?:\.worker)?\.(?:js|wasm)|assets/.*-[A-Za-z0-9_-]{8,}\.[^/]+)$
|
||||
header @immutable Cache-Control "public, max-age=31536000, immutable"
|
||||
|
||||
redir /av /av/ 308
|
||||
handle_path /av/* {
|
||||
root * /srv/av-tools
|
||||
file_server
|
||||
}
|
||||
}
|
||||
76
deployment/headers.md
Normal file
76
deployment/headers.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Static-hosting headers
|
||||
|
||||
Serve the release over HTTPS. Apply these headers to the app entry, wrapper
|
||||
worker, both core modes and every generated result page:
|
||||
|
||||
```text
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
Cross-Origin-Resource-Policy: same-origin
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
X-Frame-Options: DENY
|
||||
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' blob: data:; media-src 'self' blob:; font-src 'self'; style-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'
|
||||
```
|
||||
|
||||
The multithread core requires all three cross-origin headers. Without them the
|
||||
app must select the single-thread core; the rest of the app still works. Never
|
||||
add broad `'unsafe-eval'`: WebAssembly needs only `'wasm-unsafe-eval'`.
|
||||
|
||||
Response types:
|
||||
|
||||
```text
|
||||
*.wasm Content-Type: application/wasm
|
||||
*.js Content-Type: text/javascript
|
||||
*.mjs Content-Type: text/javascript
|
||||
*.json Content-Type: application/json
|
||||
```
|
||||
|
||||
All FFmpeg JS/WASM/worker files must be same-origin. A CDN requires careful
|
||||
cross-origin resource policy and is outside the supported deployment profile.
|
||||
|
||||
Use `no-cache` for `index.html`, `toolbox-app.json`, notices and other stable
|
||||
names. The files under the exact version directory
|
||||
`vendor/ffmpeg/0.12.10/{st,mt}/` are content-verified and may use:
|
||||
|
||||
```text
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
```
|
||||
|
||||
Vite files whose names include their content hash under `assets/` may use the
|
||||
same immutable policy. Do not make mutable or unversioned files immutable.
|
||||
|
||||
For a host with a `_headers`-style configuration, adapt:
|
||||
|
||||
```text
|
||||
/av/*
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
Cross-Origin-Resource-Policy: same-origin
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: no-referrer
|
||||
X-Frame-Options: DENY
|
||||
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' blob: data:; media-src 'self' blob:; font-src 'self'; style-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'
|
||||
Cache-Control: no-cache
|
||||
|
||||
/av/vendor/ffmpeg/0.12.10/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/av/assets/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
```
|
||||
|
||||
Confirm the provider can override `.wasm` to `application/wasm`; many
|
||||
`_headers` formats set headers but cannot correct MIME mappings. Validate a
|
||||
real response rather than relying only on configuration:
|
||||
|
||||
```sh
|
||||
curl -sSI https://tools.example.test/av/ | sed -n '1,30p'
|
||||
curl -sSI https://tools.example.test/av/vendor/ffmpeg/0.12.10/st/ffmpeg-core.wasm | sed -n '1,30p'
|
||||
```
|
||||
|
||||
In browser developer tools, also verify `window.crossOriginIsolated === true`,
|
||||
that core URLs remain below the nested `/av/` path, and that no runtime request
|
||||
targets a CDN.
|
||||
63
deployment/nginx.example.conf
Normal file
63
deployment/nginx.example.conf
Normal file
@@ -0,0 +1,63 @@
|
||||
# Complete server example. Place av-tools at /srv/www/av/ to serve it from
|
||||
# https://tools.example.test/av/. Adjust only the hostname and filesystem root.
|
||||
|
||||
map $uri $av_tools_cache_control {
|
||||
default "no-cache";
|
||||
"~^/(?:.*/)?vendor/ffmpeg/0\.12\.10/(?:st|mt)/ffmpeg-core(?:\.worker)?\.(?:js|wasm)$" "public, max-age=31536000, immutable";
|
||||
"~^/(?:.*/)?assets/.*-[A-Za-z0-9_-]{8,}\.[^/]+$" "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name tools.example.test;
|
||||
root /srv/www;
|
||||
|
||||
# Configure ssl_certificate/ssl_certificate_key or the surrounding proxy.
|
||||
|
||||
server_tokens off;
|
||||
charset utf-8;
|
||||
etag on;
|
||||
|
||||
# Explicit types avoid serving WASM or ES modules as octet-stream.
|
||||
types {
|
||||
text/html html;
|
||||
text/css css;
|
||||
text/javascript js mjs;
|
||||
application/json json;
|
||||
application/wasm wasm;
|
||||
image/svg+xml svg;
|
||||
image/png png;
|
||||
image/jpeg jpg jpeg;
|
||||
image/gif gif;
|
||||
image/webp webp;
|
||||
image/x-icon ico;
|
||||
font/woff woff;
|
||||
font/woff2 woff2;
|
||||
}
|
||||
default_type application/octet-stream;
|
||||
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' blob: data:; media-src 'self' blob:; font-src 'self'; style-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'" always;
|
||||
add_header Cache-Control $av_tools_cache_control always;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types application/json application/wasm image/svg+xml text/css text/javascript text/plain;
|
||||
|
||||
location = /av {
|
||||
return 308 /av/;
|
||||
}
|
||||
|
||||
# No SPA fallback is needed: all release resources are real static files.
|
||||
location /av/ {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user