Connect to web service error Connection Failure: Status code unavailable: - coldfusion

We are making a cfhttp call to connect to an https web service.
We are getting the this error:
Connection Failure: Status code unavailable
I searched Google but have found no solutions.
From the production server I am able to hit the web service URL.
I am a .Net developer and I am not sure of this technology.
Any pointers will be helpful.
Here is the line of code we are using to make the connection:
<cfhttp url="#arguments.TheIP#" method="post" throwonerror="true" timeout="45">
<cfhttpparam type="header" name="SOAPACTION" value="#arguments.TheHeader#">
<cfhttpparam type="XML" value="#arguments.TheXML#">
</cfhttp>

I have faced / solved this a few times, the snippet below hopefully will work for you. I highly recommend learning about it in stead of simply trying it.
I place this in my Application.cfc, but you could put it right in your script right before the cfhttp call as well.
<!--- fix for HTTPS connection failures --->
<cfif NOT isDefined("Application.sslfix")>
<cfset objSecurity = createObject("java", "java.security.Security") />
<cfset objSecurity.removeProvider("JsafeJCE") />
<cfset Application.sslfix = true />
</cfif>enter code here

Hum... First thing that appears odd is your IP argument as mentioned by barnyr. The response you are getting makes me think you are getting NO response at all (the request is completely ignored, not just erring). So some setting is causing them to ignore your request.
As of CF9 I use cfscript to do this kind of thing via HTTP when I can't use regular webservice java object proxy stubs.
Here is a working SOAP call via http() (because of .net to cf inability to communicate complex object hash maps via regular soap I resorted to this, among other things).
This is a cf to .net service call so it might be relevant for you as they are using just the built in tools to gen their SOAP service which was not perfectly Axis 1 SOAP happy-go-lucky.
In particular I had to play with some of the extra settings and headers to get it just so and specifically add the soap action into a header (which is usually derived from the SOAP body envelope).
Additionally, I am using oasis security which I had to stuff inside the envelope/body.
Here is the code (inside a cfc) that you might try updated as you need:
//////////////////////////////////////////////////////////////////////////
// BUILD HTTP REQUEST
//////////////////////////////////////////////////////////////////////////
Local['SoapAction'] = "XYZ.Commercial.Mapping.ServiceContracts/IService/#Arguments.szMethodName#"; // THIS IS CASE SENSITIVE
var oH = new Http();
oH.setMethod('post');
oH.setCharset('utf-8');
oH.setUserAgent('Axis/1.2.1');
oH.setTimeout(30);
oH.setURL(Arguments.szURL);
// INCLUDING THE SOAPACTION AS A HEADER IS SPECIFIC TO XYZ - USUALLY THE OPERATION IS DECIPHERED FROM THE ENVELOPE BODY TAGS - XYS REQUIRES THIS PATHING TO MATCH FOR THE SOAP ACTION HEADER VALUE
oH.addParam(type="HEADER", name="SOAPAction", value='#Local.SoapAction#');
oH.addParam(type="HEADER", name="Content-Type", value='text/xml');
oH.addParam(type="body", value=Arguments.szBody);
///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// EXECUTE HTTP
Local['rsHttpSend']= oH.send();
// SET RESULTS
Local.nStatusCode = val(Local.rsHttpSend.getPrefix().StatusCode);
Local.szResponse = Local.rsHttpSend.getPrefix().FileContent;
Local.szHeader = Local.rsHttpSend.getPrefix().Header;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
This approach was coupled with using SoapUI to verify the final soap body post was valid. So if you can do that too, you should be able to use this vector.
Let me know if you get any farther.

Here are a list of things to check:
The variable for the URL is TheIP. Make sure this actually a properly
formatted URL, not just a URL.
Check that the target server's certificate is installed in the JVM's
trust store. in Windows and I think .Net, the system's own
certificate store is used, so if your browser can get to the URL
you're ok. In Java there is a file which contains a list of Trusted
Certs. Instructions on importing those certs are in the CF docs for
CFHTTP.
Check the ColdFusion logs for evidence of failure.
c:\coldfusion9\logs\exception.log is probably a good place to start.

Make sure your cfhttp link is correct. I face this issue and it totally based on incorrect cfhttp link.

