ColdFusion MultiUploader (CFMU)

Word Count: 327

When Flex 2 came out there was a lot of buzz on how programmer friendly it was. At the time I thought it sounds great but what current problems of mine would it solve. I then came across an article by Ryan Favro titled Multiple file upload with Flex and ColdFusion. I saw a real problem being solved by Flex and I thought it was a fantastic program. The big problem is at the time I did not know how to use Flex so I could not really customize the component. Fast forward a couple years and I becoming pretty handy with Flex.

The first thing I have decided to release is a mutliple file uploader. The uploader component which I am calling cfmu (I know really original) for the time being should be available in the next couple days. In the meantime I could really use a couple people to test it so drop me a note if you can. The first version of this component will be customizable via a xml settings file. After I get this up and working I plan to build in some runtime css so you can style the whole component via stylesheet. The cool thing for cfers out there not really into Flex you can just drop the cfmu folder in your project root and use the following code.

Here is a quick screen shot of the index test page that comes in the download. I have learned so much creating a bunch of small components like this and the first series will walk you through this component so you can understand how I created it. Also if you have not read the article by Ryan that I linked to above you should really check it out.

Comments

#1 Posted By: Jamie Posted On: 7/31/08 10:44 AM
Sweeeeeet
#2 Posted By: todd sharp Posted On: 7/31/08 10:44 AM
I haven't had a chance to test the version you sent yet, but why not allow for any custom filter (instead of just images). That would be really handy.
#3 Posted By: Dan Vega Posted On: 7/31/08 10:47 AM |
Author Comment
@Todd, Great minds think a like! That is in the plans and will be in the next release.
#4 Posted By: Ben Nadel Posted On: 7/31/08 12:58 PM
Dan, that looks really badass. Nice job.
#5 Posted By: Johan Posted On: 8/1/08 1:09 AM
Looks nice Dan.

Interested in if/how you are handling security between Flex/CF.

Some suggestions (you may have implemented these already):

- allow setting for max file size that can be uploaded

- I assume Remove allows removing multiple files that are selected in grid

- Cancel button that stops upload, useful if you have selected a lot of files and want to terminate uploading
#6 Posted By: Dan Vega Posted On: 8/1/08 9:15 AM |
Author Comment
@Johan - There really are no security concerns on the server end. As far CF is concerned it is just waiting for someone to call that method and pass some form parameters. On the flex side all you are doing is creating a form post using the URLRequest class. Great suggestion and I think I will use all of them, thanks!
#7 Posted By: Jose Posted On: 8/1/08 10:37 AM
Nice! Instead of "ImageFilter" why not create a "FileFilter" attribute so the user can specify list of allowable file extensions (ie: .pdf,.gif,.txt)?
#8 Posted By: Dan Vega Posted On: 8/1/08 10:47 AM |
Author Comment
Jose - Check out the next post!
#9 Posted By: Johan Posted On: 8/1/08 4:35 PM
Dan - security - I've always wondered about that, guess I need to test it. The concern being that if you know the url of the handler and the required form fields what stops someone from uploading using their own form?
#10 Posted By: Dan Vega Posted On: 8/1/08 4:38 PM |
Author Comment
I see what your saying. In that sense any component method that you expose as remote is vulnerable to this type of threat. I guess to bypass this I could always pass a keyphrase from the uploader to the component method and unless the right keyphrase is passed then the upload will not work. What are your thoughts on that.
#11 Posted By: Adrian Lynch Posted On: 8/1/08 4:41 PM
Ermmmm, maybe it's just me, but you didn't mention this was on riaforge.org did you?

cfmu.riaforge.org

Awesome job dude!
#12 Posted By: Dan Vega Posted On: 8/1/08 4:42 PM |
Author Comment
Ya I am sorry, it was not when I released this post but I got it up this morning!
#13 Posted By: Johans Posted On: 8/1/08 6:00 PM
Dan - security - an option with CF is to use cflogin/cfloginuser and set a role, then test for the role in the upload handler. To use cflogin/cfloginuser you pass form fields j_username and j_password from your Flex app. I'm not sure how secure that is either so will have to do some testing.
#14 Posted By: Johan Posted On: 8/1/08 6:21 PM
Security - I tested an as expected the j_username and j_password info is pretty easy to get at. I think if security is an issue then you could use this but only allow uploads after the user had logged in - so they would need an account. A more secure approach is something like Amazon S3 uses where you sign each request using a public and private key and request payload details. The signature is verified on the server.

