Sunday, September 19, 2010

CFHTTP + FILE + POST (Bug Byte ?)

A few years ago, I saw a post on the adobe forums about a strange problem with cfhttp. Posting a simple .zip file with <cfhttp> somehow ended up corrupting the file. So the resulting archive file could not be read by some tools, in particular <cfzip>.


<!---
   With CF8 this code fails with the error:
   Unsupported File Format
   Ensure that the file is a valid zip file and it is accessible.
--->
<cfif structKeyExists(FORM, "myFile")>
    <cffile action="upload" destination="#ExpandPath('.')#" nameconflict="overwrite" />
    <cfzip action="list" file="#cffile.serverDirectory#/#cffile.serverFile#" name="result" />
    <cfdump var="#result#" label="Zip File Contents" />
<cfelse>
    <cfhttp url="http://127.0.0.1/cfhttpTest.cfm" method="post">
        <cfhttpparam name="myFile" type="file" file="c:/test/testFile.zip" mimetype="application/zip" />
    </cfhttp>
    <cfoutput>#cfhttp.fileContent#</cfoutput>
</cfif>

The Byte
So I decided to have a look and noticed something strange about the received file. It always seemed to be two (2) bytes bigger than the original. After a bit more experimentation, I discovered the problem disappears if you add a formfield (any formfield) directly after the file.  Placing it before the file does not work.

<!---
   This DOES work
--->
<cfif structKeyExists(FORM, "myFile")>
    <cffile action="upload" destination="#ExpandPath('.')#" nameconflict="overwrite" />
    <cfzip action="list" file="#cffile.serverDirectory#/#cffile.serverFile#" name="result" />
    <cfdump var="#result#" label="Zip File Contents" />
<cfelse>
    <cfhttp url="http://127.0.0.1/cfhttpTest.cfm" method="post">
        <cfhttpparam name="myFile" type="file" file="c:/test/testFile.zip" mimetype="application/zip" />
        <cfhttpparam name="BecauseTheFileIsCorruptedWithoutThisField" type="formfield" value="" />
    </cfhttp>
    <cfoutput>#cfhttp.fileContent#</cfoutput>
</cfif>

Now I just assumed it was an issue with cfhttp. As there was a work-around, I did not really explore it further. But a recent question on stackoverflow.com prompted me to revisit the issue and take a closer look. A poster named Kip mentioned something important I had missed the first time around. That extra two (2) bytes was a newline! So armed with that key piece of information, I decided to use Fiddler to see what was happening within the cfhttp request.

The Pest
If you are unfamiliar with multipart submissions, the w3c describes them as a ".. message contain(ing) a series of parts, each representing a successful control." In loose terms, a successful control is just a form field. (There is a little more to it than that.  But the details are not relevant to this particular case.) When a multipart form is submitted, the names and values of the various fields are submitted as parts, delineated by boundary markers.

Now in this case, there is only one (1) form field. But as you can see from the image below, the information is nested within boundary markers. Obviously the request contents are separated by a newline, at various points. But notice there is an extra newline just before the closing boundary marker? That is the extra two (2) bytes. Given that <cfhttp> is responsible for generating the request content, and the separating newlines, it certainly seemed like a problem <cfhttp>



Next I submitted the same file manually with a regular <form> post.  The results from Fiddler showed there was no extra newline in the content.

So I went back and tested the extra formfield hack and surprise, surprise.. that pesky newline was gone.


Another poster, Sergii, mentioned this issue does not occur with Railo 3.1.2. So I tested the same code under Railo. Sure enough the resulting archive was fine, no corruption. Fiddler confirmed there were no pesky newline problems when using Railo's <cfhttp>. That clinched it for me. I would say this is an ACF bug with <cfhttp> in CF8 and CF9. So if you ever experience something similar, now you know why.

(Note: I do not know if this issue applies to 9.0.1)

0 comments:

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep