Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: "The system cannot locate the resource specified" on XML send request


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 25 - Last Post: Apr 3, 2018 1:46 PM Last Post By: Remy Lebeau (Te...
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
"The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 1, 2018 9:35 AM
I wrote this function which sends an XML request to the URL szGatewayURL
Intermittently and only on Windows 7 machines we get an exception on the (****) command. The error shown is "The system cannot locate the resource specified". According to Google, the error means a failure of the XML request to
communicate with the URL. The error typically happens when many XML requests are made in a short time period. But it only happens on Windows 7 machines. Once the error happens, we have to shut down the program, start up again and then it works without a problem.
This is my first time writing XML code in Delphi so I am not sure I am doing this correctly.
I have a number of questions.
1) Does szXMLString have to be defined as a widestring instead of string?
2) I am not sure about the input parameter to CreateOleObject. I am using 'MSXML2.XMLHTTP.3.0'. But I have seen other examples where the parameter is 'MSXML2.XMLHTTP.6.0' or 'MSXML2.XMLHTTP'. What should it be?
What does the input parameter really mean?
3) What windows dll's are required for this call? msxml3.dll? msxml6.dll?
4) Why does the error only happen sometimes (high XML activity). I think I am freeing all objects correctly.
5) Could it be a timing issue?
If anyone could help me with this, I would be eternally grateful.
Cornelia


function ProcessXMLRequest: integer;
var
XMLRequest, XMLResponse : IXMLDOCUMENT;
szServerResponse: string;
oXMLHTTP: IXMLHTTPRequest;
szXMLString: String;

begin

try
XMLRequest := NewXMLDocument;
XMLRequest.Encoding := 'utf-8';
XMLRequest.Options := [doNodeAutoIndent];

// here I add a whole bunch of children to the XML document
// then I save the XML document in szXMLString;

XMLRequest.SaveToXML(szXMLString);
oXMLHTTP := CreateOleObject('MSXML2.XMLHTTP.3.0') as IXMLHTTPRequest;
Application.ProcessMessages;
try
oXMLHTTP.open('POST', szGatewayURL, False, '', '');
oXMLHTTP.setRequestHeader('Content-Type', 'text/xml');
try
oXMLHTTP.send(szXMLString); (****)
except
on E: Exception do
begin
Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
end;
end;
szServerResponse := Trim(oXMLHTTP.ResponseText);
finally
oXMLHTTP := nil;
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 1, 2018 10:32 AM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

I wrote this function which sends an XML request to the URL
szGatewayURL Intermittently and only on Windows 7 machines we get an
exception on the (****) command. The error shown is "The system
cannot locate the resource specified".

That means the HTTP server likely returned a "404 NOT FOUND" reply.

According to Google, the error means a failure of the XML request to
communicate with the URL.

More accurately, communication with the server is fine, but the URL
itself doesn't exist on the server.

The error typically happens when many XML requests are made in a short
time period. But it only happens on Windows 7 machines.

The particular OS is irrelevant. Unless MSXML is putting the OS
version in the request's 'User-Agent' header, and the HTTP server is
UserAgent-aware and is failing the request based on the particular
UserAgent that is making the request.

Once the error happens, we have to shut down the program, start up
again and then it works without a problem.

1) Does szXMLString have to be defined as a widestring instead of
string?

That depends on whether the input parameter of send() is declared as a
Variant or an OleVariant. If the former, yes. If the latter, no. It
wouldn't hurt either way to make it a WideString, though. Ultimately,
it has to be converted to a BSTR anyway when passed to MSXML, so may as
well do that conversion yourself.

2) I am not sure about the input parameter to CreateOleObject. I am
using 'MSXML2.XMLHTTP.3.0'. But I have seen other examples where the
parameter is 'MSXML2.XMLHTTP.6.0' or 'MSXML2.XMLHTTP'. What should it
be?

Any of those are fine. However, note that 'MSXML2.XMLHTTP.3.0' and
'MSXML2.XMLHTTP.6.0' are specific version of the XMLHTTP object.
Typically, you should use version-independent names instead, like
'Msxml2.XMLHTTP', so you use whatever latest version is actually
installed/registered, unless you have reason to use a specific version
directly.

What does the input parameter really mean?

It is the registered ProgID of the COM object you are creating. A
ProgID is a way of referring to a COM object by a human-readable name
instead of by a unique guid number.

3) What windows dll's are required for this call? msxml3.dll?
msxml6.dll?

Yes, respectively. Read the MSDN documentation.

4) Why does the error only happen sometimes (high XML activity).

There is not enough information to diagnose that. What is szGatewayURL
actually set to? Does it ever change value? Is the URL dependent on
the creation of any server-side resources beforehand? Does the URL
contain any query parameters? Is there any pattern to the errors in
relation to the URL being requested? IE, certain parameters fail when
others don't?

5) Could it be a timing issue?

Maybe. Haard to say without seeing the actual HTTP traffic.

--
Remy Lebeau (TeamB)

Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 1, 2018 11:03 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Cornelia von Schellwitz wrote:

I wrote this function which sends an XML request to the URL
szGatewayURL Intermittently and only on Windows 7 machines we get an
exception on the (****) command. The error shown is "The system
cannot locate the resource specified".

That means the HTTP server likely returned a "404 NOT FOUND" reply.

According to Google, the error means a failure of the XML request to
communicate with the URL.

More accurately, communication with the server is fine, but the URL
itself doesn't exist on the server.

The error typically happens when many XML requests are made in a short
time period. But it only happens on Windows 7 machines.

The particular OS is irrelevant. Unless MSXML is putting the OS
version in the request's 'User-Agent' header, and the HTTP server is
UserAgent-aware and is failing the request based on the particular
UserAgent that is making the request.

Once the error happens, we have to shut down the program, start up
again and then it works without a problem.

1) Does szXMLString have to be defined as a widestring instead of
string?

That depends on whether the input parameter of send() is declared as a
Variant or an OleVariant. If the former, yes. If the latter, no. It
wouldn't hurt either way to make it a WideString, though. Ultimately,
it has to be converted to a BSTR anyway when passed to MSXML, so may as
well do that conversion yourself.

2) I am not sure about the input parameter to CreateOleObject. I am
using 'MSXML2.XMLHTTP.3.0'. But I have seen other examples where the
parameter is 'MSXML2.XMLHTTP.6.0' or 'MSXML2.XMLHTTP'. What should it
be?

Any of those are fine. However, note that 'MSXML2.XMLHTTP.3.0' and
'MSXML2.XMLHTTP.6.0' are specific version of the XMLHTTP object.
Typically, you should use version-independent names instead, like
'Msxml2.XMLHTTP', so you use whatever latest version is actually
installed/registered, unless you have reason to use a specific version
directly.

What does the input parameter really mean?

It is the registered ProgID of the COM object you are creating. A
ProgID is a way of referring to a COM object by a human-readable name
instead of by a unique guid number.

3) What windows dll's are required for this call? msxml3.dll?
msxml6.dll?

Yes, respectively. Read the MSDN documentation.

4) Why does the error only happen sometimes (high XML activity).

There is not enough information to diagnose that. What is szGatewayURL
actually set to? Does it ever change value? Is the URL dependent on
the creation of any server-side resources beforehand? Does the URL
contain any query parameters? Is there any pattern to the errors in
relation to the URL being requested? IE, certain parameters fail when
others don't?

5) Could it be a timing issue?

Maybe. Haard to say without seeing the actual HTTP traffic.

--
Remy Lebeau (TeamB)


Hi Remy,
Thanks so much for your response. That was very helpful.
szGatewayURL is a specific website that does not change ever. It does not have any query parameters.
We are going to add some error logging and write both szXMLString and
szGatewayURL to a log when the "Send" fails to see if either variable is getting trashed.
Cornelia
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2018 4:48 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy and everyone else
I made some changes after your last reply such as changing szXMLString to widestring and the ProgID to be version independent
but unfortunately the problem persists. The URL (szGatewayURL) is a constant that never changes. We have added CodeSite code
to output the input of the "Send" command to a Codesite log. Every time the "Send" fails, the input parameters to the "Send" are
intact, so this is not a scenario of memory getting trashed. There are no resource leaks in the code, we have plugged them all.
The error does not seem to have anything to do with high XML activity after all. Once the problem has happened, if the user simply shuts down the program
and then starts up again and tries the same thing again , it works.
I have seen other samples of XML requests with several Setrequestheader calls specifying depth and user-agent. Are those required? Do they have anything to do with my problem?
Help is much appreciated

This is the code now:

function ProcessXMLRequest: integer;
var
XMLRequest, XMLResponse : IXMLDOCUMENT;
szServerResponse: string;
oXMLHTTP: IXMLHTTPRequest;
szXMLString: widestring;

begin

try
XMLRequest := NewXMLDocument;
XMLRequest.Encoding := 'utf-8';
XMLRequest.Options := [doNodeAutoIndent];

// here I add a whole bunch of children to the XML document
// then I save the XML document in szXMLString;

XMLRequest.SaveToXML(szXMLString);
oXMLHTTP := CreateOleObject(''MSXML2.XMLHTTP'') as IXMLHTTPRequest;
Application.ProcessMessages;
try
oXMLHTTP.open('POST', szGatewayURL, False, '', '');
oXMLHTTP.setRequestHeader('Content-Type', 'text/xml');
try
oXMLHTTP.send(szXMLString); (****)
except
on E: Exception do
begin
{$ifdef DebugCodeSite}
CodeSite.Send( 'szGatewayURL', szGatewayURL );
CodeSite.Send( 'szXMLString', szXMLString );
{$endif DebugCodeSite}
Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
end;
end;
szServerResponse := Trim(oXMLHTTP.ResponseText);
finally
oXMLHTTP := nil;
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 9, 2018 8:17 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

I have seen other samples of XML requests with several
Setrequestheader calls specifying depth and user-agent. Are those
required? Do they have anything to do with my problem?

I can't answer that. I suggest you contact the Gateway admin and ask
for help with debugging the requests. Clearly there is a problem on
the server side.

This is the code now:

Do you have the same errors if you use Indy instead of XMLHTTP?

function ProcessXMLRequest: integer;
var
  XMLRequest, XMLResponse : IXMLDOCUMENT;
  szServerResponse: string;
  HTTP: TIdHTTP;
  szXMLString: string;
  PostData: TStringStream;
begin
  try
    XMLRequest := NewXMLDocument;
    try
      XMLRequest.Encoding := 'utf-8';
      XMLRequest.Options := [doNodeAutoIndent]; 
 
      // here I add a whole bunch of children to the XML document
      // then I save the XML document in szXMLString;
 
      XMLRequest.SaveToXML(szXMLString);
    finally
      XMLRequest := nil;
    end;
 
    Application.ProcessMessages;
 
    try
      HTTP := TIdHTTP.Create; 
      try 
        HTTP.Request.ContentType := 'text/xml';
        HTTP.Request.Charset := 'utf-8';
 
        PostData := TStringStream.Create(szXMLString, TEncoding.UTF8);
        try
          szServerResponse := Trim(HTTP.Post(szGatewayURL, PostData)); 
        finally
          PostData.Free;
        end;
      finally
        HTTP.Free; 
      end;
    except
      on E: Exception do 
      begin
        {$ifdef DebugCodeSite}
        CodeSite.Send( 'szGatewayURL', szGatewayURL );
        CodeSite.Send( 'szXMLString', szXMLString );
        {$endif DebugCodeSite}
        Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
      end;
    end;
    ...
end;


--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2018 2:14 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks so much for your suggestion to use a different component.
Unfortunately I get the same error if I use Indy instead of XMLHTTP. It is intermittent, and I have added more debugging code to see what the exception is exactly.
The error happened again today using Indy code and both
We will try to figure out in the next couple of days if it only happens on Win 7 or on both Win 7 and Win 10.
Since we make so many XML requests I have made it a procedure shown below.

