ora-29259 end-of-input reached using UTL_HTTP.BEGIN_REQUEST - oracle

I am making a stored procedure with 2 seperate HTTP Requests.
The first one to get an Atuthentication Token and the second one that uses the token.
The first Request works without a problem and I get the token back.
The second Request throws the ora-29259 end-of-input reached exception.
They both look exactly the same besides of the URL:
begin
req := utl_http.begin_request(url,'POST',utl_http.http_version_1_1);
utl_http.set_header(req, 'Authorization', Token/Credentials);
utl_http.set_header(req, 'Content-Type', 'application/json');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
loop
utl_http.read_text(res, buffer);
dbms_output.put_line(buffer);
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body then
utl_http.end_response(res);
end;
I have found this from nearly 3 years ago which suggests updating the database.
I am using Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production, is this the issue? I can't find any answer to this googling myself.
The first Website uses TLS 1.2 while the second one uses TLS 1.3, is my Oracle Version too old?

Please provide a sample of your code for a more detailed answer.
But looking at the link you provided, I can already see something missing in the code, which is the exception for utl_http.end_of_body.
This is an example of my code, I used somewhere else:
begin
req := utl_http.begin_request(url,'POST',utl_http.http_version_1_1);
utl_http.set_header(req, 'Content-Type', 'application/xml;charset=UTF-8');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
loop
utl_http.read_text(res, buffer);
dbms_output.put_line(buffer);
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body then
utl_http.end_response(res);
end;

Related

How to send special characters using utl_http?

I'm trying to send some text using utl_http. The Text I'm sending includes special characters
Declare
HttpRequest utl_http.req;
HttpResponse utl_http.resp;
ResponseText clob;
URL varchar2(500) := 'someurl';
PostPrameters varchar2(30000);
begin
PostPrameters := 'From=SenderName&To=+336...&Body=très cool';
PostPrameters := utl_url.escape(PostPrameters);
URL := utl_url.escape(URL);
HttpRequest := utl_http.begin_request(URL, 'POST', 'HTTP/1.1');
utl_http.set_authentication(HttpRequest, TwilioUserName, TwilioPassword);
utl_http.set_header(HttpRequest,'Content-Type','application/x-www-form-urlencoded;');
utl_http.set_header(HttpRequest, 'Content-Length',length(PostPrameters));
utl_http.write_text(HttpRequest, PostPrameters);
HttpResponse := utl_http.get_response(HttpRequest);
utl_http.read_text(HttpResponse,ResponseText);
utl_http.end_response(HttpResponse);
end;
The body of the text I'm sending should be "très cool"
When sending the request, it's received as "tr�s cool"
I tried to add UTL_HTTP.SET_BODY_CHARSET('UTF-8'); but it's not working.
Can anyone help please ?
Thanks.

Getting Response Headers from Apex Web Service Response with PL/SQL

I have to get the response headers of my "apex_web_service.make_rest_request" request.
I know that it was possible with the "UTL_HTTP" package, as documented here: https://docs.oracle.com/database/121/ARPLS/u_http.htm#BHAHDHHB
But how can I do this with "apex_web_service"? Is it even possible, as I can't find it in this documentation? http://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI537
Thanks in advance for your answer(s)!
Ok I found it now. The answer can be found here: http://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI1933
There is no such thing as a "get_Header()" or something like that. You set your headers and send the request (here example code):
--Set Request Headers
apex_web_service.g_request_headers(1).name := 'Authorization';
apex_web_service.g_request_headers(1).value := '[MY API TOKEN]';
apex_web_service.g_request_headers(2).name := 'Content-Type';
apex_web_service.g_request_headers(2).value := 'application/json';
apex_web_service.g_request_headers(3).name := 'Content-Length';
apex_web_service.g_request_headers(3).value := '[CONTENT LENGTH IN BYTES OF REQUEST BODY]';
l_lcResult := apex_web_service.make_rest_request(p_url => 'MY API URL'
,p_http_method => 'POST'
,p_body => 'REQUEST BODY IN JSON FORMAT');
After the request the headers "change" automatically to the response headers. You can get the response headers as followed:
for i in 1.. apex_web_service.g_headers.count loop
l_vcHeaderName := apex_web_service.g_headers(i).name;
l_vcHeaderValue := apex_web_service.g_headers(i).value;
end loop;
If you are searching for a specific response header (like me), you can use this:
--Here we search for the header-field called 'Location'
for i in 1.. apex_web_service.g_headers.count loop
l_vcHeaderName := apex_web_service.g_headers(i).name;
l_vcHeaderValue := apex_web_service.g_headers(i).value;
exit when l_vcHeaderName = 'Location';
end loop;
dbms_output.put_line('Name: ' || l_vcHeaderName);
dbms_output.put_line('Value: ' || l_vcHeaderValue);
If you want the HTTP response code , use:
apex_web_service.g_status_code

Request Body of REST Call using utl_http through Oracle 12c DB having 78000 chars

I have tried the following way to make the http call :
v_doc_fin clob;
if v_doc_fin is not null then
DBMS_OUTPUT.PUT_LINE (v_doc_fin);
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
utl_http.set_header(req, 'user-agent', 'mozilla/4.0');
utl_http.set_header(req, 'content-type', 'application/json');
utl_http.set_header(req, 'Content-Length', length(v_doc_fin));
utl_http.write_text(req, v_doc_fin);
res := utl_http.get_response(req);
end if;
I tried using the WRITE_RAW and write_text to make the HTTP request, but neither helped.
UTL_HTTP.write_text (req, v_doc_fin) ;
UTL_HTTP.WRITE_RAW (r => req, data => UTL_RAW.CAST_TO_RAW(v_doc_fin));
I also tried breaking the request body in chunks, but it didn't help either.
The request within 30000 chars limits are working fine, but when they exceed that limit it fails.
Please suggest or advice on the way to send this request body with such large amount of data in Oracle 12c.
If you have Apex installed in the database maybe using apex_web_service.make_rest_request is an option for you.
It sends and receives clob data.
https://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI537
Example
l_result_clob := apex_web_service.make_rest_request(p_url => my_url
,p_http_method => 'POST'
,p_body => l_content_clob);

