A redefinição da conexão TCP ocorre quando o aplicativo WSGI responde antes de consumir o Environ ['wsgi.input'

StackOverflow https://stackoverflow.com/questions/2099752

Pergunta

Para o nosso serviço da web, escrevi uma lógica para prevenir multipart/form-data Postagens maiores que, digamos, 4 MB.

Tudo se resume ao seguinte (eu tirei todo o uso do webob e apenas reduzi para o código WSGI de baunilha simples):

import paste.httpserver

form = """\
<html>
<body>
  <form method="post" enctype="multipart/form-data" action="/">
    <input type="file" name="photopicker" />
    <input type="submit" />
  </form>
</body>
</html>
"""

limit = 4 * 1024 * 1024

def upload_app(environ, start_response):
    if environ['REQUEST_METHOD'] == 'POST':
        if int(environ.get('CONTENT_LENGTH', '0')) > limit:
            start_response('400 Ouch', [('content-type', 'text/plain')])
            return ["Upload is too big!"]
    # elided: consume the file appropriately
    start_response('200 OK', [('content-type', 'text/html')])
    return [form]

paste.httpserver.serve(upload_app, port=7007)

A lógica mostrada funciona bem quando a unidade foi testada. Mas assim que tentei enviar arquivos reais maiores que 4 MB para esse ponto de extremidade, recebi erros como esses no lado do cliente:

  • Error 101 (net::ERR_CONNECTION_RESET): Unknown error. Do Google Chrome
  • The connection to the server was reset while the page was loading. de Firefox

O mesmo erro ocorre ao usar o python embutido wsgiref Servidor HTTP.

Fato: uma vez que eu adicionei environ['wsgi.input'].read() Pouco antes de responder com o HTTP 400, o problema de redefinição da conexão desapareceu. Claro, essa não é uma boa solução. Ele apenas mostra o que acontece quando você consome completamente a entrada.

Eu vi Http: o guia definitivo e encontrou algumas diretrizes interessantes sobre como era importante manifestar as conexões TCP cuidadosamente ao implementar servidores e clientes HTTP. Continuou sobre como, em vez de close-ing soquete, era preferido fazer shutdown, para que o cliente tenha chance de reagir e parar de enviar mais dados ao servidor.

Talvez eu esteja perdendo alguns detalhes cruciais de implementação que impede essas redefinições de conexão. Insights alguém?

Ver a essência.

Foi útil?

Solução

Isso está acontecendo porque você está descartando o fluxo de entrada sem lê -lo, e isso está forçando -o. O navegador fez fila uma boa parte do arquivo a ser enviada e, em seguida, recebe um erro de gravação porque o servidor fecha a conexão com força.

Não há maneira de contornar isso que conheço sem ler toda a entrada.

Eu recomendaria algum JavaScript para testar o tamanho do arquivo antes de ser enviado. Então, as únicas pessoas que recebem o erro são aquelas que estão ignorando a verificação do lado do cliente porque não têm JavaScript ou porque estão tentando propositalmente ser maliciosas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top