Werkzeug: Solicitações fragmentadas ainda não funcionam

Criado em 16 jul. 2017  ·  4Comentários  ·  Fonte: pallets/werkzeug

(Atualizado porque percebi que estava tentando consertar isso, então fiquei confuso com o problema original e o problema que me fez desistir)

Estou fazendo uma solicitação em partes para um aplicativo que usa Werkzeug (git master atual). get_input_stream acaba chamando LimitedStream(wsgi.input, min(content_length, max_content_length)) . min(content_length, max_content_length) sempre será Nenhum se usar codificação em partes.

Em uma tentativa de progredir, tentei usar LimitedStream(stream, content_length or max_content_length) , mas acabei obtendo uma exceção ClientDisconnected , porque não podemos dizer a diferença entre a desconexão de um cliente e a solicitação em partes simplesmente realizada , como wsgi.input.read() apenas retorna uma string de comprimento 0 em ambos os casos.

bug

Comentários muito úteis

Qual wsgi suporta atualmente input_terminated ? Depois de queimar o dia todo na depuração de porque os dados estão vazios, então porque o stream está vazio e então perceber que é devido à codificação de stream em partes, agora não consigo encontrar nada que suporte isto: /

Todos 4 comentários

Isso é mais do que um simples bug com min . Depois de consertar isso, o problema é que fazer wsgi.input.read(max_content_length) com blocos de Werkzeug para sempre se houver menos de max_content_length para ler. Ou usando Gunicorn, que oferece suporte a fragmentos analisando e armazenando em buffer a mensagem inteira, o comprimento sai para menos de max_content_length , então LimitedStream pensa que o cliente desconectou.

Eu testei isso no Django apenas para ter certeza de que não estamos fazendo algo estranho, ele vê um fluxo vazio também.

A maneira mais simples de avançar é fornecer um middleware que configure environ['wsgi.input_terminated'] e dizer às pessoas para usá-lo quando usarem um servidor que suporte transferência em partes.

Qual wsgi suporta atualmente input_terminated ? Depois de queimar o dia todo na depuração de porque os dados estão vazios, então porque o stream está vazio e então perceber que é devido à codificação de stream em partes, agora não consigo encontrar nada que suporte isto: /

Além de verificar environ.get('wsgi.input_terminated') , devemos também verificar environ.get('HTTP_TRANSFER_ENCODING') == 'chunked' e, nesse caso, também retornar o fluxo não empacotado diretamente? Isso corrige problemas como um simples curl -H 'Transfer-Encoding: chunked' ... retornando um fluxo vazio.

Por RFC2616

4.4.2
Se um campo de cabeçalho Transfer-Encoding (seção 14.41) estiver presente e
tem qualquer valor diferente de "identidade", então o comprimento da transferência é
definido pelo uso da codificação de transferência "fragmentada" (seção 3.6),
a menos que a mensagem seja encerrada com o fechamento da conexão.

4.4.3
Se um campo de cabeçalho Content-Length (seção 14.13) estiver presente, seu
valor decimal em OCTETs representa o comprimento da entidade e o
comprimento de transferência. O campo de cabeçalho Content-Length NÃO DEVE ser enviado
se esses dois comprimentos forem diferentes (ou seja, se um Transfer-Encoding
campo de cabeçalho está presente). Se uma mensagem for recebida com um
Campo de cabeçalho Transfer-Encoding e campo de cabeçalho Content-Length,
o último DEVE ser ignorado.

... observando que Transfer-Encoding de chunked exige que qualquer cabeçalho Content-Length seja ignorado e, portanto, nenhum processamento de fluxo deve ser feito com base nele. Este é o caso atualmente, a menos que wsgi.input_terminated seja definido.

Deve realmente ser necessário definir wsgi.input_terminated para que a codificação normal em partes, por exemplo, de uma carga útil JSON de 10 bytes, funcione?

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

Questões relacionadas

davidism picture davidism  ·  9Comentários

alexgurrola picture alexgurrola  ·  5Comentários

paihu picture paihu  ·  7Comentários

SimonSapin picture SimonSapin  ·  12Comentários

d42 picture d42  ·  6Comentários