まず、twisted.web
フレームワークを使用しています。Twisted.web
のファイルアップロードは、私が望んでいたように機能しませんでした(ファイルデータのみが含まれ、他の情報は含まれてcgi.parse_multipart
いません)、私が望むように機能しません(同じこと、twisted.web
この関数を使用します)、機能cgi.FieldStorage
しませんでした(CGIインターフェイスではなくツイストを介してPOSTデータを取得しているため、私が知る限り、FieldStorage
stdinを介してリクエストを取得しようとします)、混乱して激怒しtwisted.web2
たため、機能しませんでしたDeferred
(私が欲しいものには複雑すぎます)。
そうは言っても、私は自分でHTTPリクエストを解析してみることにしました。
Chromeを使用すると、HTTPリクエストは次のように形成されます。
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="upload_file_nonce"
11b03b61-9252-11df-a357-00266c608adb
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="file"; filename="login.html"
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
...
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="file"; filename=""
------WebKitFormBoundary7fouZ8mEjlCe92pq--
これは常にそれが形成される方法ですか?私はそれを次のような正規表現で解析しています(コードの壁を許してください):
(注:コードの大部分を切り取って、関連性があると思われるものだけを表示しました(正規表現(ええ、ネストされた括弧)、これは私が作成__init__
したクラスのメソッド(これまでのところ唯一のメソッド)Uploads
です。完全なコードは改訂履歴に表示されます(括弧が一致していなかったと思います)
if line == "--{0}--".format(boundary):
finished = True
if in_header == True and not line:
in_header = False
if 'type' not in current_file:
ignore_current_file = True
if in_header == True:
m = re.match(
"Content-Disposition: form-data; name=\"(.*?)\"; filename=\"(.*?)\"$", line)
if m:
input_name, current_file['filename'] = m.group(1), m.group(2)
m = re.match("Content-Type: (.*)$", line)
if m:
current_file['type'] = m.group(1)
else:
if 'data' not in current_file:
current_file['data'] = line
else:
current_file['data'] += line
境界に達するたびに、新しい「ファイル」辞書を開始することがわかります。私はヘッダーを解析していると言うように設定in_header
しました。True
空白行に達したら、それを-に切り替えますが、そのフォーム値にが設定されているFalse
かどうかを確認する前ではありません-そうでない場合は、ファイルのアップロードのみを探しているため、設定します。Content-Type
ignore_current_file
ライブラリを使用する必要があることはわかっていますが、ドキュメントを読んだり、プロジェクトでさまざまなソリューションを機能させようとしたり、コードを合理的に見せたりすることにうんざりしています。この部分を乗り越えたいだけです。ファイルのアップロードを使用してHTTPPOSTを解析するのがこれほど簡単な場合は、それを使い続けます。
注:このコードは今のところ完全に機能します。特定のブラウザからのリクエストを抑制/吐き出すかどうか疑問に思っています。