2013-01-03 6 views
9

Wir versuchen, einen Flask-Web-Service zu arbeiten, und wir haben einige Probleme mit dem Streaming von Posts - d. H. Wenn die Kopfzeile Transfer-Encoding: Chunked enthält.Flask und Transfer-Encoding: chunked

Es scheint, als ob die Standard-Flasche HTTP 1.1 nicht unterstützt. Gibt es dafür eine Arbeit?

Wir laufen diesen Befehl ein:

$ curl -v -X PUT --header "Transfer-Encoding: chunked" -d @pylucene-3.6.1-2-src.tar.gz "http://localhost:5000/async-test" 

Vor diesem Code:

@app.route("/async-test", methods=['PUT']) 
def result(): 
    print '------->'+str(request.headers)+'<------------' 
    print '------->'+str(request.data)+'<------------' 
    print '------->'+str(request.form)+'<------------' 
    return 'OK' 

Hier ist die curl Ausgabe:

$ curl -v -X PUT --header "Transfer-Encoding: chunked" -d @pylucene-3.6.1-2-src.tar.gz "http://localhost:5000/async-test" 
* About to connect() to localhost port 5000 (#0) 
* Trying ::1... Connection refused 
* Trying 127.0.0.1... connected 
* Connected to localhost (127.0.0.1) port 5000 (#0) 
> PUT /async-test HTTP/1.1 
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 
> Host: localhost:5000 
> Accept: */* 
> Transfer-Encoding: chunked 
> Content-Type: application/x-www-form-urlencoded 
> Expect: 100-continue 
> 
* HTTP 1.0, assume close after body 
< HTTP/1.0 200 OK 
< Content-Type: text/html; charset=utf-8 
< Content-Length: 2 
< Server: Werkzeug/0.8.3 Python/2.7.1 
< Date: Wed, 02 Jan 2013 21:43:24 GMT 
< 

Und hier ist der Flask Server-Ausgabe:

* Running on 0.0.0.0:5000/ 
------->Transfer-Encoding: chunked 
Content-Length: 
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 
Host: localhost:5000 
Expect: 100-continue 
Accept: */* 
Content-Type: application/x-www-form-urlencoded 

<------------ 
-------><------------ 
------->ImmutableMultiDict([])<------------ 
+0

Haben Sie jemals eine Lösung für diese finden? –

+0

Ich habe keine Benachrichtigungen aktiviert, daher habe ich diesen Kommentar bisher nicht gesehen. Waqas 'Antwort ist richtig; Wir haben den Testcode nach Java verschoben. –

Antwort

3

Es ist nicht der Flask Python, es ist der mod_wsgi. Nur mod_wsgi-Versionen 3.0+ haben begonnen, Chunked-HTTP-Übertragungen zu unterstützen. Flask Python verwenden intern Werkzeug-Tool-Kit als Schnittstelle zu mod_wsgi. Wenn Sie es aus den Apt-Quellen installiert haben, kann es sich um eine alte Version handeln.

Versuchen Sie, die neueste Version von mod_wsgi zu kompilieren und dann das Flask-Framework zu installieren, damit das Problem möglicherweise gelöst wird.

1

Dies funktioniert für mich, aber es ist nicht die eleganteste Art des Shimming Chunked Parsing. Ich benutzte die Methode, den Körper in die Umgebung der Antwort zu stecken.

Get raw POST body in Python Flask regardless of Content-Type header

Aber hinzugefügt Code mit chunked zu beschäftigen

class WSGICopyBody(object): 
    def __init__(self, application): 
     self.application = application 

    def __call__(self, environ, start_response): 
     from cStringIO import StringIO 
     input = environ.get('wsgi.input') 
     length = environ.get('CONTENT_LENGTH', '0') 
     length = 0 if length == '' else int(length) 
     body = '' 
     if length == 0: 
      environ['body_copy'] = '' 
      if input is None: 
       return 
      if environ.get('HTTP_TRANSFER_ENCODING','0') == 'chunked': 
       size = int(input.readline(),16) 
       while size > 0: 
        body += input.read(size+2) 
        size = int(input.readline(),16) 
     else: 
      body = environ['wsgi.input'].read(length) 
     environ['body_copy'] = body 
     environ['wsgi.input'] = StringIO(body) 

     # Call the wrapped application 
     app_iter = self.application(environ, 
            self._sr_callback(start_response)) 

     # Return modified response 
     return app_iter 

    def _sr_callback(self, start_response): 
     def callback(status, headers, exc_info=None): 

      # Call upstream start_response 
      start_response(status, headers, exc_info) 
     return callback 


app.wsgi_app = WSGICopyBody(app.wsgi_app) 

Verwendung Parsen dies, um es zu bekommen

request.environ['body_copy'] 
Verwandte Themen