|
|
4 dní pred | |
|---|---|---|
| .. | ||
| data | 4 dní pred | |
| .htaccess | 4 dní pred | |
| README.md | 4 dní pred | |
| index.php | 4 dní pred | |
A small temporary file drop in the spirit of transfer.sh, but plain PHP — no Go binary, no daemon, no database. One script, one storage folder.
curl --upload-file ./hello.txt https://tool.medowar.de/drop/
The response body is the download URL:
https://tool.medowar.de/drop/9f2c1ab73d40/hello.txt
Mind the trailing slash — curl --upload-file only appends the local
filename when the URL ends in /. Without it the file is stored as
upload.bin (or as whatever X-Filename: says).
Optional request headers:
| Header | Meaning |
|---|---|
Max-Days: 1 |
Expire after 1 days instead of the default 3 (max 30). |
Max-Downloads: 1 |
One-shot link — deleted after that many downloads. |
X-Filename: name.txt |
Filename when the URL carries none. |
Show the response headers to get the delete URL:
curl -D- -H 'Max-Downloads: 1' --upload-file ./secret.zip https://tool.medowar.de/drop/
X-Url-Delete: https://tool.medowar.de/drop/d/9f2c1ab73d40/8f3c…
X-Expires: Wed, 19 Aug 2026 09:12:44 GMT
Delete early:
curl -X DELETE https://tool.medowar.de/drop/d/9f2c1ab73d40/8f3c…
Opening that delete URL in a browser shows a confirmation page instead of deleting straight away, so link previews and prefetchers can't wipe a file.
There is also a browser UI at /drop/ with drag & drop and an upload progress
bar, and ?meta=1 on a download URL returns the file's metadata as JSON.
Every file gets an expiry timestamp at upload time (default 14 days). Expired files are refused on download and physically removed by a sweep that runs on roughly every 20th request — there is no cron job to set up. If the drop is idle for a long time, files simply linger on disk until the next request; add a cron entry if you want that tightened:
*/30 * * * * curl -sf -o /dev/null https://tool.medowar.de/drop/
| File | Purpose |
|---|---|
index.php |
Everything: router, upload, download, delete, web UI. |
.htaccess |
Rewrites all paths to index.php, raises LimitRequestBody. |
data/ |
One directory per file: blob + meta.json. Git-ignored. |
data/.htaccess |
Denies direct web access to stored files. |
Set at the top of index.php:
| Constant | Default | Meaning |
|---|---|---|
MAX_FILE_BYTES |
512 MB | Per file. Keep LimitRequestBody in .htaccess in sync. |
MAX_TOTAL_BYTES |
10 GB | Whole drop; further uploads get a 507. |
DEFAULT_DAYS |
3 | Default expiry. |
MAX_DAYS |
30 | Ceiling for Max-Days. |
MAX_PER_IP_HOUR |
60 | Uploads per IP per hour. |
GC_CHANCE |
20 | 1-in-N requests sweep expired files. |
Max-Downloads: 1 for anything sensitive — or encrypt before uploading.application/octet-stream with
Content-Disposition: attachment and nosniff. This host serves other tools
from the same origin, so an uploaded .html must never render here.memory_limit is not the
constraint; LimitRequestBody and the PHP max_execution_time are.upload_max_filesize / post_max_size only apply to the browser form
fallback — a raw PUT body bypasses PHP's multipart parser entirely.blob, so the client's name never
touches the filesystem.