ORA-29270: too many open HTTP requests - plsql

Can someone help me with this problem that occurs whenever you run a TRIGGER, but works in a normal PROCEDURE?
TRIGGER:
create or replace
procedure testeHTTP(search varchar2)
IS
Declare
req sys.utl_http.req;<BR>
resp sys.utl_http.resp;<BR>
url varchar2(500);
Begin
url := 'http://www.google.com.br';
dbms_output.put_line('abrindo');
-- Abrindo a conexão e iniciando uma requisição
req := sys.utl_http.begin_request(search);
dbms_output.put_line('preparando');
-- Preparandose para obter as respostas
resp := sys.utl_http.get_response(req);
dbms_output.put_line('finalizando response');
-- Encerrando a comunicação request/response
sys.utl_http.end_response(resp);
Exception
When Others Then
dbms_output.put_line('excecao');
dbms_output.put_line(sys.utl_http.GET_DETAILED_SQLERRM());
End;

close your user session and then the problem is fixed.
Internal there is a limit from 5 http requests.
Might a problem is the missing: utl_http.end_response
or an exception in the app and not a close from the resp object.
modify the code like that:
EXCEPTION
WHEN UTL_HTTP.TOO_MANY_REQUESTS THEN
UTL_HTTP.END_RESPONSE(resp);

you need to close your requests once you are done with them, it does not happen automatically (unless you disconnect form the db entirely)
It used to be utl_http.end_response, but I am not sure if it is the same api any more.

