Files
apollinare-catering-software/docs/packages/XLIB_HTTP.md
2025-12-17 13:02:12 +01:00

478 lines
15 KiB
Markdown
Raw Blame History

# XLIB_HTTP
## Package Specification
```sql
PACKAGE "XLIB_HTTP"
AS
/*=========================================================================
Purpose : Make http callouts
License : Copyright (c) 2010 Dietmar Aust (opal-consulting.de)
Licensed under a BSD style license (license.txt)
http://www.opal-consulting.de/pls/apex/f?p=20090928:14
Version Date Author Comment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19.02.2007 D. Aust initial creation
07.08.2008 D. Aust - added check_get_request
- display_url_raw: pass all request headers
to the client
05.08.2012 D. Aust suppress mime header TRANSFER-ENCODING,
causes lots of problems with XMLDB listener
and others choking.
2.3.0.0 19.05.2014 D. Aust - #294 - Fix chunked encoding problem in
xlib_http.get_report
- added version information to this package
2.3.0.0 09.05.2015 D. Aust pass JSESSIONID from backend J2EE server to client
for image rendering in html reports
2.6.1 28.09.2020 D. Aust - #40 - APEX 20.1 security bundle (PSE 30990551) rejects response header "Cache-Control: private"
2.6.2 13.10.2020 D. Aust - added function check_acl()
=========================================================================*/
c_success CONSTANT CHAR (1) := '1';
c_fail CONSTANT CHAR (1) := '0';
-- version of this package
version_c constant varchar2(20 char) := '2.6.2';
TYPE vc_arr_t IS TABLE OF VARCHAR2 (32767) INDEX BY BINARY_INTEGER;
g_empty_vc_arr vc_arr_t;
/* Function: MyFunction
*
* Parameters:
*
* x - Description of x.
* y - Description of y.
* z - Description of z.
*/
PROCEDURE display_url_raw (
p_url VARCHAR2,
p_mime_type_override IN VARCHAR2 DEFAULT NULL,
p_charset IN VARCHAR2 DEFAULT NULL,
p_header_name_arr IN vc_arr_t default g_empty_vc_arr,
p_header_value_arr IN vc_arr_t default g_empty_vc_arr
);
/* Procedure: retrieve_blob_from_url
Multiplies two integers.
Parameters:
p_url - url to be called
o_blob - output: the resulting out blob
o_mime_type - output: the resulting out mime type from the call
Returns:
The two integers multiplied together.
o_blob - the resulting out blob
See Also:
<escape_form_data>
*/
PROCEDURE retrieve_blob_from_url (
p_url VARCHAR2,
o_blob OUT BLOB,
o_mime_type OUT VARCHAR2
);
/*
Function: escape_form_data
Here is some describing text ...
--- SQL
declare
l_i number;
begin
null;
Select count(*)
into l_count
from dual;
end;
---
Parameters:
s - string to be escaped
Returns:
the escaped data
*/
FUNCTION escape_form_data (s VARCHAR2)
RETURN VARCHAR2;
/*
Function: check_get_request
Parameters:
p_url the url to be called
Returns:
Returns c_fail or c_success
*/
FUNCTION check_get_request (p_url VARCHAR2)
RETURN CHAR;
/*
Function: check_acl
Parameters:
p_url the url to be called
Returns:
Returns c_fail or c_success
*/
FUNCTION check_acl (p_url VARCHAR2)
RETURN CHAR;
END;```
## Package Body
```sql
PACKAGE BODY "XLIB_HTTP"
AS
/*=========================================================================
Purpose : Make http callouts
License : Copyright (c) 2010 Dietmar Aust (opal-consulting.de)
Licensed under a BSD style license (license.txt)
https://github.com/daust/JasperReportsIntegration
Version Date Author Comment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19.02.2007 D. Aust initial creation
07.08.2008 D. Aust - added check_get_request
- display_url_raw: pass all request headers
to the client
05.08.2012 D. Aust suppress mime header TRANSFER-ENCODING,
causes lots of problems with XMLDB listener
and others choking.
2.3.0.0 19.05.2014 D. Aust - #294 - Fix chunked encoding problem in
xlib_http.get_report
- added version information to this package
2.3.0.0 09.05.2015 D. Aust pass JSESSIONID from backend J2EE server to client
for image rendering in html reports
2.6.1 28.09.2020 D. Aust - #40 - APEX 20.1 security bundle (PSE 30990551) rejects response header "Cache-Control: private"
2.6.2 13.10.2020 D. Aust - added function check_acl()
=========================================================================*/
m_module VARCHAR2 (50) := 'XLIB_HTTP';
PROCEDURE display_url_raw (
p_url VARCHAR2,
p_mime_type_override IN VARCHAR2 DEFAULT NULL,
p_charset IN VARCHAR2 DEFAULT NULL,
p_header_name_arr IN vc_arr_t default g_empty_vc_arr,
p_header_value_arr IN vc_arr_t default g_empty_vc_arr
)
IS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_blob BLOB;
l_raw RAW (32767);
l_buffer_size NUMBER := 32767;
--
l_proc VARCHAR2 (100) := m_module || '.DISPLAY_URL_RAW';
--
l_mime_type VARCHAR2 (100);
l_header_name VARCHAR2 (256);
l_header_value VARCHAR2 (1024);
l_jsession VARCHAR2 (256);
l_path VARCHAR2 (1024);
--
l_header_name_arr vc_arr_t;
l_header_value_arr vc_arr_t;
--
l_msg varchar2(32767);
BEGIN
xlog (l_proc, 'show url: ' || p_url);
--htp.flush();
--htp.init();
-- Initialize the BLOB.
DBMS_LOB.createtemporary (l_blob, FALSE);
l_http_request := UTL_HTTP.begin_request (url => p_url,
method => 'GET',
http_version => utl_http.http_version_1_0);
utl_http.set_header (l_http_request, 'Connection', 'Keep-Alive');
-- pass additional headers to the target service
for i in 1..p_header_name_arr.count loop
xlog(l_proc, 'pass additional headers to target service: '|| p_header_name_arr(i) ||': '||p_header_value_arr(i));
utl_http.set_header(l_http_request, p_header_name_arr(i), p_header_value_arr(i));
end loop;
-- get response from target service
l_http_response := UTL_HTTP.get_response (l_http_request);
FOR i IN 1 .. UTL_HTTP.get_header_count (l_http_response)
LOOP
UTL_HTTP.get_header (l_http_response,
i,
l_header_name,
l_header_value
);
-- store header value in arr
l_header_name_arr (i) := l_header_name;
l_header_value_arr (i) := l_header_value;
IF LOWER (l_header_name) = 'content-type'
THEN
l_mime_type := l_header_value;
xlog(l_proc, 'content-type from server: ' || l_mime_type);
END IF;
END LOOP;
-- override mime type
IF p_mime_type_override IS NOT NULL
THEN
l_mime_type := p_mime_type_override;
END IF;
-- Copy the response into the BLOB.
BEGIN
LOOP
UTL_HTTP.read_raw (l_http_response, l_raw, l_buffer_size);
DBMS_LOB.writeappend (l_blob, UTL_RAW.LENGTH (l_raw), l_raw);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (l_http_response);
END;
xlog(l_proc, 'set content-type: ' || l_mime_type);
OWA_UTIL.mime_header (ccontent_type => l_mime_type,
bclose_header => FALSE,
ccharset => p_charset
);
FOR i IN 1 .. l_header_name_arr.COUNT
LOOP
IF UPPER (l_header_name_arr (i)) IN
('CONTENT-LENGTH', 'CONTENT-TYPE', 'MIME-TYPE', 'TRANSFER-ENCODING',
'STRICT-TRANSPORT-SECURITY', 'CACHE-CONTROL', 'PRAGMA', 'EXPIRES')
THEN
--xlog (l_proc, 'skip header ' || l_header_name_arr (i));
null;
ELSE
if upper(l_header_name_arr(i)) = 'SET-COOKIE' and l_header_value_arr (i) like 'JSESSIONID%' then
xlog(l_proc , 'JSESSION_ID found !!!:'||l_header_value_arr (i));
--extract path
l_jsession := regexp_substr(l_header_value_arr (i), 'JSESSIONID=(.*);[ ]*Path',1, 1,'i',1);
l_path := regexp_substr(l_header_value_arr (i), ';[ ]*Path=(.*)',1, 1,'i',1);
xlog(l_proc, 'xx:full:'||l_header_value_arr (i)|| '; xx:session:'||l_jsession || '; xx:path:'||l_path);
else
l_header_value := l_header_value_arr (i);
end if;
xlog (l_proc,
'set header:'
|| l_header_name_arr (i)
|| ': '
|| l_header_value
);
HTP.p (l_header_name_arr (i) || ': ' || l_header_value);
END IF;
END LOOP;
-- JSESSION Cookies ausgeben
-- if using tunnel, then the cookie is JRI_JSESSIONID
-- if not using tunnel, then cookie is JSESSIONID directly
--
if xlib_jasperreports.get_use_images_no_tunnel=false then
l_msg := 'Set-Cookie: ' || xlib_jasperreports.m_jri_cookie_name_c || '=' || l_jsession;
xlog (l_proc, 'set header:' || l_msg );
HTP.p (l_msg);
l_msg := 'Set-Cookie: ' || xlib_jasperreports.m_jri_path_cookie_name_c || '=' || l_path;
xlog (l_proc, 'set header:' || l_msg );
HTP.p (l_msg);
else
l_msg := 'Set-Cookie: JSESSIONID=' || l_jsession;
if xlib_jasperreports.get_cookie_path_no_tunnel is not null then
l_msg := l_msg || '; Path=' || xlib_jasperreports.get_cookie_path_no_tunnel;
end if;
xlog (l_proc, 'set header:' || l_msg );
HTP.p (l_msg);
end if;
-- set content length
HTP.p ('Content-length: ' || DBMS_LOB.getlength (l_blob));
OWA_UTIL.http_header_close;
WPG_DOCLOAD.download_file (l_blob);
-- Relase the resources associated with the temporary LOB.
DBMS_LOB.freetemporary (l_blob);
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (l_http_response);
DBMS_LOB.freetemporary (l_blob);
RAISE;
WHEN OTHERS
THEN
xlog (l_proc, 'Error: ' || SQLERRM, 'ERROR');
RAISE;
END;
PROCEDURE retrieve_blob_from_url (
p_url VARCHAR2,
o_blob OUT BLOB,
o_mime_type OUT VARCHAR2
)
IS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_raw RAW (32767);
--
l_proc VARCHAR2 (100)
:= m_module || '.RETRIEVE_BLOB_FROM_URL';
--
l_header_name VARCHAR2 (256);
l_header_value VARCHAR2 (1024);
BEGIN
-- Initialize the BLOB.
dbms_lob.createtemporary (o_blob, false);
l_http_request := utl_http.begin_request (url => p_url,
method => 'GET',
http_version => utl_http.http_version_1_0);
l_http_response := UTL_HTTP.get_response (l_http_request);
FOR i IN 1 .. UTL_HTTP.get_header_count (l_http_response)
LOOP
UTL_HTTP.get_header (l_http_response,
i,
l_header_name,
l_header_value
);
IF LOWER (l_header_name) = 'content-type'
THEN
o_mime_type := l_header_value;
END IF;
END LOOP;
-- Copy the response into the BLOB.
BEGIN
LOOP
UTL_HTTP.read_raw (l_http_response, l_raw, 32767);
DBMS_LOB.writeappend (o_blob, UTL_RAW.LENGTH (l_raw), l_raw);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (l_http_response);
END;
-- Relase the resources associated with the temporary LOB.
--DBMS_LOB.freetemporary (l_blob);
EXCEPTION
WHEN OTHERS
THEN
UTL_HTTP.end_response (l_http_response);
DBMS_LOB.freetemporary (o_blob);
xlog (l_proc, 'Error: ' || SQLERRM, 'ERROR');
RAISE;
END;
FUNCTION escape_form_data (s VARCHAR2)
RETURN VARCHAR2
IS
l_s VARCHAR2 (500 CHAR);
FUNCTION r (s VARCHAR2, c VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN REPLACE (s, c, '%' || TRIM (TO_CHAR (ASCII (c), 'XX')));
END;
BEGIN
l_s := s;
l_s := REPLACE (l_s, ' ', '+');
l_s := r (l_s, chr(37)); -- %
l_s := r (l_s, chr(37)); -- /
l_s := r (l_s, chr(63)); -- ?
l_s := r (l_s, chr(38)); -- &
l_s := r (l_s, chr(228)); -- <20><><EFBFBD>
l_s := r (l_s, chr(196)); -- <20><>
l_s := r (l_s, chr(246)); -- <20><>
l_s := r (l_s, chr(214)); -- <20><>
l_s := r (l_s, chr(252)); -- <20><>
l_s := r (l_s, chr(220)); -- <20><><EFBFBD>
l_s := r (l_s, chr(223)); -- <20><><EFBFBD>
RETURN l_s;
END;
FUNCTION check_get_request (p_url VARCHAR2)
RETURN CHAR
IS
l_clob CLOB;
BEGIN
IF p_url IS NULL
THEN
RETURN c_fail;
END IF;
SELECT HTTPURITYPE (p_url).getclob ()
INTO l_clob
FROM DUAL;
/*SELECT c_success
INTO l_ret
FROM DUAL
WHERE EXISTS (SELECT HTTPURITYPE (p_url).getclob ()
FROM DUAL);
*/
RETURN c_success;
EXCEPTION
WHEN OTHERS
THEN
RETURN c_fail;
END;
FUNCTION check_acl (p_url VARCHAR2)
RETURN CHAR
IS
l_clob CLOB;
BEGIN
IF p_url IS NULL
THEN
RETURN c_fail;
END IF;
SELECT HTTPURITYPE (p_url).getclob ()
INTO l_clob
FROM DUAL;
/*SELECT c_success
INTO l_ret
FROM DUAL
WHERE EXISTS (SELECT HTTPURITYPE (p_url).getclob ()
FROM DUAL);
*/
RETURN c_success;
EXCEPTION
WHEN OTHERS
THEN
-- acl problem
if sqlcode=24247 then
RETURN c_fail;
else
-- no acl problem
return c_success;
end if;
END;
END;```