Supported by
When a HTTP client sends a multipart/form-data stream, the stream is saved by server in memory. When the files are big, the server can get an out of memory exception, to avoid these exceptions, the server has a property called HTTPUploadFiles where you can configure how the POST streams are handled: in memory or as a file streams. If the streams are handled as file streams, the streams received are stored directly in the hard disk so the memory problems are avoided.
To configure your server to save multipart/form-data streams as file streams, follow the next steps:
1. Set the property HTTPUploadFiles.StreamType = pstFileStream. Using this setup, the server will store these streams in the hard disk.
2. You can configure which is the minimum size in bytes where the files will be stored as file stream. By default the value is zero, which means all streams will be stored as file stream.
3. The folder where the streams are stored using SaveDirectory, if not set, will be stored in the same folder where the application is.
4. When a client sends a multipart/form-data, the content is encoded inside boundaries, if the property RemoveBoundaries is enabled, the content of boundaries will be extracted automatically after the full stream is received.
Sample Code
First create a new server instance and set the Streams are saved as File Streams.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;
Then create a new html file with the following configuration
<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>
Finally open the html file with a web browser and send a file to the server. The server will create a new file stream with the extension ".sgc_ps" and when the stream is fully received, it will extract the file from the boundaries.
There are 2 events which can be used to customize the upload file flow (requires the property HTTPUploadFiles.RemoveBoundaries is enabled)
OnHTTPUploadBeforeSaveFile
This event is fired BEFORE the file is saved and allows to customize the name of the file received.
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
if aFileName = "test.jpg" then
aFileName := "custom_test.jpg";
end;
OnHTTPUploadAfterSaveFile
This event is fired AFTER the file is saved and allows to know the name of the file saved.
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName);
end;
OnHTTPUploadReadInput
This event is fired when the decoder reads an input value received different from the file input (example: if the form has some variables like name, date...).
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue);
end;