PL/SQL: UTL_HTTP POST with UTF8 string results in broken characters

I want to send an UTF8 json string via utl_http to a node.js Server via POST. Sending the string
["Sant Julià de Lòria"]
does arrive as
["Sant Juli� de L�ria"]
The PL/SQL code goes like:
FUNCTION http_post_varchar(
p_url VARCHAR2,
p_request_body VARCHAR2 )
RETURN VARCHAR2
AS
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(32767); -- URL to post to
v_url VARCHAR2(200) := p_url;
-- Post Parameters
v_param VARCHAR2(32767) := p_request_body;
v_param_length NUMBER := length(v_param);
BEGIN
req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Type',
value => 'application/json;charset=UTF-8');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Length',
value => v_param_length);
UTL_HTTP.WRITE_TEXT (r => req,
data => v_param);
resp := UTL_HTTP.GET_RESPONSE(req);
LOOP
UTL_HTTP.READ_LINE(resp, value, TRUE);
END LOOP;
UTL_HTTP.END_RESPONSE(resp);
RETURN 'OK';
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(resp);
RETURN 'OK';
END http_post_varchar;
You should change your code to:
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Length',
value => LENGTHB(v_param));
UTL_HTTP.WRITE_RAW (r => req,
data => UTL_RAW.CAST_TO_RAW(v_param));
LENGTHB for byte length because of UTF-8. Otherwise the calculated length will be false and you get an error on the target side (unexpected end of input or something).
Same goes for the response body e.g. when you're getting a response from a web service:
UTL_HTTP.SET_BODY_CHARSET(r=> resp, charset=>'UTF-8');
Place this call directly after Get_response.
Sometimes the problem is not with Unicode. You can use the conversion to ASCII code
v_param := REPLACE (ASCIISTR (v_param), '\', '\u');

Downloading a file in Delphi

A google search shows a few examples on how to download a file in Delphi but most are buggy and half of the time don't work in my experience.
I'm looking for a simple robust solution which will let me download a single exe (for updating my app) and will hold the execution of the current update thread until the download is done or errors out. The process is already threaded so the download code should hold execution until it's done (hopefully).
Here's two implementations, both seem very complicated
1. http://www.scalabium.com/faq/dct0116.htm
2. http://delphi.about.com/od/internetintranet/a/get_file_net.htm
Why not make use of Indy? If you use the TIdHTTP component, it's simple:
procedure TMyForm.DownloadFile;
var
IdHTTP1: TIdHTTP;
Stream: TMemoryStream;
Url, FileName: String;
begin
Url := 'http://www.rejbrand.se';
Filename := 'download.htm';
IdHTTP1 := TIdHTTP.Create(Self);
Stream := TMemoryStream.Create;
try
IdHTTP1.Get(Url, Stream);
Stream.SaveToFile(FileName);
finally
Stream.Free;
IdHTTP1.Free;
end;
end;
You can even add a progress bar by using the OnWork and OnWorkBegin events:
procedure TMyForm.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;AWorkCountMax: Int64);
begin
ProgressBar.Max := AWorkCountMax;
ProgressBar.Position := 0;
end;
procedure TMyForm.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
ProgressBar.Position := AWorkCount;
end;
procedure TMyForm.DownloadFile;
var
IdHTTP1: TIdHTTP;
Stream: TMemoryStream;
Url, FileName: String;
begin
Url := 'http://www.rejbrand.se';
Filename := 'download.htm';
IdHTTP1 := TIdHTTP.Create(Self);
Stream := TMemoryStream.Create;
try
IdHTTP1.OnWorkBegin := IdHTTPWorkBegin;
IdHTTP1.OnWork := IdHTTPWork;
IdHTTP1.Get(Url, Stream);
Stream.SaveToFile(FileName);
finally
Stream.Free;
IdHTTP1.Free;
end;
end;
I'm not sure if these events fire in the context of the main thread, so any updates done to VCL components may have to be done using the TIdNotify component to avoid threading issues. Maybe someone else can check that.
The second approach is the standard way of using Internet resources using WinINet, a part of Windows API. I have used it a lot, and it has always worked well. The first approach I have never tried. (Neither is "very complicated". There will always be a few additional steps when using the Windows API.)
If you want a very simple method, you could simply call UrlMon.URLDownloadToFile. You will not get any fine control (at all!) about the download, but it is very simple.
Example:
URLDownloadToFile(nil,
'http://www.rejbrand.se',
PChar(ExtractFilePath(Application.ExeName) + 'download.htm'),
0,
nil);
For people that has later version of delphi, you can use this:
var
http : TNetHTTPClient;
url : string;
stream: TMemoryStream;
begin
http := TNetHTTPClient.Create(nil);
stream := TMemoryStream.Create;
try
url := YOUR_URL_TO_DOWNLOAD;
http.Get(url, stream);
stream.SaveToFile('D:\Temporary\1.zip');
finally
stream.Free;
http.Free;
end;
end;
Using URLMon.
errcode := URLMon.URLDownloadToFile(nil,
PChar('http://www.vbforums.com/showthread.php?345726-DELPHI-Download-Files'),
PChar( 'a:\download.htm'),
0,
nil);
if errcode > 0 then
showmessage('Error while downloading: ' + inttostr(errcode));

Resources