오늘 소개할 HttpRequest 클래스는 HTTP 또는 HTTPS 서버와 접속하여 Get, Post, Put 등의 요청을 수행할 수 있도록 해주며, IDL 9.0 버전에서 처음 도입되었습니다. 오늘은 HttpRequest 클래스의 기능에 관하여 간략히 소개를 해볼까 합니다. 사실 이와 유사한 기능이 기존에 없었던 것은 아닙니다. 제가 예전에 관련 게시물을 통하여 소개했던 IDLnetURL 클래스 역시 그 역할은 비슷합니다. 다만 둘 사이에는 기능상의 차이가 좀 있는데 대략 요약해보면 다음과 같습니다.
< IDLnetURL >
(1) HTTP, HTTPS 또는 FTP 서버에 접속
(2) Get, Put 등의 메서드들이 지원되지만 Post 메서드는 지원하지 않음
(3) 파일 다운로드 기능 탑재
< HttpRequest >
(1) HTTP 또는 HTTPS 서버에 접속 (FTP는 지원하지 않음)
(2) Get, Put, Post 등의 메서드들 및 JSON parse 기능 등이 지원됨
(3) 파일 다운로드 기능은 명시적으로 지원되지는 않음 (다만 읽은 컨텐츠를 별도로 파일로 저장할 수 있음)
따라서 접속하고자 하는 서버의 프로토콜 및 요청할 작업의 종류 등에 따라서 적합한 것을 선택하여 사용하면 됩니다. 그러면 HttpRequest 클래스를 사용하는 간단한 예제를 살펴봅시다. 먼저 아래와 같은 링크의 텍스트 파일로부터 그 데이터를 가져오기로 합니다.
https://services.swpc.noaa.gov/text/srs.txt
이를 위해서는 다음과 같이 HttpRequest 클래스의 Get 메서드를 이용하면 됩니다.
result = HttpRequest.Get('https://services.swpc.noaa.gov/text/srs.txt')
이와 같이 링크에 해당되는 문자열을 Get 메서드의 인수로 투입하면 됩니다. 이러한 내용을 실행하면 그 결과는 객체(object)의 형태로 획득되는데, 여기서는 result라는 이름으로 얻었습니다. 그 다음에는 이 result라는 이름으로 획득된 객체에 속한 하위 속성들(properties)로부터 각종 결과들을 입수할 수 있습니다. 먼저 STATUS_CODE 및 OK 속성 값들을 출력해봅시다.
PRINT, result.status_code
PRINT, result.ok
200
1
먼저 STATUS_CODE 속성은 HTTP 상태를 나타내는 값으로서 통상적으로는 200, 302, 401 등과 같은 값을 갖습니다. 이 속성이 이와 같이 100보다 큰 값들일 경우는 정상이라는 의미입니다. 하지만 만약 그 값이 100보다 작다면 뭔가 오류가 발생한 상황이라고 보면 됩니다. 그리고 OK 속성은 요청된 작업이 정상적으로 수행되었는가 여부를 나타내며 위와 같이 그 값이 1이면 정상 0이면 비정상이라는 의미가 됩니다. 이번에는 다음과 같이 TEXT 속성 값을 출력해봅시다.
PRINT, result.text
여기서 TEXT 속성의 값은 요청에 의하여 획득된 결과를 텍스트의 형태로 담은 문자열이 됩니다. 그리고 위와 같이 접속 대상 링크가 텍스트 파일인 경우라면 그 텍스트 파일의 내용을 그대로 담게 됩니다. 실제로 출력된 내용을 보면 다음과 같습니다. 참고로 링크의 대상인 srs.txt는 주기적으로 갱신되기 때문에 아래에 출력된 내용은 여러분이 직접 얻게될 내용과는 다를 것입니다.
:Product: Solar Region Summary
:Issued: 2024 Dec 06 0030 UTC
# Prepared jointly by the U.S. Dept. of Commerce, NOAA,
# Space Weather Prediction Center and the U.S. Air Force.
#
Joint USAF/NOAA Solar Region Summary
SRS Number 341 Issued at 0030Z on 06 Dec 2024
Report compiled from data received at SWO on 05 Dec
I. Regions with Sunspots. Locations Valid at 05/2400Z
Nmbr Location Lo Area Z LL NN Mag Type
3910 N16W47 106 0140 Hax 04 01 Alpha
3912 S06W16 075 0180 Dai 10 09 Beta
3913 S07W33 092 0030 Bxo 07 06 Beta
3915 N14E27 032 0010 Bxo 03 02 Beta
3916 S16E42 017 0160 Dai 08 06 Beta-Gamma
3917 S08E51 008 0090 Dri 07 06 Beta-Gamma
3918 N13W47 106 0030 Hrx 02 01 Alpha
IA. H-alpha Plages without Spots. Locations Valid at 05/2400Z Dec
Nmbr Location Lo
3908 N13W84 143
3914 N07W57 116
II. Regions Due to Return 06 Dec to 08 Dec
Nmbr Lat Lo
3904 S14 324
3896 N05 323
3893 S19 305
3898 S15 303
다만 위의 내용은 Get 메서드로 얻은 결과의 TEXT 속성을 통하여 가져온 데이터이며 실제로 srs.txt 파일 자체를 다운로드한 것은 아님을 유의해야 합니다. 만약 위와 같은 문자열을 프로그램 내에서 데이터로서 취급하는 것까지가 유저의 목적이었다면 여기까지의 작업만으로도 충분합니다. 하지만 위의 문자열을 담은 텍스트 파일 자체를 다운로드하는 것이 필요할 경우라면 추가적인 작업이 필요합니다. 물론 앞서 서두에서 언급했듯이 HttpRequest 클래스에서는 파일을 직접 다운로드하는 기능은 명시적으로 지원되지는 않습니다. 그 대신 Get 메서드로 가져온 데이터를 별도의 프로세스에 의하여 파일로 저장하는 것은 가능합니다. 만약 위와 같이 TEXT 속성으로 가져온 문자열을 텍스트 파일로 저장하고자 한다면 다음과 같이 처리하면 됩니다.
OPENW, lun, 'srs.txt', /GET_LUN
PRINTF, lun, result.text
FREE_LUN, lun
이렇게 하면 srs.txt라는 파일이 작업 디렉토리 내에 생성될 것입니다. 여기서는 텍스트 파일로 저장하기 위하여 OPENW 프로시저에서 파일 이름을 명시하고 PRINTF 프로시저로 result.text의 내용을 파일 내에 수록하였음에 주목하면 됩니다. 사실 엄밀히 따진다면 파일 자체를 직접 다운로드한 것은 아니지만, 파일이 담고있던 데이터를 가져와서 그 데이터를 그대로 담은 동일한 이름의 파일로 저장함으로써 그 파일을 유저가 재생산하였다고 보는 것이 맞습니다. 어쨌든 결과적으로만 보면 유저는 그 파일을 획득한 셈입니다.
그런데 위의 경우와 같이 링크의 대상이 텍스트 파일이 아닌 다른 형식일 경우에는 어떻게 해야 할까요? 예를 들면 그림 파일(png, jpg, gif 등)이나 netCDF, HDF 등과 같이 텍스트 형식이 아닌 다른 형식의 파일을 그 대상으로 하는 경우입니다. 그러면 이러한 예제로서 다음과 같이 GIF 파일을 가리키는 링크를 대상으로 해봅시다.
https://services.swpc.noaa.gov/images/ace-mag-swepam-7-day.gif
일단 이러한 링크에 대하여 HttpRequest 클래스의 Get 메서드를 이용하는 방식은 동일합니다.
result = HttpRequest.Get('https://services.swpc.noaa.gov/images/ace-mag-swepam-7-day.gif')
그리고 이 내용을 실행하여 얻은 결과인 result에는 분명히 그 대상이 된 GIF 파일의 내용이 담겨있습니다. 다만 이번에는 텍스트의 형태가 아니라 바이너리(binary) 형태로 얻어진 데이터를 파일로 저장해야 합니다. 이러한 데이터는 CONTENT 속성에 담겨있습니다. 즉 이번과 같은 경우에는 TEXT 속성이 아님에 유의해야 합니다. 어쨌든 Get 메서드를 사용하여 가져온 데이터를 GIF 파일로 담으려면 다음과 같이 처리하면 됩니다.
OPENW, lun, 'ace-mag-swepam-7-day.gif', /GET_LUN
WRITEU, lun, result.content
FREE_LUN, lun
이렇게 하면 ace-mag-swepam-7-day.gif라는 GIF 파일이 작업 디렉토리 내에 생성될 것입니다. 여기서는 GIF 파일로 저장하기 위하여 OPENW 프로시저에서 파일 이름을 명시하고 WRITEU 프로시저로 result.content의 내용을 파일 내에 수록하였음에 주목하면 됩니다. 실제로 이러한 과정에 의하여 얻어진 GIF 파일의 모습은 다음과 같습니다. 참고로 이 파일 역시 주기적으로 갱신되기 때문에 여러분이 얻게 될 모습과 아래의 모습은 다를 것입니다.
이와 같이 HttpRequest 클래스의 Get 메서드를 사용하면 HTTP 또는 HTTPS 프로토콜의 링크로부터 그 데이터를 가져올 수 있습니다. 다만 가져온 데이터를 파일의 형태로 얻으려면 별도의 파일 저장 과정이 필요하다는 점을 유의하면 됩니다.
그리고 대상 링크에 접속하기 위하여 별도의 계정이 필요한 경우가 있습니다. 즉 아이디와 패스워드가 필요한 경우인데, 그런 경우에는 Get 메서드의 HEADERS 속성에 관련 내용을 명시해야 합니다. 그러한 예문을 보면 다음과 같습니다.
basic = 'Basic ' + IDL_BASE64(BYTE('myname:mypass'))
response = HttpRequest.Get('myserver.org', HEADERS=HASH('Authorization', basic))
여기서는 HTTP 기본 인증(Basic Authentification)에 해당되는 경우를 예로 든 것입니다. 그리고 여기서 명시된 myname, mypass, myserver.org 등은 예시를 위하여 임의로 적은 가상의 문자열입니다.
지금까지 HttpRequest 클래스에 관하여 주로 Get 메서드를 사용하는 방법 위주로 소개를 해보았습니다. 물론 이 클래스에는 Get 외에도 Put, Post, JSON 등의 메서드들도 지원됩니다. Put 메서드는 링크의 자원(resource)의 내용을 수정 업데이트하는 경우이며 Post 메서드는 기존에 없는 자원을 새로 추가하는 경우에 해당됩니다. 이와 관련된 자세한 내용은 여기서는 생략하기로 하겠습니다. 다만 이와 관련된 내용은 아래 링크를 참조하시면 됩니다.
HttpRequest 클래스에 관한 전체적인 문법 및 세부 내용
https://www.nv5geospatialsoftware.com/docs/httprequest.html#HttpRequ
HttpRequest 클래스의 사용 예제들
https://www.nv5geospatialsoftware.com/docs/httprequestexamples.html
그리고 마지막으로 참조를 위하여, 앞서 GIF 파일을 얻는 예제를 만약 IDLnetURL 클래스를 이용하여 처리한다면 어떻게 하면 되는지도 한번 살펴봅시다. 그 과정은 다음과 같습니다.
oURL = OBJ_NEW('IDLnetUrl', URL_SCHEME='http', $
URL_HOST='services.swpc.noaa.gov', $
URL_PATH='images/ace-mag-swepam-7-day.gif')
result = oURL->Get(FILENAME='ace-mag-swepam-7-day.gif')
이와 같이 IDLnetURL 클래스의 객체를 생성하면서 URL_SCHEME, URL_HOST, URL_PATH 등의 속성들을 적절하게 설정한 다음 이 객체에 대하여 Get 메서드를 적용하면서 FILENAME 키워드를 함께 사용하면 됩니다. 이렇게 하면 해당 GIF 파일이 작업 디렉토리로 다운로드될 것입니다.
이와 같이 동일한 작업을 하는데 있어서 HttpRequest와 IDLnetURL은 세부적인 처리 방법이 서로 다릅니다. 당연한 얘기지만 어떤 방법을 택할 것인지에 대한 판단은 전적으로 유저의 몫입니다. 다만 유저 입장에서는 기존에 이미 IDLnetURL이 있는데 굳이 HttpRequest를 새로 도입할 필요가 있는가에 대한 궁금증이 생길 수도 있습니다. 저도 IDL 9.0이 출시된 직후에 이러한 궁금증을 갖기도 했었는데, 이와 관련하여 지금까지 제가 파악한 내용을 요약해보면 대략 다음과 같습니다.
(1) HTTP, HTTPS 프로토콜에 대한 기능들을 폭넓게 그리고 최신 동향에 맞춰서 대응할 수 있는 별도의 기능으로서 HttpRequest 클래스가 앞으로 그러한 역할을 할 것이다. 그러한 차원에서 HttpRequest 클래스는 Get, Put, Post, Escape, JSON 등과 같은 다양한 메서드들을 지원한다.
(2) 기존의 IDLnetURL은 그대로 유지되지만 기능상의 업데이트는 더 이상 없을 것 같다. 만약 IDLnetURL을 지금까지 잘 사용해오던 유저 입장에서는 굳이 갑자기 HttpRequest로 갈아타야 할 필요까지는 없을 것이다. 다만 그러한 경우라 하더라도 향후에 HttpRequest로 갈아타는 것을 한번 고려해보는 것도 나쁘지 않을 것이다.
(3) FTP 프로토콜의 경우 IDLnetURL에서는 지원이 되지만 HttpRequest에서는 지원되지 않는다. 사실 최근의 동향을 보면 FTP는 점점 그 사용 빈도가 점진적으로 줄어드는 추세에 있고, 기존에 FTP로 지원되던 서비스들이 HTTP로 대체되는 경우들도 있는 것 같다. 따라서 HttpRequest가 FTP를 지원하지 않는 것은 이러한 경향과 연관이 있다고 보면 된다.
대략 이와 같이 정리해보면 될 것 같습니다.
이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > Programming' 카테고리의 다른 글
LABEL_DATE 함수의 활용법 (1) | 2024.09.24 |
---|---|
IDL 8.9에서 추가된 상수 정의 기능 (1) | 2023.06.29 |
IDL 8.9의 Literal Strings 문법 (0) | 2023.06.28 |
음수 범위를 로그 스케일(Log Scale)로 표시하기 (0) | 2023.04.25 |
WHILE 및 REPEAT 구문의 이해 (0) | 2023.02.10 |