Adding Your Own File Uploads to Forms
Remember the article I wrote called Creating In-line Response Documents? It describes how to fake forms like the one you would use to add a comment to this blog.
These fake forms work well, until you try and add a file upload control (FUC) to them. This is a problem I've had to address recently. Here's how:
If you simply add a file upload element to the fake form, using PassThru HTML, you will get an error back from the server:
HTTP Web Server: File Upload Not Allowed Exception
To get round this we add a real Domino-style FUC to the actual form in the backend. Then we preview this form in the browser, view the source and copy the HTML for the Domino-rendered FUC, which will look something like this:
The format is %%File.DBRepID.FormID.$Body.0.???. With the FUC on the real form, you can take this string and paste it in as the name of the PassThru FUC on your fake form. You will then be able to upload files as normal.
But! Not only is this an ugly way of doing it, you then have to wonder what happens when you create new copies of this database. Will it still work? Well, for some strange reason, it seems to, but it's not a chance I'd like to take with my designs. Thankfully, there's another way of doing it.
Dimitris Ilaridis recently told me about a Notes.ini setting that is well documented by IBM. The parameter is:
If you add this parameter then you no longer need a FUC on the real form or for the names to match.
There are a couple of gotchas I've discovered though. Firstly, you obviously need to change the enctype of your fake form to "multipart/form-data" before file uploads are allowed. Secondly, I've found that the FUCs you add need to have name beginning with "%%File". You can have more than one FUC on a form, a sample form might look something like this:
<form name="FUCDomino" action="FUCDomino?createdocument" method="post" enctype="multipart/form-data"> <input type="file" name="%%File.1" /><br /> <input type="file" name="%%File.2" /><br /> <input type="submit" value="Upload" /> </form>
Hope you find this as useful as I have recently.
This is something I wanted to do many times, but had to workaround in other ways. But how is the security handled? It would be possible for users (hackers?) to create their own forms with FUC and be able to upload files to forms that should not have files attached to them?
This is a test to try to upload a file to a document that should not have file attachments.
Did that create a file attachment in the comment?
Peter. Apparently security is the reason for the whole "not allowed" error in the first place. Adding this Notes.ini setting bypasses this security.
I guess it's down to the risk. I won't be enabling it on this server and will only be suggesting it to clients for intranet installs.
One way round the hackers would be to remove the $file "field" in the WQS agent for any form where you don't want attachments.
No Peter, it didn't. The parameter is not set on this server.
Smart move. :-)
So we learn that it can be done, and that we have to take precautions to maintain control over our applications.
That's great !
Jake - I know you took a look at our CoexEdit earlier, but one of the customizations I added there seemed to make sense even outside of that product. I have the upload happen on a separate form and simply add the uploaded document from the temp form back to the original. I can do it a bit more cleanly with CoexEdit because of the API hooks (e.g., it can be added anywhere in the rich text), but the basic approach seems so much easier than adding multiple upload controls to a form, and it allows you to have as many file attachments as you like without worrying about file upload controls. Do you know of any reason why this sort of approach isn't used more frequently? I am not enough of a web developer to know potential gotchas.
YoGi. I'm not sure I see the point in that. If you can add a real FUC, why mimic it with JS? My aim here is to add FUCs when you wouldn't be able to add them with Domino.
Ben. I didn't get chance to look at it in the end as a part of that project. I'm still interested in having a play with it though, if ever I get the chance, ahem.
That seems like a reasonable way of doing it. Not seen it done that way before though. Maybe because there's another level of complication involved.
The way Ben describes is how it is typically done in webmail (e.g. Yahoo! Mail, Excite Mail, Mail.com). You click on 'Attach files' and you're taken to a separate form which allows you to add your attachments. When you've finished you're taken back to the original form (mail message) so you can deal with that.
I wrote something back in R5 that mimicked these upload forms, so it can be done. Can't remember exactly how it worked, though.
I've just realized i've misunderstood your blog.
Jake and Peter,
I guess one more way of preventing hackers from posting attachments using their own forms in your server would be by checking the "HTTP_Referer" field in the WQS. Unless you need to have an attachment control in you home page (so HTTP_Referer not yet set) you can check that the HTTP_Referer is your domain in order to allow attachments (or even the submission of the form). If it is not your domain then you can set the SaveOptions field to prevent the form from saving. I have not tested this but in theory should work :-)
I wrote a set of routines to allow the user to 'add another' and 'remove' FUCs as they saw fit. I also set it up so the user thought they were attaching the file to a specific field instead of the document.
I had the server administrator set the .ini parameter and everything worked great. All of a sudden, *something* broke and it was as if the server lost the .ini parm even though there was a configuration document in the NAB.
I tried getting my admin to restart the server but I guess he had other higher priority items to deal with because after a week of pestering him, I still didn't get the restart.
I'm curious as to why whatever it was broke. I suppose it could have been our installation but I'm also wondering about the stability of that parameter.
the referer http header can be spoofed, so that in its self would not save you.
FUC me thats clever :-o
There is also this from 2004:
Which lead to this, with a fantastic working example:
None of which is comprehensible to me :-(
I sure don't want to copy an offset and hope it works when design refreshed into another database and replicated out to another server, and I sure don't want to mess with ini settings and open up potential security holes, even if I could.
What I have is a simple form laid out in html, built in Domino Designer with Notes fields for each html input field, which gets me everything into a Notes document very nicely. I do it this way to get better control over everything about the page, which doesn't seem very common, and which doesn't let me use the built in File Upload Control everyone talks about which does work nicely (pass-through Notes-content?).
Then I put a type="file" input on it. Then I submit it to Domino. All that comes through is the file path, as displayed in the browser. :-(
With entype="multipart/form-data", I get the contents of the file! Hurray! :-)
But what I want is the file as an attachment.
It works great as is for text files, the contents appear in whatever field name I give to my input type="file". But for an image or anything else, I get the gibberish you would expect.
If Domino handles any other type of field, why not take type="file" and create a rich text field with the file as an attachment? Then I would be playing with power! There seems to be no need to mess with offsets and whatnot, the contents of the file are making it to the right place, they just aren't being handled sensibly :-(
Any magic sauce I can sprinkle on what I have so far to take it that last step over the finish line? I have the contents of the file, any way to transform that into an attachment? Without messing with the file system or ini files and such?
Just taking a gamble posting here, you never know...
I hope the other links I've found helps someone else (smarter than me!) by bringing it all together. Heaps of praise on anyone who comes along and fills me in on the (fantasy?) final step to wrap this up. Wish me luck!
We are planning to have this setting on intranet servers.
Will this affect any existing applications?
You should be able to apply this setting to an intranet server without it having a negative affect on existing apps. They'll continue to work as normal.
I apologize for being naive, I am trying to use this technique with a rich text field and storing the uploaded file as an attachment in a rich text field and I seem to be running to an error. Does the real form have to have a FUC or can this be done with a rich text field?
It's been a while and I'm a bit rusty on it Richard, but I'm sure your webquerysave agent can take the attachment and put it in the RT field. Seem to remember that involving putting it on the disk first, but I could be wrong.
I found some code that I will try to use. I was hoping that I would be able to upload the file directly into a rich text field, but it sounds like that is not possible. Is my assumption correct that the %%File.1 represents the first FUC on the real form and %%File.2 represents the second FUC? I am trying to create a upload process that I can reuse using Dojo and Domino that is why I am asking. I know it can be done with XPages, but then my interface is not generic enough for me to use it with other data stores beside Domino.
Keep up the good work.
The "%%File.1" references are merely to pretend FUCs and these only work when the INI parameter is in effect. Not sure what you're asking.
We set the Notes.ini parameter on the server. But it does not seem to work. Don't you need to have real FUC controls on the back-end Domino form associated with each upload control on the HTML form with the name %%File.1, etc?
Did you re-start the server Richard? You might need a real FUC on the form somewhere, so that Domino generates the right enctype attribute for the HTML Form tag. But you don't need to have one for each that you add using the %%File.X method.
No, we did not restart the server. My admin wasn't sure if we needed to. I will try that. Thanks for the tip.
Here is a solution that I came up with recently for the File Upload Control.
I have done this but I can not get files saved in document.
Is there special I have to do in WQS agent?
Hi Jake, I don't suppose you could post a demo db of this could you? I'm trying to rewrite my sites in HTML5 so need to it all by hand in domino. I just can't get this technique working.