Delphi 2010, XE에서 Indy로 HTTPS 프로토콜 사용하기
절름발이 프로그래머/Delphi / 2011. 5. 18. 20:59
참고한 내용은 http://www.ciuly.com/delphi/indy/ 입니다.
HTTP/HTTPS 프로토콜을 델파이로 Indy 로 구현한 예제들입니다. (주로 웹 메일 로그인 부분에 집중된 내용)
가장 중요한 점 HTTP/HTTPS의 Get 요청에 대한 응답이 Indy 컴포넌트에서 대부분 exception의 ErrorMessage 로 저장된다는 점입니다.
웹 브라우저에서 보이는 것이 항상 Get 함수의 리턴 값 문자열이 아닌 예외 상황으로 많이 처리되는 것 때문에 상당히 어려움을 겪었습니다.
위 구문을 추가하시고, 다음과 같이 코드를 작성하면 됩니다.
아래 코드에서 memo 컴포넌트에 html, response_cdoe, err_code, err_msg 를 출력해보면, 감이 오시리라 생각합니다.
html만 중요한 게 아니라, err_ 쪽도 상당히 중요합니다. 처리가 항상 필요합니다.
unit Unit1;
interface
uses
Classes, SysUtils,
IdHTTP, IdSSL, IdSSLOpenSSL;
implementation
procedure btn1click(IP:string);
var
idhttps: TIdHTTP;
sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
URL, html, response_code, err_code, err_msg : string;
MemoryStream: TMemoryStream;
rbstr: RawByteString;
begin
try
idhttps := TIdHTTP.Create();
sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
sslIOHandler.SSLOptions.Method := sslvSSLv23;
sslIOHandler.SSLOptions.Mode := sslmClient;
idhttps.IOHandler := sslIOHandler;
idhttps.HandleRedirects:=False;
idhttps.ConnectTimeout := 5000;
idhttps.ReadTimeout := 5000;
URL := 'https://' + IP + '/index.html';
try
MemoryStream := TMemoryStream.Create;
try
try
// HTTP Get Method
idhttps.Get(url, MemoryStream);
rbstr := PAnsiChar(MemoryStream.Memory);
if (Pos('utf-8', idhttps.Response.ContentType)=0) and (AnsiPos('charset=utf-8', string(rbstr))=0) then
SetCodePage(rbstr, 949, false)
else
SetCodePage(rbstr, 65001, false);
response_code := IntToStr(idhttps.Response.ResponseCode); // HTTP 응답 코드
html := string(rbstr); // 정상적인 페이지 응답은 여기에 저장
except on e: EIdHTTPProtocolException do
begin
err_code := IntToStr(e.ErrorCode); // 예외 상황의 에러 코드 (idhttps.Response.ResponseCode 와 거의 동일)
err_msg := e.ErrorMessage; // 예외 상황의 메시지, 웹 페이지 상에 보여주는 HTML 페이지 내용
end;
end;
finally
MemoryStream.Free;
end;
except on E:Exception do
end;
finally
idhttps.Disconnect;
sslIOHandler.Free;
idhttps.Free;
end;
except on E:Exception do
end;
end;
end.
HTTP/HTTPS 프로토콜을 델파이로 Indy 로 구현한 예제들입니다. (주로 웹 메일 로그인 부분에 집중된 내용)
가장 중요한 점 HTTP/HTTPS의 Get 요청에 대한 응답이 Indy 컴포넌트에서 대부분 exception의 ErrorMessage 로 저장된다는 점입니다.
웹 브라우저에서 보이는 것이 항상 Get 함수의 리턴 값 문자열이 아닌 예외 상황으로 많이 처리되는 것 때문에 상당히 어려움을 겪었습니다.
위 구문을 추가하시고, 다음과 같이 코드를 작성하면 됩니다.
아래 코드에서 memo 컴포넌트에 html, response_cdoe, err_code, err_msg 를 출력해보면, 감이 오시리라 생각합니다.
html만 중요한 게 아니라, err_ 쪽도 상당히 중요합니다. 처리가 항상 필요합니다.
unit Unit1;
interface
uses
Classes, SysUtils,
IdHTTP, IdSSL, IdSSLOpenSSL;
implementation
procedure btn1click(IP:string);
var
idhttps: TIdHTTP;
sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
URL, html, response_code, err_code, err_msg : string;
MemoryStream: TMemoryStream;
rbstr: RawByteString;
begin
try
idhttps := TIdHTTP.Create();
sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
sslIOHandler.SSLOptions.Method := sslvSSLv23;
sslIOHandler.SSLOptions.Mode := sslmClient;
idhttps.IOHandler := sslIOHandler;
idhttps.HandleRedirects:=False;
idhttps.ConnectTimeout := 5000;
idhttps.ReadTimeout := 5000;
URL := 'https://' + IP + '/index.html';
try
MemoryStream := TMemoryStream.Create;
try
try
// HTTP Get Method
idhttps.Get(url, MemoryStream);
rbstr := PAnsiChar(MemoryStream.Memory);
if (Pos('utf-8', idhttps.Response.ContentType)=0) and (AnsiPos('charset=utf-8', string(rbstr))=0) then
SetCodePage(rbstr, 949, false)
else
SetCodePage(rbstr, 65001, false);
response_code := IntToStr(idhttps.Response.ResponseCode); // HTTP 응답 코드
html := string(rbstr); // 정상적인 페이지 응답은 여기에 저장
except on e: EIdHTTPProtocolException do
begin
err_code := IntToStr(e.ErrorCode); // 예외 상황의 에러 코드 (idhttps.Response.ResponseCode 와 거의 동일)
err_msg := e.ErrorMessage; // 예외 상황의 메시지, 웹 페이지 상에 보여주는 HTML 페이지 내용
end;
end;
finally
MemoryStream.Free;
end;
except on E:Exception do
end;
finally
idhttps.Disconnect;
sslIOHandler.Free;
idhttps.Free;
end;
except on E:Exception do
end;
end;
end.