지원 컴포넌트
HTTP 클라이언트가 multipart/form-data 스트림을 전송하면, 해당 스트림은 서버의 메모리에 저장됩니다. 파일이 큰 경우 서버에서 out of memory 예외가 발생할 수 있습니다. 이러한 예외를 방지하기 위해 서버에는 HTTPUploadFiles라는 속성이 있으며, 여기서 POST 스트림을 메모리에 저장할지 파일 스트림으로 처리할지를 구성할 수 있습니다. 스트림을 파일 스트림으로 처리하면, 수신된 스트림이 하드 디스크에 직접 저장되므로 메모리 문제를 피할 수 있습니다.
서버가 multipart/form-data 스트림을 파일 스트림으로 저장하도록 구성하려면 다음 단계를 따르십시오.
1. HTTPUploadFiles.StreamType = pstFileStream 속성을 설정하십시오. 이 설정을 사용하면 서버가 이러한 스트림을 하드 디스크에 저장합니다.
2. 파일이 파일 스트림으로 저장될 최소 바이트 크기를 구성할 수 있습니다. 기본값은 0이며, 이는 모든 스트림이 파일 스트림으로 저장됨을 의미합니다.
3. 스트림이 저장되는 폴더는 SaveDirectory를 사용하여 지정하며, 설정하지 않으면 애플리케이션이 있는 동일한 폴더에 저장됩니다.
4. 클라이언트가 multipart/form-data를 전송하면 콘텐츠는 경계(boundary) 안에 인코딩됩니다. 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>
마지막으로 웹 브라우저로 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;