Files
webdav-handler-rs/doc/Apache-PUT-with-Content-Range.md

86 lines
2.9 KiB
Markdown

# HTTP PUT-with-Content-Range support.
The [mod_dav](https://httpd.apache.org/docs/2.4/mod/mod_dav.html) module of
the [Apache web server](https://httpd.apache.org/) was one of the first
implementations of [Webdav](https://tools.ietf.org/html/rfc4918). Ever since
the first released version, it has had support for partial uploads using
the Content-Range header with PUT requests.
## A sample request
```text
PUT /file.txt
Content-Length: 4
Content-Range: bytes 3-6/*
ABCD
```
This request updates 'file.txt', specifically the bytes 3-6 (inclusive) to
`ABCD`.
There is no explicit support for appending to a file, that is simply done
by writing just past the end of a file. For example, if a file has size
1000, and you want to append 4 bytes:
```text
PUT /file.txt
Content-Length: 4
Content-Range: bytes 1000-1003/*
1234
```
## Apache `mod_dav` behaviour:
- The `Content-Range` header is required, and the syntax is `bytes START-END/LENGTH`.
- END must be bigger than or equal to START.
- LENGTH is parsed by Apache mod_dav, and it must either be a valid number
or a `*` (star), but mod_dav otherwise ignores it. Since it is not clearly
defined what LENGTH should be, always use `*`.
- Neither the start, nor the end-byte have to be within the file's current size.
- If the start-byte is beyond the file's current length, the space in between
will be filled with NULL bytes (`0x00`).
## Notes
- `bytes<space>`, _not_ `bytes=`.
- The `Content-Length` header is not required by the original Apache mod_dav
implementation. The body must either have a valid Content-Length, or it must
use the `Chunked` transfer encoding. It is *strongly encouraged* though to
include Content-Length, so that it can be validated against the range before
accepting the PUT request.
- If the `Content-Length` header is present, its value must be equal
to `END - START + 1`.
## Status codes
### The following status codes are used:
Status code | Reason
----------- | ------
200 or 204 | When the operation was successful
400 | Invalid `Content-Range` header
416 | If there was something wrong with the bytes, such as a `Content-Length` not matching with what was sent as the start and end bytes, or an end byte being lower than the start byte.
501 | Content-Range header present, but not supported.
## RECKOGNIZING PUT-with-Content-Range support (client).
There is no official way to know if PUT-with-content-range is supported by
a webserver. For a client it's probably best to do an OPTIONS request,
and then check two things:
- the `Server` header must contain the word `Apache`
- the `DAV` header must contain `<http://apache.org/dav/propset/fs/1>`.
In that case, your are sure to talk to an Apache webserver with mod_dav enabled.
## IMPLEMENTING PUT-with-Content-Range support (server).
Don't. Implement [sabredav-partialupdate](SABREDAV-partialupdate.md).
## MORE INFORMATION.
https://blog.sphere.chronosempire.org.uk/2012/11/21/webdav-and-the-http-patch-nightmare