We have recently gone through the process of upgrading from CF11 to CF2023. On our development servers, everything seemed work as expected. However, after installing on our production server, we have found a weird issue.
The fileRead
command in a cfc file, seems to read the file, but then a 500 error is thrown after the cfc has finished processing. The issue does not happen with any other command in any other cfc (that we have found yet). I can reproduce this issue on our production serve; but using the same test page in development (or test) the code works fine.
Our immediate workaround is to use cffile action="read"
. This seems to work fine in development and production.
Sample test code that works in development but not in production (the file is read, contents dumped per the code, but then the 500 error is overlayed on the file dump) - fileReadTest.cfc:
component {
struct function getRules() {
try {
var _rules = fileRead('[path]/configuration.json');
_rules = deserializeJSON(_rules);
return _rules;
} catch( any e) {
cfdump( var = e);
}
}
remote string function test() {
try {
var _r = getRules()
cfdump(var = _r);
return 'test'
} catch( any e) {
cfdump( var = e);
}
}
}
These test is being called (for testing purposes) via the url with method as a parameter:
https://ourdoman.edu/fileReadTest.cfc?method=test
I do have access to the coldfusion administrator pages. I have compared prod to dev via the Settings Summary page and everything seems in line. I do not have access to IIS, but I am assured that those settings match from server to server.
One thing to note is that our dev server cannot be accessed from outside our network. In other words, you have to be on campus to use dev.
In looking at the coldfusion-error.log, I can see a
SEVERE: Servlet.service() for servlet [CFCServlet] in context with path [] threw exception
which seems to coincide with when the 500 error is generated. Looking up that error seems to lead to an IIS issue but I don't see anything definitive that I could point our network administrator to review.
Any insight would be super helpful. While we can use cffile as the workaround, my concern is that this is a sign of a bigger configuration issue.
Thanks
Edit:
Slimmed down version of the code to reproduce the error:
component {
string function getRules() {
var _rules = fileRead('c:/applications/test/test.txt');
return _rules;
}
remote string function test() {
var _r = getRules();
return _r;
}
}
test.txt = This is a test.
Results: File is read, data is cfdumped, and then the 500 error
1
Update: As a test, I tried using fileRead to read a fileObject as returned by fileOpen. For example:
var x = fileOpen('[path]/test.txt')
var y = fileRead(x, 16);
fileClose(x);
The result is the same. The file is read and outputted (see sample code above), but then the 500 error is displayed. If I take out the fileRead, the fileOpen and fileClose seem to work without issue.
Also, it was suggested to me that I look at the application.cfc onRequestStart / onRequestEnd. I can verify that those are executing normally - as a test, I had them send an email per start and end. Also, the onError in the application.cfc will send an email as well if an error where to occur.
Testing Update
In my test cfc, I created a loop to iterate over the function that calls the fileRead. Each iteration calls the fileRead successfully as indicated by the data being cfdumped. Once the iteration is completed, the 500 error is generated.
Response
I thought it might helpful to see what the console response looks like. For example if the file is "this is a test", the response looks like the following. First file content and then the 500 Error is appended to the response.
<wddxPacket version='1.0'>
<header/>
<data>
<string>
this is a test<char code='0d'/>
<char code='0a'/>
</string>
</data>
</wddxPacket>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>500</title>
<style>
body {
...
A Clue?
An important clue (?): If the .cfc that does the fileRead is called from a .cfm, using cfhttp
,createObject
,invoke
, it works with no error. But if called via [URL]/test.cfc?method=getData
or (as the app was initially doing) via $http
(AngularJS), the error is generated. Both of those methods are using the same URL. It also fails if called from another cfc
.
Another tidbit
FileWrite
behaves the same way as FileRead
. When called from a .cfc, it writes the file, but then throws the 500 Error.
Stack Trace
Jul 11, 2023 1:08:07 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [CFCServlet] in context with path [] threw exception
java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:143)
at coldfusion.monitor.beans.RequestData.isGraphQlService(RequestData.java:795)
at coldfusion.monitor.beans.RequestData.updateFunctionMetrics(RequestData.java:618)
at coldfusion.monitor.beans.RequestData.updateTagData(RequestData.java:459)
at coldfusion.monitor.beans.RequestData.updateData(RequestData.java:223)
at coldfusion.monitor.event.RequestMonitorEventProcessor.onRequestEnd(RequestMonitorEventProcessor.java:419)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:82)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:373)
at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:459)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)