Copy link to clipboard
Copied
Hello,
I am using cf 23 and facing the issue when trying to communicate with remote api on spring.
This is my cf codebase:
Copy link to clipboard
Copied
I would suggest that you stop using the script-based CFC, new http(). Script-based CFCs, such as http(), were deprecated since ColdFusion 2018, unsupported since ColdFusi....
You should use instead the tag or cfscript version of CFHTTP. For example,
<cfhttp
url="http://localhost:8806/sftp/private/remove/import/test.xml"
method="delete"
timeout="5"
result="httpServiceResponse">
<cfhttpparam type="header" name="Accept" value="application/json">
<cfhttpparam type="header" name="cfId" value="123">
<cfhttpparam type="header" name="cfToken" value="555-555">
</cfhttp>
Another reference:
Copy link to clipboard
Copied
Hi,
Thanks for response, but using script language is not the issue.
I did configured the same way you suggested:
I get this on backend
2025-05-15 18:27:40,081 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [2b049cca15a7;;;] - REQUEST headers: [cfid=7254; accept=application/xml, text/xml; charset=UTF-8; cftoken=81ed7be3e4701804-4FBA98CF-FB24-1A00-6AC399B24A037C35; user-agent=ColdFusion; content-length=0; host=172.23.200.150:8080; connection=Keep-Alive; accept-encoding=gzip,deflate]
If i remove .xml from url like url="http://localhost:8806/sftp/private/remove/import/test"
I get
2025-05-15 18:28:26,219 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [1cc594821162;;;] - REQUEST headers: [cfid=7255; accept=application/json; cftoken=88252445ef2587ec-4FC1A2C8-CF95-6EB0-A51EFDECCEAA7388; user-agent=ColdFusion; content-length=0; host=172.23.200.150:8080; connection=Keep-Alive; accept-encoding=gzip,deflate]
so the <cfhttpparam type="header" name="Accept" value="application/json"> is respected.
Any time u use .xml or .json on url end you will get accept accept=application/xml, text/xml or accept=application/json in headers no matter if you using script or markup language
Thanks
Copy link to clipboard
Copied
Sorry, I think I misunderstood your question. Do I understand correctly that you wish to delete a file from an FTP server? If so, why not use CFFTP instead of CFHTTP?
I still don't understand your question about the application/xml and application/json headers. Does one work (with cfhttp) and the other does not? If so, which one works and which one doesn't?
In any case, if you place the following line at the end of the cfhttp code, what do you get?
<cfdump var="#httpServiceResponse#" >
Copy link to clipboard
Copied
That service that is working with files on sftp server and already created and implemented on springboot and it's already working properly.
We are sending path to file in the url in couple of endpoints and the example I posted is for endpoint that is removing file from sftp over spring service where we don't consume any "Accept" property in header. When you invoke any http call from ColdFusion (with <cfhttp>, new http() or cfhttp in cfscript) and url of that request ends in .xml or .json (like "Providing accept header" in https://helpx.adobe.com/coldfusion/developing-applications/changes-in-coldfusion/restful-web-service... describes) like I suggested in my example, coresponding to that sufix of url when http service is invoked ColdFusion will automatically add accept=application/xml, text/xml or accept=application/json, depending on url sufix, to request headers.
If url sufix is .xml or .json you can't change the value of "Accept" param in header and you can't even remove it from header. It's fixed always accept=application/xml, text/xml for "http://localhost:8806/sftp/private/remove/import/test.xml" and always accept=application/json for "http://localhost:8806/sftp/private/remove/import/test.json"
This is a serious issue and thus the exception happens 406 - No acceptable representation because spring is expecting headers without accept property
Here is the dump
We get 406 - No acceptable representation, because accept=application/xml, text/xml; is forced to http header even if there is <cfhttpparam type="header" name="Accept" value="application/json"> configured
Here is the complete trace from spring:
2025-05-15 20:09:54,457 [pas-sftp] INFO c.a.p.c.c.f.RequestLoggingFilter [0cb662839cd8;;;] - REQUEST: DELETE to /sftp/private/sftp/remove/import/test.xml
2025-05-15 20:09:54,457 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [0cb662839cd8;;;] - REQUEST headers: [cfid=123; accept=application/xml, text/xml; charset=UTF-8; cftoken=555-555; user-agent=ColdFusion; content-length=0; host=localhost:8806; connection=Keep-Alive; accept-encoding=gzip,deflate]
2025-05-15 20:09:54,457 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [0cb662839cd8;;;] - REQUEST body:
2025-05-15 20:09:54,458 [pas-sftp] INFO c.a.p.c.s.r.InternalRestApiService [0cb662839cd8;;;] - REST API call GET to url http://localhost:8080/iam/private/access/validate
2025-05-15 20:09:54,478 [pas-sftp] INFO c.a.p.c.s.r.InternalRestApiService [0cb662839cd8;;;] - REST API call finished in 20ms with status 200 OK
2025-05-15 20:09:54,479 [pas-sftp] ERROR c.a.p.c.c.h.e.ApiExceptionHandler [0cb662839cd8;2179;143;1] - API request exception:
org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:287)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:441)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:382)
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:127)
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:68)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:509)
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1284)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1065)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:936)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at com.artensis.pas.common.config.filter.AccessManagementFilter.doFilter(AccessManagementFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at com.artensis.pas.common.config.filter.RequestLoggingFilter.doFilter(RequestLoggingFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at com.artensis.pas.common.config.filter.HeadersCheckFilter.doFilter(HeadersCheckFilter.java:124)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter.doFilterInternal(HttpExchangesFilter.java:89)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:114)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:124)
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:79)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:666)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:396)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:59)
at java.base/java.lang.Thread.run(Unknown Source)
2025-05-15 20:09:54,480 [pas-sftp] INFO c.a.p.c.c.f.RequestLoggingFilter [0cb662839cd8;2179;143;1] - RESPONSE: Completed in 23ms with status 406
Copy link to clipboard
Copied
Flipout, I really think you have something else going on there in your environment--perhaps a proxy or firewall or a/v tool that is making that manipulation. Here's how you can prove it.
Change the URL in your code to call this domain instead:
<cfscript>
cfhttp( url="https://httpbin.org/delete", timeout=5, result="httpServiceResponse", method="delete" ) {
cfhttpparam( name="Accept", type="header", value="application/json" );
cfhttpparam( name="cfId", type="header", value=session.CFID );
cfhttpparam( name="cfToken", type="header", value=session.CFTOKEN );
}
writeDump( var=httpServiceResponse );
</cfscript>
As always, just trying to help. I hope you both will let me know what you think of the above.
Copy link to clipboard
Copied
Hi Charlie,
There is nothing in between these two machines that is making any kind of manipulation and I can prove this by using my chunk of code and just removing .xml from url
<cfhttp
url="http://localhost:8806/sftp/private/remove/import/test"
method="delete"
timeout="5"
result="httpServiceResponse">
<cfhttpparam type="header" name="Accept" value="application/json">
<cfhttpparam type="header" name="cfId" value="#session.CFID#">
<cfhttpparam type="header" name="cfToken" value="#session.CFTOKEN#">
</cfhttp>
This will be passed to spring:
2025-05-16 07:17:18,398 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [471dcac405ab;;;] - REQUEST headers: [cfid=123; accept=application/json; cftoken=555-555; user-agent=ColdFusion; content-length=0; host=localhost:8806; connection=Keep-Alive; accept-encoding=gzip,deflate]
If I remove <cfhttpparam type="header" name="Accept" value="application/json">, like this:
<cfhttp
url="http://localhost:8806/sftp/private/remove/import/test"
method="delete"
timeout="5"
result="httpServiceResponse">
<cfhttpparam type="header" name="cfId" value="#session.CFID#">
<cfhttpparam type="header" name="cfToken" value="#session.CFTOKEN#">
</cfhttp>
This is what I get (NO ACCEPT PROPERTY):
2025-05-16 07:19:14,961 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [2bc599e487b1;;;] - REQUEST headers: [cfid=123; cftoken=555-555; user-agent=ColdFusion; content-length=0; host=localhost:8806; connection=Keep-Alive; accept-encoding=gzip,deflate]
If you again just return .xml at the end of xml like the first example I posted without accept as cfhttpparam
<cfhttp
url="http://localhost:8806/sftp/private/remove/import/test.xml"
method="delete"
timeout="5"
result="httpServiceResponse">
<cfhttpparam type="header" name="cfId" value="#session.CFID#">
<cfhttpparam type="header" name="cfToken" value="#session.CFTOKEN#">
</cfhttp>
It will be added with fixed value again (accept=application/xml, text/xml; charset=UTF-8;😞
2025-05-16 07:21:30,629 [pas-sftp] DEBUG c.a.p.c.c.f.RequestLoggingFilter [79c0be7d1193;;;] - REQUEST headers: [cfid=7548; cftoken=443e2e6bc2450ac9-6B676FA6-A19C-0455-21EE963AAAF094EF; user-agent=ColdFusion; accept=application/xml, text/xml; charset=UTF-8; content-length=0; host=localhost:8806; connection=Keep-Alive; accept-encoding=gzip,deflate]
Unfortunately on httpbin there is no url with file extension .xml or .json defined at the end, we would have the same problem there.
So to sum it all up, if url string is ending with .xml or .json extension accept header property will be added to headers with fixed value.
I tested with bunch of other url strings that are paths to file with extensions like pdf, csv, txt, ai, tiff etc. and all of them work without issues.
If you guys can configure some remote endpoint to accept filepath as parametar like localhost/service/remove/{pathToFileWithFile} you would get the same issue when the call is invoked from coldfusion and invoking localhost/service/remove/someFolder/test.xml or localhost/service/remove/someFolder/test.json
Headers will work if you remove file extension
Thanks
Copy link to clipboard
Copied
Yeah, you're going to need to contact cfsup at adobe.com and file a bug in tracker.adobe.com.
Copy link to clipboard
Copied
Thanks Dave
To be completely honest, I created a ticket immediately after I posted here.
If someone needs to keep track https://tracker.adobe.com/#/view/CF-4226609
Copy link to clipboard
Copied
Hi @flipout ,
Thanks for the updates. They show that, as I had suspected, I had misunderstood the issue you reported.
As I now understand it, the issue is that cfhttp forces the request's Accept header to have a value of application/xml or application/json. Whereas, the server you're dealing with would rather not receive an Accept header.
You are in fact confronted with a shortcoming of ColdFusion. Perhaps of Lucee, too. Even when you use
<cfhttpparam type="header" name="Accept" value="">
that will not prevent ColdFusion from sending its default Accept header, which is typically */*. This is a known limitation. So, Dave's suggestion to report a bug is spot-on.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now