サポート対象
HTTPクライアントがmultipart/form-dataストリームを送信すると、そのストリームはサーバーによってメモリに保存されます。ファイルが大きい場合、サーバーでout of memory例外が発生することがあります。これらの例外を回避するために、サーバーにはHTTPUploadFilesというプロパティがあり、POSTストリームの処理方法をメモリ上で処理するか、ファイルストリームとして処理するかを設定できます。ストリームをファイルストリームとして処理する場合、受信したストリームは直接ハードディスクに保存されるため、メモリの問題を回避できます。
multipart/form-dataストリームをファイルストリームとして保存するようにサーバーを設定するには、次の手順に従ってください。
1.HTTPUploadFiles.StreamType = pstFileStreamプロパティを設定します。この設定を使用すると、サーバーはこれらのストリームをハードディスクに保存します。
2.ファイルがファイルストリームとして保存される最小サイズ(バイト単位)を設定できます。デフォルト値はゼロで、これはすべてのストリームがファイルストリームとして保存されることを意味します。
3.SaveDirectoryを使用してストリームが保存されるフォルダーを指定します。設定されていない場合、アプリケーションと同じフォルダーに保存されます。
4.クライアントがmultipart/form-dataを送信すると、コンテンツはバウンダリ内にエンコードされます。RemoveBoundariesプロパティが有効になっている場合、ストリーム全体を受信した後にバウンダリのコンテンツが自動的に抽出されます。
サンプルコード
まず、新しいサーバーインスタンスを作成し、ストリームをファイルストリームとして保存するように設定します。
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;
次に、以下の設定で新しいhtmlファイルを作成します
<html>
<head><title>sgcWebSockets - Upload Big File</title></head>
<body>
<form action="http://127.0.0.1:5555/file" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
<input type="file" name="file_1" />
<input type="submit" />
</form>
</body>
</html>
最後に、Webブラウザーでhtmlファイルを開き、サーバーにファイルを送信します。サーバーは拡張子「.sgc_ps」を持つ新しいファイルストリームを作成し、ストリームを完全に受信すると、バウンダリからファイルを抽出します。
アップロードファイルのフローをカスタマイズするために使用できる2つのイベントがあります(HTTPUploadFiles.RemoveBoundariesプロパティが有効になっている必要があります)
OnHTTPUploadBeforeSaveFile
このイベントはファイルが保存される前に発生し、受信したファイルの名前をカスタマイズできます。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
if aFileName = "test.jpg" then
aFileName := "custom_test.jpg";
end;
OnHTTPUploadAfterSaveFile
このイベントはファイルが保存された後に発生し、保存されたファイルの名前を知ることができます。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName);end;
OnHTTPUploadReadInput
このイベントは、デコーダーがファイル入力とは異なる入力値を受信したときに発生します(例: フォームにname、dateなどの変数がある場合)。
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue);end;