Enviar Arquivos Grandes por POST

Suportado por

TsgcWebSocketHTTPServer

TsgcWebSocketServer_HTTPAPI

Quando um cliente HTTP envia um stream multipart/form-data, o stream é salvo pelo servidor na memória. Quando os arquivos são grandes, o servidor pode gerar uma exceção de falta de memória. Para evitar essas exceções, o servidor possui uma propriedade chamada HTTPUploadFiles na qual você pode configurar como os streams POST são tratados: na memória ou como file streams. Se os streams forem tratados como file streams, os streams recebidos são armazenados diretamente no disco rígido, evitando assim os problemas de memória.

Para configurar seu servidor para salvar streams multipart/form-data como file streams, siga os próximos passos:

1. Defina a propriedade HTTPUploadFiles.StreamType = pstFileStream. Com essa configuração, o servidor armazenará esses streams no disco rígido.

2. Você pode configurar qual é o tamanho mínimo em bytes a partir do qual os arquivos serão armazenados como file stream. Por padrão o valor é zero, o que significa que todos os streams serão armazenados como file stream.

3. A pasta onde os streams são armazenados é definida por SaveDirectory; se não for definida, eles serão armazenados na mesma pasta onde está a aplicação.

4. Quando um cliente envia um multipart/form-data, o conteúdo é codificado dentro de boundaries; se a propriedade RemoveBoundaries estiver habilitada, o conteúdo dos boundaries será extraído automaticamente após o stream completo ser recebido.

Código de Exemplo

Primeiro crie uma nova instância de servidor e defina que os Streams sejam salvos como File Streams.


oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;

Em seguida crie um novo arquivo html com a seguinte configuração

<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 fim abra o arquivo html com um navegador web e envie um arquivo para o servidor. O servidor criará um novo file stream com a extensão ".sgc_ps" e, quando o stream for totalmente recebido, extrairá o arquivo dos boundaries.

Eventos

Existem 2 eventos que podem ser utilizados para personalizar o fluxo de upload de arquivos (requer que a propriedade HTTPUploadFiles.RemoveBoundaries esteja habilitada)

OnHTTPUploadBeforeSaveFile

Este evento é disparado ANTES de o arquivo ser salvo e permite personalizar o nome do arquivo recebido.


procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
  if aFileName = "test.jpg" then
    aFileName := "custom_test.jpg";
end;

OnHTTPUploadAfterSaveFile

Este evento é disparado DEPOIS de o arquivo ser salvo e permite que você saiba o nome do arquivo salvo.


procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string);
begin
  DoLog("File Received: " + aFileName);end;

OnHTTPUploadReadInput

Este evento é disparado quando o decodificador lê um valor de entrada recebido diferente da entrada de arquivo (exemplo: se o formulário tiver algumas variáveis como nome, data...).


procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string);
begin
  DoLog("Input value received: " + aName + ":" + aValue);end;