From 9c8dceb9854c27407980518cb366d9c4348674a9 Mon Sep 17 00:00:00 2001 From: Eric Olson Date: Fri, 20 Mar 2015 18:46:33 -0500 Subject: [PATCH] Create ntlm_http_pkg.get_response_blob Added a function to ntlm_http_pkg to retrieve the URL as a BLOB. --- ora/ntlm_http_pkg.pkb | 224 ++++++++++++++++++++++++++++++++++++++++++ ora/ntlm_http_pkg.pks | 8 ++ 2 files changed, 232 insertions(+) diff --git a/ora/ntlm_http_pkg.pkb b/ora/ntlm_http_pkg.pkb index bdf93b4..cee54bd 100755 --- a/ora/ntlm_http_pkg.pkb +++ b/ora/ntlm_http_pkg.pkb @@ -51,6 +51,230 @@ begin end headers_contain_value; +function get_response_blob (p_url in varchar2, + p_username in varchar2, + p_password in varchar2, + p_wallet_path in varchar2 := null, + p_wallet_password in varchar2 := null, + p_proxy_server in varchar2 := null) return blob +as + + l_req utl_http.req; + l_resp utl_http.resp; + l_returnvalue blob; + + l_authenticate_with_ntlm boolean; + + l_name varchar2(500); + l_value varchar2(500); + + l_ntlm_message varchar2(500); + + l_negotiate_message varchar2(500); + + l_server_challenge raw(4000); + l_negotiate_flags raw(4000); + + l_authenticate_message varchar2(500); + + + function get_response_body (p_resp in out utl_http.resp) return blob + as + l_data raw(32767); + l_returnvalue blob; + begin + + /* + + Purpose: get the response body as a blob + + Remarks: + + Who Date Description + ------ ---------- -------------------------------- + MBR 24.06.2011 Created + + */ + + dbms_lob.createtemporary( l_returnvalue, true ); + + begin + loop + utl_http.read_raw(r => p_resp, data => l_data); + dbms_lob.append( l_returnvalue, to_blob( l_data )); + end loop; + exception + when utl_http.end_of_body then + null; + end; + + return l_returnvalue; + + end get_response_body; + + + procedure debug_response (p_resp in out utl_http.resp) + as + l_name varchar2(255); + l_value varchar2(2000); + l_body blob; + begin + + /* + + Purpose: print debug info about the response + + Remarks: + + Who Date Description + ------ ---------- -------------------------------- + MBR 24.06.2011 Created + + */ + + debug_pkg.printf('Response Status Code: %1', p_resp.status_code); + + for i in 1 .. utl_http.get_header_count (p_resp) loop + utl_http.get_header (p_resp, i, l_name, l_value); + debug_pkg.printf('#%1 %2 : %3', i, l_name, l_value); + end loop; + + l_returnvalue := get_response_body (p_resp); + + debug_pkg.printf('Body length = %1', dbms_lob.getlength (l_returnvalue)); + debug_pkg.printf('Persistent connection count: %1', utl_http.get_persistent_conn_count); + + end debug_response; + + +begin + + /* + + Purpose: Get response clob from URL + + Remarks: see http://davenport.sourceforge.net/ntlm.html#ntlmHttpAuthentication + + Who Date Description + ------ ---------- -------------------------------- + FDL 11.05.2011 Created + MBR 03.06.2011 Lots of changes + + */ + + utl_http.set_detailed_excp_support (enable => true); + utl_http.set_response_error_check (false); + + utl_http.set_persistent_conn_support (true, 10); + + debug_pkg.printf('Persistent connection count: %1', utl_http.get_persistent_conn_count); + + -- support for HTTPS + if instr(lower(p_url),'https') = 1 then + utl_http.set_wallet (p_wallet_path, p_wallet_password); + end if; + + -- support for proxy server + if p_proxy_server is not null then + utl_http.set_proxy (p_proxy_server); + end if; + + ------------ + -- Request 1 + ------------ + + debug_pkg.printf(' '); + debug_pkg.printf(p_url); + + l_req := utl_http.begin_request(p_url); + + l_resp := utl_http.get_response (l_req); + + debug_response (l_resp); + + if l_resp.status_code = utl_http.HTTP_UNAUTHORIZED then + + l_authenticate_with_ntlm := headers_contain_value (l_resp, 'WWW-Authenticate', 'NTLM'); + + utl_http.end_response (l_resp); + + if l_authenticate_with_ntlm then + + l_negotiate_message := 'NTLM ' || ntlm_util_pkg.get_negotiate_message(p_username); + -- need to send negotiation message + + debug_pkg.printf('Negotiate message: %1', l_negotiate_message); + + ------------ + -- Request 2 + ------------ + + debug_pkg.printf(' '); + debug_pkg.printf(p_url); + l_req := utl_http.begin_request(p_url); + utl_http.set_header (l_req, 'Authorization', l_negotiate_message); + + l_resp := utl_http.get_response(l_req); + + debug_response (l_resp); + + if l_resp.status_code = utl_http.HTTP_UNAUTHORIZED then + + -- received server challenge + utl_http.get_header_by_name(l_resp, 'WWW-Authenticate', l_value, 1); + + utl_http.end_response(l_resp); + + if substr(l_value, 1, 4) = 'NTLM' then + + -- get value + l_value := substr(l_value, 6); + + ntlm_util_pkg.parse_challenge_message (l_value, l_server_challenge, l_negotiate_flags); + + l_authenticate_message := 'NTLM ' || ntlm_util_pkg.get_authenticate_message(p_username, p_password, l_server_challenge, l_negotiate_flags); + debug_pkg.printf('Authenticate message: "%1"', l_authenticate_message); + + ------------ + -- Request 3 + ------------ + + -- sending NTLM message 3 + debug_pkg.printf(' '); + debug_pkg.printf(p_url); + l_req := utl_http.begin_request(p_url); + + utl_http.set_header (l_req, 'Connection', 'close'); + utl_http.set_header (l_req, 'Authorization', l_authenticate_message); + + l_resp := utl_http.get_response (l_req); + + debug_response (l_resp); + + -- this is already done inside debug_response + --l_returnvalue := get_response_body (l_resp); + + utl_http.end_response(l_resp); + + end if; + + end if; + + else + debug_pkg.printf('Server is not configured with NTLM security (missing "WWW-Authenticate: NTLM" header).'); + end if; + + end if; + + + utl_http.close_persistent_conns; + debug_pkg.printf('Persistent connection count (should be zero): %1', utl_http.get_persistent_conn_count); + + return l_returnvalue; + +end get_response_blob; + + function get_response_clob (p_url in varchar2, p_username in varchar2, p_password in varchar2, diff --git a/ora/ntlm_http_pkg.pks b/ora/ntlm_http_pkg.pks index 9625ea1..1cfe91f 100755 --- a/ora/ntlm_http_pkg.pks +++ b/ora/ntlm_http_pkg.pks @@ -17,6 +17,14 @@ as */ + -- get blob from url + function get_response_blob (p_url in varchar2, + p_username in varchar2, + p_password in varchar2, + p_wallet_path in varchar2 := null, + p_wallet_password in varchar2 := null, + p_proxy_server in varchar2 := null) return blob; + -- get clob from url function get_response_clob (p_url in varchar2, p_username in varchar2,