A redefinição da conexão TCP ocorre quando o aplicativo WSGI responde antes de consumir o Environ ['wsgi.input'
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 ChromeThe 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.
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.