본 장에서는 HTTP/1.1을 기준으로 작성되었으며, UTL_HTTP 패키지의 기본 개념과 패키지 내의 함수를 사용하는 방법을 설명한다.
UTL_HTTP는 웹 표준(RFC2616)인 HTTP 프로토콜에 따라 클라이언트 역할을 제공하는 패키지이다.
프로토콜을 세부 조작하거나 간단히 웹 페이지만을 얻어올 수 있는 서브 프로그램을 제공한다.
HTTP 버전의 종류를 나타낸다.
HTTP_VERSION_1 CONSTANT VARCHAR2(10) := 'HTTP/1.1'; DEFAULT_HTTPS_PORT CONSTANT PLS_INTEGER := 443;
HTTP에서 사용할 네트워크 포트 번호를 나타낸다.
DEFAULT_HTTP_PORT CONSTANT PLS_INTEGER := 80; DEFAULT_HTTPS_PORT CONSTANT PLS_INTEGER := 443;
HTTP 프로토콜에 따라 서버로부터 응답받은 응답의 상태를 나타내는 코드이다.
상태 코드 상수의 세부 내용은 다음과 같다. 이때 상태 코드는 번호 순으로 정렬되어 있다.
HTTP_CONTINUE CONSTANT PLS_INTEGER := 100; HTTP_SWITCHING_PROTOCOLS CONSTANT PLS_INTEGER := 101; HTTP_OK CONSTANT PLS_INTEGER := 200; HTTP_CREATED CONSTANT PLS_INTEGER := 201; HTTP_ACCEPTED CONSTANT PLS_INTEGER := 202; HTTP_NON_AUTHORITATIVE_INFO CONSTANT PLS_INTEGER := 203; HTTP_NO_CONTENT CONSTANT PLS_INTEGER := 204; HTTP_RESET_CONTENT CONSTANT PLS_INTEGER := 205; HTTP_PARTIAL_CONTENT CONSTANT PLS_INTEGER := 206; HTTP_MULTIPLE_CHOICES CONSTANT PLS_INTEGER := 300; HTTP_MOVED_PERMANENTLY CONSTANT PLS_INTEGER := 301; HTTP_FOUND CONSTANT PLS_INTEGER := 302; HTTP_SEE_OTHER CONSTANT PLS_INTEGER := 303; HTTP_NOT_MODIFIED CONSTANT PLS_INTEGER := 304; HTTP_USE_PROXY CONSTANT PLS_INTEGER := 305; HTTP_TEMPORARY_REDIRECT CONSTANT PLS_INTEGER := 307; HTTP_BAD_REQUEST CONSTANT PLS_INTEGER := 400; HTTP_UNAUTHORIZED CONSTANT PLS_INTEGER := 401; HTTP_PAYMENT_REQUIRED CONSTANT PLS_INTEGER := 402; HTTP_FORBIDDEN CONSTANT PLS_INTEGER := 403; HTTP_NOT_FOUND CONSTANT PLS_INTEGER := 404; HTTP_NOT_ACCEPTABLE CONSTANT PLS_INTEGER := 406; HTTP_PROXY_AUTH_REQUIRED CONSTANT PLS_INTEGER := 407; HTTP_REQUEST_TIME_OUT CONSTANT PLS_INTEGER := 408; HTTP_CONFLICT CONSTANT PLS_INTEGER := 409; HTTP_GONE CONSTANT PLS_INTEGER := 410; HTTP_LENGTH_REQUIRED CONSTANT PLS_INTEGER := 411; HTTP_PRECONDITION_FAILED CONSTANT PLS_INTEGER := 412; HTTP_REQUEST_ENTITY_TOO_LARGE CONSTANT PLS_INTEGER := 413; HTTP_REQUEST_URI_TOO_LARGE CONSTANT PLS_INTEGER := 414; HTTP_UNSUPPORTED_MEDIA_TYPE CONSTANT PLS_INTEGER := 415; HTTP_REQ_RANGE_NOT_SATISFIABLE CONSTANT PLS_INTEGER := 416; HTTP_EXPECTATION_FAILED CONSTANT PLS_INTEGER := 417; HTTP_NOT_IMPLEMENTED CONSTANT PLS_INTEGER := 501; HTTP_BAD_GATEWAY CONSTANT PLS_INTEGER := 502; HTTP_SERVICE_UNAVAILABLE CONSTANT PLS_INTEGER := 503; HTTP_GATEWAY_TIME_OUT CONSTANT PLS_INTEGER := 504; HTTP_VERSION_NOT_SUPPORTED CONSTANT PLS_INTEGER := 505;
본 절에서는 UTL_HTTP 패키지에서 제공하는 별도 정의된 타입들을 알파벳 순으로 설명한다.
서버로부터 응답받은 페이지를 문자열의 배열 형태로 받아올 때 사용하는 타입이다.
HTML_PIECES 타입의 세부 내용은 다음과 같다.
프로토타입
TYPE html_pieces IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
서버로 보낼 요청 정보를 담고 있는 타입이다.
프로토타입
TYPE req IS RECORD ( url VARCHAR2(32767), method VARCHAR2(64), http_version VARCHAR2(64) );
필드
필드 이름 | 설명 |
---|---|
url | 웹 페이지의 주소이며, 자세한 내용은 “56.7. URL”을 참고한다. |
method | 서버에 어떠한 종류의 메서드를 요청할지를 나타낸다. 'OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'의 값만을 허용한다. (이외는 미지원) |
http_version | 프로토콜 버전을 나타내며, 값의 종류는 “56.2.1. HTTP 버전 상수”를 참고한다. |
서버에서 온 응답에 대한 상태 정보를 담고 있는 타입이다.
프로토타입
TYPE resp IS RECORD ( status_code PLS_INTEGER, reason_phrase VARCHAR2(256), http_version VARCHAR2(64) );
필드
필드 이름 | 설명 |
---|---|
status_code | 요청에 따른 응답에 대한 상태를 나타내는 3자리의 숫자이며, 값의 종류는 “56.2.3. 상태 코드 상수”를 참고한다. |
reason_phrase | 상태 코드에 따르는 간단한 설명이다. |
http_version | 프로토콜 버전을 나타내며, 값의 종류는 “56.2.1. HTTP 버전 상수”를 참고한다. |
다음은 UTL_HTTP 패키지에서 미리 제공된 예외이다. 자세한 내용은 “56.5. 함수”와 “56.6. 프러시저”의 "예외 사항" 항목을 참고한다.
BAD_ARGUMENT
END_OF_BODY
REQUEST_FAILED
본 절에서는 UTL_HTTP 패키지에서 제공하는 함수를 알파벳 순으로 설명한다.
웹 서버와 커넥션을 맺고, 어떤 메서드를 통해서 서버에 요청을 할 지 정한다.
BEGIN_REQUEST 함수의 세부 내용은 다음과 같다.
프로토타입
FUNCTION BEGIN_REQUEST ( url IN VARCHAR2, method IN VARCHAR2 DEFAULT 'GET', http_version IN VARCHAR2 DEFAULT NULL ) RETURN req;
파라미터
파라미터 | 설명 |
---|---|
url | 웹 페이지의 주소이며, 자세한 내용은 “56.7. URL”을 참고한다. |
method | 서버에 어떠한 종류의 메서드를 요청할지를 나타낸다. 'OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'의 값만을 허용한다. (이외는 미지원) |
http_version | 프로토콜 버전을 나타내며, 값의 종류는 “56.2.1. HTTP 버전 상수”를 참고한다. |
예외 사항
예외 사항 | 설명 |
---|---|
REQUEST_FAILED | 잘못된 요청으로 웹 서버와 통신할 수 없는 경우에 발생한다. URL이 올바른지 또는 웹 서버가 정상적으로 동작하는지 확인한다. |
PKG_TRANSFER_TIMEOUT | 20초 이상 웹 서버로부터 응답이 없을 때 타임아웃이 발생한 경우이다. |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
웹 서버에 요청을 보내고, 응답의 헤더를 읽고, 바디를 읽을 준비를 한다. 메시지 BODY를 읽는 방법은 2가지이다.
첫 번째 방법은 메시지 헤더에 "Content-Length: 길이"가 있는 경우이며, 동작은 주어진 길이만큼 메시지 바디를 읽어온다. 두 번째 방법은 메시지 헤더에 "Transfer-Encoding: Chunked"가 오는 경우이며, 캐리지 리턴, 라인피드 문자가 나오는 경우까지 메시지 바디를 읽는다. 헤더에 "Content-Length:길이"와 Tranfer-Encoding: Chunked"이 둘다 주어진 경우 전자는 무시된다.
GET_RESPONSE 함수의 세부 내용은 다음과 같다.
프로토타입
FUNCTION GET_RESPONSE ( r IN OUT NOCOPY req ) RETURN resp;
파라미터
파라미터 | 설명 |
---|---|
r | 요청 식별자이다. |
예외 사항
예외 사항 | 설명 |
---|---|
BAD_ARGUMENT | BEGIN_REQUEST 또는 SET_HEADER를 선행하지 않고 해당 함수를 호출하거나, 파라미터를 잘못 사용하게 되는 경우 발생한다. |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
URL을 통해 웹 서버로 요청을 보내 최대 2000bytes의 데이터를 반환하는 함수이다. 웹 서버로 요청을 보낼 경우 HTTP/1.1 표준의 GET 메서드를 이용한다.
프로토타입
FUNCTION REQUEST ( url IN VARCHAR2, proxy IN VARCHAR2 DEFAULT NULL, wallet_path IN VARCHAR2 DEFAULT NULL, wallet_password IN VARCHAR2 DEFAULT NULL ) RETURN VARCHAR2;
파라미터
파라미터 | 설명 |
---|---|
url | 웹 페이지의 주소이며, 자세한 내용은 “56.7. URL”을 참고한다. |
proxy | 프록시 서버의 이름이다. (기본값: NULL, 다음에 구현할 예정이다) |
wallet_path | 클라이언트 쪽에서 HTTPS를 사용하기 위해 필요한 인증서를 저장하는 경로이다. (기본값: NULL, 다음에 구현할 예정이다) |
wallet_password | 인증서를 보기 위한 패스워드이다. (기본값: NULL, 다음에 구현할 예정이다) |
예외 사항
예외 사항 | 설명 |
---|---|
REQUEST_FAILED | 잘못된 요청으로 웹 서버와 통신할 수 없는 경우에 발생한다. URL이 올바른지 또는 웹 서버가 정상적으로 동작하는지 확인한다. |
PKG_TRANSFER_TIMEOUT | 20초 이상 웹 서버로부터 응답이 없을 때 타임아웃이 발생한 경우이다. |
예제
DECLARE resp VARCHAR2(32767); BEGIN resp := UTL_HTTP.REQUEST('http://www.w3.org/Protocols/'); END;
HTTP 요청을 끝낸다. 이때 자원(버퍼 메모리, 소켓)이 모두 반환되고, 초기화 상태로 변경된다.
END_RESPONSE 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE END_RESPONSE ( r IN OUT NOCOPY resp );
파라미터
파라미터 | 설명 |
---|---|
r | http의 response 이다 |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
세션에 설정된 기본 메시지 바디 문자 집합의 이름을 가져온다.
GET_BODY_CHARSET 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE GET_BODY_CHARSET ( charset OUT NOCOPY VARCHAR2 );
파라미터
파라미터 | 설명 |
---|---|
charset | 세션에 설정된 문자 집합 이름(캐노니컬 문자 집합 이름)이다. |
예제
DECLARE
charset varchar(64);
BEGIN
UTL_HTTP.GET_BODY_CHARSET(charset); -- 캐노니컬 문자 집합의 이름
END;
/
세션에 설정된 UTL_HTTP 패키지 수행도중 발생하는 에러의 자세한 메시지 출력 여부 정보를 가져온다.
GET_DETAILED_EXCP_SUPPORT 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE GET_DETAILED_EXCP_SUPPORT ( enable OUT BOOLEAN );
파라미터
파라미터 | 설명 |
---|---|
enable | 기능 활성화 여부를 나타낸다. |
예제
DECLARE
enable BOOLEAN;
BEGIN
UTL_HTTP.GET_DETAILED_EXCP_SUPPORT(enable); -- 활성화 여부
END;
/
현재 세션에 설정되어 있는 타임아웃 시간을 읽어온다. (기본 타임아웃 시간: 50초)
GET_TRANSFER_TIMEOUT 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE GET_TRANSFER_TIMEOUT ( timeout OUT PLS_INTEGER );
파라미터
파라미터 | 설명 |
---|---|
timeout | 세션에 설정된 타임아웃 시간이다. |
예제
DECLARE timeout PLS_INTEGER; BEGIN utl_http.get_transfer_timeout(var); END;
헤더를 제외한 요청 페이지의 바디를 읽어온다.
READ_TEXT 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE READ_TEXT ( r IN OUT NOCOPY resp, data OUT NOCOPY VARCHAR2, len IN PLS_INTEGER DEFAULT NULL );
파라미터
파라미터 | 설명 |
---|---|
r | 응답 식별자이다. |
data | 헤더를 제외한 바디 문자열이다. |
len | 0 이상의 값이어야 하며, 최대 읽어올 문자열의 길이이다. 이때 요청한 길이보다 바디가 짧게 남아 있는 경우에는 해당 길이보다 적게 읽어온다. |
예외 사항
예외 사항 | 설명 |
---|---|
BAD_ARGUMENT | GET_RESPONSE 함수를 선행하지 않고 해당 함수를 호출하거나, 파라미터를 잘못 사용하게 되는 경우 발생한다. |
END_OF_BODY | 바디 내용을 모두 읽었는데, 다시 한번 읽기 요청을 하게 되는 경우 발생한다. |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
HTTP 요청이나 HTTP 응답 메시지 바디의 문자 집합을 지정한다.
SET_BODY_CHARSET의 세부 내용은 다음과 같다.
CASE1
HTTP 요청이나 HTTP 응답에 문자 집합(Character Set)을 지정하지 않는 경우 그리고 메시지 헤더에 Content-Type이 지정되지 않은 경우, 문자 집합을 지정할수 있다. 메시지 헤더에 Content-Type이 지정된 경우에는 무시된다. 세션 단위로 해당 정보의 설정이 가능하다.
프로토타입
PROCEDURE SET_BODY_CHARSET ( charset IN VARCHAR2 DEFAULT NULL );
파라미터
파라미터 | 설명 |
---|---|
charset | 문자 집합(캐노니컬 문자 집합)의 이름이다. (기본값: 'ISO-8859-1') (예: ASCII, UTF-8, EUC-KR, CP949 ... 등) |
CASE2
HTTP 요청의 헤더에 Content-Type이 지정되지 않은 경우, 바디의 문자 집합을 지정한다. 문자열을 생략하는 경우, 'ISO-8859-1'로 간주된다. HTTP 요청 메시지 바디는 DB 문자 집합 문자열에서 지정된 문자열 집합의 문자열로 자동 변환된다. 메시지 헤더에 Content-Type이 지정된 경우에는 무시된다. 한번의 HTTP 요청에 대하여 설정 가능하다.
프로토타입
PROCEDURE SET_BODY_CHARSET ( r IN OUT NOCOPY req, charset IN VARCHAR2 DEFAULT NULL );
파라미터
파라미터 | 설명 |
---|---|
charset | 문자 집합(캐노니컬 문자 집합)의 이름이다. (기본값: 'ISO-8859-1') (예: ASCII, UTF-8, EUC-KR, CP949 ... 등) |
req | HTTP 요청이다. |
CASE3
HTTP 응답의 헤더에 Content-Type이 지정되지 않은 경우, 바디의 문자열로 간주되는 문자열 집합을 지정한다. 문자열을 생략하는 경우, 'ISO-8859-1'로 간주된다. HTTP 응답 메시지 바디는 지정된 문자열 집합의 문자열에서 DB 문자 집합 문자열로 자동 변환된다. 메시지 헤더에 Content-Type이 지정된 경우에는 무시된다. 한번의 HTTP 응답에 대하여 설정 가능하다.
프로토타입
PROCEDURE SET_BODY_CHARSET ( r IN OUT NOCOPY resp, charset IN VARCHAR2 DEFAULT NULL );
파라미터
파라미터 | 설명 |
---|---|
charset | 문자 집합(캐노니컬 문자 집합)의 이름이다. (기본값: 'ISO-8859-1') (예: ASCII, UTF-8, EUC-KR, CP949 ... 등) |
resp | HTTP 응답이다. |
예외 사항
예외 사항 | 설명 |
---|---|
BAD_ARGUMENT | 올바른 문자 집합 문자열을 넣지 않는 경우 발생한다. |
예제
-- HTTP 요청과 응답의 바디 문자 집합을 UTF-8로 변경함 DECLARE req UTL_HTTP.REQ; resp UTL_HTTP.RESP; value varchar(32767); BEGIN req := UTL_HTTP.BEGIN_REQUEST('http://www.naver.com', 'GET','HTTP/1.1'); UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0'); UTL_HTTP.WRITE_TEXT(req, 'test_value'); UTL_HTTP.SET_BODY_CHARSET(req, 'UTF-8'); resp := UTL_HTTP.GET_RESPONSE(req); UTL_HTTP.SET_BODY_CHARSET(resp, 'UTF-8'); FOR i in 1 .. 200000 LOOP UTL_HTTP.READ_TEXT(resp, value); DBMS_OUTPUT.PUT_LINE ( value ); END LOOP; UTL_HTTP.END_RESPONSE(resp); exception when others then UTL_HTTP.END_RESPONSE(resp); end; / -- HTTP 요청과 응답에 대한 세션의 기본 문자 집합을 UTF-8로 변경함 BEGIN UTL_HTTP.SET_BODY_CHARSET('UTF-8'); END; /
세션에 설정된 UTL_HTTP 패키지 수행도중 발생하는 에러의 자세한 메시지 출력 여부를 설정한다.
SET_DETAILED_EXCP_SUPPORT 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE SET_DETAILED_EXCP_SUPPORT ( enable OUT BOOLEAN DEFAULT FALSE );
파라미터
파라미터 | 설명 |
---|---|
enable | 기능 활성화 여부를 나타낸다. (기본값: 비활성화) |
예제
BEGIN
UTL_HTTP.SET_DETAILED_EXCP_SUPPORT(false); -- 비활성화
END;
/
서버로 보낼 요청에 헤더를 설정한다. 여러 번 반복 수행하여 추가적인 헤더 정보의 추가가 가능하다.
SET_HEADER 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE SET_HEADER ( r IN OUT NOCOPY req, name IN VARCHAR2, value IN VARCHAR2 );
파라미터
파라미터 | 설명 |
---|---|
r | 요청 식별자이다. |
name | 설정할 헤더 이름이다. |
value | 설정할 헤더 값이다. |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
웹 서버로부터 받은 상태 코드가 에러에 대한 코드일 경우, 이를 GET_RESPONSE GET_RESPONSE에서 상태 에러를 예외로 처리할 지를 설정하는 프러시저다. 400부터 599까지의 상태 코드가 상태 에러에 해당한다.
SET_RESPONSE_ERROR_CHECK 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE SET_RESPONSE_ERROR_CHECK ( enable IN BOOLEAN DEFAULT FALSE );
파라미터
파라미터 | 설명 |
---|---|
enable | 상태 에러 확인 기능 활성화 여부를 나타낸다. (기본값: 비활성화) |
예제
DECLARE
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(1024);
BEGIN
UTL_HTTP.SET_RESPONSE_ERROR_CHECK(enable => TRUE); -- 활성화
req := UTL_HTTP.BEGIN_REQUEST('http://getstatuscode.com/400','GET', 'HTTP/1.1');
UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0');
resp := UTL_HTTP.GET_RESPONSE(req);
UTL_HTTP.END_RESPONSE(resp);
END;
/
현재 세션에 타임아웃 시간을 설정한다. (기본 타임아웃 시간: 50초)
SET_TRANSFER_TIMEOUT 프러시저의 세부 내용은 다음과 같다.
프로토타입
PROCEDURE SET_TRANSFER_TIMEOUT ( timeout IN PLS_INTEGER );
파라미터
파라미터 | 설명 |
---|---|
timeout | 세션에 설정할 타임아웃 시간이다. |
예제
BEGIN utl_http.set_transfer_timeout(30); END; /
서버로 보낼 요청의 바디를 설정한다.
프로토타입
PROCEDURE WRITE_TEXT ( r IN OUT NOCOPY REQ, data IN VARCHAR2 );
파라미터
파라미터 | 설명 |
---|---|
r | 요청 식별자이다. |
data | 요청 바디의 내용이다. |
예외 사항
예외 사항 | 설명 |
---|---|
BAD_ARGUMENT | BEGIN_REQUEST 또는 SET_HEADER를 선행하지 않고 해당 함수를 호출하거나, 파라미터를 잘못 사용하게 되는 경우 발생한다. |
END_OF_BODY | 바디 내용을 모두 읽었는데, 다시 한번 읽기 요청을 하게 되는 경우 발생한다. |
예제
단일 함수 사용의 예가 아니므로, “56.8. 예제”를 참고한다.
URL(Uniform Resource/ Locator)은 서버의 웹 페이지 주소를 나타내는 형태이며, 다음과 같은 형태로 구성된다.
scheme://[user[password]@]host[:port]/[...]
다음은 각 항목에 대한 설명이다.
항목 | 설명 |
---|---|
scheme | http와 https가 있으며, https는 다음에 구현할 예정이다. |
user | proxy를 위해 존재하며, 다음에 구현할 예정이다. |
password | proxy를 위해 존재하며, 다음에 구현할 예정이다. |
host | HTTP 서버 호스트 이름이다. |
port | 통신에 사용할 포트 번호이다. |
다음은 BEGIN_REQUEST, SET_HEADER, WRITE_TEXT, GET_RESPONSE, END_RESPONSE를 이용하여 ims.tmaxsoft.com의 로그인 웹 페이지의 html 스크립트를 읽어오는 예이다.
DECLARE req UTL_HTTP.REQ; resp UTL_HTTP.RESP; value VARCHAR2(1024); BEGIN req := UTL_HTTP.BEGIN_REQUEST('http://ims.tmaxsoft.com/tody/auth/login.do', 'POST', 'HTTP/1.1'); UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0'); UTL_HTTP.WRITE_TEXT(req, 'test_value'); resp := UTL_HTTP.GET_RESPONSE(req); LOOP UTL_HTTP.READ_TEXT(resp, value); DBMS_OUTPUT.PUT_LINE ( value ); END LOOP; EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE(resp); END; /