Of course if the handler moves files after upload then chances of a user guessing path and trying to execute a file is harder. Also will pay to check file extensions on the server, not just the flex client.
#15 Posted By: Johan Posted On: 8/1/08 6:55 PM
Security - thinking about this some more - if you use cflogin/cfloginuser and require a user to sign in before they can upload then you can secure the upload hander method (cfc) using the roles attribute.
#16 Posted By: Johan Posted On: 8/1/08 6:59 PM
I should have mentioned - by signing in first and establishing the role you do not then need to pass the j_username and j_password fields with the upload. The role is maintained by a cookie (or session if you choose that option).
#17 Posted By: Johan Posted On: 8/1/08 7:47 PM
Another feature suggestion - add radio options for file name conflicts: Skip, Overwrite, Make Unique and pass that to your cffile tag - that way I can easily re-upload a file.
#18 Posted By: Dan Vega Posted On: 8/1/08 9:57 PM |
Author Comment
I think you have some good ideas on security but I am going to leave that up to the user to define. As far as the radio button, I don't think you would want to do this for every file but that might be a good option to set in the xml file
#19 Posted By: RyanTJ Posted On: 8/5/08 1:21 PM
The security of the handler concerns me also. Granted we can implement our own but the supplied example should be best practice. I would also use the same config file on the cfc to limit uploaded file types. You need to do the checking after upload (cffile.ServerFileExt) rather than the "accept" attribute since that can be faked out. the server. A security key between flex and the handler is good but you are giving the source so not we'd figure it out.
#20 Posted By: Dan Vega Posted On: 8/6/08 1:04 PM |
Author Comment
I understand, security should always be a concern. I have a couple thoughts on your comment. First off what about just checking the referer in the method, you would have to hard core this on a per usage basis but this would limit anyone from calling it. Also checking the upload extension is a good idea. The component in the download is really just an example and my thought behind this was someone would already have a component in place to handle this. The source may come one day, I am still working on gettting it up and running
#21 Posted By: Johan Posted On: 8/6/08 6:23 PM
@Ryan - security the easiest solution is to use cflogin/cfloginuser

@Dan - another suggestion is that the server could (should?) confirm to the client the upload has in fact completed with the file saved on the server.

For example the UI could display a tick/cross next to each item based on server response or only remove items that upload correctly from the list.

On a different note: it would be nice to consider reducing network traffic/time for uploads. The XStandard editor does this by zipping files and then chunking them into packets. On the server side you count and reassemble the packets and unzip to recover the file. As far as I know there is a ZIP library for AS.
#22 Posted By: Johan Posted On: 8/11/08 8:01 PM
@Ryan - on further investigation cflogin/cfloginuser only works nicely with MSIE and not Firefox, Safari or Opera.

In my test case I login from my Flex app via AMF and then pass "roles" back to the CF methods.

MSIE will pass the cookies set by CF back with file upload (http not AMF) and CF can then tie the upload request to the appropriate cfloginunser session and associated role/s.

However the other browsers will not send the cookie so CF does not link the request to a user session/roles and the CFC authentication fails.

A solution is to pass the j_username and j_password fields with the http request and use cflogin/cfloginuser in say your onRequestStart() method - but it's not nice sending the username/password with each request.

Probably a better solution is to pass a validation key value (made up of the file details and logged in user details value) in a field with the upload and verify that before handling upload.
#23 Posted By: Johan Posted On: 8/23/08 4:55 PM
@Ryan - further to using cflogin/cfloginuser

You can get it to work across all browsers by appending the JSESSIONID value to the URL:

_uploadURL.url = "uploader.cfc&method=upload" + "&jsessionid=" + _sessionID;

To get the value of the JSESSIONID cookie (_sessionID above) I simply pass it back from ColdFusion when the user has logged in.

I tested on MSIE, Firefox, Safari and Opera and works on all.

I also tested using standard CF session to secure the upload and again this worked fine in MSIE but failed in others, so I expect the solution is the same - append the CFID and CFTOKEN cookie values to the URL and then you can use your own session security scheme.
#24 Posted By: Bernhard Posted On: 11/20/08 10:14 AM
Hi Dan,

I really 'd enjoy CFMU but when I hit "Upload" I get the error #2038. It seems the error occours for each file I selected.
And here a very important suggestion:
Is it possible to make every text like the button texts editable via the settings.xml? It would be very handy if german users get german text.
#25 Posted By: Bernhard Posted On: 11/20/08 10:26 AM
Hiho, another clue. It would be very nice, if there'd be a URL parameter to reload the calling template after the uploads are done. This would show the user its new files in his directory.
#26 Posted By: Dan Vega Posted On: 11/20/08 1:18 PM |
Author Comment
The 2038 error has something to do with uploading the files and the location of the cfc. Put some error handling in the cfc and make sure its being hit. Also, a reload would not show new files as this is not a file manager, just an uploader. I am working on a full scaled file manager though so I will keep that in mind. I will see what I can do about the settings.
#27 Posted By: Bernhard Posted On: 11/21/08 3:41 AM
Dear Dan,
thank you very much for your answers. With "reload" I just mean to reload the template that opened/included the cfmu template.
See, I have a file manager. In the direcotry tree I open the cfmu and upload files. At this time after the upload happens nothing, the new files can't be seen because the template doesn't reload after upload. So it would be nice to give cfmu some action to do after the upload has finished.

BTW: Is there any way to buy or get the source of main.swf?

Greetings, thanks in advance
Bernhard


Post Your Comment







Show Captcha

If you subscribe, any new posts to this thread will be sent to your email address.

Copyright © 2007 Dan Vega | BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.