Compatible con
Cuando un cliente HTTP envía un flujo multipart/form-data, el servidor guarda el flujo en memoria. Cuando los archivos son grandes, el servidor puede generar una excepción de memoria insuficiente. Para evitar estas excepciones, el servidor tiene una propiedad llamada HTTPUploadFiles donde puede configurar cómo se gestionan los flujos POST: en memoria o como flujos de archivo. Si los flujos se gestionan como flujos de archivo, los flujos recibidos se almacenan directamente en el disco duro, de modo que se evitan los problemas de memoria.
Para configurar su servidor de modo que guarde los flujos multipart/form-data como flujos de archivo, siga los pasos siguientes:
1. Establezca la propiedad HTTPUploadFiles.StreamType = pstFileStream. Con esta configuración, el servidor almacenará estos flujos en el disco duro.
2. Puede configurar cuál es el tamaño mínimo en bytes a partir del cual los archivos se almacenarán como flujo de archivo. De forma predeterminada el valor es cero, lo que significa que todos los flujos se almacenarán como flujo de archivo.
3. La carpeta donde se almacenan los flujos se establece mediante SaveDirectory; si no se establece, se almacenarán en la misma carpeta donde se encuentra la aplicación.
4. Cuando un cliente envía un multipart/form-data, el contenido se codifica dentro de límites (boundaries); si la propiedad RemoveBoundaries está habilitada, el contenido de los límites se extraerá automáticamente después de recibir el flujo completo.
Código de ejemplo
Primero cree una nueva instancia de servidor y configure que los flujos se guarden como flujos de archivo.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;
A continuación, cree un nuevo archivo html con la siguiente configuración
<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>
Por último, abra el archivo html con un navegador web y envíe un archivo al servidor. El servidor creará un nuevo flujo de archivo con la extensión ".sgc_ps" y, cuando el flujo se reciba por completo, extraerá el archivo de los límites.
Hay 2 eventos que pueden usarse para personalizar el flujo de carga de archivos (requiere que la propiedad HTTPUploadFiles.RemoveBoundaries esté habilitada)
OnHTTPUploadBeforeSaveFile
Este evento se activa ANTES de que el archivo se guarde y permite personalizar el nombre del archivo recibido.
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
if aFileName = "test.jpg" then
aFileName := "custom_test.jpg";
end;
OnHTTPUploadAfterSaveFile
Este evento se activa DESPUÉS de que el archivo se guarde y permite conocer el nombre del archivo guardado.
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName);end;
OnHTTPUploadReadInput
Este evento se activa cuando el decodificador lee un valor de entrada recibido distinto de la entrada de archivo (ejemplo: si el formulario tiene algunas variables como nombre, fecha...).
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue);end;