본문 바로가기
delphi

웹 페이지 요청 시 응답 헤더 처리 문제 해결 방법

by doran365 2024. 8. 7.

개요

TInetHTTP (WininetHTTP Suite) 컴포넌트를 이용하여 웹페이지를 요청할 때 응답 헤더가 이상하게 넘어오는 경우가 Delphi XE 이상 버전에서 발생한다. 예를 들어 INetHttp.QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF)를 호출하여 얻은 응답 헤더에 "Content-Type"에 대한 문자열이 "'C'#0'o'#0'n'#0't'#0'e'#0'n'#0't'#0 ..." 식으로 리턴된다. 이 문자열을 직접 사용하고자 하면 문자열 변수에 다음과 같이 담게 되는데

ResponseHeader := INetHttp.QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF);

그러면 결과는 자동으로 널 스트링을 인지하고 TypeCasting 되어서 ResponseHeader에는 'C'만 들어가서 정상적인 헤더 처리가 곤란해진다. 이때 해당 널 값을 제거해 주는 방법을 고찰해 보자.

SetLength를 이용한 Null Char(#0) 제거 방법

function RemoveNullChars(const Input: string): string;
var
  OutputLen, Index: Integer;
  C: Char;
begin
  SetLength(Result, Length(Input));
  OutputLen := 0;
  for Index := 1 to Length(Input) do
  begin
    C := Input[Index];   
    if C <> #0 then
    begin
      inc(OutputLen);
      Result[OutputLen] := C;
    end;
  end;
  SetLength(Result, OutputLen);
end;
 

 

Delete를 이용한 Null Char(#0) 제거 방법

function RemoveNullChars(const Input: string): string;
var
  i: Integer;
begin
  Assert(Input<> '');
  i := 1;
  while i <= Length(Input) do
    if Input[i] = #0 then
      Delete(Input, i, 1)
    else
      Inc(i);
  result := Input;
end;

 

TMemoryStream을 대상으로 Null Char(#0) 제거 방법

procedure RemoveNullCharsFromMemoryStream(Stream: TMemoryStream);
var
  i: Integer;
  pIn, pOut: PByte;
begin
  pIn := Stream.Memory;
  pOut := pIn;
  for i := 0 to Stream.Size-1 do
  begin
    if pIn^ <> 0 then
    begin
      pOut^ := pIn^;
      inc(pOut);
    end;
    inc(pIn);
  end;
  Stream.SetSize(NativeUInt(pOut)-NativeUInt(Stream.Memory));
end;

 

성능 문제

위 함수 호출은 순식간에 처리되기 때문에 성능에 큰 영향을 미치지는 않지만, 성능이 조금 높은 것을 치자면 SetLength를 이용한 방법이 Delete를 이용한 방법보다 거의 3배 정도 빠르게 동작한다(10000회 / 31ms).

결론

Delphi XE 이상 버전에서 발생하는 응답 헤더 처리 문제는 다양한 방법으로 해결할 수 있으며, 각 방법마다 장단점이 존재한다. SetLength를 이용한 방법이 성능 면에서 가장 우수하지만, 상황에 따라 Delete나 TMemoryStream을 이용한 방법도 고려해볼 만하다. 최적의 방법을 선택하여 응답 헤더를 정상적으로 처리함으로써 웹 페이지 요청 시 발생하는 문제를 해결할 수 있다.