4

残念ながら、私の以前の質問は、質問の「正確なコピー」であるために閉じられましたが、間違いなくそうではありません。

これは Python の複製ではありません: HTTP Post a large file with streaming

それは大きなファイルのストリーミングを扱います。ファイルの任意のチャンクを 1 つずつ同じ http 接続に送信したいと考えています。つまり、たとえば 20 MB のファイルがあり、HTTP 接続を開いてから 1 MB を送信し、さらに 1 MB を送信するなどの処理を、完了するまで行います。同じ接続を使用するため、サーバーはその接続に 20 MB のチャンクが表示されることを認識します。

ファイルのマッピングは私もやろうとしていることですが、データが標準入力から読み取られるときは機能しません。そして、主にその2番目のケースでは、この部分ごとのデータの供給を探しています。

正直なところ、それができるかどうか疑問に思っています。できない場合は、知りたいので、問題を解決できます。しかし、それができるとしたら、どうすればできるのでしょうか?

4

1 に答える 1

6

クライアントの観点からは、簡単です。httplibの低レベル インターフェイス <a href="http://docs.python.org/library/httplib.html#httplib.HTTPConnection.putrequest" rel="nofollow"> putrequestputheaderendheaders、および— を使用sendして送信できます。任意のサイズのチャンクでサーバーに送信したいものは何でも。

ただし、ファイルの終了位置も示す必要があります。

ファイルの合計サイズが事前にわかっている場合は、単純にContent-Lengthヘッダーを含めることができます。サーバーは、その数バイト後にリクエスト本文の読み取りを停止します。コードは次のようになります。

import httplib
import os.path

total_size = os.path.getsize('/path/to/file')
infile = open('/path/to/file')
conn = httplib.HTTPConnection('example.org')
conn.connect()
conn.putrequest('POST', '/upload/')
conn.putheader('Content-Type', 'application/octet-stream')
conn.putheader('Content-Length', str(total_size))
conn.endheaders()
while True:
    chunk = infile.read(1024)
    if not chunk:
        break
    conn.send(chunk)
resp = conn.getresponse()

事前に合計サイズがわからない場合、理論的な答えはチャンク転送エンコーディングです。問題は、応答には広く使用されていますが、要求には (同様に明確に定義されていますが) あまり一般的ではないように思われることです。ストック HTTP サーバーはそのままでは処理できない場合があります。ただし、サーバーも制御下にある場合は、リクエスト本文からチャンクを手動で解析し、それらを元のファイルに再構築してみてください。

もう 1 つのオプションはContent-Length、同じ接続を介して各チャンクを個別の要求として ( を使用して) 送信することです。ただし、サーバーにカスタム ロジックを実装する必要があります。さらに、リクエスト間で状態を保持する必要があります。

2012-12-27 追加。チャンクされたリクエストを通常のリクエストに変換するnginxモジュールがあります。真のストリーミングを必要としない限り、役に立つかもしれません (クライアントが送信を完了する前にリクエストの処理を開始してください)。

于 2012-10-13T11:06:10.983 に答える