function TAPSCCObj.MakeXMLRequest_Indy(szXMLString: widestring; var szServerResponse: string): integer;
var HTTP: TIdHTTP;
PostData: TStringStream;
begin
{$ifdef DebugCodeSite}
CodeSite.EnterMethod( Self, 'MakeXMLRequest_Indy');
try
{$endif DebugCodeSite}

Result := 0; // No Error
szServerResponse := '';
try
HTTP := TIdHTTP.Create;
Application.ProcessMessages;
try
HTTP.Request.ContentType := 'text/xml';
HTTP.Request.Charset := 'utf-8';
try
PostData := TStringStream.Create(szXMLString, TEncoding.UTF8);
try
szServerResponse := Trim(HTTP.Post(szGatewayURL, PostData));
except
on E: Exception do
begin
{$ifdef DebugCodeSite}
SSIMessageDlg(E.Message, '', mtError, [mbOK], mbOK, E.HelpContext);
CodeSite.Send( 'ExceptionOn', 'HTTP Post' );
CodeSite.Send( 'ExceptionMessage', E.Message );
CodeSite.Send( 'ExceptionNo', E.HelpContext );
CodeSite.Send( 'szGatewayURL', szGatewayURL );
CodeSite.Send( 'szXMLString', szXMLString );
CodeSite.Send( 'szServerResponse', szServerResponse );
{$endif DebugCodeSite}
Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
end;
end;
finally
PostData.Free;
end;
finally
HTTP.Free;
end;
except
on E: Exception do
begin
{$ifdef DebugCodeSite}
SSIMessageDlg(E.Message, '', mtError, [mbOK], mbOK, E.HelpContext);
CodeSite.Send( 'ExceptionOn', 'TIdHTTP Create' );
CodeSite.Send( 'ExceptionMessage', E.Message );
CodeSite.Send( 'ExceptionNo', E.HelpContext );
CodeSite.Send( 'szGatewayURL', szGatewayURL );
CodeSite.Send( 'szXMLString', szXMLString );
{$endif DebugCodeSite}
Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
end;
end;
{$ifdef DebugCodeSite}
finally
CodeSite.ExitMethod(Self, 'MakeXMLRequest_Indy');
end;
{$endif DebugCodeSite}
end;
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2018 4:46 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Hi Remy,
After testing the Indy version of sending the xml request we found out which statement is causing the error.
It fails on the HTTP Post with exception message: Socket Error# 10093
I googled to see what the error means and got this information:

Successful WSAStartup not yet performed. Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

Does each TIdHTTP.Create do a WSAStartup? Does every HTTP.Free do a WSACleanup?
Since we do a create and free for every xml request, perhaps we should just define HTTP as a global object, create it only once at the beginning of the program, and then free it when the program terminates?

Any ideas on how I can fix this problem? How do we avoid it and how can we recover from it programmatically?
Shutting down the program and restarting clears up the issue but is not an acceptable solution.
Thanks for your time
Cornelia

Edited by: Cornelia von Schellwitz on Mar 13, 2018 5:43 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2018 6:07 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:
After testing the Indy version of sending the xml request we found out which statement is causing the error.
It fails on the HTTP Post with exception message: Socket Error# 10093

Because you switched HTTP libraries, that does not guarantee that is the same reason why XMLHTTP was failing.

In any case, no you have not found the cause of the original problem, just a new unrelated symptom of your app doing something it probably shouldn't be doing. Your original problem is an HTTP error from the server. Socket error 10093 is local to your app, and can't cause HTTP errors (because you wouldn't be able to communicate over HTTP in the first place).

Does each TIdHTTP.Create do a WSAStartup? Does every HTTP.Free do a WSACleanup?

No, Indy calls them only once. WSAStartup() is called the first time TIdStackWindows is constructed by any Indy component. WSACleanup() is called during finalization of the IdStackWindows unit.

Since we do a create and free for every xml request, perhaps we should just define HTTP as a global object, create it only once at the beginning of the program, and then free it when the program terminates?

That is not necessary. You can freely create TIdHTTP objects on an as-needed basis.

Any ideas on how I can fix this problem? How do we avoid it and how can we recover from it programmatically?
Shutting down the program and restarting clears up the issue but is not an acceptable solution.

I still think you are encountering a problem on the server side, not a problem with your app. Especially since the problem is intermittent, and especially since the problem affects multiple unrelated HTTP client libraries. Something on the server side is likely interfering with the URL resource you are trying to requests. Either the resource is being temporarily destroyed and recreated at times, or maybe server maintenance is locking access to it at times. There is no way for us to know what is going on with the limited information you have provided so far. You really need to contact the server admin for help.

--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 10:30 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy, thanks for your prompt reply. I have updated the procedure as per your suggestion in the last posting you send.

I still think you are encountering a problem on the server side, not a problem with your app.
If we shut down the program and start up again, the same XML request that previously failed, will work instantly. This makes me doubt the problem is on the server side. But on the hand I have no idea what we could be doing that we shouldn't be doing.
You have seen all the XML/HTTP code there is to see.

No, Indy calls them only once. WSAStartup() is called the first time TIdStackWindows is constructed by any Indy component. >>WSACleanup() is called during finalization of the IdStackWindows unit.
Does this mean that if I run my program WSAStartup would be called the first time I create an object of type TIdHTTP?
When would finalization of the IdStackWindows unit occurr? When I close down the app?
Socket error 10093 is local to your app, and can't cause HTTP errors (because you wouldn't be able to communicate over >>HTTP in the first place).
Sorry, I don't understand this, I Thought that the socket error is precisely an HTTP error meaning failure to communicate with the URL.

I may still try creating the TIdHTTP object as a global object to see if it makes any difference.

Thanks
Cornelia

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 10:58 AM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

If we shut down the program and start up again, the same XML request
that previously failed, will work instantly.

That does not negate what I have said. During the time it takes you to
restart your app and send a new HTTP request, the server could have had
time to recover from whatever condition is causing it to temporarily
fail HTTP requests to the URL.