Related

Add cookie to HTTP header for SOAP call in ColdFusion

I basically want to add the ASP.NET_SessionId cookie to my HTTP request header when calling a SOAP web service through ColdFusion.
The web service is registered in the OnApplicationStart function of the Application.cfc component in ColdFusion.
<cfscript>
objSoapHeader = XmlParse("<wsse:Security mustUnderstand=""true"" xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""><wsse:UsernameToken><wsse:Username>MY_USERNAME</wsse:Username><wsse:Password>MY_PASSWORD</wsse:Password></wsse:UsernameToken></wsse:Security>");
Application.UserWebService = CreateObject("webservice","MY_URL/UserService.asmx?WSDL");
addSOAPRequestHeader(Application.UserWebService,"","",objSoapHeader,true);
</cfscript>
My web service is called as such:
<cfset Result = "#Application.UserWebService.SomeFunction("1", "DATA")#">
In order for the .Net server (where the web services are located) to remember my session state, I must pass the ASP.NET_SessionId cookie in the HTTP request header, but have no idea if this is even possible in ColdFusion.
I've researched for several hours but nothing has come of it as of yet, so has anyone successfully managed to pull this off?
Short Answer:
For CF9 / Axis1 try enabling sessions on the web service object.
ws = createObject("webservice", "http://localhost/MyWebService.asmx?wsdl");
ws.setMaintainSession( true );
For CF10+ / Axis2, see longer answer below:
(Disclaimer: Using cfhttp might be simpler, but I was curious and did some digging ..)
From what I have read, since CF10+ uses Axis2 for web services it should be possible to use the underlying methods to maintain session state through HTTP cookies.
How to set Cookies in ColdFusion SOAP requests - (circa 2006) - Written for a much older version of CF/Axis, so some of it is outdated, but it still provides a good overview of the general concept.
Maintain session in Axis2
Java axis web service client setMaintainSession on multiple services (cookies?)
Axis2 Manage Session Cookie Manually
Using the the links above, I put together a quick POC using a basic web service and was able to extract the cookie header from the web service client response:
// make initial request
ws = createObject("webservice", "http://localhost/MyWebService.asmx?wsdl");
ws.firstMethod();
// For maintainability, use constants instead of hard coded strings
wsdlConstants = createObject("java", "org.apache.axis2.wsdl.WSDLConstants");
// Extract headers
operation = ws._getServiceClient().getLastOperationContext();
context = operation.getMessageContext( wsdlConstants.MESSAGE_LABEL_IN_VALUE );
headers = context.getProperty( context.TRANSPORT_HEADERS );
Then set the cookie and instruct the web service client to send it with subsequent requests:
if ( structKeyExists(headers, "Set-Cookie") ) {
// include http cookies with request
httpConstants = createObject("java", "org.apache.axis2.transport.http.HTTPConstants");
options = ws._getServiceClient().getOptions();
options.setManageSession( true );
options.setProperty( httpConstants.COOKIE_STRING, headers["Set-Cookie"] );
}
// ... more requests
ws.secondMethod();
ws.thirdMethod();
NB: Side note, I noticed you are storing the instance in the shared Application scope. Just keep in mind web service instances are probably NOT thread safe.
Inside your CFHPPT tags, set the cookie with CFHTTPPARAM

Can I use ColdFusion tags in JavaScript?

