[bug] `fetch` and `XHR` response has no `content-range` header
Closed this issue · 7 comments
Describe the bug
I don't know if it is intended or not but in both asset
protocol and the http
protocol the content-range
header is discarded in fetch
response. Without the content-range
header successive range requests cannot be performed such as in pdf.js.
This is a normal fetch
in macOS Safari browser:
And this is a fetch
in Tauri app in macOS:
The static HTTP server http://localhost:9000
is started with http-server -p 9000 -d . --cors
for testing purpose.
And the asset
protocol is also affected in Tauri app.
Note that in the network inspector the content-range
header is present but it's like being discarded somewhere in the fetch
response.
I also try to figure out where the response headers are intercepted. At least the wry
layer hold the intact headers:
[2024-10-15][14:44:11][wry::wkwebview::class::url_scheme_handler][INFO] wry::custom_protocol::handle; uri="asset://localhost/%2FUsers%2Fchrox%2FDocuments%2FReadest%2FBooks%2F3ec18259cf5e8a916a553f14ebf4f7d3%2Fl11manual_zh.pdf"
[2024-10-15][14:44:11][tracing::span][INFO] wry::custom_protocol::call_handler;
response headers: {
"content-type": "application/pdf",
"content-range": "bytes 0-65535/91848117",
"accept-ranges": "bytes",
"application/pdf": "content-type",
"content-length": "65536",
"65536": "content-length",
"access-control-allow-origin": "http://localhost:3000",
}
Let's set aside for now these two malformed headers "65536": "content-length" and "application/pdf": "content-type"
that were introduced by recent code refactoring of wry; the wry
url_scheme_handler writes the correct content-range
header. I tried to add Access-Control-Allow-Headers: *
or Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Range
in tauri/src/protocol/asset.ts
but it makes no difference on the response headers of fetch
and XHR
. I have no clue on how the response headers are sent to the Javascript world. Could someone give a hint?
Reproduction
No response
Expected behavior
No response
Full tauri info
output
> tauri "info"
[✔] Environment
- OS: Mac OS 14.3.1 arm64 (X64)
✔ Xcode Command Line Tools: installed
✔ rustc: 1.81.0 (eeb90cda1 2024-09-04)
✔ cargo: 1.81.0 (2dbb1af80 2024-08-20)
✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
✔ Rust toolchain: stable-aarch64-apple-darwin (default)
- node: 22.9.0
- pnpm: 9.12.1
- yarn: 1.22.22
- npm: 10.8.3
[-] Packages
- tauri 🦀: 2.0.3
- tauri-build 🦀: 2.0.1
- wry 🦀: 0.46.1
- tao 🦀: 0.30.3
- @tauri-apps/api : 2.0.2
- @tauri-apps/cli : 2.0.3
[-] Plugins
- tauri-plugin-http 🦀: 2.0.1
- @tauri-apps/plugin-http : 2.0.0
- tauri-plugin-os 🦀: 2.0.1
- @tauri-apps/plugin-os : 2.0.0
- tauri-plugin-fs 🦀: 2.0.1
- @tauri-apps/plugin-fs : 2.0.0
- tauri-plugin-log 🦀: 2.0.1
- @tauri-apps/plugin-log : 2.0.0
- tauri-plugin-dialog 🦀: 2.0.1
- @tauri-apps/plugin-dialog : 2.0.0
[-] App
- build-type: bundle
- CSP: style-src 'self' 'unsafe-inline' blob: asset: http://asset.localhost; default-src 'self' 'unsafe-inline' blob: customprotocol: asset: http://asset.localhost ipc: http://ipc.localhost; frame-src 'self' blob: asset: http://asset.localhost; img-src 'self' blob: data: asset: http://asset.localhost
- frontendDist: ../out
- devUrl: http://localhost:3000/
- framework: React (Next.js)
- bundler: Webpack
Stack trace
No response
Additional context
No response
This is my app.security
in tauri.conf.json
:
"security": {
"csp": {
"default-src": "'self' 'unsafe-inline' blob: customprotocol: asset: http://asset.localhost ipc: http://ipc.localhost",
"img-src": "'self' blob: data: asset: http://asset.localhost",
"style-src": "'self' 'unsafe-inline' blob: asset: http://asset.localhost",
"frame-src": "'self' blob: asset: http://asset.localhost"
},
"assetProtocol": {
"enable": true,
"scope": {
"allow": ["$RESOURCE/**", "$DOCUMENT/**/*", "$APPDATA/**/*", "$TEMP/**/*"],
"deny": []
}
}
}
And this is the capability config:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": ["main"],
"permissions": [
"core:default",
"fs:default",
{
"identifier": "fs:scope-document-recursive",
"allow": [
{
"path": "$DOCUMENT/**/*"
}
],
"deny": []
},
{
"identifier": "fs:scope-appdata-recursive",
"allow": [
{
"path": "$APPDATA/Readest/**/*"
}
],
"deny": []
},
{
"identifier": "fs:allow-appdata-read",
"allow": [
{
"path": "$APPDATA/settings.json"
}
]
},
{
"identifier": "fs:allow-appdata-write",
"allow": [
{
"path": "$APPDATA/settings.json"
}
]
},
"dialog:default",
"os:default",
"http:default"
]
}
@chrox feel free to open a PR and @tweidinger will take a look from security prespective.
Let's set aside for now these two malformed headers
"65536": "content-length" and "application/pdf": "content-type"
that were introduced by recent code refactoring of wry;
Could you open an issue or better a PR if you have a fix?
Sure.
According to MDN on Access-Control-Expose-Headers, content-range
is not a simple response header
and not exposed to client scripts by default in CORS response except that it's listed in the Access-Control-Expose-Headers
header. The first example I provided above however is not a CORS request thus not affected.
It sounds pretty safe to expose the content-range
header in a range
request in the asset
protocol. I'm opening a PR to do this.