Instead of restarting the app, if you simply make the app delay awhile
before retrying an HTTP request, does the problem still occur? With
both HTTP libraries?

You have seen all the XML/HTTP code there is to see.

You have shown code, but not the actual HTTP requests/responses that
are being transmitted over the wire.

Does this mean that if I run my program WSAStartup would be called
the first time I create an object of type TIdHTTP?

Yes.

When would finalization of the IdStackWindows unit occurr?

When the app exits.

Socket error 10093 is local to your app, and can't cause HTTP
errors (because you wouldn't be able to communicate over HTTP
in the first place).

Sorry, I don't understand this, I Thought that the socket error is
precisely an HTTP error meaning failure to communicate with the URL.

No. A socket error is local to your app only. It means the WinSock
API itself reported an error in using the API. But "The system cannot
locate the resource specified" means you got far enough along to send
an HTTP request to the server and get an HTTP "404 NOT FOUND" error
response back. You can't get that far if you are getting socket error
10093, which means WinSock itself is not even operational at all.

--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 1:08 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Instead of restarting the app, if you simply make the app delay awhile
before retrying an HTTP request, does the problem still occur? With
both HTTP libraries?
We did try a one second delay with the IXMLHTTP library and it did not fix the problem. I have not tried the delay with Indy, but I will do this next.

You can't get that far if you are getting socket error
10093, which means WinSock itself is not even operational at all.
Thanks for the clarification. Is there a way to programmatically check if WinSock is operational and if not make it operational again?

The gateway (szGatewayURL) we are making the request to is the gateway for credit card processing by a company called American Payment Solutions. We have been advised that we should pass information to their site using the TLS 1.1 or higher.
I am wondering which TLS Indy uses and if there is a property to set it.

You mentioned that you have no information on what the input parameters are to the Post command so here is the information.
szXMLString will be something like this:

<?xml version="1.0" encoding="UTF-8"?>
<auth>
<api-key>U4d8nrtY5TnW2Jx8R8kxF23Acg7f8733</api-key>
<redirect-url>C:\AdagioSource\Softrak\AddOns\SoftrakRedirect.html</redirect-url>
<amount>9.81</amount>
<processor-id>APSCAD</processor-id>
<customer-vault-id>ABL01MC</customer-vault-id>
<billing>
<first-name>Lynne</first-name>
<last-name>Cullen</last-name>
<address1>1400 Bettman Street</address1>
<address2>5th Floor</address2>
<city>Windsor</city>
<state>ON</state>
<country>Canada</country>
<postal>N9A 8K3</postal>
<company/>
<phone/>
</billing>
</auth>

szGatewayURL is a constant and has this value:
'https://secure.apspaymentgateway.com/api/v2/three-step';

The code site logs show that when the HTTP.Post fails the parameters are intact.
Thanks
Cornelia
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 4:02 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

We did try a one second delay with the IXMLHTTP library and it did
not fix the problem. I have not tried the delay with Indy, but I will
do this next.

Does it take longer than 1 second to restart your app? Have you tried
longer delays? 5 seconds, 10 seconds, 30 seconds, etc...

Is there a way to programmatically check if WinSock is operational
and if not make it operational again?

No. You are responsible for making sure that calls to WSAStartup() and
WSACleanup() inside your app are always balanced. Indy's calls to them
are balanced. Sounds like your app did something it shouldn't have to
unbalance them, like maybe invoking a premature WSACleanup() in another
second of code.

The gateway (szGatewayURL) we are making the request to is the
gateway for credit card processing by a company called American
Payment Solutions. We have been advised that we should pass
information to their site using the TLS 1.1 or higher. I am
wondering which TLS Indy uses and if there is a property to set it.

That is dependent on which SSLIOHandler component you use with your
Indy connection. If you use Indy's default OpenSSL-based
TIdSSLIOHandlerSocketOpenSSL component, then it supports SSL 2, SSL 3,
TLS 1.0, TLS 1.1, and TLS 1.2, uses TLS 1.0 by default, and yes it does
have a property to set that.

You mentioned that you have no information on what the input
parameters are to the Post command

That is not what I said. I said you haven't shown the complete HTTP
requests and responses. I don't care what the XML looks like, since
you are getting an HTTP error, not an XML error.

--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 5:13 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy, thanks for your reply
1)
That is dependent on which SSLIOHandler component you use with your
Indy connection. If you use Indy's default OpenSSL-based
TIdSSLIOHandlerSocketOpenSSL component, then it supports SSL 2, SSL 3,
TLS 1.0, TLS 1.1, and TLS 1.2, uses TLS 1.0 by default, and yes it does
have a property to set that.
Yikes, we are not using a TIdSSLIOHandlerSocketOpenSSL component at all, and maybe that is the problem. I.e. we are not creating a component of type
TIdSSLIOHandlerSocketOpenSSL prior to creating the TIdHTTP object and attempting the Post command.
Where should this component be created? On startup of the app?
Should I do something like this?:

SSLIOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create;
SSLIOHandler.SSLOptions.Method := sslvTLSv1_1;
SSLIOHandler.SSLOptions.Mode := sslmClient; // what should the value be??

and would I have to set the IOHandler property of each TIdHTTP object like this?

HTTP.IOHandler:= SSLIOHandler;

2)
Sounds like your app did something it shouldn't have to
unbalance them, like maybe invoking a premature WSACleanup() in another
second of code.
The only thing I can think of here is another process which creates a control of type TWebBrowser and does a silent webpage submission with a redirect
that returns a token Once we receive that token we make another XML request . Is this possible?
I can send you the code if the solution is not in the fact that we are not specifying an IOHandler.
Thanks for your help
Cornelia
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 14, 2018 7:35 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

Yikes, we are not using a TIdSSLIOHandlerSocketOpenSSL component at
all, and maybe that is the problem. I.e. we are not creating a
component of type TIdSSLIOHandlerSocketOpenSSL prior to creating the
TIdHTTP object and attempting the Post command.

