aio-libs / aio-libs/aiohttp

MultipartWriter.as_bytes() does not apply part Content-Encoding / Content-Transfer-Encoding, diverging from write()

Aperta
#13,495 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug
Lingua principale
Python
Stelle
16.5k
Fork
2.4k
Merge medio
17h 22m
PR unite (30g)
212

Descrizione

### Describe the bug

When a part appended to a non-form-data `MultipartWriter` carries `Content-Encoding` (gzip/deflate) or `Content-Transfer-Encoding` (base64/quoted-printable), `write()` compresses/encodes the part on the wire via `MultipartPayloadWriter`, but `as_bytes()` returns the raw, untransformed part content. The result contradicts the part's own headers and does not match the body a server actually receives.

This also breaks digest authentication with `qop=auth-int` for such bodies: the middleware hashes `await body.as_bytes()` (`client_middleware_digest_auth.py`), so the entity hash never matches what is sent, and authentication always fails.

### To Reproduce

```python
import asyncio
from aiohttp import MultipartWriter, payload

class Buf:
def __init__(self): self.data = bytearray()
async def write(self, chunk): self.data.extend(chunk)

async def main():
mp = MultipartWriter("mixed", boundary="XBOUND")
part = payload.StringPayload("hello world")
part.headers["Content-Encoding"] = "gzip"
mp.append_payload(part)
buf = Buf()
await mp.write(buf)
print("wire == as_bytes():", bytes(buf.data) == await mp.as_bytes())

asyncio.run(main())
```

Output: `wire == as_bytes(): False` — `as_bytes()` contains the literal `hello world` after headers declaring `Content-Encoding: gzip`.

### Expected behavior

`as_bytes()` returns the same bytes `write()` produces, per its docstring ("bytes representation of the multipart data").

### aiohttp Version

Reproduced on 3.14.3 and current master (4.0.0a2.dev0). Introduced with `as_bytes()` in #11017.

### Root cause

`MultipartWriter.as_bytes()` in `aiohttp/multipart.py` iterates `self._parts` ignoring the stored `encoding`/`te_encoding` values that `write()` honors.

### Related component

Client

I have a fix ready and will open a PR.

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.