bug: WebDAV writer rejects streaming writes larger than one buffer
- Dominant language
- Rust
- Stars
- 5.4k
- Forks
- 825
- Avg merge
- 1d 14m
- Merged PRs (30d)
- 127
Description
### OpenDAL version or commit
v0.58.1 (the same one-shot writer is still present on main)
### Affected service or component
services/webdav against a dav-server WebDAV endpoint
### Describe the bug
The WebDAV writer is a one-shot writer (`oio::OneShotWriter`). One writer only accepts a single `write` call, so any streaming write that exceeds one internal buffer (256 KiB) fails with:
```
Unsupported (permanent) at write => OneShotWriter doesn't support multiple write
Context:
service: webdav
path: ...
size: 262144
written: 262144
```
`FuturesAsyncWriter` (returned by `Operator::writer(...).into_futures_async_write()`) flushes its 256 KiB buffer by calling `write` again, which the one-shot writer rejects. As a result, a single writer cannot upload files larger than 256 KiB.
### Steps to Reproduce
```rust
use futures::AsyncWriteExt;
let mut writer = op.writer("big.bin").await?.into_futures_async_write();
writer.write_all(&vec![0u8; 600 * 1024]).await?; // fails with the error above
writer.close().await?;
```
Reproduced against a real `dav-server` WebDAV endpoint (`dav_server::localfs::LocalFs`) through `opendal::services::Webdav`.
### Actual Behavior
The second `write` on the same writer fails with `Unsupported (permanent) at write => OneShotWriter doesn't support multiple write`.
### Expected Behavior
A single writer accepts multiple writes and uploads the data in ordered chunks (for example, the first chunk with a regular PUT and the following chunks with partial PUTs carrying `Content-Range`), and the service reports `write_can_multi = true`.
### Additional Context
`write_can_multi` is currently `false` for webdav even though `Operator::writer` hands users a writer they can write to multiple times. `write_total_max_size` / server support for partial PUTs may need to be documented as part of the fix.
### Reproduction confirmation
- [x] I reproduced this issue against the affected component. For a service-specific report, I used the actual service rather than only a mock, emulator, or source-code analysis.
### Are you willing to submit a PR to fix this bug?
- [x] Yes, I would like to submit a PR.
Contributor guide
Research direction
Start with the services/webdav writer and the Operator::writer(...).into_futures_async_write() entry point, then trace how write_can_multi is reported. Reproduce the 600 KiB streaming write against a dav-server endpoint and verify that multiple ordered writes succeed, including the documented partial-PUT and size-limit behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100