AlistGo / AlistGo/alist

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

Abierto
#9,606 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Go
Estrellas
50.2k
Forks
7.9k
Merge medio
7 d 21 h
PR fusionados (30 d)
6

Descripción

### 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)

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.