See:

New HTTPS functionality for TIdHTTP
http://www.indyproject.org/Sockets/Blogs/ChangeLog/20141222.aspx

The fact that you were getting an HTTP response at all meant that HTTPS
was working without creating an explicit SSLIOHandler object in your
own code.

Where should this component be created?

Anywhere you want, as long as you create it before attempting to send
any HTTPS requests. Ideally,, you would create it at the same time you
create the TIdHTTP object.

Should I do something like this?:

SSLIOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create;
SSLIOHandler.SSLOptions.Method := sslvTLSv1_1;
SSLIOHandler.SSLOptions.Mode := sslmClient;

Yes. Just note that you are not assigning an Owner, so you will have
to manually Free() the SSLIOHandler when you are done using it.
Otherwise, I would suggest making the TIdHTTP be the Owner.

would I have to set the IOHandler property of each TIdHTTP
object like this?

HTTP.IOHandler:= SSLIOHandler;

Yes.

The only thing I can think of here is another process which creates a
control of type TWebBrowser and does a silent webpage submission with
a redirect that returns a token Once we receive that token we make
another XML request .

Why are you using TWebBrowser for "silent" submissions? Unless the
user needs to interact with it, you should be using TIdHTTP or other
HTTP library for "silent" submissions.

In any case, that alone would not unbalance the WSAStartup/WSACleanup
calls. In part because TWebBrowser doesn't use WinSock directly at
all, it uses WinInet instead.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2018 6:32 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:
Unfortunately I get the same error if I use Indy instead of XMLHTTP.

Then the problem is definitely on the server side.

It is intermittent, and I have added more debugging code to see what the exception is exactly.

And what does it say exactly? You didn't show that.

Since we make so many XML requests I have made it a procedure shown below.

Note that szServerResponse will be empty if TIdHTTP.Post() raises an exception. If the exception is an EIdHTTPProtocolException, the content of the server's response will be in the exception's ErrorMessage property (not its Message property).

Try this:

function TAPSCCObj.MakeXMLRequest_Indy(szXMLString: string; var szServerResponse: string): integer;
{$ifdef DebugCodeSite}
type
  MyActions = (CreatingHTTP, PreparingHTTP, PostingHTTP, CleanupHTTP);
const
  MyActionStrs: array[MyActions] of string = ('HTTP Create', 'Preparing HTTP', 'HTTP Post', 'Cleanup HTTP');
{$endif DebugCodeSite}
var
  HTTP: TIdHTTP;
  PostData: TStringStream;
  {$ifdef DebugCodeSite}
  CurrentAction: MyActions;  
  {$endif}
begin
  {$ifdef DebugCodeSite}
  CodeSite.EnterMethod(Self, 'MakeXMLRequest_Indy');
  try
  {$endif DebugCodeSite}
 
    Result := 0; // No Error
    szServerResponse := '';
 
    try
      {$ifdef DebugCodeSite}
      CurrentAction := CreatingHTTP;
      {$endif DebugCodeSite}
 
      HTTP := TIdHTTP.Create;
      try
        {$ifdef DebugCodeSite}
        CurrentAction := PreparingHTTP;
        {$endif DebugCodeSite}
 
        HTTP.Request.ContentType := 'text/xml';
        HTTP.Request.Charset := 'utf-8';
 
        PostData := TStringStream.Create(szXMLString, TEncoding.UTF8);
        try
          {$ifdef DebugCodeSite}
          CurrentAction := PostingHTTP;
          {$endif DebugCodeSite}
 
          szServerResponse := Trim(HTTP.Post(szGatewayURL, PostData));
 
          {$ifdef DebugCodeSite}
          CurrentAction := CleanupHTTP;
          {$endif DebugCodeSite}
        finally
          PostData.Free;
        end;
      finally
        HTTP.Free;
      end;
    except
      on E: Exception do
      begin
        Result := APS_VC_STEP_ONE_XML_REQ_FAILED;
        {$ifdef DebugCodeSite}
        SSIMessageDlg(E.Message, '', mtError, [mbOK], mbOK, E.HelpContext);
        CodeSite.Send( 'ExceptionOn', MyActionStrs[CurrentAction] );
        CodeSite.Send( 'ExceptionMessage', E.Message );
        CodeSite.Send( 'ExceptionNo', E.HelpContext );
        CodeSite.Send( 'szGatewayURL', szGatewayURL );
        CodeSite.Send( 'szXMLString', szXMLString );
        if E is EIdHTTPProtocolException then
          CodeSite.Send( 'szServerResponse', EIdHTTPProtocolException(E).ErrorMessage )
        else
          CodeSite.Send( 'szServerResponse', szServerResponse );
        {$endif DebugCodeSite}
      end;
    end;
  {$ifdef DebugCodeSite}
  finally
    CodeSite.ExitMethod(Self, 'MakeXMLRequest_Indy');
  end;
  {$endif DebugCodeSite}
end;


--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 15, 2018 8:15 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thank you once more for your reply.
I have no created the IO handler as follows:
SSLIOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create;
SSLIOHandler.SSLOptions.Method := sslvTLSv1_1; // to use TLS version 1.1
SSLIOHandler.SSLOptions.Mode := sslmClient;

and I set the handler for the HTTP object as follows.
HTTP.IOHandler := SSLIOHandler;
I have not added a delay yet because I want to see first if just setting the handler makes the socket error go away.
If the problem persists I will add a delay of 2 seconds between the TIdHTTP.Create and the TIdHTTP. Post.
Is this the correct place to place a delay?

Why are you using TWebBrowser for "silent" submissions? Unless the user needs to interact with it, you should be using TIdHTTP or other HTTP library for "silent" submissions.
The reasons are historical. Originally we were using a Webpage to collect the sensitive credit card information such as card no and exp date. But since verification of the data on the webpage
was so difficult, we decided to collect this data in a native Delphi form instead and then populate a webpage with this data. The webpage is never shown and does a submit programmatically.
For every credit card transaction there is a 3 step process communicating with American Payment Solutions. According to their documentation Step 1and 3 are xml requests which I am now handling
using TIdHTTP. The second step is a webpage submission. APS doc is very sparse and we are the first Delphi developer integrating with APS. The only code samples we were given were written in C
and used a webbrowser. Unfortunately I have no idea how to submit the data on the webpage using TIdHTTP.
The webpage is an html file residing on hard disk, I have omitted the style info but the body is this
</head>

