Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is UTL_HTTP.GET_RESPONSE throwing HTTP protocol error

I am calling a webservice from Oracle 11g using UTL_HTTP. I am certain that my certificate and wallet are set up correctly for connecting over HTTPS. The call works consistently for valid business data.

When I pass invalid data (non existant user id in this case) the call to UTL_HTTP.GET_RESPONSE throws an exception:

ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1369
ORA-29263: HTTP protocol error

I don't get the UTL_HTTP.RESP object returned to investigate any HTTP error code or content. A number of other invalid data use cases have returned responses with error codes but these have not thrown the exception. I am able to process the response for an HTTP error code and get the error message from the response body.

What I have noticed in the particular case throwing the exception is:

  • The response body is larger than other cases; ~2600 bytes.
  • The response body contains ampersands (it's an HTML response with escaped XML content within. I have no control over the server response)

I discovered these by calling via curl. Could either of these conditions be the reason for UTL_HTTP.GET_RESPONSE throwing an HTTP protocol error?

Thanks.

like image 363
Gordon Little Avatar asked Apr 02 '26 19:04

Gordon Little


1 Answers

It looks that the errors raised by utl_http are intentionally opaque, unless you ask Oracle to be a little more explicit.

To make the error message more detailed when the exception is raised, somewhere in your session invoke:

utl_http.set_response_error_check(true)

Otherwise according to the docs in the utl_http package itself, you can get the error leveraging the following methods in your exception handling code:

utl_http.get_detailed_sqlcode
utl_http.get_detailed_sqlerrm

As for handling large requests, if it is your real problem, chunking the response and accumulating it in a clob may fix your issue:

function get_request(p_url varchar2, p_payload_text varchar2)
return clob
is
    v_req utl_http.req;
    v_resp utl_http.resp;
    v_req varchar2(32767);
    v_resp clob;
    v_resp_chunked varchar2(32767);
    v_xml_resp xmltype;

begin

        utl_http.set_response_error_check(true);

        v_req := utl_http.begin_request(
            url => p_url
            , method => 'POST'
            , http_version => 'HTTP/1.1'
        );
        utl_http.set_body_charset(v_req, 'UTF-8');
        utl_http.set_persistent_conn_support(false, 0);

        utl_http.set_header(v_req, 'Content-Type', 'text/xml;charset=UTF-8');
        utl_http.set_header(v_req, 'Content-Length', length(p_payload_text));


        utl_http.write_text(v_req, p_payload_text);

        v_resp := utl_http.get_response(v_req);

        dbms_output.put_line(v_resp_chunked);

        dbms_lob.createtemporary(v_resp,true, dbms_lob.session);

        begin
            loop
                utl_http.read_text(v_resp, v_resp_chunked, 32767);
                --dbms_output.put_line(v_resp_chunked);
                dbms_lob.append(v_resp, v_resp_chunked);
            end loop;

            exception
            when utl_http.end_of_body or UTL_HTTP.TOO_MANY_REQUESTS then
                utl_http.end_response(v_resp);
                dbms_output.put_line('mess:' ||SQLERRM);
        end;

        dbms_lob.freetemporary(v_resp);

        return v_resp;
end;
like image 131
Antonio Avatar answered Apr 08 '26 17:04

Antonio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!