Aiohttp: Não é possível acessar facilmente max_field_size na resposta do cliente

Criado em 7 out. 2017  ·  5Comentários  ·  Fonte: aio-libs/aiohttp

Longa história curta

O cliente http realmente não suporta a substituição do comprimento do valor do cabeçalho padrão de 8190, mesmo que o parâmetro do analisador esteja lá https://github.com/aio-libs/aiohttp/blob/e7c9390111932dd6dbb642170d7a0da1876271ec/aiohttp/http_parser.py#L59

Isso resulta na mensagem de erro:

aiohttp.client_exceptions.ClientResponseError: 400, message='Got more than 8190 bytes when reading Header value is too long.'

Stack trace do aplicativo real:

<snip>
File "/usr/local/lib/python3.6/site-packages/pyportify/google.py", line 113, in _http_get
params=merged_params,
File "/usr/local/lib/python3.6/site-packages/aiohttp/helpers.py", line 97, in iter
ret = yield from self._coro
File "/usr/local/lib/python3.6/site-packages/aiohttp/client.py", line 241, in _request
yield from resp.start(conn, read_until_eof)
File "/usr/local/lib/python3.6/site-packages/aiohttp/client_reqrep.py", line 564, in start
message=exc.message, headers=exc.headers) from exc
aiohttp.client_exceptions.ClientResponseError: 400, message='Got more than 8190 bytes when reading Header value is too long.'

Comportamento esperado

Eu posso definir o analisador na solicitação de sessão/obter ou definir o max_field_size.

Comportamento real

eu também não consigo

Passos para reproduzir

Eu acredito que isso vai fazer isso:

import aiohttp
import asyncio

@asyncio.coroutine
def main():
        with aiohttp.ClientSession() as session:
                resp = yield from session.get('http://test.xr6.me')
                print(len(resp.headers['X-TEST-HEADER']))
                resp.close()

if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(
            asyncio.gather(main())
        )
        loop.close()

Seu ambiente

Ubuntu jessie (bash para windows, reproduz em outros embora)
python3.4 (também reproduz em outros)

Comentários muito úteis

Eu me deparei com isso esta noite, implantando a estrutura de bot do MS Teams (aiohttp) como um dos nossos microsserviços.
Como usamos OpenID/Oauth2, os atributos do usuário em seu cabeçalho x-userinfo quebram o limite de 8Kb.

Estamos bastante dependentes desses cabeçalhos assinados, pois eles são a única fonte de verdade em que confiamos na carga útil como não sendo adulterada, identificando o usuário, os escopos e os atributos que eles possuem.

Se houver suporte para essa mudança, um de nossos caras provavelmente pode tentar um PR?

Posso dizer que esses valores tendem a ser configuráveis, em nossa experiência
Bowsers : Chrome/ium suporta 250KB de headers, outros mainstream iguais ou maiores
Daemons HTTP flexíveis neste limite, via opções de configuração:

  • nginx - client_header_buffer_size 64k;
  • npm - "start": "react-scripts --max-http-header-size=60000 start"
  • gunicorn - limit_request_field_size: 65536
  • IIS: MaxFieldLength
  • Apache: LimitRequestFieldsize 65536

Todos 5 comentários

Infelizmente, o design do cliente atual não tem lugar para o parâmetro solicitado.
Após a conclusão do #2019, poderíamos voltar ao assunto.

Nosso objetivo não é ser mais generoso que um navegador? Não sei se os navegadores descartam essas longas linhas ou não, mas certamente não cometem erros. Nesse caso, 8190 é obviamente muito pequeno. Se não vamos tornar este limite configurável, aumentar muito é uma ótima solução.

Os navegadores IFAIK descartam silenciosamente as coisas que são mais longas do que o navegador espera.
A ignorância silenciosa não é uma opção para uma biblioteca IMHO, mas deve ser a coisa configurável.

Eu me deparei com isso esta noite, implantando a estrutura de bot do MS Teams (aiohttp) como um dos nossos microsserviços.
Como usamos OpenID/Oauth2, os atributos do usuário em seu cabeçalho x-userinfo quebram o limite de 8Kb.

Estamos bastante dependentes desses cabeçalhos assinados, pois eles são a única fonte de verdade em que confiamos na carga útil como não sendo adulterada, identificando o usuário, os escopos e os atributos que eles possuem.

Se houver suporte para essa mudança, um de nossos caras provavelmente pode tentar um PR?

Posso dizer que esses valores tendem a ser configuráveis, em nossa experiência
Bowsers : Chrome/ium suporta 250KB de headers, outros mainstream iguais ou maiores
Daemons HTTP flexíveis neste limite, via opções de configuração:

  • nginx - client_header_buffer_size 64k;
  • npm - "start": "react-scripts --max-http-header-size=60000 start"
  • gunicorn - limit_request_field_size: 65536
  • IIS: MaxFieldLength
  • Apache: LimitRequestFieldsize 65536

Eu iria em frente e faria o PR, já vi coisas semelhantes serem aceitas antes.

Esta página foi útil?
0 / 5 - 0 avaliações