ORA-29273:HTTP 请求失败/ORA-29259:输入结束在第一次调用时出现异常,但在 Oracle PL/SQL 中的后续调用中未出现异常

问题描述 投票:0回答:1

我遇到了

PL/SQL
函数的问题,该函数使用
HTTP(S)
发出
UTL_HTTP
请求。该函数应该向特定 URL 发送 POST 请求。它几乎按预期工作,但有一个特殊的问题。

这是我正在使用的功能:

create or replace function send_post_request (p_url           in varchar2,
                                p_content       in clob default null)
        return clob
    is
        v_url      varchar2 (255);
        req        utl_http.req;
        resp       utl_http.resp;
        buffer     varchar2 (32767);
        response   clob;
    begin
         v_url := p_url;


        utl_http.set_wallet (
            'file:/wallet_path',
            'password');
        utl_http.set_transfer_timeout (300);
        req :=
            utl_http.begin_request (v_url, 'post', utl_http.http_version_1_1);
        utl_http.set_authentication (req, '<hidden>', '<hidden>');

        utl_http.set_header (req, 'user-agent', 'mozilla/4.0');
        utl_http.set_header (req, 'content-type', 'application/json');

        if p_content is not null
        then
            utl_http.set_body_charset ('utf-8');
            utl_http.set_header (req,
                                 'content-length',
                                 lengthb (to_char (p_content)));
            utl_http.write_text (req, p_content);
        end if;

        resp := utl_http.get_response (req);

        utl_http.set_body_charset (r => resp, charset => 'utf-8');

        if resp.status_code != utl_http.http_ok
        then

            raise_application_error (
                -20001,
                'response status code: ' || resp.status_code);
        end if;

        begin
            loop
                utl_http.read_text (resp, buffer);
                response := response || buffer;
            end loop;

            utl_http.end_request (req);
            utl_http.end_response (resp);

            return response;
        exception
            when utl_http.end_of_body
            then
                utl_http.end_request (req);
                utl_http.end_response (resp);

                return response;
        end;
    exception
        when others
        then
            utl_http.end_request (req);
            utl_http.end_response (resp);

            raise_application_error (
                -20002,
                sqlerrm || ' / ' || utl_http.get_detailed_sqlerrm);
    end;

我遇到的问题是,第一次调用这个函数时,它会抛出异常,并显示以下错误消息:

ORA-29273: HTTP request failed / ORA-29259: end-of-input reached.
奇怪的是,当我在遇到错误后立即第二次调用该函数时,它执行时没有任何问题并给出了预期的结果。

我已经检查了 Oracle Wallet 设置、HTTPS 端点和请求有效负载,它们似乎配置正确,特别是考虑到该函数在第二次和后续执行时有效。

是否有其他人遇到过这种情况,或者对为什么第一次执行可能失败而后续执行运行没有任何问题有任何想法?任何见解将不胜感激。

注意:出于安全目的隐藏了 set_authentication 参数

到目前为止,我已尝试以下步骤来调试并解决此问题:

  • 检查了提供给
    UTL_HTTP.SET_WALLET
    的钱包文件路径和密码,以确保它们正确。
  • 已验证
    UTL_HTTP.BEGIN_REQUEST
    中指定的 HTTP 版本是否适合我正在与之通信的服务器。
  • 调查问题是否与网络延迟或超时有关。然而,即使没有明显的网络问题,问题似乎仍然存在。
  • 探索该错误是否可能是由于错误计算的 Content-Length 标头造成的。但是,内容长度似乎根据 JSON 有效负载的字节长度正确设置。
  • 检查设置的 HTTP 标头是否存在任何问题,例如
    'Content-Type'
    。它们似乎针对我的用例进行了正确设置。 尽管做出了这些尝试,问题仍然存在。特殊的问题是,错误仅发生在函数的第一次执行时,而不会发生在后续执行时,我正在努力解释这一点。

我正在寻找有关为什么会发生这种情况的见解,以及如何确保该函数即使在第一次执行时也能正常工作。

oracle ssl plsql httprequest utl-http
1个回答
0
投票

尝试设置 HTTP 标头

Transfer-Encoding: chunked
并删除标头“content-length”。它适用于 HTTP 版本 1.1。

© www.soinside.com 2019 - 2024. All rights reserved.