Can I use ColdFusion tags in JavaScript? For example:
<script language="javascript" type="text/javascript">
function validateUser() {
var userName = document.getElementById("username");
<CFQUERY DATASOURCE="mydatasourcename" NAME="getUser">
select USER_ID,COUNT(*) from user u
where u.firstname=userName;
</CFQUERY>
<cfif getUser.recordCount EQ 0>
<!--- Show eroor message --->
<cfelse>
<!--- Assign userId to hidden field --->
document.getElementById("userid").value=#USER_ID#
</cfif>
}
</script>
<input type='textbox' name='username' id='username' onblur=validateUser()/>
<input type='hidden' name='userid' id='userid'/>
When the end user enters their username, I would like to check in a database if this username exists or not. If it exists, I have to keep the userid in the hiddenfield or else throw an error.
Am I doing this correctly? If it is wrong, could you suggest the correct way?
Long version: http://blog.adamcameron.me/2012/10/the-coldfusion-requestresponse-process.html
Short version: no, you're not doing it right.
Mid-sized StackOverflow-friendly version: CFML code runs on the server side of a request; JavaScript runs on the client browser. And to be clear: the ColdFusion server never communicates with the browser directly at all: there's a web server in between. The client browser requests a file, the web server is configured to pass .cfm requests to the ColdFusion server, and it runs its code, returning the resulting string (eg: an HTML web page) to the web server which then returns that to the browser. That HTML might include JavaScript (inline or as external requests) which the browser will then execute.
Hopefully from that you can see that there's no direct interaction between server-side code and client-side code.
You have two facilities at your disposal to get the two communicating asynchronously though. Firstly: CFML code writes out text, but that text can be JS which the browser then runs when it finally receives it. Something like:
<cfset msg ="G'day world">
<script>alert("<cfoutput>#msg#</cfoutput>");</script>
Once the CFML server has processed that, what gets sent back to the browser is:
<script>alert("G'day world");</script>
In this way server-side code data can be used in client-side process if the server-side code "writes out" the data as part of its response. The example above is very trivial and not a "good practice" way of going about this, but it demonstrates the technique.
If you need to use JS code on the client to communicate back with the server, your only (real) recourse is to make an AJAX request back to the server to pass it client-side information for further server-side processing and for the server to respond with something. It is outwith the scope of your question to explain how best to do this, but there is a tonne of information out there to do this.
CFML provides some "wizards" to write HTML and JS out for you to facilitate this, but on the whole this is a bad approach to achieving this end, so I will not recommend it. However I will point you to a project which offers HTML/JS/CSS solutions to the inbuilt CFML wizardry: https://github.com/cfjedimaster/ColdFusion-UI-the-Right-Way
Back to the short answer: no, you cannot do what you are setting out to do for very good reasons, but if you revise your approach, you can achieve the ends that you want.
What you need to look at is passing the form fields back to the server via AJAX (jQuery makes this very easy), and run your <cfquery> code in a separate request.
If you read that blog article I mention from the outset (discloure: I wrote it, but I wrote it specifically for situations like this), then you'll understand why.
If you get stuck when working on part of your solution: raise another question more focused on whatever part you are stuck on.

COM.Allaire.ColdFusion.HTTPFailure

I'm working on a web app that is ran nightly to retrieve a large XML file from another server. We're using ColdFusion MX7. We run a CFHTTP GET with username, pass, and url. Then we write the field with a cffileaction write to our temp location. So that it can be parsed and sorted into a database. There are a few CFHTTP calls on the page cut one of them is failing. In the CFCatch I have the system email me the catch type and the message and I'm getting this.
COM.Allaire.ColdFusion.HTTPFailure
Connection Failure: Status code unavailable
This the call an write action as is (the credentials are right):
<cfhttp method="GET"
username="#uname#"
password="#pw#"
url="#url#"
resolveurl="yes"
throwonerror="yes">
</cfhttp>
<cffile action="write" file="#getdirectoryfrompath(GetCurrentTemplatePath())#\XML_FileName.xml" output="#cfhttp.fileContent#">
Is anyone familiar with his error?
As it turns out we were getting the Cert from the other groups 'test' server and then trying to using to get things from their production server. So Peter was right! If you run into this problem check out these links:
CFHTTP Over SSL
http://www.houseoffusion.com/groups/cf-talk/thread.cfm/threadid:48687

Consuming ColdFusion webservice - Web service operation with parameters {} cannot be found