<body>
<form name='ccForm' action='" + url2 + "' method='post'>
<table>
<tr>
<td width=40%><label for='cc'>Card Number</label></td>
<td><input type='text' id='cc_number' pattern='
d*' title='Numbers Only' value='&nbsp' name='cc_number' maxlength='16' required></td>
</tr>

<tr>
<td width=30%><label for='xmonth'>Expiration Date</label></td>
<td width=20%><input type='month' id='cc_exp' name='cc_exp' required> MM/YY</td>
</tr>

<tr>
<td colspan="2"><input type='submit' id='submit' value='Submit'></td>
</tr>

</table>
</form>


</body>
</html>

The values of cc_number,cc_exp, and the action are set programmatically:

document := GetCreditCardPage.DefaultInterface.Document as IHTMLDocument2; // GetCreditCardPage is of type TWebBrower

firstForm := GetFormByNumber(document,0);

if Assigned(firstForm) then
begin
field := Firstform.Item('cc_number','') as IHTMLElement;
if field <> nil then
begin
if field.tagName = 'INPUT' then
(field as IHTMLInputElement).value := objCreditCardInfo.szCCNumber;
end;
field := Firstform.Item('cc_exp','') as IHTMLElement;
if field <> nil then
begin
if field.tagName = 'INPUT' then
(field as IHTMLInputElement).value := objCreditCardInfo.szCCExp;
end;
FirstForm.action := szFormUrl;
szSubmitButtonStartValue := SUBMIT_VALUE;//GetWebFormFieldValue(document, 0, 'submit') ;
FirstForm.submit; // this executes the submit action on the form

Any suggestions on how to replace my code with TIdHTTP code would be much appreciared.
Cornelia

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 16, 2018 10:20 AM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

The reasons are historical. Originally we were using a Webpage to
collect the sensitive credit card information such as card no and
exp date. But since verification of the data on the webpage was so
difficult, we decided to collect this data in a native Delphi form
instead and then populate a webpage with this data. The webpage is
never shown and does a submit programmatically.

You don't need to, nor should you, use TWebBrowser to do things that
way. For instance, you can use the TStrings overloaded version of
TIdHTTP.Post() to submit HTML webforms.

Unfortunately I have no idea how to submit the data on the
webpage using TIdHTTP.

Like this:

var
  PostData: TStringList;
begin
  IdHTTP.Get('URL of html page'); // to get any cookies that the POST
may need...
 
  PostData := TStringList.Create;
  try
    PostData.Add('cc_number=' + objCreditCardInfo.szCCNumber);
    PostData.Add('cc_exp=' + objCreditCardInfo.szCCExp);
    PostData.('submit=Submit');
 
    IdHTTP.Post('URL to post to', PostData); // URL from the <form>'s
"action" attribute...
  finally
    PostData.Free;
  end;
end;


--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 16, 2018 6:11 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks for your help Remy. Unfortunately it did not work.
The first problem I have is with the HTTP.Get which generates an exception and returns the error "Unknown Protocol". In truth I don't think I need this statement, since the htmfile is not a live url but a file residing on hard disk and it contains no data.
If I comment out the HTTP get, then it craps out on the HTTP Post with the following error "HTTP/1.0 403 Forbidden".
Perhaps I should explain how the data was submitted using the TWebbrowser object. As I mentioned before a webpage was never shown and after I triggered the submit button programmatically, I check for a change of the URL in the webbrowser to determine if the submission is done because as soon as it is, APS redirects us from szFormURL to a redirect-url that we specify in an earlier XML submission. The redirect-url is also never shown.
szFormURL changes everytime you run the program and is something like this: 'https://secure.apspaymentgateway.com/api/v2/three-step/4j7q1e0s'. The last portion of this URL is a token representing the current transaction.

Any ideas? Perhaps I have to stick with the method I am currently using?
Thanks
Cornelia

Code below:
HTTP := TIdHTTP.Create;
try
{$ifdef DebugCodeSite}
CurrentAction := PreparingHTTP;
{$endif DebugCodeSite}
szHtmlFile := GetHtmlFile;
HTTP.Request.ContentType := 'application/x-www-form-urlencoded'; // do I need this ???
HTTP.Request.Charset := 'utf-8'; // do I need this ???
HTTP.Request.Method := 'GET'; // do I need this ???

HTTP.IOHandler := SSLIOHandler;
HTTP.Get(szHtmlFile); // to get any cookies that the POST may need... (**** Problem 1 ****)
PostData := TStringList.Create;
try
{$ifdef DebugCodeSite}
CurrentAction := PostingHTTP;
{$endif DebugCodeSite}
PostData.Add('cc_number=' + objCreditCardInfo.szCCNumber);
PostData.Add('cc_exp=' + objCreditCardInfo.szCCExp);
PostData.Add('submit=Submit');
HTTP.Request.Method := 'POST';
// (**** Problem 2 ****)

szServerResponse := Trim(HTTP.Post(szFormUrl, PostData)); // // URL from the <form>'s action attribute

{$ifdef DebugCodeSite}
CurrentAction := CleanupHTTP;
{$endif DebugCodeSite}
finally
PostData.Free;
end;
finally
HTTP.Free;
end;
finally
SSLIOHandler.Free;
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2018 4:19 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

The first problem I have is with the HTTP.Get which generates an
exception and returns the error "Unknown Protocol".

That means you did not give it a proper URL that begins with 'http:' or
'https:'.

In truth I don't think I need this statement, since the htmfile is not
a live url but a file residing on hard disk and it contains no data.

You can't use TIdHTTP to load a local file, only a URL from a live HTTP
server.

