Monday, July 27, 2015

CF11 is setting cache-control and expires headers

We have received few bugs and customer cases where CF11 is adding cache-control and expire headers as part of the response. Thereby causing few issues to the existing code.

We have investigated this issue and found that this issue is happening only when the server is installed using development profile.  And we found that in development profile we are enabling some settings on the server which will he helpful when setting environment for development purpose. The one setting which is causing this issue is Remote Inspection. Remote inspection helps in debugging & inspecting the mobile applications generated by coldfusion.


It is recommended to use Production profile or Production secure profile when installing CF for production environments. In case of production profile this setting is not enabled and its respective web.xml filters are disabled. But still in development environment some might be running some regression tests and this feature might be causing the test cases to fail.

Enabling this feature is includes cache-control headers in each and every CF response. This issue needs to be fixed but for now one can disable this feature in their development environment by unchecking the Allow Remote Inspection feature. The setting can be found at Debugging & Logging -> Remote Inspection  in CF admin. Optionally one can even disable this feature  in web.xml by commenting out the remote inspection j2ee filter. When someone again accidentally changes this setting does not make it effective when it commented out in web.xml.



Thanks,
Pavan Kumar.

CFFTP listdir fails when SYST command is disabled on remote FTP server

In this blog article we are going to discuss an issue which prevents CFFTP to display list of folders and files retrieved from FTP server when SYST command is disabled on the remote FTP server.

Let's look at why this issue is happening when SYST command is disabled. CFFTP for listing the directories and files (action="listdir") from the remote FTP server invokes ftp list command. Remote ftp server executes issued list command and sends the directory listing as part of the response. Once CFFTP receives the response it needs to perform the parsing and represent it as a listing. But the parsing of the response depends on the file list layout style of the remote FTP server. FTP provides this information through SYST command using which CFFTP knows how to parse the the listing response.

Many ftp servers disable this SYST command as it reveals the target ftp server information and its OS type.  Then in this case the request for listing will fail. But there is a way to override this behaviour of not calling SYST command with a JVM flag named org.apache.commons.net.ftp.systemType. If this jvm flag is specified with a value which specifies how to parse list command response, SYST command will not be invoked and parsing happens as specified in the JVM flag. But if the CF instance is connecting to multiple remote FTP servers hosted on different operating systems which does not allow SYST command setting this flag will result in errors which lead us to add a new attribute to the CFFTP tag.

A new attribute has been added to CFFTP tag called systemType which specifies how to parse the file list response without invoking SYST command. This attribute is available from CF11 update 3.

Possible values for the attribute are (The same values are also applicable for the JVM flag)
     WINDOWS: if specified CFFTP treats the response as Windows-Style directory listing
      UNIX:  if specified CFFTP treats the response as Unix-Style directory listing
     Also, can specify any class name which implements org.apache.commons.net.ftp.FTPFileEntryParser

The attribute can be set at multiple levels one during the connection open operation or when doing any of the FTP operation like listdir.  If this attribute is set during named ftp connection then the systemtype will be used across all ftp operations  where systemType is left unspecified.

Lets take a look at an example. For this example purpose i am using IIS ftp server and disabled the SYST command as shown in the screenshot.


then ran the below script to retrieve the files from this ftp server.
<cfscript>
ftpService = new ftp(server = "localhost", username = "pavan", password="P#$a12$3", connection="myconn");
files = ftpService.listdir(directory="/", connection="myconn", name="files");
writeDump(files);
files = ftpService.listdir(directory="/sample", connection="myconn", name="files");
writeDump(files);
</cfscript> 
Running the above script thrown the below error saying that the remote ftp server does not allow SYST command



To fix this add the systemtype attribute to the listdir operation and run the example
<cfscript>
ftpService = new ftp(server = "localhost", username = "pavan", password="P#$a12$3", connection="myconn");
files = ftpService.listdir(directory="/", connection="myconn", name="files", systemtype = "WINDOWS");
writeDump(files);
files = ftpService.listdir(directory="/sample", connection="myconn", name="files", systemtype = "WINDOWS");
writeDump(files);
</cfscript>
Now the script executes successfully and returns the listing

This code further can be optimized by specifying the systemtype at the named connection level (then no need to specify at listdir operation)

<cfscript>
ftpService = new ftp(server = "localhost", username = "pavan", password="P#$a12$3", connection="myconn", systemtype = "WINDOWS");
files = ftpService.listdir(directory="/", connection="myconn", name="files");
writeDump(files);
files = ftpService.listdir(directory="/sample", connection="myconn", name="files");
writeDump(files);
</cfscript>
 Here is the order how CFFTP looks for System Type
1) Checks if there is any systemtype specified at the tag/script. If found uses it for parsing
2) Otherwise looks at the JVM flag org.apache.commons.net.ftp.systemType if any value specified uses it.
3) As a last resort invokes SYST command if SYST command is unsuccessful listing fails otherwise listing is successful.

Thanks,
Pavan Kumar.