Oracle può essere utilizzato per effettuare una connessione HTTP: mi è capitato di affrontare un simile scenario quando ho dovuto “arricchire” dei dati a partire da informazioni che venivano erogate da un servizio di rete. Ho dovuto scrivere una routine Get_Stream() per recuperare l’XML dalla rete ed effettuare un parsing per estrarre i valori e caricarli nel database.
| DECLARE | |
| v_url VARCHAR2(255) := 'http://mysite.it:80'; | |
| v_clob CLOB; | |
| v_size NUMBER; | |
| v_time TIMESTAMP; | |
| v_duration INTERVAL DAY TO SECOND; | |
| BEGIN | |
| DBMS_OUTPUT.put_line('Connessione HTTP = ' || v_url); | |
| v_time := SYSTIMESTAMP; | |
| PKG_UTILITY_HTTP.Get_Stream(v_url, v_clob); | |
| v_duration := SYSTIMESTAMP - v_time; | |
| v_size := DBMS_LOB.Getlength(v_clob); | |
| DBMS_OUTPUT.put_line('Letti bytes ' || v_size || ' in ' || v_duration); | |
| END; | |
L’apertura di una connessione TCP/IP verso un indirizzo esterno al database è un’operazione delicata, quindi non permessa di default. Eseguendo il codice precedente ci si può imbattere nell’eccezione:
ORA-29273: richiesta HTTP non riuscita
ORA-06512: a "SYS.UTL_HTTP", line xxxx
ORA-24247: accesso alla rete negato dalla lista di controllo dell'accesso (ACL)
ORA-06512: a line xxxx
Bisogna dunque verificare che le Access Control Lists (ACL) del database consentano l’apertura di una connessione verso l’indirizzo ‘http://mysite.it’ sulla porta 80.
SELECT *
FROM DBA_NETWORK_ACLS;
NOTE
-
La creazione/modifica di un’ACL può essere fatta solo da un utente con i privilegi DBA. Per maggiori informazioni consiglio gli articoli:
Fine-Grained Access to Network Services in Oracle Database 11g su oracle-base-com
DBMS_NETWORK_ACL_ADMIN su download.oracle.com - Quando ho incluso la procedura in un package, sono stato costretto a specificare la clausola AUTHID CURRENT_USER per poter utilizzare l’ACL precedentemente creata. Questo forza il package ad essere eseguito con i privilegi dell’utente effettivamente loggato e non con quelli dell’utente che ha creato il package.