diff --git a/ora/ntlm_http_pkg.pkb b/ora/ntlm_http_pkg.pkb index cee54bd..cb5adcf 100755 --- a/ora/ntlm_http_pkg.pkb +++ b/ora/ntlm_http_pkg.pkb @@ -1,5 +1,13 @@ create or replace package body ntlm_http_pkg as + c_blob constant number(1) := 0; + c_clob constant number(1) := 1; + + type t_response_body is record ( + l_blob blob, + l_clob clob, + l_blob_or_clob number(1) default 1 + ); /* @@ -51,12 +59,55 @@ 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 +procedure get_response_body (p_resp in out utl_http.resp, p_response_body in out nocopy t_response_body) +as + l_bdata raw(32767); + l_cdata string_util_pkg.t_max_pl_varchar2; +begin + /* + + Purpose: get the response body as a blob + + Remarks: + + Who Date Description + ------ ---------- -------------------------------- + MBR 24.06.2011 Created + EAO 22.03.2015 Works with BLOBs + + */ + + if p_response_body.l_blob_or_clob = c_blob then + begin + loop + utl_http.read_raw(r => p_resp, data => l_bdata); + dbms_lob.append( p_response_body.l_blob, to_blob( l_bdata )); + end loop; + exception + when utl_http.end_of_body then + null; + end; + else + begin + loop + utl_http.read_text(r => p_resp, data => l_cdata); + p_response_body.l_clob := p_response_body.l_clob || l_cdata; + end loop; + exception + when utl_http.end_of_body then + null; + end; + end if; +end get_response_body; + + +procedure get_response (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, + p_response_body in out nocopy t_response_body) as l_req utl_http.req; @@ -76,62 +127,14 @@ as 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; + l_body clob; 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 @@ -139,7 +142,7 @@ as debug_pkg.printf('#%1 %2 : %3', i, l_name, l_value); end loop; - l_returnvalue := get_response_body (p_resp); + get_response_body (p_resp, p_response_body); debug_pkg.printf('Body length = %1', dbms_lob.getlength (l_returnvalue)); debug_pkg.printf('Persistent connection count: %1', utl_http.get_persistent_conn_count); @@ -148,7 +151,6 @@ as begin - /* Purpose: Get response clob from URL @@ -270,7 +272,45 @@ begin 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; + + +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_response_body t_response_body; +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 + EAO 22.03.2015 Most functionality moved to get_response + + */ + + dbms_lob.createtemporary( l_response_body.l_blob, true); + l_response_body.l_blob_or_clob := c_blob; + get_response( + p_url => get_response_blob.p_url, + p_username => get_response_blob.p_username, + p_password => get_response_blob.p_password, + p_wallet_path => get_response_blob.p_wallet_path, + p_wallet_password => get_response_blob.p_wallet_password, + p_proxy_server => get_response_blob.p_proxy_server, + p_response_body => l_response_body); + + return l_response_body.l_blob; end get_response_blob; @@ -282,219 +322,22 @@ function get_response_clob (p_url in varchar2, p_wallet_password in varchar2 := null, p_proxy_server in varchar2 := null) return clob as - - l_req utl_http.req; - l_resp utl_http.resp; - l_returnvalue clob; - - 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 clob - as - l_data string_util_pkg.t_max_pl_varchar2; - l_returnvalue clob; - begin - - /* - - Purpose: get the response body as a clob - - Remarks: - - Who Date Description - ------ ---------- -------------------------------- - MBR 24.06.2011 Created - - */ - - begin - loop - utl_http.read_text(r => p_resp, data => l_data); - l_returnvalue := l_returnvalue || 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 clob; - 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; - - + l_response_body t_response_body; 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 - - */ + dbms_lob.createtemporary( l_response_body.l_clob, true); + l_response_body.l_blob_or_clob := c_clob; - utl_http.set_detailed_excp_support (enable => true); - utl_http.set_response_error_check (false); + get_response( + p_url => get_response_clob.p_url, + p_username => get_response_clob.p_username, + p_password => get_response_clob.p_password, + p_wallet_path => get_response_clob.p_wallet_path, + p_wallet_password => get_response_clob.p_wallet_password, + p_proxy_server => get_response_clob.p_proxy_server, + p_response_body => l_response_body); - 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; + return l_response_body.l_clob; - -- 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_clob; @@ -697,4 +540,3 @@ end end_request; end ntlm_http_pkg; / - diff --git a/ora/ntlm_http_pkg.pks b/ora/ntlm_http_pkg.pks index 1cfe91f..34d1485 100755 --- a/ora/ntlm_http_pkg.pks +++ b/ora/ntlm_http_pkg.pks @@ -47,4 +47,3 @@ as end ntlm_http_pkg; / -