ColdFusion CFFTP action="listdir" returns nothing

2k views Asked by At

I am trying to use CFFTP to log onto buy.com's marketplace and download an account's orders. Buy.com allows you to FTP into your account folder and download your orders as TXT files for your own reference. I know the credentials I have are working fine because I can log in successfully using any FTP desktop program, so that's not an issue.

What am I having trouble with is actually listing the contents of the FTP's root folder. I should be seeing folders like these:

  • Cancellations
  • Fulfillment
  • Inventory
  • NewSku
  • Orders
  • Payments
  • Refunds

The folder "Orders" contains the TXT files with the customer's orders, and is the folder I eventually want to get a listing of. However, I get an empty listing (empty query when I dump the "dirlist" variable below) even though the CFFTP call looks like it connects and disconnects fine. I tried changing the directories to get a listing of, "/" or "/Orders/", even "/Orders", but all come back empty.

Here is my code (I edited the username and password for obvious reasons). Any ideas are welcome.

<cfparam name="dirlist" type="query" default="#queryNew('')#" />

<cfftp connection="myConnection"
    username="***************"
    password="*********"
    server="trade.marketplace.buy.com"
    action="open"
    stopOnError="yes"
    />

<p>Successful open? <cfoutput>#cfftp.succeeded#</cfoutput></p>

<cfftp connection="myConnection" 
    action="listdir" 
    stopOnError="yes" 
    name="dirlist" 
    directory="/Orders" 
    />

<cfdump var="#dirlist#" />

<cfftp connection="myConnection"
    action="close"
    stopOnError="yes"
    />

<p>Successful close? <cfoutput>#cfftp.succeeded#</cfoutput></p>

And these are the results as seen in the browser ("query" is basically the empty var dump of the directory listing):

Successful open? YES

query

Successful close? YES
2

There are 2 answers

0
Evagoras Charalambous On BEST ANSWER

After much fidgeting with this, I gave up on CFFTP. I don't think I was doing anything wrong, the code was right, the credentials were OK, nothing was blocking access to the FTP account through the firewall.

Instead, I found a Java library at edtftpj which worked fine. It's LGPL open source and its API is pretty easy to figure out.

So, I first downloaded the JAR file form their website, put it in the [ColdFusion Install Folder]/bin folder, restarted CF, and then used this code:

<!--- page variables --->
<cfparam name="VARIABLES.ftp" type="any" default="" />
<cfparam name="VARIABLES.aFiles" type="array" default="#arrayNew(1)#" />
<cfparam name="VARIABLES.index" type="numeric" default="1" />
<cfparam name="VARIABLES.cLocalFolder" type="string" default="#expandPath('/integrations/buy/txt/queue/')#" />
<cfparam name="VARIABLES.cLocalFile" type="string" default="" />
<cfparam name="VARIABLES.cFileName" type="string" default="" />

<!--- create instance of edtftpj.jar custom FTP --->    
<cfset VARIABLES.ftp = createObject( "java", "com.enterprisedt.net.ftp.FileTransferClient" ) />

<!--- connect with custom java object and get the contents of the 'Orders' folder --->
<cfset VARIABLES.ftp.setRemoteHost( "trade.marketplace.buy.com" ) />
<cfset VARIABLES.ftp.setUserName( "*************" ) />
<cfset VARIABLES.ftp.setPassword( "*************" ) />
<cfset VARIABLES.ftp.connect() />

<cfset VARIABLES.ftp.changeDirectory('/Orders') />

<cfset VARIABLES.aFiles = ftp.directoryList(".") />

<!--- Proceed only if folder has contents --->
<cfif arrayLen(VARIABLES.aFiles)>

    <!--- Loop through ftp directory contents (files and folders) --->
    <cfloop from="1" to="#arrayLen(VARIABLES.aFiles)#" step="1" index="VARIABLES.index">

        <!--- Download only files and not folders --->
        <cfif VARIABLES.aFiles[VARIABLES.index].isFile()>

            <!--- Set the local file name and download to it --->
            <cfset VARIABLES.cFileName = aFiles[VARIABLES.index].getName() />
            <cfset VARIABLES.cLocalFile = VARIABLES.cLocalFolder & VARIABLES.cFileName />
            <cfset VARIABLES.ftp.downloadFile( VARIABLES.cLocalFile, VARIABLES.cFileName ) />

        </cfif>

    </cfloop>

</cfif>

<!--- Disconnect --->
<cfset VARIABLES.ftp.disconnect() />

I should write a blog post about this :)

0
CfSimplicity On

I've found that some FTP servers require a wildcard asterisk at the end of the directory path:

<cfftp connection="myConnection" 
    action="listdir" 
    stopOnError="yes" 
    name="dirlist" 
    directory="/Orders/*" 
    />

I also usually add passive=true.