Usually we need UTL_HTTP.END_RESPONSE(resp); to avoid of ORA-29270: too many open HTTP requests, but I think I reproduced the problem of #Clóvis Santos in Oracle 19c.
If web-service always returns status 200 (success) then too many open HTTP requests never happens. But if persistent connections are enabled and web-service returns status 404, behavior becomes different.
Let`s call something that always return 404.
First call of utl_http.begin_request returns normally and opens new persistent connection. We can check it with select utl_http.get_persistent_conn_count() from dual;. Second call causes an exception inside utl_http.begin_request and persistent connection becomes closed. (Exception is correctly handled with end_response/end_request).
If I continue then each odd execution returns 404 normally and each even execution gives an exception (handled correctly of course).
After some iterations I get ORA-29270: too many open HTTP requests. If web-service returns status 200 everything goes normally.
I guess, it happens because of the specific web-service. Probable it drops persistent connection after 404 and doesn't after 200. Second call tries to reuse request on persistent connection but it doesn't exist and causes request leak.
If I use utl_http.set_persistent_conn_support (false, 0); once in my session the problem disappears. I can call web-service as many times as I need.
Resolution:
Try to switch off persistent connection support. Probable, on the http-server persistent connections work differently for different requests. Looks like a bug.

Related

Asynchronous WebSockets in Winhttp Windows 8

I want just to add WebSockets to my app that uses WinHTTP in async mode.
When I need a WebSocket I call the following.
Before sending request:
WinHttpSetOption(context->hRequest, WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET, NULL, 0);
In WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
appContext->pIoRequest->hWebSocketHandle = WinHttpWebSocketCompleteUpgrade(appContext->hRequest, NULL);
WinHttpWebSocketReceive(appContext->pIoRequest->hWebSocketHandle, appContext->pszOutBuffer,RESPONSE_BUFFER_SIZE, NULL, NULL);
all without errors.
Now I see in Fiddler that the server sends some data to my WebSocket but there is no WINHTTP_CALLBACK_STATUS_READ_COMPLETE triggered.
Any ideas why this is? How can I read asynchronously from my WebSocket? Sending data to the WebSocket works well.
Omg! I found how its work!
You MUST call additional WinHttpSetStatusCallback to set WebSocket callback for WebSocketHandle returned in WinHttpWebSocketCompleteUpgrade and this callback MUST differ then that from call WinHttpWebSocketCompleteUpgrade was made!
It is no possible to set a context pointer by WinHttpSetOption with WINHTTP_OPTION_CONTEXT_VALUE flag! Its not work. dwContext In WebSocketCallback has wrong data. Call to WinHttpQueryOption in WebSocketCallback return wrong context data. I think that is a BUG in Windows 8.1. I write my own handler to connect my context with WebSocketHandle.
All of this is NOT documented in MSDN! Most of all, I did not google any info about async winhttp websocket usage... So, I am the first=) I will be very glad if my research will help you!
It seems websockets do not get PING and PONG messages to the callback!

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.
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;
ORA-29263: HTTP protocol error is thrown in following scenarios:-
Case 1: URL is not https.
--> Check the URL and make sure it is https and not http.
Case 2: wallet certificate is not set up correctly.
Do you use something like UTL_ENCODE.BASE64_ENCODE for building of request? Try to fix request string using
REPLACE(your_request, UTL_TCP.CRLF, '');

Google OpenId: No OpenID endpoint found (intermittent)

Usually using the Google OpenId works fine, thousands of times a day, then it will start intermittently going wrong and timing out for an hours or so (some requests will validate but not all). Repeated validation will eventually work.
Error messages are:
Event code: 200000
Event message: No OpenID endpoint found. : https://www.google.com/accounts/o8/id
Sequence contains no elements
Adding in log4net yields:
DotNetOpenAuth.Yadis:
Error while performing discovery on: "https://www.google.com/accounts/o8/id":
DotNetOpenAuth.Messaging.ProtocolException:
Error occurred while sending a direct message or getting the response.
---> System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetResponse()
at DotNetOpenAuth.Messaging.StandardWebRequestHandler.GetResponse
(HttpWebRequest request, DirectWebRequestOptions options)
in c:\...\Dot...Core\Messaging\StandardWebRequestHandler.cs:line 127
--- End of inner exception stack trace ---
at DotNetOpenAuth.Messaging.StandardWebRequestHandler.GetResponse
(HttpWebRequest request, DirectWebRequestOptions options)
in c:\...\Dot...Core\Messaging\StandardWebRequestHandler.cs:line 175
at DotNetOpenAuth.Messaging.UntrustedWebRequestHandler.GetResponse
(HttpWebRequest request, DirectWebRequestOptions options)
in c:\...\Dot...Core\Messaging\UntrustedWebRequestHandler.cs:line 250
at DotNetOpenAuth.Yadis.Yadis.Request
(IDirectWebRequestHandler requestHandler,
Uri uri, Boolean requireSsl, String[] acceptTypes)
in c:\...\Dot...OpenId\Yadis\Yadis.cs:line 172
at DotNetOpenAuth.Yadis.Yadis.Discover
(IDirectWebRequestHandler requestHandler, UriIdentifier uri, Boolean requireSsl)
in c:\...\DotNetOpenAuth.OpenId\Yadis\Yadis.cs:line 63
at DotNetOpenAuth.OpenId.UriDiscoveryService.Discover
(Identifier identifier, IDirectWebRequestHandler requestHandler,
Boolean& abortDiscoveryChain)
in c:\...\DotNet...OpenId\OpenId\UriDiscoveryService.cs:line 51
at DotNetOpenAuth.OpenId.IdentifierDiscoveryServices.Discover
(Identifier identifier)
in c:\...\Dot...OpenId\OpenId\IdentifierDiscoveryServices.cs:line 58
at DotNetOpenAuth.OpenId.RelyingParty.AuthenticationRequest.Create
(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty,
Realm realm, Uri returnToUrl, Boolean createNewAssociationsAsNeeded)
in ...OpenId.RelyingParty\OpenId\RelyingParty\AuthenticationRequest.cs:line 364
And
DotNetOpenAuth.Http WebException:
Timeout from https://www.google.com/accounts/o8/id, no response available.
Any ideas?
It sounds like you need to fix your network latency. It seems highly unlikely that Google would be the bottleneck here.
You may also want to increase the HTTP timeouts on your end to reduce the failure rate. The full set of options is available here. Specifically you're probably looking for:
<untrustedWebRequest
timeout="00:00:10"
readWriteTimeout="00:00:01.500" />
Check out the configurations link to see the context of where this goes.
We recently ran into this same issue. Having read several different scenarios and having gone through the trace steps I finally concluded, as I have seen elsewhere that this problem can be caused by a DNS server issue. In our case we had a production server that has been in use for over 18 months and just recently started getting the same issue as mentioned above, but it was very consistent on this one server. Another server on a another network and our development computers did not have any issues.
Long story short I changed the primary DNS for the production server to Google's public DNS, 8.8.8.8 and it instantly started working. I had manually flushed the DNS cache on the production server prior to this (without positive outcome) so it leads me to believe the DNS server (provided by our hosting center) had a bad cache entry that was ultimately causing the problem.
Hope this helps someone else who runs across this scenario.

Graceful recovery from policy file load failure

First off: This is not another question about how to load a policy file.
I have an app in development that connects to a socket server, gets the policy file and works just dandy. However, when the socket server is down for whatever reason, I need to gracefully fallback to an alternative method of getting messages from the server (polling, basically).
This is not a problem, except for one thing:
Error: Request for resource at xmlsocket://[ip]:4770 by requestor from http://[ip]/cooking/Client.swf has failed because the server cannot be reached.
There doesn't appear to be a way to catch this. I have these event listeners on my socket:
addEventListener(Event.CLOSE, closeHandler);
addEventListener(Event.CONNECT, connectHandler);
addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
SecurityErrorEvent is what you might think fires, but it doesn't. The docs say it fires for these reasons:
Local untrusted SWF files may not communicate with the Internet. You can work around this limitation by reclassifying the file as local-with-networking or as trusted.
You cannot specify a socket port
higher than 65535.
In the HTML page that contains the
SWF content, the allowNetworking
parameter of the object and embed
tags is set to "none".
So none of those apply. It appears what I really want to catch is the failure of the policy file to load, but even doing an explicit Security.loadPolicyFile() won't help, since that load is deferred to the first socket request AND doesn't fire any events.
For completeness, I also surrounded the call to connect() with a try{}catch (e:*){}, no result.
There's got to be a way to sort this. Any ideas? I simply need a way to tell when the connection has failed because of networking issues and try an alternate path.
EDIT: Despite my previous tests and the docs, it appears SecurityErrorEvent does fire - only it does it about 20 seconds after the load fails, so it's not obvious. I guess that's as immediate as I'm going to get from Flash.
Don't forget to retry connecting :)
private function onIOError(e:IOErrorEvent):void {
e.stopPropagation();
++this.retryCount;
if( this.retryCount >= 12 ){
this.connectTimer.stop();
this.dispatchEvent( new Event( 'TIMIEDOUT' ) );
}else{
this.err = 'IO-ERROR-EVENT - ' + e.text + '\r\nAttempting to reconnect';
}
}

MSXML2.XMLHTTP Request to validate entered URL in ASP Classic

Thanks in advance for any help received.
I want to allow our client to enter a URL into a text field which then checks whether the URL exists and works.
There are 3 possible outcomes I want to check for:
A status of 200 - OK,
A status of 500 - Server Error,
Or a status of 404 - page not found.
When executing the following code in ASP classic I get a status code of 12007 when I should be getting 404. Is this because it can't find a webserver to return a code of 404?
Function CheckURL(vURL)
ON ERROR RESUME NEXT
Set oXML=Server.CreateObject("MSXML2.XMLHTTP") : oXML.Open "POST",vURL,false : oXML.Send()
CheckURL = oXML.status
Set oXML = nothing
End Function
Or is something amiss here. What status codes am I likely to see other than the standard mentioned above.
The 12007 is a Windows HTTP error which means name hasn't been resolved. You can't get a 200, 404, 500 or any such thing if the host name can't be resolved to an IP address or a connection can't be established to that IP address. In these cases you will get error codes in the 12000s range which aren't HTTP status codes but are windows exception numbers.
See this list for a list of these exception numbers.
BTW, XMLHTTP is not a safe item object to use in ASP. Also why are you using a POST? This is the code I would use:-
Function CheckURL(vURL)
On Error Resume Next
Set xhr = CreateObject("MSXML2.ServerXMLHTTP.3.0")
xhr.Open "HEAD", vURL, false
xhr.Send
CheckURL = xhr.status
End Function
Using HEAD allows you test the URL without actually downloading a potentially large entity body.

Resources