Coldfusion GetHttpRequestData()? - coldfusion

Does anyone have an example of how Coldfusion's GetHttpRequestData() works? I'm looking to use this func to save data from the AJAX Upload script: http://valums.com/ajax-upload/
The script works in FireFox but not Safari, Chrome, etc...
Ideas?

What error do you get?
Maybe these links will help:
http://www.coldfusionjedi.com/index.cfm/2007/7/1/Undocumented-change-to-GetHTTPRequestData-in-ColdFusion-8
http://www.bennadel.com/blog/1602-GetHTTPRequestData-Breaks-The-SOAP-Request-Response-Cycle-In-ColdFusion.htm

You might also want to read this recent thread about that script. As valums suggested, you should be able to extract the binary data from getHttpRequestData().content (when needed).
In my very limited tests, it seemed to work okay with IE8/FF/Chrome/Opera. However, I had no luck with Safari (windows). It seemed like the request data was getting mangled (or possibly misinterpreted by CF?). So the final content-type header reported by CF was incorrect, causing an http 500 error. Granted, I did not test this extensively.
Here is my quick and dirty test script (lame by design...)
<cfset uploadError = "" />
<cfif structKeyExists(FORM, "qqFile")>
<!--- upload as normal --->
<cffile action="upload" filefield="qqFile" destination="c:/temp" />
<cfelseif structKeyExists(URL, "qqFile")>
<!--- save raw content. DON'T do this on a prod server! --->
<!--- add security checks, etc... --->
<cfset FileWrite( "c:/temp/"& url.qqFile, getHttpRequestData().content) />
<cfelse>
<!--- something is missing ...--->
<cfset uploadError = "no file detected" />
</cfif>
<!--- return status old fashioned way (for compatibility) --->
<cfif not len(uploadError)>
{"success": true}
<cfelse>
<cfoutput>{error": "#uploadError#"}</cfoutput>
</cfif>

You want to look into using cffile with action="upload" to upload the file: http://cfdocs.org/cffile

GetHttpRequestData() is intended for decoding protocols like SOAP, XML-RPC, and some of the more complex REST-ful protocols. HTTP file uploads are normally done as POSTs using the multipart/form-data MIME type. Looking at http://www.cfquickdocs.com/it doesn't appear that GetHttpRequestData() has any special support for multipart data, which means you'd have to split and decode the parts yourself. Not my idea of fun, and completely unnecessary if you're just doing file uploading.
<cffile action="upload"> or <cffile action="uploadAll"> (new for CF9) should be quite sufficient for processing file uploads, even for those done via an AJAX upload script.

Related

How to change the user image using cfldap?

I'm able to get all the values that I want from cfldap.
But when I try to update the user image I don't know how to send the correct value for the binary image attribute.
I tried getting the image variable from the cffile upload
<cffile action="UPLOAD" filefield="file" destination="c:\inetpub\wwwroot\test" nameconflict="OVERWRITE" result="image" />
Also tried using cfimage with a static image -
<cfimage action="read" source="c:\inetpub\wwwroot\test\image.png" name="anotherImage">
Or even with
<cffile action="READBINARY" file="c:\inetpub\wwwroot\test\image.png" variable="BinaryImageContent">
But in any case, when I call
<cfldap action="modify"
DN="#results.dn#"
attributes="thumbnailPhoto=#obj.image#"
modifytype="replace"
server="myserver"
username="mydomain\myuser"
password="mypass">
The #results.dn# is the DN from the user that I get before (Everything ok on that)
I created the #obj.image# to be able to try all types of variables
Also tried these params:
<cfset obj.test1 = BinaryImageContent />
<cfdump var="#imageGetBlob(anotherImage)#" />
<cfdump var="#toString(obj.test1)#" />
By the way, the error that I get its
One or more of the required attributes may be missing or incorrect or
you do not have permissions to execute this operation on the server.
The problem is that I'm using the domain administrator account to update that
(THIS ERROR IS SOLVED - The network guys hadn't given me this permission... now I have it).
Now what I'm using is the following:
<cffile action="UPLOAD" filefield="file" destination="c:\inetpub\wwwroot\test" nameconflict="OVERWRITE" result="imagem" />
<cfset filename = "C:\inetpub\wwwroot\test\#imagem.serverFile#">
<cffile action="readbinary" file="#filename#" variable="img">
<cfset imgStr = BinaryEncode(img, "hex")>
<cfset imgStr2 = REReplace(imgStr, "..", "\\\0", "ALL")>
<cfldap
action="modify"
DN="#results.dn#"
attributes="thumbnailPhoto=#imgStr2#"
modifytype="replace"
server="myserver"
username="mydomain\myuser"
password="mypass"
>
but I get this binary code
Whats strange, is that before I had a binary code like -1-41 and now, nothing similar...
and when I try to show the pic
And this is one correct image....
EDIT: The original code sample below shows how it could work if ColdFusion wouldn't have a bug (or "very unfortunate design decision") in CFLDAP.
CFLDAP encodes the parameter values you pass to it before sending them to the server. This is nice because you don't have to worry about value encoding. But... it is also not helpful because it means you can't send encoded values yourself anymore, since CF invariably encodes them again.
Bottom line: As far as LDAP is concerned, encoding a file into a hex-string is correct, but CFLDAP mangles that string before sending it to the server. Combined with the fact that CFLDAP does not accept raw binary data this means that you can't use it to update binary attributes.
The comments contain a suggestion for a 3rd-party command line tool that can easily substitute CFLDAP for this task.
You need to send an encoded string to the server as the attribute value. The encoding scheme for binary data in LDAP queries has the form of attribute=\01\02\03\ab\af\cd.
Read your image into a byte array, encode that array into a hex string and prefix every encoded byte with a backslash.
<cffile action="readbinary" file="#filename#" variable="img">
<cfset imgStr = BinaryEncode(img, "hex")>
<cfset imgStr = REReplace(imgStr, "..", "\\\0", "ALL")>
<cfldap
action="modify"
DN="#results.dn#"
attributes="thumbnailPhoto=#imgStr#"
modifytype="replace"
server="myserver"
username="mydomain\myuser"
password="mypass"
>
Also don't forget what the documentation has to say about modifyType.

Excluding items from a list in coldfusion by type

Is there a way to exclude certain items by filetype in a list in Coldfusion?
Background: I just integrated a compression tool into an existing application and ran into the problem of the person's prior code would automatically grab the file from the upload destination on the server and push it to the Network Attached Storage. The aim now is to stop their NAS migration code from moving all files to the NAS, only those which are not PDF's. What I want to do is loop through their variable that stores the names of the files uploaded, and exclude the pdf's from the list then pass the list onto the NAS code, so all non pdf's are moved and all pdf's uploaded remain on the server. Working with their code is a challenge as no one commented or documented anything and I've been trying several approaches.
<cffile action="upload" destination= "c:\uploads\" result="myfiles" nameconflict="makeunique" >
<cfset fileSys = CreateObject('component','cfc.FileManagement')>
<cfif Len(get.realec_transactionid)>
<cfset internalOnly=1 >
</cfif>
**This line below is what I want to loop through and exclude file names
with pdf extensions **
<cfset uploadedfilenames='#myfiles.clientFile#' >
<CFSET a_insert_time = #TimeFormat(Now(), "HH:mm:ss")#>
<CFSET a_insert_date = #DateFormat(Now(), "mm-dd-yyyy")#>
**This line calls their method from another cfc that has all the file
migration methods.**
<cfset new_file_name = #fileSys.MoveFromUploads(uploadedfilenames)#>
**Once it moves the file to the NAS, it inserts the file info into the
DB table here**
<cfquery name="addFile" datasource="#request.dsn#">
INSERT INTO upload_many (title_id, fileDate, filetime, fileupload)
VALUES('#get.title_id#', '#dateTimeStamp#', '#a_insert_time#', '#new_file_name#')
</cfquery>
<cfelse>
<cffile action="upload" destination= #ExpandPath("./uploaded_files/zip.txt")# nameconflict="overwrite" >
</cfif>
Update 6/18
Trying the recommended code helps with the issue of sorting out filetypes when tested outside of the application, but anytime its integrated into the application to operate on the variable uploadedfilenames the rest of the application fails and the multi-file upload module just throws a status 500 error and no errors are reported in the CF logs. I've found that simply trying to run a cfloop on another variable not related to anything in the code still causes it to error.
As per my understanding, you want to filter-out file names with a specific file type/extension (ex: pdf) from the main list uploadedfilenames. This is one of the easiest ways:
<cfset lFileNames = "C:\myfiles\proj\icon-img-12.png,C:\myfiles\proj\sample-file.ppt,C:\myfiles\proj\fin-doc1.docx,C:\myfiles\proj\fin-doc2.pdf,C:\myfiles\proj\invoice-temp.docx,C:\myfiles\proj\invoice-final.pdf" />
<cfset lResultList = "" />
<cfset fileExtToExclude = "pdf" />
<cfloop list="#lFileNames#" index="fileItem" delimiters=",">
<cfif ListLast(ListLast(fileItem,'\'),'.') NEQ fileExtToExclude>
<cfset lResultList = ListAppend(lResultList,"#fileItem#") />
</cfif>
</cfloop>
Using only List Function provided by ColdFusion this is easily done, you can test and try the code here. I would recommend you to wrap this code around a function for easy handling. Another way to do it would be to use some complex regular expression on the list (if you're looking for a more general solution, outside the context of ColdFusion).
Now, applying the solution to your problem:
<cfset uploadedfilenames='#myfiles.clientFile#' >
<cfset lResultList = "" />
<cfset fileExtToExclude = "pdf" />
<cfloop list="#uploadedfilenames#" index="fileItem" delimiters=",">
<cfif ListLast(ListLast(fileItem,'\'),'.') NEQ fileExtToExclude>
<cfset lResultList = ListAppend(lResultList,fileItem) />
</cfif>
</cfloop>
<cfset uploadedfilenames = lResultList />
<!--- rest of your code continues --->
The result list lResultList is copied to the original variable uploadedfilenames.
I hope I'm not misunderstanding the question, but why don't you just wrap all of that in an if-statement that reads the full file name? Whether the files are coming one by one or through a delimited list, it should be easy to work around.
<cfif !listContains(ListName, '.pdf')>
OR
<cfif FileName does not contain '.pdf'>
then
all the code you posted

grabbing JSON data using coldfusion

I have a URL which when run in the browser, displays JSON data, since I am new to coldfusion, I am wondering, what would be a good way to
grab the data from the web browser? Later on I will be storing the individial JSON data into MySQL database, but I need to figure out step 1
which is grabbing the data.
Please advise.
Thanks
You'll want to do a cfhttp request to load the external content.
Then you can use deserializeJSON to convert the JSON object into the appropriate cfml struct.
See the example Adobe gives in the deserializeJSON documentation.
Here is quick example:
<!--- Set the URL address. --->
<cfset urlAddress="http://ip.jsontest.com/">
<!--- Generate http request from cf --->
<cfhttp url="#urlAddress#" method="GET" resolveurl="Yes" throwOnError="Yes"/>
<!--- handle the response from the server --->
<cfoutput>
This is just a string:<br />
#CFHTTP.FileContent#<br />
</cfoutput>
<cfset cfData=DeserializeJSON(CFHTTP.FileContent)>
This is object:<br />
<cfdump var="#cfData#">
Now you can do something like this:<br />
<cfoutput>#cfData.ip#</cfoutput>
Execute this source here http://cflive.net/

How to deliver large file with Coldfusion 8?

I am using Coldfusion 8 and I am trying to serve a file of 15mo with cf_content. The problem is that the download freezes randomly. At the moment, I only tried locally, therefore the network is not the problem. I have tried with smaller files and freezes happen less often. I have no idea of the root of the problem. Here is my coldfusion code:
<cfheader name="Content-Disposition" value="attachment; filename=test.zip">
<cfcontent type="application/zip" file="C:\Test.zip" deletefile="no">
I tried to download the file with Chrome, IE and with a piece of java code to download the file (freeze on the read method after some iteration).
Do you have any idea of how I can easily stream a file using Coldfusion? Maybe it is possible using a Java Custom tags but how to write bytes to page as the custom tag write method of the Response object only allows to write a String?
I did this for a client. I am gathering a number of documents and zipping them for download. Rather than stream them, I save the zip file on the server:
<cfzip action="zip" file="#expandpath('/data/briefcase/')##session.order_id#.zip" source="#expandpath('/data/briefcase/')##session.order_id#" overwrite="yes" storepath="no">
Then I provide the user a link to download the file. That way, if it fails, they can always try again.
I then wrote a scheduled task that runs every day and delete any zip files more than 24 hours old.
<cfdirectory action="list" directory="#expandpath('/data/briefcase/')#" name="filelist" >
<cfquery name="filter_file" dbtype="query" >
SELECT * from filelist WHERE datelastmodified < #dateadd("h", -48, now())# AND type = 'File'
</cfquery>
<cfquery name="filter_dir" dbtype="query" >
SELECT * from filelist WHERE datelastmodified < #dateadd("h", -48, now())# AND type = 'Dir'
</cfquery>
<cfset path = expandpath('/data/briefcase/')>
<cfoutput query="filter_file">
<cfif fileexists('#directory#/#name#')>
<cffile action="delete" file="#directory#/#name#" >
</cfif>
</cfoutput>
<cfoutput query="filter_dir">
<cfif directoryexists('#directory#/#name#')>
<cfdirectory action="delete" directory="#directory#/#name#" recurse="true" >
</cfif>
</cfoutput>
See if helps to prepend your code with:
<cfheader name="Content-Length" value="#GetFileInfo('C:\Test.zip').size#">
That tells the browser how much data to expect.

how to save xml in user's computer in coldfusion?

I am invoking a ColdFusion webservice through cfinvoke
<cfinvoke
method="getUsers"
returnvariable="rawXMLUserList"
webservice="http://www.xyz.com/getusers.cfc?wsdl"
>
<cfinvokeargument name="userid" value="123">
</cfinvoke>
And I am storing XML returnvariable into userList variable
<cfset userList = XmlParse(rawXMLUserLis)><br/>
how to save abc.xml on user's computer, using cffile it is saving on server's computer, i have to save it on user's computer who invokes this "getUsers" method.
Thanks
Kishor
When you run XMLParse(), you're turning it into a CF XML Document Object. You need to use ColdFusion's toString(xmlObject) function when outputting it.
<cfheader name="content-disposition" value="attachment;filename=abc.xml">
<cfcontent type="application/xml;charset=utf-8" reset="true">
<cfoutput>#toString(userList)#</cfoutput>
Another way is to write the file to a web directory (cffile action=write) and then cflocation the user to the file.
You need to tell the user's browser to download the file, not display it. Generally with something like this (not tested):
<cfheader name="content-disposition" value="attachment;filename=abc.xml">
<cfcontent type="application/xml;charset=utf-8" reset="true">
<cfoutput>#userList#</cfoutput>
cfheader generates a custom HTTP header.
cfcontent sets the MIME content encoding header for the page.