
File manipulation in Cold Fusion (CF) 2.0 is provided through the CFFILE tag. This addition to CF 2.0 takes advantage of features introduced in Web browsers such as Netscape Navigator 2.0, which permit file upload using the HTTP protocol. Traditionally the Web environment has lent itself primarily to one-way file access. That is, the user interacted with the Web server to receive content. With the advent of the HTTP file upload capability, the user can have bi-directional interaction with the web server. The method by which files are uploaded to the server using HTTP is documented in the Internet Request for Comment RFC 1867, which can be found at http://www.cis.ohio-state.edu/htbin/rfc/rfc1867.html. These features are browser-specific, therefore you should use them carefully in order to provide the maximum capability to your users, while also providing the maximum level of flexibility. In addition to the ability to upload files, CFFILE also permits local file access through the templates. Files can be moved, copied, or deleted using different action parameters for the CFFILE tag. Taking advantage of the CFFILE tag provides you with the ability to produce complex applications with file manipulation using a single interface, without having to deal with the additional complexities of protocols such as FTP or NFS. The templates in which the CFFILE tag are used can be protected using native server security when the templates are stored in directories below the document root defined for the HTTP server, or by taking advantage of the built-in application security discussed in Chapter 15.
NOTE: RFC 1867 is the formal documentation of the HTTP file upload process. It specifies the concepts relating to file uploads using MIME file extensions.
CAUTION: The file upload mechanism is browser-specific. Netscape Navigator 2.0 and higher support this feature. Other browsers such as Lynx and Mosaic may not support this feature. Use of the file upload mechanism should be implemented with this in mind.
The CFFILE tag utilizes standard HTTP protocols to permit file uploads using a POST operation. The files are transmitted from the client to the server using a multi-part form field definition. Syntax for the CFFILE tag can be seen in Listing 24.1.
<CFFILE ACTION=[] FILEFIELD=[] DESTINATION=[] NAMECONFLICT=[] OUTPUT=[] VARIABLE=[] SOURCE=[] ACCEPT=[]>
The parameters of the CFFILE tag can be set to multiple values which permit the behavior of the tag to be modified to fit your needs. Each of the parameters can be set dynamically using variables created using the CFSET tag, or the values of query or form fields. When using form fields, extreme care should be taken to ensure that security restrictions are in place to prevent malicious action as a result of dynamic file action. Table 24.1 indicates the parameters for CFFILE and the associated values. Table 24.2 gives further explanation of the NAMECONFLICT attribute.
| Parameter | Permitted Values | Comments |
| SOURCE | File name to process | |
| FILEFIELD | Form Field containing File Name, used with UPLOAD action | |
| ACTION | UPLOAD, COPY, MOVE, DELETE, RENAME, READ, WRITE, APPEND | |
| DESTINATION | Required except with DELETE action. Indicates directory where file will be uploaded, moved or copied | File name will default to the SOURCE or client file name |
| NAMECONFLICT | Optional. Used only with UPLOAD action. Valid choices: ERROR (default), SKIP, OVERWRITE, MAKEUNIQUE | Used to specify action to take if a duplicate file name is encountered. See Table 24.2 for details |
| ACCEPT | Optional. Used only with UPLOAD action | Defaults to any data type. Can be used to limit permitted data by specifying a particular MIME file type |
| Value | Meaning |
| ERROR | Generates error if file specified already exists. |
| SKIP | Allows the problem file to be skipped. The file cannot be saved. |
| OVERWRITE | File will be overwritten with new file. |
| MAKEUNIQUE | If a duplicate file is found, CF tries to use the client file name passed as part of the form field. If that fails, an algorithm is applied to change the file name until a unique value is found. |
Once a file is uploaded, or other file manipulation operation is completed, information about the file is available in reference attributes of the file object. Similar to the URL, FORM, and CGI objects, the FILE object maintains status information about the most recent file operation completed or attempted. The attributes of the FILE object are READ-ONLY. Attributes in the FILE object are referenced in the same manner as other variables (i.e. #FILE.ContentType#). Table 24.3 identifies the attributes maintained and their meanings.
| Attribute | Explanation |
| ContentType | MIME content type of file Valid with UPLOAD action only |
| ContentSubType | MIME content sub-type of file Valid with UPLOAD action only |
| ClientDirectory | Full client-side path of file |
| ClientFile | Client-side file name (with extension) |
| ClientFileName | Client-side file name (without extension) |
| ClientFileExt | Client-side file name extension |
| ServerDirectory | Full directory name on the server |
| ServerFile | File name of the saved file |
| AttemptedServerFile | Did Cold Fusion attempt to save the file? (Yes/No) |
| FileExisted | Did a file with same name exist in the specified destination prior to upload, copy, or move? (Yes/No) |
| FileWasSaved | Was the file saved by Cold Fusion? (Yes/No) |
| FileWasOverwritten | Was an existing file overwritten by Cold Fusion? (Yes/No) |
| FileWasRenamed | Was the uploaded file renamed to avoid a conflict? (Yes/No) |
The syntax of the CFFILE tag explained above can be used with selected parameters in order to facilitate the uploading of files to the server. Prior to writing the HTML/CFML necessary to process a file upload, you must carefully examine a number of issues. First and foremost is security. The directory where the files will be uploaded must be secure from outside view, and the templates used to perform the file operations must be protected from unauthorized access. Since the threat of computer viruses is increasing, you must take precautions to protect your system from malicious users. The second issue to examine is the reason you are providing file operations to the users. Is it necessary? Can it be accomplished using other means? Once you decide on CFFILE you can move on to the next step, which is preparing the user interface. This requires the development of an HTML form, either through writing static HTML or by creating an HTML form using dynamic code generated using CFML. In either case, the structure of the form is basically the same. Chapter 11, "Cold Fusion Forms," introduced basic form operations. Listing 24.2 shows the HTML code necessary to create a form which prompts the user for a file to be uploaded to the server.
<HTML> <TITLE>CF 2.0 CFFILE Upload Demonstration - Example 1</TITLE> <BODY> <CENTER>CF 2.0 CFFILE Upload Demonstration - Example 1</CENTER> <HR> <FORM ACTION="/cf20/cffile.cfm" ENCTYPE="multipart/form-data" METHOD=POST> File to upload: <INPUT NAME="FileName" SIZE=50 TYPE=FILE><BR> <INPUT TYPE=SUBMIT VALUE="Upload the File"> </FORM> </BODY> </HTML>
The structure of the form is the same as shown in Chapter 13 "Web Application Wizards." The primary difference is the specification of the ENCTYPE value as "multipart/form-data," which is necessary to process the uploaded file. A second difference is the addition of a new INPUT type called FILE, which tells the browser to process file selection using the standard user interface functionality of the underlying operating system. The ACTION parameter of the FORM tag identifies which CF template will be used to process the file. The METHOD parameter is set to POST, which is required by CF. Figure 24.1 shows the resulting HTML form and its user interface elements. Figure 24.2 shows the file selection dialog box which will be displayed if the user presses the Browse button. Figure 24.3 shows the HTML form with the filename filled in.
For more information about HTML forms see Chapter 11, "Cold Fusion Forms."
Figure 24.1 What the example form will look like in Netscape.
Figure 24.2 If the user presses the Browse button, a file selection dialog box will be displayed. The user can select the desired field from the dialog box.
Figure 24.3 Example form with the file name field filed, as seen in Netscape.
Listing 24.3 shows the CFML code required to process the uploaded file.
<HTML> <TITLE>CFFILE File Upload Demonstration Results - Example 1</TITLE> <BODY> <CFFILE ACTION="UPLOAD" DESTINATION="C:\website\uploads\" NAMECONFLICT="OVERWRITE" FILEFIELD="FORM.FileName"> <PRE> <CFOUTPUT> File Upload was Successful! Information about the file is detailed below. <HR> Content Type: #File.ContentType# Content SubType: #File.ContentSubType# Client Directory: #File.ClientDirectory# Client File: #File.ClientFile# Client FileName: #File.ClientFileName# Client FileExt: #File.ClientFileExt# Server Directory: #File.ServerDirectory# Server File: #File.ServerFile# Attempted ServerFile: #File.AttemptedServerFile# File Existed? #File.FileExisted# File Was Saved? #File.FileWasSaved# File Was Overwritten? #File.FileWasOverWritten# File Was Renamed? #File.FileWasRenamed# </CFOUTPUT> </BODY> </HTML>
The CFML template shown above processes the uploaded file, stores it in the appropriate directory, and then prints out the contents of the attributes in the FILE object. Some of the FILE object attributes may not have values depending on the parameters passed to the CFFILE tag. Figure 24.4 shows the output resulting from the file upload.
Figure 24.4 This figure shows the results of the example upload, with variables from the FILE object displayed for demonstration purposes.
Listing 24.4 breaks down the syntax of the CFFILE tag as used in this simple example.
<CFFILE ACTION="UPLOAD" DESTINATION="C:\website\uploads\" NAMECONFLICT="OVERWRITE" FILEFIELD="FileName">
In this example CFML code, the ACTION attribute is set to "UPLOAD," which will save the file on the server. The DESTINATION parameter was set to the value "C:\website\uploads\", which is a directory created by WebSite specifically for storing uploaded files. The directory you choose may be anywhere on the server, provided that the appropriate file access privileges (read, write, delete, etc.) are set. The NAMECONFLICT parameter is set to "OVERWRITE," indicating that CF should overwrite the file if it finds a file with the same name in the destination directory. The last parameter set is the FILEFIELD parameter. Its value is "FileName," indicating the name of the field on the form from which the multipart/form-data containing the file data will be passed. The remaining code in the example uses attributes from the FORM object to show details about the selected file.
CAUTION: The trailing slash (\) in the destination directory name is required.
The following example (see Listing 24.5) builds on the HTML/CFML code you just wrote, to demonstrate the utilization of variables to set the various attributes of the CFFILE tag. The HTML form will be modified to add a radio button group which you will use to set the NAMECONFLICT parameter in the CFFILE tag.
<HTML> <TITLE>CF 2.0 CFFILE Upload Demonstration - Example 2</TITLE> <BODY> <CENTER>CF 2.0 CFFILE Upload Demonstration - Example 2</CENTER> <HR> <FORM ACTION="/cf20/cffile.cfm" ENCTYPE="multipart/form-data" METHOD=POST> File to upload: <INPUT NAME="FileName" SIZE=50 TYPE=FILE><BR> Action if File Exists: <INPUT TYPE=RADIO NAME="FileAction" VALUE="OVERWRITE" CHECKED>Overwrite <INPUT TYPE=RADIO NAME="FileAction" VALUE="MAKEUNIQUE">Make Unique <INPUT TYPE=RADIO NAME="FileAction" VALUE="SKIP">Skip <INPUT TYPE=SUBMIT VALUE="Upload the File"> </FORM> </BODY> </HTML>
The radio group was added with the name of FileAction, which will be used in the template to identify the appropriate action to take if a duplicate file is detected. Figure 24.5 shows what the modified form looks like in the browser.
Figure 24.5 The modified form showing the radio button group for selecting the NAMECONFLICT action.
The CFML template from the first example has to be modified to take into account the data being passed to the template to specify the action to take when a duplicate file exists. Listing 24.6 shows the modifications required.
<HTML> <TITLE>CFFILE File Upload Demonstration Results - Example 2</TITLE> <BODY> <CFFILE ACTION="UPLOAD" DESTINATION="C:\website\uploads\" NAMECONFLICT="#FORM.FileAction#" FILEFIELD="FileName"> <PRE> <CFOUTPUT> File Upload was Successful! Information about the file is detailed below. <HR> Content Type: #File.ContentType# Content SubType: #File.ContentSubType# Client Directory: #File.ClientDirectory# Client File: #File.ClientFile# Client FileName: #File.ClientFileName# Client FileExt: #File.ClientFileExt# Server Directory: #File.ServerDirectory# Server File: #File.ServerFile# Attempted ServerFile: #File.AttemptedServerFile# File Existed? #File.FileExisted# File Was Saved? #File.FileWasSaved# File Was Overwritten? #File.FileWasOverWritten# File Was Renamed? #File.FileWasRenamed# </CFOUTPUT> </BODY> </HTML>
The CFFILE tag in this example used data passed from the form in the FileAction field to set the value of the NAMECONFLICT attribute. Any of the other attributes can also be set using CFSET variables, FORM, or URL parameters. Note, however, that setting the DESTINATION parameters base on user input can have far-reaching consequences. For security reasons, users should not be permitted to specify the DESTINATION parameter using TEXT input fields. The DESTINATION parameters should only be set using template-based code, which is conditionally executed, to provide maximum security.
The CFFILE tag provides the ability to perform local file operations such as COPY, MOVE, RENAME, and DELETE. Local in this example means local to the HTTP server, not local to the client. These actions have the potential for causing severe damage to the file system; security considerations should be evaluated carefully before developing CF templates which provide the ability to COPY, MOVE, RENAME, or DELETE files.
To provide local file access, the CFFILE tag is used with the ACTION parameter set to COPY, MOVE, or DELETE. In the case of the DELETE action value, the DESTINATION parameter is not required. In all other cases, the DESTINATION parameter is required. The next series of listings demonstrates the function of the COPY, MOVE, and DELETE values of the ACTION parameter. Listing 24.7 is an example of using CFFILE to copy a local file.
<CFFILE ACTION="COPY" SOURCE="C:\WEBSITE\UPLOADS\FILE1.TXT" DESTINATION="C:\WEBSITE\PROCESS\">
This example shows the ability of CF 2.0 to copy files on the local file system. The ACTION parameter is set to COPY. The SOURCE parameter is set to the name of the file that is to be copied. The DESTINATION parameter is set to the directory into which the file will be copied. The DESTINATION parameter may also specify a file name in addition to the directory name, allowing you to copy one file to another while changing the name in the process. Listing 24.8 shows the use of the MOVE value of the ACTION parameter.
<CFFILE ACTION="MOVE" SOURCE="C:\WEBSITE\UPLOADS\FILE2.TXT" DESTINATION="C:\WEBSITE\PROCESS\">
This example shows the ability of CF 2.0 to move files on the local file system. The ACTION parameter is set to MOVE. The SOURCE parameter is set to the name of the file that is to be copied. The DESTINATION parameter is set to the directory into which the file will be moved. Listing 24.9 shows the use of the DELETE value of the ACTION parameter.
<CFFILE ACTION="DELETE" SOURCE="C:\WEBSITE\UPLOADS\FILE3.TXT">
In this example the ACTION parameter is set to DELETE. The SOURCE parameter is set to the name of the file you are going to delete. The DESTINATION parameter is not used when the ACTION parameter is set to DELETE.
CAUTION: Use the DELETE action carefully. Access to templates which delete files should be carefully restricted.
Now that you have seen the CFFILE tag used in simple examples, you can move on to modify your example application to add file upload capabilities. We will accomplish this by creating three CFML templates for the purposes of uploading an employee photo to the server and updating the employee record to reflect the location of the photo. The first template will provide a list of employees to pick from (see Listing 24.10). The second template will prompt you for the name of the file containing the photo (see Listing 24.11), and the third template will actually accept the file (see Listing 24.12) and update the employee record. We will start off by creating the template to provide the employee list.
<
CFQUERY
DATASOURCE="A2Z"
NAME="Employees"
SQL="SELECT FirstName, LastName, EmployeeId
FROM Employees
ORDER BY LastName, FirstName"
>
<HTML>
<HEAD>
<TITLE>Maintain Employee Photos</TITLE>
</HEAD>
<BODY>
<H1>Maintain Employee Photos</H1>
<HR>
<H3>Click on Employee Name to Add Employee Photo</H3>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>ID</TH>
</TR>
<CFOUTPUT QUERY="Employees">
<TR>
<TD><A HREF="/cgi-shl/cf.exe?template=/a2z/employee_photo2.cfm&EmployeeId=#EmployeeId#">#LastName#, #FirstName#</A></TD>
<TD>#NumberFormat(EmployeeId,'___0')#</TD>
</TR>
</CFOUTPUT>
</TABLE>
</BODY>
</HTML>
Figure 24.6 shows what the screen looks like using the template you just created, which selects a list of employees from the EMPLOYEES table and presents a table to select an employee for photo processing. A link is created to another template where the photo information can be added or updated.
Figure 24.6 Employee Photo Maintenance List.
Listing 24.11 shows the CFML code used to create the form necessary to upload the file to the server.
< CFQUERY NAME="Employee" DATASOURCE="A2Z" SQL="SELECT LastName,FirstName,EmployeeId from Employees where EmployeeId=#URL.EmployeeId#" > <HTML> <TITLE>Employee Photo Maintenance Form</TITLE> <BODY> <CENTER>Employee Photo Maintenance Form</CENTER> <HR> <FORM ACTION="/cgi-shl/cf.exe?template=/a2z/employee_photo3.cfm" ENCTYPE="multipart/form-data" METHOD=POST> <CFOUTPUT> <INPUT TYPE="hidden" NAME="EmployeeId" VALUE=#Employee.EmployeeId#> <B> Employee: Id: #NumberFormat(Employee.EmployeeId,'___0')#<BR> Name: #Employee.LastName#, #Employee.FirstName#<BR> </B> </CFOUTPUT> <BR> Photo File to upload: <INPUT NAME="PhotoFile" SIZE=50 TYPE=FILE><BR> <INPUT TYPE=SUBMIT VALUE="Upload the Photo"> </FORM> </BODY> </HTML>
The following template code shows a simple modification of the first file upload template that you wrote. The employee's name and Id are retrieved from the EMPLOYEE table, using the employee Id selected from the previous template. This information is displayed along with the File Input box. The button labeled "Upload the Photo" will cause the browser to upload the file to the server where it will be processed by the next template. Listing 24.12 shows the CFML code necessary to process the uploaded employee photo.
Figure 24.7 Modified Employee Photo Upload Form.
< CFQUERY NAME="Employee" DATASOURCE="A2Z" SQL="SELECT LastName,FirstName,EmployeeId from Employees where EmployeeId=#Form.EmployeeId#" > <HTML> <TITLE>A2Z Employee Photo Upload Results</TITLE> <BODY> <CFFILE DESTINATION="C:\a2z\employee\photos\" NAMECONFLICT="OVERWRITE" SOURCE="FORM.PhotoFile"> <CFQUERY NAME="UPDATE_EMP" DATASOURCE="A2Z" SQL="UPDATE Employees SET Photo = `#FILE.ServerDirectory#\#FILE.ServerFile#' WHERE EmployeeId=#FORM.EmployeeId#"> <CFOUTPUT> Employee Photo File Upload was Successful! Information about the file is detailed below. <HR> Photo Information For:<BR>
Employee Id: #NumberFormat(Employee.EmployeeId,'0000')#<BR> Employee Name: #Employee.LastName#, #Employee.FirstName#<BR> Photo File Name: #File.ServerDirectory#\#FILE.ServerFile#<BR> <HR> <PRE> Content Type: #File.ContentType# Content SubType: #File.ContentSubType# Client Directory: #File.ClientDirectory# Client File: #File.ClientFile# Client FileName: #File.ClientFileName# Client FileExt: #File.ClientFileExt# Server Directory: #File.ServerDirectory# Server File: #File.ServerFile# Attempted ServerFile: #File.AttemptedServerFile# File Existed? #File.FileExisted# File Was Saved? #File.FileWasSaved# File Was Overwritten? #File.FileWasOverWritten# File Was Appended? #File.FileWasAppended# File Was Renamed? #File.FileWasRenamed# </CFOUTPUT> </BODY> </HTML>
Figure 24.8 shows the screen results. The template you just completed processes the uploaded file, storing it in the specified directory. It also updates the employee record to indicate that an employee photo is on file. This will be used in the next chapter to demonstrate the CFCONTENT tag.
Figure 24.8 Results of the Employee Photo Upload.
The CFFILE tag provides you with the capability to provide file uploading features to your users. Additionally, it offers the ability to have your CFML templates perform local file system operations, based on programmatic conditions. It also provides the capability to read and write files which can be used to package data for transmission to the user.
In the next chapter, the CFCONTENT tag will be introduced, which will build on some of the CFFILE techniques to allow you to provide dynamic file-based content to your users.
© Copyright, Macmillan Computer Publishing. All rights reserved.