2015-10-20 152 views
4

我正在爲Flask應用程序編寫一個模糊器。我已經例如請求存儲爲文本文件,這樣get.txt:用Werkzeug解析原始HTTP請求

GET /docs/index.html HTTP/1.1 
Host: www.w3.org 

理想情況下,我會解析此爲werkzeug.wrappers.Request對象,像這樣(僞代碼):

from werkzeug.wrappers import Request 

req = Request() 

with open('get.txt') as f: 
    req.parse_raw(f.read()) 

但是,它看起來像Werkzeug中沒有發生原始HTTP解析。相反,Werkzeug從BaseHTTPServer.BaseHTTPRequestHandler開始使用WSGI環境,並且需要使用BaseHTTPServer.HTTPServer實例來解析請求。這對於簡單的事情來說似乎過分了。

我也遇到了http-parser,這更接近我想要的,但它重複了大多數Werkzeug的數據結構與不兼容的類型。我不得不將數據從一個轉換到另一個。

是否有一種更簡單的方法可以從原始HTTP請求轉到Werkzeug中的WSGI環境(或使用BaseHTTPRequestHandler而不使用HTTP服務器)?

+0

疑難雜症。所以最好的選擇可能是從http解析器 - > WSGI環境 - > Werkzeug? – nathancahill

+0

對不起,正在考慮將其擴展爲答案,因此我將其刪除。它看起來像Werkzeug已經包含'HTTPServer'和'HTTPRequestHandler'子類,有沒有你不想使用它們的原因? – davidism

+0

出於同樣的原因,它似乎是從原始HTTP到WSGI環境(最終是Werkzeug請求)的重要方式。我的目標是從測試中排除服務器和網絡。 – nathancahill

回答

3

沒有找到一個簡單的方法來做到這一點,所以我編寫了一個名爲Werkzeug-Raw的庫來解析原始HTTP請求到WSGI環境(甚至打開測試客戶端上的請求)。

它的工作原理是這樣的:

from flask import Flask, request 
import werkzeug_raw 

app = Flask(__name__) 

environ = werkzeug_raw.environ('GET /foo/bar?tequila=42 HTTP/1.1') 

with app.request_context(environ): 
    print request.args # ImmutableMultiDict([('tequila', u'42')]) 

要打開一個測試客戶端上一個原始的HTTP請求:

client = app.test_client() 
rv = werkzeug_raw.open(client, 'GET /foo/bar?tequila=42 HTTP/1.1')