Cherrypy はそのままマルチパート/混合 POST を受信できますか?
質問
マルチパート/混合エンコーディングのみを提供するデバイスから、XML + 任意のバイナリ ファイル (画像や音声など) の POST データを受信しています。
受信側にcherrypyアップロード/POSTハンドラーをセットアップしました。multipart/form-data を使用して、任意の数のパラメータを実行できるようにしました。ただし、マルチパートが混合されたデータを送信しようとしても、何も処理されません。
@cherrypy.expose
def upload(self, *args,**kwargs):
"""upload adapted from cherrypy tutorials
We use our variation of cgi.FieldStorage to parse the MIME
encoded HTML form data containing the file."""
print args
print kwargs
cherrypy.response.timeout = 1300
lcHDRS = {}
for key, val in cherrypy.request.headers.iteritems():
lcHDRS[key.lower()] = val
incomingBytes = int(lcHDRS['content-length'])
print cherrypy.request.rfile
#etc..etc...
したがって、multipart/form-data を送信するとき、args と kwargs は明確に定義されます。
args はフォームフィールド、kwargs=vars と値のハッシュです。multipart/mixed を送信すると、args と kwargs は空で、生の POST 情報としてcherrypy.request.rfile だけが存在します。
私の質問は、cherrypyにはPOSTのマルチパート/混合およびチャンクエンコーディングを処理するためのハンドラーが組み込まれているのかということです。それとも、cherrypy.tools.process_request_bodyをオーバーライドして、独自のデコーダをロールする必要がありますか?
Cherrypy を備えた組み込みの wsgi サーバーがこれを HTTP/1.1 仕様の一部として処理しているようですが、この機能にアクセスする際の Cherrypy のドキュメントが見つからないようです。
...明確にするために
Cherrypyの最新バージョン3.1.1程度を使用しています。
デフォルトのフォームを作成するには、アップロード関数でパラメータを作成するだけです。
multipart/form-data の場合、curl -F param1=@file1.jpg -F param2=sometext -F param3=@file3.wav を呼び出しています。 http://宛先:ポート/アップロード
この例では、次のようになります。
args = ['param1','param2','param3]
kwargs = {'param1':CString<>, 'param2': 'sometext', 'param3':CString<>}
multipart/mixed を送信しようとしたときに、request.body を見てみましたが、本文の処理の設定に関係なく、None が返され続けました。
取得している入力は次のようになります。
user-agent:UNTRUSTED/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1
content-language:en-US
content-length:565719
mime-version:1.0
content-type:multipart/mixed; boundary='newdivider'
host:192.168.1.1:8180
transfer-encoding:chunked
--newdivider
Content-type: text/xml
<?xml version='1.0' ?><data><Stuff>....
etc...etc...
--newdivider
Content-type: image/jpeg
Content-ID: file://localhost/root1/photos/Garden.jpg
Content-transfer-encoding: binary
<binary data>
multipart/mixed が問題で、cherrypy が rfile だけを提供しているのではないかと私は密かに疑っています。私たちの目標は、受信側での処理を最小限に抑えて、cherrypy にボディをそのパーツに処理させることです (つまり、cherrypy に魔法を実行させます)。そのために、送信フォーマットをcherrypyが好むコンテンツタイプにするためにもっと厳しくする必要があるのなら、それはそれで構いません。受け入れられる形式は何ですか?マルチパート/フォームデータのみですか?
解決
悪いです。Content-Type のタイプが「multipart/*」の場合、CP はコンテンツを request.params に挿入しようとします (他の Content-Type の場合は、request.body に挿入されます)。
残念ながら、CP はマルチパート メッセージはすべてフォームデータであると想定しており、他のサブタイプについては規定していません。これをトランクで修正したところです。3.1.2 でリリースされるはずです。ご不便をおかけして申し訳ありません。短期的には、変更セットをローカルに適用してみることができます。見る http://www.cherrypy.org/ticket/890.