AlistGo / AlistGo/alist

Local driver FsStream (/api/fs/put) fails with strconv.ParseInt error when Content-Length header is absent

Aperta
#9,606 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
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.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.