Why are you loading a local HTML file that posts to a live HTTP server?
Why doesn't the live website have its own login page?

If I comment out the HTTP get, then it craps out on the HTTP Post with
the following error "HTTP/1.0 403 Forbidden".

Then either you are not posting everything the HTTP server requires, or
the credentials you are submitting are wrong.

As I mentioned before a webpage was never shown and after I triggered
the submit button programmatically, I check for a change of the URL in
the webbrowser to determine if the submission is done because as soon
as it is, APS redirects us from szFormURL to a redirect-url that we
specify in an earlier XML submission.

You can replicate that behavior by handling the TIdHTTP.OnRedirect
event. Set the TIdHTTP.HandleRedirects property to false, call
TIdHTTP.Post(), have your OnRedirect handler return Handled=True, and
then check the TIdHTTP.ResponseCode and TIdHTTP.Response.Location
properties when TIdHTTP.Post() exits.

Perhaps I have to stick with the method I am currently using?

Absolutely not. You are using a visual control for non-visual work.
Everything you are trying to accomplish, you cn do with TIdHTTP (or any
other non-visual HTTP library).

HTTP.Request.ContentType := 'application/x-www-form-urlencoded'; //
do I need this ???
HTTP.Request.Charset := 'utf-8'; // do I need this ???

Not when calling Get(), no.

HTTP.Request.Method := 'GET'; // do I need this ???

No. The Request.Method property is set automtically by TIdHTTP, based
on which method you are calling (Get(), Post(), etc). You never need
to set the Request.Method property manually.

HTTP.Get(szHtmlFile); // to get any cookies that the POST may need...
(**** Problem 1 ****)

You can't use TIdHTTP to load a local file, only a URL from a live HTTP
server.

--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 19, 2018 4:01 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks for your reply Remy.
Why are you loading a local HTML file that posts to a live HTTP server?
Why doesn't the live website have its own login page?
Purely historical, we originally translated somebody else's VB code.
In truth we do not need the HTTP.Get(szHtmlFile); at all, since the webpage is not used to collect any information that we need. We were preloading the form with the cc_number and cc-exp.
So I have omitted the Get Statement.
But I still have the exception "HTTP/1.0 403 Forbidden". on the HTTP.Post command.
Note that szFormURL looks like this:

'https://secure.apspaymentgateway.com/api/v2/three-step/7u5q3b3t'
The last 8 characters represent a token and this token changes for every time.
Then either you are not posting everything the HTTP server requires, or the credentials you are submitting are wrong.
I am submitting everything that was previously submitted on the webpage. One of my previous messages shows the html code of the Page used in the TWebBrowser.Navigate.

If access to szFormURL is forbidden, why did my solution using TWebBrowser work?
I will talk to APS to see if they can help us, because I have run into a brick wall here.
Thanks again
Cornelia

HTTP.IOHandler := SSLIOHandler;
HTTP.HandleRedirects := False;
HTTP.OnRedirect := RedirectProc;

PostData := TStringList.Create;
try
PostData.Add('cc_number=' + objCreditCardInfo.szCCNumber);
PostData.Add('cc_exp=' + objCreditCardInfo.szCCExp);
PostData.Add('submit=Submit');
szServerResponse := Trim(HTTP.Post(szFormUrl, PostData)); // // URL from the <form>'s action attribute
finally
PostData.Free;
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 19, 2018 4:41 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

I still have the exception "HTTP/1.0 403 Forbidden". on the HTTP.Post
command. Note that szFormURL looks like this:

'https://secure.apspaymentgateway.com/api/v2/three-step/7u5q3b3t'

The last 8 characters represent a token and this token changes for
every time.

Again, that means either you are requesting a URL that you really don't
have access to, or you are not sending everything the website login
requires, or your login credentials are wrong.

How are you determining the current URL to post to each time? A local
HTML file is static, so did it use client-side scripting to post to a
new URL each time?

I am submitting everything that was previously submitted on the
webpage. One of my previous messages shows the html code of the Page
used in the TWebBrowser.Navigate.

But you didnt show the complete HTML, or the raw HTTP request that
the TWebBrowser actually sends, so for all I know there could have been
a client-side script injecting additional values into the submitted
webform.

If access to szFormURL is forbidden, why did my solution using
TWebBrowser work?

I can't answer that without seeing both TWebBrowser's HTTP traffic and
TIdHTTP's HTTP traffic to see what is different between them.
Obviously there is something missing that you are not accounting for.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 19, 2018 4:42 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Again, that means either you are requesting a URL that you really
don't have access to, or you are not sending everything the website
login requires, or your login credentials are wrong.

Do you have any documentation whatsoever on what APS is actually
expecting in the HTTP requests?

--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2018 1:44 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy, I was finally able to get the Post data to webpage to work
The "HTTP/1.1 403 Forbidden error: disappeared when I added statement (***)

HTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0'; (***)
HTTP.Post(szFormUrl, PostData); // // URL from the <form>'s action attribute

Can you please confirm that I am setting the UserAgent to the correct value?

I have several other questions.
1) Someone in our QA department got the error "Could not load SSL library". I understand that TIdSSLIOHandlerSocketOpenSSL requires these dlls:

libeay32.dll
ssleay32.dll

We would like for our install program to install these dlls in a central directory such as "c:\softrak\system". is there a method to tell TIdSSLIOHandlerSocketOpenSSL
where to load these dlls from, or is that accomplished in a different way. If so how?

b) I have defined the following redirect procedure for HTTP:

HTTP.OnRedirect := RedirectProc;

and I have this while loop after the post
HTTP.Post(szFormUrl, PostData); // // URL from the <form>'s action attribute
while True do
begin
if bRedirectComplete then
begin
Result := 1;
break
end
else
Application.ProcessMessages;
end;

If the redirect works we break out right away, but what if there was a problem. I want to have a time limit after which I bail
Do I do this with the HTTP.ConnectTimeout property? Does it generate an exception when the time is up?
Thanks for your help, I think we are finally getting somewhere.
Cornelia


