Update: I've found a workaround. If I submit a dummy form field along with the file, it works. Is this a ColdFusion bug, or is there something in the HTTP spec that says forms must contain at least one non-file form field?
Update 2: I'm convinced this is a ColdFusion cfhttp bug. This is based on Leigh's answer and the fact that I used the code below to submit a form with only the file element using javascript, and it works fine:
<form enctype="multipart/form-data" action="<cfoutput>#CGI.PATH_INFO#</cfoutput>" method="POST" name="theForm">
<input name="theFile" type="file" /><br/>
</form>
<a href="#" onclick="document.theForm.submit()">submit</a>
I'm running into a problem uploading files from a ColdFusion server to another webserver. It seems that cfhttpparam type="file"
is indiscriminately appending a newline (carriage return and line feed) to the end of the file. This is breaking binary files. This does not happen when I manually upload the file via form field. I have tried with and without mimetype parameter, and I've tried lying about mimetype with various binary formats (exe, zip, jpg), but nothing has worked. Is there some parameter I'm missing, or is this a bug in ColdFusion? (I'm running on CF 8.0.1.195765 on WinXP.)
Below is test code I'm using, it just uploads the file to the same directory. The manual upload works, but the server-based upload ends up appending a CRLF to the file.
<cfset MyDir = "C:\test" />
<cfset MyFile = "test.zip" />
<cfif IsDefined("Form.TheFile")>
<cffile action="upload" fileField="theFile" destination="#MyDir#" nameConflict="MakeUnique" />
<cfelse>
<cfhttp url="http://#CGI.SERVER_NAME##CGI.SCRIPT_NAME#" method="POST" throwOnError="Yes">
<cfhttpparam type="file" name="theFile" file="#MyDir#\#MyFile#" />
</cfhttp>
</cfif>
<html><body>
<h2>Manual upload</h2>
<form enctype="multipart/form-data" action="<cfoutput>#CGI.PATH_INFO#</cfoutput>" method="POST">
<input name="theFile" type="file" /><br/>
<input type="submit" value="Submit" />
</form>
</body></html>
or is there something in the HTTP spec that says forms must contain at least one non-file form field?
I do not know for certain. But according to these definitions it seems like a POST containing only a file input should be valid. So I suspect the problem may be CFHTTP in ACF.
According to Fiddler the raw content from the cfhttp call in ACF contains an extra new line just before the end boundary (0D 0A in hex view). But under Railo it does not. So I think ACF's cfhttp might be the culprit.
Sample Code:
<cfhttp url="http://127.0.0.1:8888/cfusion/receive.cfm" method="post">
<cfhttpparam name="myFile" type="file" file="c:/test/testFile.zip" mimetype="application/octet-stream" />
</cfhttp>
Results Railo 3.1.2
POST /railo/receive.cfm HTTP/1.1
User-Agent: Railo (CFML Engine)
Host: 127.0.0.1:8888
Content-Length: 382
Content-Type: multipart/form-data; boundary=m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn
--m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn
Content-Disposition: form-data; name="myFile"; filename="testFile.zip"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
PK
&�1=�cN'testFile.txtTestingPK
&�1=�cN' testFile.txtPK:1
--m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn--
Results ACF (versions 8 and 9)
POST /cfusion/receive.cfm HTTP/1.1
Host: 127.0.0.1:8888
... other headers removed for brevity ....
Content-type: multipart/form-data; boundary=-----------------------------7d0d117230764
Content-length: 350
-------------------------------7d0d117230764
Content-Disposition: form-data; name="JobFile"; filename="c:\test\testFile.zip"
Content-Type: application/octet-stream
PK
&�1=�cN'testFile.txtTestingPK
&�1=�cN' testFile.txtPK:1
-------------------------------7d0d117230764--
Maybe Railo 3.1.2 and ColdFusion 9 handle this a bit differently, but your code looks a bit incorrect for me.
Your CGI.PATH_INFO
is not applicable here.
While browser is smart enough to use path without hostname, CFHTTP feels better with full hostname + script path + script name. Note: cgi.SCRIPT_NAME
worked in CF9, Railo required cgi.SERVER_NAME
to be prepended, though I feel this more correct in general.
That's why a bit modified version of the code works fine for me. Zip file is uploaded and posted without being corrupted.
Form:
<form enctype="multipart/form-data" action="<cfoutput>#cgi.SCRIPT_NAME#</cfoutput>" method="POST">
<input name="theFile" type="file" /><br/>
<input type="submit" value="Submit" />
</form>
CFHTTP:
<cfhttp url="#cgi.SERVER_NAME##cgi.SCRIPT_NAME#" method="POST" throwOnError="Yes">
<cfhttpparam type="file" name="theFile" file="#MyDir#/#MyFile#" />
</cfhttp>
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With