Copy link to clipboard
Copied
In building out a new server for ColdFusion 2021, I migrated code running on CF2016 which is returning a strange error. One of my GET REST services which calls another using cfhttp is returning the following:
{
Message: "JSON parsing failure at character 1:'<' in <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://myservername.ddns.net/rest/services/grantPermission">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at myservername.ddns.net Port 80</address>
</body></html>"
}
What makes this even stranger is the fact that there is no redirect in either service.
See the below snippet of error from the exception log:
"Error","ajp-nio-127.0.0.1-8020-exec-2","04/21/23","18:57:09","","HTTP 500 Internal Server Error"
coldfusion.rest.method.dispatch.CFRestException: HTTP 500 Internal Server Error
Flowed by:
Caused by: coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.JSONUtils$JSONParseException : JSON parsing failure at character 1:'<' in <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://myservername.ddns.net/rest/services/grantPermission">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at myservername.ddns.net Port 80</address>
</body></html>. ]
Has anyone encountered this issue before?
Again, though, you show doing DeserializeJSON(grantPermissionRes.fileContent). We've asked to just show the output of dumping that grantPermissionRes.fileContent. Even if you think you "know" what it will show, please humor us as we try to help.
Also, are the log messages from the first post from the calling or called cf instance? That called instance is cf also, right? And is it calling itself or some other cf instance? If it's another, what cf version is that? Either way, where is that call
...Hi @KARMA28699455uxq6 ,
There is no mystery about the error you're getting. It results from the following sequence of events:
<cfset jsonData = DeserializeJSON(grantPermissionRes.fileContent)>​
generates the error
"JSON parsing failure at character 1:'<' in <!DOCTYPE HTML PUBLIC "
So, lI found the issue shortly after responding to your previous email. localservice referenced in the call was using a CGI variable in my dev environment which was apparently adding something to the URL string which was not shown in the error message. I changed it to call the full server name instead which resolved the issue.
Many thank to you and @Charlie Arehart for your patience and effort in assisting me with troubleshooting this issue.
Copy link to clipboard
Copied
To answer your question, I'll say no (have not seen this before). But I suspect this is not about cf2021 but instead either a) your new server or b) the Java version underlying your two versions.
Can you clarify what your cf2021 and cf2016 Java versions are, and the cf update level of each? Both are shown on the cf admin settings summary or system info pages.
Also, if you want to prove/disprove my theory, you could install cf2016 on the new server--yes, even just for this one test. It would take just minutes. And no need to setup the web server connector. Just drop a test page into the cfusion/wwwroot of cf2016, and call it with the same port used for the cf admin.
And note that there were important changes to the jvm in Apr 2021, which affect calling out to https urls, if the server being called does not support tls 1.2. If your cf2016 had been running earlier than Java 1.8.0_291 or 11.0.11, and your cf2021 is 11.0.11 or later, that could underlie your issue. I have a blog post with more detail:
https://www.carehart.org/blog/2021/4/26/new_java_updates_for_Java_8_and_11_as_of_Apr_2021
As for the redirect, you may want modify your cfhttp to not follow redirects, to what it then responds with (dumping the cfhttp result variable to see what it shows).
Hope something there is helpful.
Copy link to clipboard
Copied
Thanks for your speedy response. I suspected it could have been an issue with the Java version so I upgraded from jre 11.0.11 to jdk 11.0.18. Unfortunately, there was no change.
The service being called is actually on the server and it has TLSv1.2 and 1.3 enabled.
I tried disabling the redirect as you suggested, but I got the same response.
Copy link to clipboard
Copied
Ok, but since you say your java was 11.0.11, I did not suggest you update that. I'd said "If your cf2016 had been running earlier than Java 1.8.0_291 or 11.0.11, and your cf2021 is 11.0.11 or later, that could underlie your issue."
Also, I'd asked what was the Java version and cf update level for both. I sense you may feel these are not pertinent, but I will persist as it could be relevant.
Finally, I still would argue you look at the cfhttp return variable. Like Eddie is saying, you may see something that surprises you.
Copy link to clipboard
Copied
I was explaining that I had already done that prior to posting the issue. Sorry if I mislead you.
I forgot to mention that I had the error running update 4 and updated to update 6 (2021.0.06.330132).
I have followed Eddie's suggestion. This is the call to grantPermission:
<cfset webservice = localservice & "/grantPermission">
<cfhttp url="#webservice#" method="post" redirect="no" result="grantPermissionRes">
<cfhttpparam name="renewal_id" type="formfield" value="#rnw_id#">
</cfhttp>
<cfset jsonData = DeserializeJSON(grantPermissionRes.fileContent)>
<cfset tmp_document = jsonData.TMP_DOCUMENT>
Copy link to clipboard
Copied
Again, though, you show doing DeserializeJSON(grantPermissionRes.fileContent). We've asked to just show the output of dumping that grantPermissionRes.fileContent. Even if you think you "know" what it will show, please humor us as we try to help.
Also, are the log messages from the first post from the calling or called cf instance? That called instance is cf also, right? And is it calling itself or some other cf instance? If it's another, what cf version is that? Either way, where is that called service relative to the calling cf instance? Again, please don't presume it immaterial.
You never know when challenging presumptions may spot an unexpected issue.
Copy link to clipboard
Copied
I am struggling to get cfdump to work within a cfcomponent. However, I used cflog which logged the following:
"Severity","ThreadID","Date","Time","Application","Message"
"Information","ajp-nio-127.0.0.1-8020-exec-4","04/21/23","22:39:24","","/opt/ColdFusion2021/cfusion/logs/grantPermissionRes.log initialized"
"Information","ajp-nio-127.0.0.1-8020-exec-4","04/21/23","22:39:24","","grantPermissionRes: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://myserver.ddns.net/rest/services/grantPermission">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at myserver.ddns.net Port 80</address>
</body></html>
"
"Information","ajp-nio-127.0.0.1-8020-exec-5","04/21/23","22:39:30","","grantPermissionRes: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://myserver.ddns.net/rest/services/grantPermission">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at myserver.ddns.net Port 80</address>
</body></html>
"
Also, are the log messages from the firs post from the calling or called cf instance? That called instance is cf also, right? And is it calling itself or some other cf instance? If it's another, what cf version is that?
Yes, the log messages are from the initial call which uses cfhttp to call grantPermission (calling). The instance is also cf both sit within the same rest services directory on the same server so it is the same cf version.
I hope that explains it. If not let me know.
Copy link to clipboard
Copied
Firstly, it appears that you are assuming you are getting a JSON response, which of course fails when you get an HTTP response. You should first verify that the response you got is indeed JSON before trying to treat it as such.
Next, have you used PostMan or cUrl or a similar utility to test the endpoint to verify that the response is what you expect?
Copy link to clipboard
Copied
Hi @EddieLotter,
I have verified that the response is indeed JSON. See the response below:
{
"MESSAGE": "A Certificate will be issued.",
"DOCUMENT": "cert",
"TMP_DOCUMENT": "cert"
}
This is a snippet of the function within the component of what is being called:
<cffunction access="remote" name="grantPermission" output="false" httpmethod="POST" returnFormat="plain" returntype="Any" produces="application/json">
Copy link to clipboard
Copied
Your first post shows a "JSON parsing failure" message. It's at that point that it appears that JSON is being assumed without verification.
Are you in control of the entire pipeline or are you making a call to an external service, outside of your control?
Copy link to clipboard
Copied
I am in control of the entire pipeline.
Copy link to clipboard
Copied
So at what point in the pipeline are you getting the "JSON parsing failure" message?
Copy link to clipboard
Copied
That message is returned when I call a service that is calling the grantPermission service via cfhttp
Copy link to clipboard
Copied
Hi @KARMA28699455uxq6 ,
There is no mystery about the error you're getting. It results from the following sequence of events:
<cfset jsonData = DeserializeJSON(grantPermissionRes.fileContent)>​
generates the error
"JSON parsing failure at character 1:'<' in <!DOCTYPE HTML PUBLIC "
So, long story short, the REST request is posting to the wrong URLCopy link to clipboard
Copied
In my original post, I mentioned that these services have been working correctly in a production environment running CF2016. It also worked previously in CF10. I realise that I didn't properly explain how everything ties together so I will try to explain it better this time.
The error thrown comes from the service checkLocksJSON. This service is a GET and calls several services including grantPermission which according to the logs is the cause of the error. Please see a screenshot of checkLocksJSON being called in Postman below:
The service grantPermission which is the cause of the error (at least according to the exception log) is a POST. When called independently, works fine and returns a JSON as expected. See the screenshot below:
I you can see from both screenshots, both services are being run on the same server which is referenced as {{ebroker_services}}.
I can also confirm that the REST request post is calling the correct URL. See code snippet below:
<cfset webservice = localservice & "/grantPermission">
<cfhttp url="#webservice#" method="post" redirect="no" result="grantPermissionRes">
<cfhttpparam name="renewal_id" type="formfield" value="#rnw_id#">
</cfhttp>
<cfset jsonData = DeserializeJSON(grantPermissionRes.fileContent)>
<cfset tmp_document = jsonData.TMP_DOCUMENT>
localservice is referencing the same server {{ebroker_services}} shown in Postman.
I how that made it clearer.
Copy link to clipboard
Copied
The description in your first message says the issue is about "One of my GET REST services". But the request you showed later is:
<cfhttp url="#webservice#" method="post" .../>
which is a POST instead of a GET.
Confusing.
Copy link to clipboard
Copied
I found the issue shortly after responding to your previous email. localservice referenced in the call was using a CGI variable in my dev environment which was apparently adding something to the URL string which was not shown in the error message. I changed it to call the full server name instead which resolved the issue.
Many thank to you and @Charlie Arehart for your patience and effort in assisting me with troubleshooting this issue.
Copy link to clipboard
Copied
@KARMA28699455uxq6 , thanks for sharing your findings.