procedure TAPSCCObj.RedirectProc(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
var iPos: integer;
szToken, szRedirect: string;
begin
Handled :=True;
bRedirectComplete := True;
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2018 5:37 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

Can you please confirm that I am setting the UserAgent to the correct
value?

Set it to whatever you want/need. Apparently the server you are
posting to is UserAgent-aware, and doesn't like Indy's default
UserAgent. So give the server whatever it will accept.

1) Someone in our QA department got the error "Could not load SSL
library". I understand that TIdSSLIOHandlerSocketOpenSSL requires
these dlls:

libeay32.dll
ssleay32.dll

Yes.

We would like for our install program to install these dlls in a
central directory such as "c:\softrak\system". is there a method to
tell TIdSSLIOHandlerSocketOpenSSL where to load these dlls from, or
is that accomplished in a different way. If so how?

There is an IdOpenSSLSetLibPath() function in Indy's
IdSSLOpenSSLHeaders unit.

b) I have defined the following redirect procedure for HTTP:

I would take a slightly different approach:

- set the TIdHTTP.HandleRedirects property to true to let TIdHTTP
handle normal redirects to actual HTTP URLs for you.

- have the TIdHTTP.OnRedirect event handler return Handled=False when
redirecting to the target callback URL, and also to enable the
hoNoProtocolErrorException flag in the TIdHTTP.HTTPOptions property to
avoid raising a subsequent exception.

- check the TIdHTTP.Response after TIdHTTP.Post() exits to make sure
the callback URL was actually reached.

For example:

procedure TAPSCCObj.RedirectProcprocedure(Sender: TObject; var dest:
string; var NumRedirect: Integer; var Handled: boolean; var VMethod:
TIdHTTPMethod);
begin
  Handled := (dest <> TargetURL);
  if not Handled then
    HTTP.HTTPOptions := HTTP.HTTPOptions + [hoNoProtocolErrorException];
end;
 
...
 
HTTP.HTTPOptions := HTTP.HTTPOptions - [hoNoProtocolErrorException];
HTTP.OnRedirect := RedirectProc;
 
HTTP.Post(szFormUrl, PostData); // raises an exception if any
non-redirect error occurs...
 
if ((HTTP.ResponseCode div 100) = 3) {and (HTTP.Response.Location =
TargetURL)} then
begin
  // Target URL reached ...
  Result := 1;
end;


--
Remy Lebeau (TeamB)
Cornelia von Sc...

Posts: 21
Registered: 4/26/07
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 3, 2018 11:50 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
The problem has finally been resolved.
Our software uses novaPDF SDK, a PDF software development kit for developers that want to add PDF creation capabilities to their applications. This products uses Windows socket calls to verify our license, load print profiles etc.
A trace into the ws2_32.dll indicated that the WSAStartp and WSACleanup calls generated by Nova were balanced. These calls were done on the main thread.
However, we also use Crystal Reports .Net for our reporting needs, which reads our database via ODBC. The debugger showed that the ODBC dll was also calling Nova to verify our license but it was doing this on a different thread!.
The WSAStartp and WSACleanup calls on this thread were balanced as well. According to what I have read, in a multithreaded environment, WSACleanup terminates Windows Sockets operations for all threads.
This explains why after printing a Crystal report via ODBC, the next TIdHTTP post failed. When our programmer removed the call to Nova in the ODBC dll, the problem goes away.
Remy Lebeau, thanks so much for your unwavering resolve in helping us resolve an issue that has puzzled us for months. Our development team is very grateful for all the help we have received on the forum.
Cornelia
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: "The system cannot locate the resource specified" on XML send request  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 3, 2018 1:46 PM   in response to: Cornelia von Sc... in response to: Cornelia von Sc...
Cornelia von Schellwitz wrote:

A trace into the ws2_32.dll indicated that the WSAStartp and
WSACleanup calls generated by Nova were balanced. These calls were
done on the main thread. However, we also use Crystal Reports .Net
for our reporting needs, which reads our database via ODBC. The
debugger showed that the ODBC dll was also calling Nova to verify our
license but it was doing this on a different thread!. The WSAStartp
and WSACleanup calls on this thread were balanced as well.

So far, so good. It is perfectly valid to call WSAStartup() multiple
times, even across threads. The first call to WSAStartup() loads
WinSock, subsequent calls simply increment a reference count inside of
WinSock. Likewise, WSACleanup() decrements the reference count, and
the last call unloads Winsock. That is why calls to WSAStartup() and
WSACleanup() need to be balanced.

According to what I have read, in a multithreaded environment,
WSACleanup terminates Windows Sockets operations for all threads.

Yes, but that only happens on the final call to WSACleanup() (when
WinSock's reference count falls to 0). You didn't read the rest of the
documentation, which also states:

There must be a call to WSACleanup for each successful call to
WSAStartup. **Only the final WSACleanup function call performs the
actual cleanup**. The preceding calls simply decrement an internal
reference count in the WS2_32.DLL.

This explains why after printing a Crystal report via ODBC, the next
TIdHTTP post failed.

It shouldn't be, since WinSock's reference count should not be 0 yet
due to Indy's own calls to WSAStartup()/WSACleanup().

I did a test, where I had a client connected to a server and sent data
back and forth for 15 seconds. 5 seconds after connected, I started
another thread that called WSAStartup() and WSACleanup().

I can confirm that calling WSACleanup() in one thread while another
thread is actively performing socket operations DOES NOT terminate the
socket operations, as you claim (provided that the cleanup thread has
its own call to WSAStartup(), otherwise it shouldn't be calling
WSACleanup() at all).

So, something else has to be going on in your case. ODBC should not be
calling WSACleanup() unless it has its own call to WSAStartup(), in
which case, the TIdHTTP socket should have been affected at all.

When our programmer removed the call to Nova in the ODBC dll, the
problem goes away.

Hmm... probably as a side effect of something else that was also fixed
when ODBC stopped accessing Nova.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02