Local driver FsStream (/api/fs/put) fails with strconv.ParseInt error when Content-Length header is absent
- Lingua principale
- Go
- Stelle
- 50.2k
- Fork
- 7.9k
- Merge medio
- 7g 21h
- PR unite (30g)
- 6
Descrizione
### Describe the bug
`PUT /api/fs/put` (used by the web UI's "create new file" button) fails with a 400 error whenever the incoming HTTP request does not carry an explicit `Content-Length` header (e.g. a zero-byte body sent without that header, or a request proxied through Cloudflare Tunnel / any reverse proxy that drops/transforms the header for empty bodies).
The error returned is:
```json
{"code":400,"message":"strconv.ParseInt: parsing \"\": invalid syntax","data":null}
```
### Root cause
In `server/handles/fsup.go`, `FsStream` reads the `Content-Length` header directly from `gin.Context` and parses it with `strconv.ParseInt`, with no fallback for a missing/empty header:
```go
sizeStr := c.GetHeader("Content-Length")
size, err := strconv.ParseInt(sizeStr, 10, 64)
if err != nil {
common.ErrorResp(c, err, 400)
return
}
```
If `Content-Length` is not present (returns `""`), `strconv.ParseInt("", 10, 64)` always fails, and the whole upload/create-file request is rejected with a generic parse error instead of falling back to `c.Request.ContentLength` (which Go's net/http already parses reliably, including for HTTP/2 requests where Content-Length is not delivered as a literal header at all) or defaulting to 0 for an empty body.
### Steps to reproduce
1. Run Alist (tested on v3.62.0 and v3.63.0, linux/arm64) with a Local storage mounted.
2. Send a PUT request to `/api/fs/put` with a valid `File-Path` header and an empty body, but without an explicit `Content-Length` header, e.g.:
```
PUT /api/fs/put HTTP/1.1
Host: 127.0.0.1:5244
File-Path: /mydrive/test.txt
Authorization:
```
3. Observe the response:
```json
{"code":400,"message":"strconv.ParseInt: parsing \"\": invalid syntax","data":null}
```
4. This also reproduces reliably through Cloudflare Tunnel (`cloudflared tunnel --url http://127.0.0.1:5244`) when using the web UI's "New file" feature to create an empty file, because Cloudflare's HTTP/2-to-HTTP/1.1 proxying does not always forward a literal `Content-Length: 0` header for the resulting request.
Uploading a file with actual content (non-zero body length) works fine in all cases, and creating a folder is unaffected. Only creating a new empty file via the web UI / raw API call without a `Content-Length` header is broken.
### Expected behavior
Creating an empty file should succeed (treating a missing `Content-Length` as size 0), consistent with how folder creation behaves, and consistent with the fact that `c.Request.ContentLength` is already populated by Go's `net/http`/`http2` stack independent of the literal header being present.
### Suggested fix
Use `c.Request.ContentLength` instead of (or as a fallback for) parsing the header string, e.g.:
```go
size := c.Request.ContentLength
if size < 0 {
size = 0
}
```
### Environment
- Alist version: v3.62.0 and v3.63.0 (both reproduce)
- OS/Arch: Debian 13 (trixie), linux/arm64
- Storage driver: Local
- Reverse proxy: reproduced both directly (raw TCP request without Content-Length) and through Cloudflare Tunnel (quick tunnel, http2 protocol)
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.