2013-01-03 21 views
9

我們正在嘗試讓一個Flask Web服務正常工作,而且我們在流發佈帖子時遇到了一些問題 - 即當頭包含Transfer-Encoding:chunked時。Flask和Transfer-Encoding:chunked

它似乎像默認燒瓶不支持HTTP 1.1。有沒有解決這個問題的方法?

我們正在運行此命令:

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

在此代碼:

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

這裏的捲曲輸出:

$ 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 
< 

而這裏的瓶服務器輸出:

* 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

你有沒有找到一個解決這個? –

+0

我不能打開通知,所以直到現在我纔看到此評論。 Waqas的回答是正確的;我們將測試代碼移至Java。 –

回答

3

它不是Flask Python,它是mod_wsgi。只有mod_wsgi版本3.0+纔開始支持分塊的http傳輸。 Flask Python內部使用Werkzeug工具套件作爲mod_wsgi的接口。如果您從apt源安裝它,它可能是舊版本。

嘗試編譯最新版本的mod_wsgi,然後安裝Flask框架,它可能會解決問題。

1

這適用於我,但它並不是最好的分塊分析方法。我使用了將身體貼在響應環境中的方法。

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

但添加代碼來處理分塊解析

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) 

利用這個得到它

request.environ['body_copy']