PUT requests for zero-byte files get 'Transfer-Encoding': 'chunked' header

Aperta
#6,294 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
python
Ambito
api

Direzione di ricerca

Inizia riproducendo il problema tramite i punti di ingresso requests.put o session.put con un file vuoto, quindi esamina gli header della richiesta preparata e il percorso di transfer-encoding. Il lavoro è completato quando un PUT vuoto invia Content-Length: 0 senza Transfer-Encoding: chunked, anche quando Content-Length viene fornito esplicitamente, con una copertura di regressione per i casi segnalati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Context: uploading files to AWS S3 via requests. Files may be empty. When attempting to upload an empty file, a response of 501: Not implemented is received. This seems to be because, when content length is 0, a Transfer-Encoding: chunked header is automatically added. S3 does not support the encoding.

Expected Result

When an empty file PUT is attempted via requests.put, a Content-Length: 0 header should be set on the request. A Transfer-Encoding: chunked header should not be set automatically.

Actual Result

When an empty file PUT is attempted via requests.put, a Transfer-Encoding: chunked header is set. No Content-Length header is set. If a Content-Length: 0 header is set explicitly, the Transfer-Encoding: chunked header is still set.

Reproduction Steps

If AWS account, bucket, credentials for principal with PutObject permissions aren't available:

import requests

file = open(<path_to_empty_file>, "rb")
session = requests.session()

link = "http://httpbin.org/put"

# using requests.put yields the same results. Using session.put here to examine request
# with S3 instead of httpbin.org, the call below results in a 501. Note the request headers
res_no_CL = session.put(link, data=file, headers={"Content-Type": "text/plain"})
print(res_no_CL.request.headers)
# with S3 instead of httpbin.org, the call below results in a 501. With httpbin.org it returns
# ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
# so can't examine headers, but I assume behaviour is consistent
res_explicit_CL = session.put(link, data=file, headers={"Content-Type": "text/plain", "Content-Length": "0"})
print(res_explicit_CL.request.headers)

If AWS prerequisites above are available:

import requests
import boto3

s3 = boto3.client('s3')
file = open(<path_to_empty_file>, "rb")
session = requests.session()

link = s3.generate_presigned_url(ClientMethod="put_object", Params={"Bucket": "<your_bucket>", "Key": "<path_in_bucket>", "ContentType": "text/plain"})

# using requests.put yields the same results. Using session.put here to examine request
# the call below results in a 501. Note the request headers
res_no_CL = session.put(link, data=file, headers={"Content-Type": "text/plain"})
print(res_no_CL.request.headers)
# the call below results in a 501. Note the request headers
res_explicit_CL = session.put(link, data=file, headers={"Content-Type": "text/plain", "Content-Length": "0"})
print(res_explicit_CL.request.headers)

System Information

$ python -m requests.help
{
  "chardet": {
    "version": null
  },
  "charset_normalizer": {
    "version": "2.1.1"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.4"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.9.5"
  },
  "platform": {
    "release": "5.10.102.1-microsoft-standard-WSL2",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.28.1"
  },
  "system_ssl": {
    "version": "1010106f"
  },
  "urllib3": {
    "version": "1.26.12"
  },
  "using_charset_normalizer": true,
  "using_pyopenssl": false
}
Lingua principale
Python
Stelle
54.7k
Fork
10.8k
Merge medio
18m
PR unite (30g)
1

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di psf/requests

Tutte le issue di psf/requests

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.