sgcQUIC 5분 시작 가이드
OpenSSL에 내장된 QUIC 엔진 위에서 네이티브 Object Pascal로 QUIC와 HTTP/3를 사용해요. 컴포넌트는 네 개가 포함되어 있어요. 가장 빠르게 동작하는 결과를 보려면 HTTP/3 클라이언트가 제일 좋아서, 이 페이지에서는 요청 하나를 보내고 상태 코드를 읽으며, 어떤 OpenSSL이 필요한지도 정확하게 알려 드려요.
OpenSSL에 내장된 QUIC 엔진 위에서 네이티브 Object Pascal로 QUIC와 HTTP/3를 사용해요. 컴포넌트는 네 개가 포함되어 있어요. 가장 빠르게 동작하는 결과를 보려면 HTTP/3 클라이언트가 제일 좋아서, 이 페이지에서는 요청 하나를 보내고 상태 코드를 읽으며, 어떤 OpenSSL이 필요한지도 정확하게 알려 드려요.
컴포넌트 하나, URL 하나, 그리고 실행 파일 옆에 둘 OpenSSL 라이브러리 두 개가 필요해요.
SGC QUIC 팔레트 페이지의 TsgcHTTP3Client이며 sgcQUIC.pas에 선언되어 있어요. 이 페이지에는 TsgcQUICClient, TsgcQUICServer, TsgcHTTP3Server도 있어요.
컴포넌트에는 sgcQUIC를 쓰세요. TsgcHTTP3Response를 위해 sgcHTTP3_Classes를 추가하고, Alt-Svc 이벤트를 처리한다면 sgcHTTP_AltSvc도 추가하세요.
Get(aURL)은 본문을 string으로 반환하고 실패하면 예외를 발생시켜요. 상태 코드와 헤더는 OnResponse로 따로 전달돼요.
클라이언트에는 OpenSSL 3.2 이상의 QUIC API 또는 quictls 빌드가 필요해요. 서버는 3.5 이상이 필요한데, 그 버전에만 있는 API를 호출하기 때문이에요. 모든 데모 폴더처럼 실행 파일 옆에 libcrypto-3.dll과 libssl-3.dll을 함께 배포하세요.
에디션 열은 코드를 제어하는 define이며, Source/sgcVer.inc에서 그 define이 있는 줄 번호도 함께 적었어요.
| 항목 | 값 |
|---|---|
| IDE | Delphi 7부터 RAD Studio 13까지, 그리고 C++Builder 2007부터 13까지. 별도의 sgcQUIC 다운로드는 없고, 컴포넌트는 sgcWebSockets 패키지 그룹에 들어 있어요. |
| Uses 절 | sgcQUIC, 그리고 응답 객체를 위한 sgcHTTP3_Classes와 Alt-Svc 타입을 위한 sgcHTTP_AltSvc. |
| 팩 define | SGC_PACK_QUIC은 872번째 줄에 정의되어 있으며, 870번째 줄부터 874번째 줄까지 이어지는 {$IFDEF SGC_EDT_ALL} 블록 안에 있어요. 따라서 All-Access예요. |
| 기능 define | 894번째 줄부터 899번째 줄까지의 {$IFDEF SGC_PACK_QUIC} 블록 안에 있어요. 896번째 줄의 SGC_QUIC, 897번째 줄의 SGC_HTTP3, 898번째 줄의 SGC_WEBTRANSPORT가 그것이에요. 세 가지 모두 895번째 줄의 {$IFDEF SGC_INDY_LIB} 안에 있으므로, 커스텀 Indy 라이브러리 없이 빌드하면 아무것도 사용할 수 없어요. |
| OpenSSL, 클라이언트 | 3.2 이상 또는 quictls 빌드. 라이브러리가 직접 알려 줘요. QUIC을 사용할 수 없을 때 발생하는 오류 메시지는 QUIC is not available. Requires quictls/openssl or OpenSSL 3.2+예요. |
| OpenSSL, 서버 | 3.5 이상. QUIC 서버는 SSL_new_listener를 호출하며, 이것이 없을 때 발생하는 오류 메시지는 QUIC Server requires OpenSSL 3.5 or later예요. msquic은 사용하지 않고 필요하지도 않아요. |
| 플랫폼 | sgcQUIC.pas, sgcQUIC_Client.pas, sgcHTTP3_Client.pas, sgcHTTP3_Server.pas에는 유닛 범위의 플랫폼 가드가 없고, 컴포넌트 네 개 모두 ComponentPlatforms(0)으로 등록돼요. 서버 유닛은 플랫폼별로 소켓 API를 선택하며 Windows 분기와 POSIX 분기를 모두 갖고 있어요. |
런타임에 엔진이 있는지 확실하지 않나요? IsOpenSSL_QUIC_Available을 호출하세요. 로드한 OpenSSL이 QUIC 클라이언트 메서드를 제공하는지 반환해요. 포함된 QUIC 클라이언트 데모가 시작할 때 이 값을 로그에 남기는 것도 같은 이유예요.
별도의 sgcQUIC 설치 프로그램은 없어요. 컴포넌트는 sgcWebSockets와 함께 설치되고, 에디션이 활성화하면 나타나요.
sgcWebSockets 다운로드를 폴더에 압축 해제하세요. 아래에서는 이 폴더를 {$DIR}이라고 불러요.
Tools, Options, Library로 이동해요. {$DIR}\source와 사용하는 IDE의 lib 폴더를 추가하세요. 예를 들면 {$DIR}\libD13\$(Platform)이에요.
{$DIR}\Packages\ 아래에서 IDE 버전에 맞는 패키지 그룹을 여세요. 런타임 .dpk를 먼저 컴파일하고 그다음 디자인 타임 dcl 패키지를 설치해요. QUIC 전용 패키지는 없어요.
TsgcQUICClient, TsgcQUICServer, TsgcHTTP3Client, TsgcHTTP3Server가 들어 있는 SGC QUIC 페이지가 나타나요. 페이지가 보이지 않는다면 All-Access 빌드가 아닌 거예요. SGC_PACK_QUIC은 그 블록 안의 872번째 줄에서만 정의되기 때문이에요.
libcrypto-3.dll과 libssl-3.dll을 실행 파일 옆에 복사하세요. 클라이언트는 3.2 이상, 서버는 3.5 이상이에요. Demos\22.QUIC_Protocol 아래의 모든 폴더에 들어 있으니 거기서 복사하면 돼요.
클라이언트를 만들고, 이벤트 세 개를 연결하고, Get을 호출해요. 응답은 문자열로 돌아오고 상태 코드는 OnResponse로 도착해요.
uses
Classes, SysUtils,
// sgc
sgcQUIC, sgcHTTP3_Classes;
procedure TfrmHTTP3Client.FormCreate(Sender: TObject);
begin
FClient := TsgcHTTP3Client.Create(nil);
FClient.OnConnect := OnH3Connect;
FClient.OnError := OnH3Error;
FClient.OnResponse := OnH3Response;
FClient.TLSOptions.VerifyCertificate := True;
FClient.ConnectTimeout := 10000;
FClient.ReadTimeout := 30000;
FClient.UserAgent := 'sgcWebSockets/HTTP3Client';
end;
procedure TfrmHTTP3Client.btnGetClick(Sender: TObject);
var
vResult: string;
begin
try
// the target comes from the URL, because Host and Port
// are read-only on this component
vResult := FClient.Get('https://www.google.com/');
memoBody.Lines.Text := vResult;
DoLog('Response received: ' + IntToStr(Length(vResult)) + ' bytes');
except
on E: Exception do
DoLog('Error: ' + E.Message);
end;
end;
Post, Put, Delete도 같은 형태이며, 문자열에 담고 싶지 않은 본문을 위한 스트림 오버로드도 각각 있어요. 첫 요청 전에 연결만 따로 열고 싶다면 Connect(const aHost: string; aPort: Integer = 443)을 쓰세요.
// OnConnect and OnDisconnect are plain TNotifyEvent on this
// component: one parameter, no connection object.
procedure TfrmHTTP3Client.OnH3Connect(Sender: TObject);
begin
DoLog('Connected to ' + FClient.Host + ':' + IntToStr(FClient.Port));
end;
procedure TfrmHTTP3Client.OnH3Error(Sender: TObject; const aError: string);
begin
DoLog('Error: ' + aError);
end;
procedure TfrmHTTP3Client.OnH3Response(Sender: TObject;
const aResponse: TsgcHTTP3Response);
begin
DoLog('Status: ' + IntToStr(aResponse.StatusCode));
memoHeaders.Lines.Assign(aResponse.Headers);
end;
OnConnect 안에서 FClient.Host와 FClient.Port를 읽는 것이 바로 그 두 속성의 용도예요. 연결 상태를 알려 줄 뿐, 연결을 설정하지는 않아요.
uses
Classes, SysUtils,
// sgc
sgcIdSSLOpenSSLHeaders;
procedure TfrmQUICClient.FormCreate(Sender: TObject);
begin
DoLog('OpenSSL QUIC Support:');
DoLog(' quictls API: ' +
BoolToStr(IsOpenSSL_QUIC_TLS_Available, True));
DoLog(' Builtin QUIC (3.2+): ' +
BoolToStr(IsOpenSSL_QUIC_Available, True));
end;
다른 무엇보다 먼저 이것을 한 번 실행해 보세요. 둘 다 false라면 실행 파일 옆의 OpenSSL에 QUIC이 없다는 뜻이고, 그 뒤의 모든 연결 실패는 네트워크 때문이 아니라 이 한 가지 사실에서 비롯된 증상이에요.
처음 두 탭은 포함된 데모 Demos\22.QUIC_Protocol\03.HTTP3_Client\FHTTP3Client.pas에서 가져온 것이며, 폼 컨트롤은 리터럴로 바꿨어요. 세 번째는 01.QUIC_Client\FQUICClient.pas의 런타임 사용 가능 여부 확인이에요. 그 폴더에는 WebTransport 한 쌍을 포함해 QUIC 데모가 여섯 개 있어요.
Get은 본문을 반환해요. 나머지 모든 정보는 응답 객체에 담겨 있고, 별도의 이벤트로 도착해요.
Get은 응답 본문을 string으로 반환하고 실패하면 예외를 발생시키므로, 데모는 try except로 감싸요. 예상한 길이의 본문이 오면 그것이 첫 번째 증거예요.
OnResponseprocedure(Sender: TObject; const aResponse: TsgcHTTP3Response). 실제로 필요한 숫자는 StatusCode이고, Headers는 TStringList이며, GetDataAsString으로 응답 객체에서 본문을 다시 얻을 수 있어요.
OnConnect일반 TNotifyEvent예요. 발생했다는 것 자체가 QUIC 협상이 끝나고 HTTP/3 세션이 열렸다는 뜻이며, 첫 실행에서 가장 실패하기 쉬운 부분이에요.
IsOpenSSL_QUIC_Available이 가장 먼저 물어볼 만한 유일한 질문에 답해 줘요. QUIC은 UDP 443으로도 동작하는데, TCP 443을 허용하는 네트워크가 반드시 그것을 허용하는 것은 아니에요.
실패한 첫 요청은 거의 다 여섯 가지 문제 중 하나가 원인이에요.
TsgcHTTP3Client에서 이 둘은 읽기 전용이며 property Host: string read FHost와 property Port: Integer read FPort로 선언되어 있어요. 클라이언트가 어디에 연결되어 있는지 알려 줄 뿐이에요. 대상을 정하려면 Get에 전체 URL을 넘기거나 Connect(aHost, aPort)를 호출하세요.
로드한 OpenSSL이 너무 오래되었거나 QUIC 없이 빌드된 거예요. 클라이언트에는 3.2 이상 또는 quictls가 필요해요. 네트워크를 탓하기 전에 IsOpenSSL_QUIC_Available로 런타임에 확인하세요.
QUIC 서버는 SSL_new_listener를 호출하기 때문에 OpenSSL 3.5 이상이 필요해요. 3.2 빌드는 클라이언트에는 충분하지만 서버에는 충분하지 않으며, 오류 메시지에도 그렇게 명시돼요.
이 컴포넌트의 OnConnect와 OnDisconnect는 일반 TNotifyEvent이므로 핸들러는 Sender: TObject만 받아요. WebSocket 컴포넌트와 달리 연결 객체를 전달하지 않아요.
QUIC은 443 포트의 UDP로 동작하는데, 많은 기업 네트워크가 TCP 443은 허용하고 UDP 443은 차단해요. 브라우저는 HTTP/3로 호스트에 도달하는데 애플리케이션은 안 된다면 코드보다 먼저 방화벽을 의심하세요.
SGC_PACK_QUIC은 All-Access 블록 안의 872번째 줄에서만 정의돼요. 또한 894번째 줄부터 899번째 줄까지의 팩 블록 전체가 그 가드 안에 있어서 SGC_INDY_LIB도 필요해요.
네 가지 방향이 있고, 모두 같은 패키지 안에 있어요.
TsgcHTTP3Server는 QUIC 위에서 HTTP/3를 직접 제공해요. 서버 쪽은 OpenSSL 3.5 이상이 필요하다는 점을 기억하세요.
TsgcQUICClient와 TsgcQUICServer는 HTTP/3 계층 없이 QUIC 스트림을 제공해요. 헤드 오브 라인 블로킹 없는 멀티플렉싱이 필요한 사용자 정의 프로토콜에 알맞아요.
HTTP/3를 통해 브라우저와 양방향 스트림과 데이터그램을 주고받아요. 898번째 줄의 SGC_WEBTRANSPORT가 제어하며, 데모가 두 개 포함되어 있어요.
서버는 Alt-Svc 헤더로 HTTP/3를 알려요. OnAltSvc를 처리하면 원본 서버가 제안할 때 기존 연결을 QUIC으로 업그레이드할 수 있어요.
데모 프로젝트는 다운로드 안의 Demos\22.QUIC_Protocol 아래에 있어요. 모두 여섯 개예요.
HTTP/3 클라이언트 컴포넌트
TsgcHTTP3Client가 제공하는 것을 속성별로 설명해요.
|
열기 | |
| HTTP/3 서버 컴포넌트 OpenSSL 3.5 요구 사항을 포함한 서버 측 설명. | 열기 | |
| QUIC 클라이언트 컴포넌트 HTTP/3 계층 없는 순수 QUIC 스트림. | 열기 | |
| sgcQUIC 기능 QPACK, 0-RTT, 연결 마이그레이션, WebTransport 등. | 열기 | |
| 체험판 다운로드 IDE 버전별 설치 프로그램 하나에 QUIC 컴포넌트가 이미 들어 있어요. | 열기 | |
| 온라인 도움말 자동 생성된 레퍼런스로, 항상 최신 릴리스와 일치해요. | 열기 |
함께 읽어 보세요. QUIC 클라이언트 및 서버 컴포넌트와 HTTP/3 컴포넌트. 전송 방식을 고르는 중이라면 실시간 전송 가이드에서 비교해 볼 수 있어요. 모든 제품에는 각자의 빠른 시작이 있으며, 시작하기 페이지에서 모아 볼 수 있어요.
sgcQUIC 유닛에 있는 TsgcHTTP3Client예요. OnResponse의 매개변수 타입인 TsgcHTTP3Response를 위해 sgcHTTP3_Classes를 추가하고, OnAltSvc를 처리한다면 sgcHTTP_AltSvc도 추가하세요. 팔레트 페이지에는 TsgcQUICClient, TsgcQUICServer, TsgcHTTP3Server도 있어요.
SSL_new_listener를 호출하기 때문에 3.5 이상이 필요하고, 오류 메시지에도 그 버전이 명시돼요. 실행 파일 옆에 libcrypto-3.dll과 libssl-3.dll을 함께 배포하세요. msquic은 사용하지 않아요.
TsgcHTTP3Client는 이 둘을 property Host: string read FHost와 property Port: Integer read FPort로 선언하므로, 현재 연결을 알려 줄 뿐 연결을 설정하지는 않아요. Get, Post, Put, Delete에 전체 URL을 넘기거나, 먼저 Connect(const aHost: string; aPort: Integer = 443)을 호출하세요.
TNotifyEvent이므로 procedure(Sender: TObject)예요. OnDisconnect도 같아요. 이벤트가 TsgcWSConnection을 전달하는 WebSocket 컴포넌트와 다른 점이며, 첫 컴파일 오류의 흔한 원인이에요. OnResponse는 procedure(Sender: TObject; const aResponse: TsgcHTTP3Response)이고 OnError는 procedure(Sender: TObject; const aError: string)이에요.
OnResponse의 응답 객체에서 읽어요. TsgcHTTP3Response는 StatusCode, TStringList인 Headers, 본문을 위한 GetDataAsString을 제공해요. Get 메서드 자체는 본문만 문자열로 반환하기 때문에, 데모에서도 OnResponse를 함께 연결해요.
SGC_PACK_QUIC은 sgcVer.inc의 872번째 줄에 정의되어 있으며, 870번째 줄부터 874번째 줄까지 이어지는 {$IFDEF SGC_EDT_ALL} 블록 안에 있어요. 따라서 All-Access예요. 894번째 줄부터 899번째 줄까지의 팩 블록 자체도 {$IFDEF SGC_INDY_LIB} 안에 있으므로 커스텀 Indy 라이브러리도 빌드에 포함되어야 해요. 그 블록 안에서 SGC_QUIC은 896번째 줄, SGC_HTTP3는 897번째 줄, SGC_WEBTRANSPORT는 898번째 줄이에요.
IsOpenSSL_QUIC_Available은 로드한 OpenSSL이 QUIC 클라이언트 메서드를 제공하는지 반환하고, IsOpenSSL_QUIC_TLS_Available은 QUIC TLS 콜백에 대해 같은 일을 해요. 포함된 QUIC 클라이언트 데모는 시작할 때 두 값을 모두 로그에 남기며, 이유를 알 수 없던 연결 실패를 한 줄짜리 답으로 바꿔 줘요.