I am testing consuming a web-service and I'm getting an error.
Here is the web-service component:
<cfcomponent >
<cffunction name="listBooks" access="remote" returntype="string" output="no" >
<cfquery name="getBooks" datasource="cfbookclub" >
SELECT bookID, title, bookDescription, genre
FROM books
ORDER BY title desc
</cfquery>
<cfsavecontent variable="bookList" >
<books>
<cfoutput query="getBooks" >
<book id="#getBooks.bookID#" >
<title>#XMLFormat( getBooks.title )#</title>
<description>#XMLFormat( getBooks.bookDescription )#</description>
<genre>#XMLFormat( getBooks.genre )#</genre>
</book>
</cfoutput>
</books>
</cfsavecontent>
<cfreturn bookList >
</cffunction>
Here is the consuming page:
<cfinvoke
webservice="http://127.0.0.1/books.cfc?wsdl"
method="listBooks"
returnvariable="rawXMLBookList" >
</cfinvoke>
Seems simple enough - I was actually trying to pass an argument "genre" when I got the initial error,
Web service parameter name category cannot be found in the provided parameters {genre}.
So I removed all reference to arguments, and STILL get this error
Web service operation with parameters {} cannot be found.
The error makes it sound like the web-service cannot be found, however if I cut and paste the url into my browser I get the expected XML doc...
There was another post like this on this site, but the problem was a base64 issue, I'm just returning txt so I don't think it's a similar problem, even through the error msg is similar.
Try adding the refreshWSDL argument to your <cfinvoke> call and see if that helps.
<cfinvoke
webservice="http://127.0.0.1/books.cfc?wsdl"
method="listBooks"
refreshwsdl="yes"
returnvariable="rawXMLBookList">
</cfinvoke>
Setting refreshwsdl="yes" reloads the WSDL file and regenerates the artifacts used to consume the web service.
Note you do not want to keep this setting for all of your requests. You just need to set it for one request to refresh the artifacts. Then you should change it back to refreshwsdl="no". Until you need it again.
Here is an excerpt from Charlie Arehart's Blog about the refreshWSDL argument:
Why should you have to refresh the web service metadata?
Just to back up for a moment, the problem stems from CF's attempt to help. On the first request for a given web service, CF does some caching to make future requests go faster, not caching the results of the web service method but rather the artifacts used by CF based on the description of the web service itself.
CF uses the web service description (WSDL) reported at the time of that first call to create a java proxy/stub based on that, which it then reuses on future calls from CF to that web service.
The issue arises if/when the web service metadata changes. CF won't know, and will continue to use the older cached proxy/stub, and your long-running code may fail if it doesn't match the new WSDL returned by the web service.
So we need a way to tell CF to refresh its cache of that proxy stub.
This new feature is certainly the easiest way to make that happen, but it's not the only way.

Coldfusion uses wrong (cached?) variables at random

We have a dedicated server running CentOS and Coldfusion 8.
All cfmail email is routed through Google with cfmail and smtp.
Every now and then, when cfmail is used, the 'FROM' field uses an address from a totally different website.
For instance:
Use form on Site A
Get an email: "Subject: On Site A From: siteb#siteb.com"
Where the from is a completely different variable in another set of code on another part of the server- there is no reason it should see this.
On the other side, sometimes sending an email to sitea#sitea.com has email wind up in Site B inbox, a completely different Google account.
What causes this to happen? Some kind of memory/cache issue? Or is there a funky DNS record causing issue?
Example:
Application.cfm (starts with some UDF includes, and then):
<cfinvoke component="#request.componentPath#.variables" method="getGlobal" />
Variables.cfc (a lot of variables defined within, but here is the cfmail vars):
<cffunction name="getGlobal" access="public" output="false" returntype="void">
<cfscript>
request.siteEmail = "email#mysite.com";
request.siteMailServer = "smtp.gmail.com";
request.siteMailUsername = "root#mysite.com";
request.siteMailPassword = "[redacted]";
</cfscript>
</cffunction>
It sounds like it's possible it could be a var scoping issue, but we can't know for sure until you share some code...
Looks like you're running multiple sites? there's a setting in the CF caching page in admin to do with caching web server paths:
From http://help.adobe.com/en_US/ColdFusion/9.0/Admin/WSc3ff6d0ea77859461172e0811cbf3638e6-7ffc.html :
Disabling the cacheRealPath attribute To ensure that ColdFusion always returns pages from the correct server, disable Cache Web Server Paths in the Caching page of the ColdFusion Administrator. (When you use the multiserver configuration, set the cacheRealPath attribute to false for the ProxyService in the jrun_root/servers/servername/SERVER-INF/jrun.xml file.)
Might not be it, but it's at least quick to try out.