You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Christopher Lenz <cm...@gmx.de> on 2008/05/23 18:14:11 UTC
Attachment management in Futon
Hey folks,
I've started playing with attachment support in Futon. As Futon is a
purely client-side application this is of course tricky (or actually
impossible), and it'll need some kind of hook on the server side.
I have two separate ideas on how this might be enabled, each with its
own advantages and disadvantages:
1. POST /_utils/upload/
This would be a special URL in CouchDB that would only exist to
support Futon. It would take a multipart/form-data POST request, extra
a file upload, and respond with a JSON representation of that upload,
with the content base64 encoded:
handle_upload_request(Req, 'POST') ->
Form = mochiweb_multipart:parse_form(Req),
{Name, {ContentType, _}, Content} = proplists:get_value("file",
Form),
Json = {obj, [
{name, Name},
{type, ContentType},
{content, couch_util:encodeBase64(Content)}
]},
Body = "<textarea>" ++ cjson:encode(Json) ++ "</textarea>",
{ok, Req:ok({"text/html", Body})};
The JSON needs to be wrapped in HTML, because AJAX file uploads need
to go through a separate hidden <iframe> and an impressive number of
hacks. We'd be using the jQuery Form plugin <http://malsup.com/jquery/form/
> to handle that in Futon.
So after submitting the attachment upload form, Futon would get back a
JSON representation of the upload, and add that JSON representation to
the _attachments member of the currently open document. When the
document is saved, the attachment data is part of the JSON
representation of the document, and is thus saved in the database.
The main drawback of this approach is that the file data is sent back
and forth: the initial upload, the server response, and the document
update request. For large files this will be somewhere between
noticable and a showstopper.
One advantage is that the attachment is only stored to the database
when the document is saved, same as for adding, modifying and deleting
fields. Another advantage is that Futon would be more flexible
(compared to the alternative presented below), as it could allow users
to specify the MIME type and maybe the encoding of the file, or to
provide a different target file name (for example, the local file is
called "NONAME.rtf" but the user would like to store it in the
document as "example.rtf").
2. POST /database/docid/
Here we'd accept a multipart/form-data POST on the document URI. The
form data may have one or more parts called "_attachments", each of
which would be a file upload that would get added to the attachments
of the document, possibly replacing existing attachments with the same
file name.
I don't think POST methods are supposed to use Etags and If-Match, so
we'd probably have to specify the document revision using a query
string parameter. So the POST request might look something like:
POST /database/docid/?rev=123456 HTTP/1.1
Host: example.org
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="_attachments";
filename="example.rtf"
Content-Type: application/rtf
... contents of example.rtf ...
--AaB03x--
It would need to be decided whether this interface should only be used
for attachments. It *might* be nice to be able to use this as a sort
of "edit document" interface, allowing you to add/update individual
fields, for example:
POST /database/docid/?rev=123456 HTTP/1.1
Host: example.org
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x--
Content-Disposition: form-data; name="full_name"
Content-Type: application/json
"Christopher Lenz"
--AaB03x--
Content-Disposition: form-data; name="_attachments";
filename="example.rtf"
Content-Type: application/rtf
... contents of example.rtf ...
--AaB03x--
Besides adding the attachment as before, this would either add or
update the "full_name" field in the specified document (or bail with a
conflict error).
I'm not sure about all this, so feedback / alternative suggestions
would be highly appreciated.
Thanks,
--
Christopher Lenz
cmlenz at gmx.de
http://www.cmlenz.net/
Re: Attachment management in Futon
Posted by Noah Slater <ns...@apache.org>.
On Fri, May 23, 2008 at 06:14:11PM +0200, Christopher Lenz wrote:
> I'm not sure about all this, so feedback / alternative suggestions would
> be highly appreciated.
Interesting stuff! I will reserve comment on the technical implementations and
only offer the opinion that it might be nice to provide this with the intention
of integration with other Web based interfaces to CouchDB. I can imagine it
being very useful in the general sense.
--
Noah Slater - The Apache Software Foundation <http://www.apache.org/>
Re: Attachment management in Futon
Posted by Christopher Lenz <cm...@gmx.de>.
On 23.05.2008, at 18:14, Christopher Lenz wrote:
> I've started playing with attachment support in Futon. As Futon is a
> purely client-side application this is of course tricky (or actually
> impossible), and it'll need some kind of hook on the server side.
>
> I have two separate ideas on how this might be enabled, each with
> its own advantages and disadvantages:
>
> 1. POST /_utils/upload/
>
> This would be a special URL in CouchDB that would only exist to
> support Futon. It would take a multipart/form-data POST request,
> extra a file upload, and respond with a JSON representation of that
> upload, with the content base64 encoded:
>
> handle_upload_request(Req, 'POST') ->
> Form = mochiweb_multipart:parse_form(Req),
> {Name, {ContentType, _}, Content} = proplists:get_value("file",
> Form),
> Json = {obj, [
> {name, Name},
> {type, ContentType},
> {content, couch_util:encodeBase64(Content)}
> ]},
> Body = "<textarea>" ++ cjson:encode(Json) ++ "</textarea>",
> {ok, Req:ok({"text/html", Body})};
>
> The JSON needs to be wrapped in HTML, because AJAX file uploads need
> to go through a separate hidden <iframe> and an impressive number of
> hacks. We'd be using the jQuery Form plugin <http://malsup.com/jquery/form/
> > to handle that in Futon.
>
> So after submitting the attachment upload form, Futon would get back
> a JSON representation of the upload, and add that JSON
> representation to the _attachments member of the currently open
> document. When the document is saved, the attachment data is part of
> the JSON representation of the document, and is thus saved in the
> database.
>
> The main drawback of this approach is that the file data is sent
> back and forth: the initial upload, the server response, and the
> document update request. For large files this will be somewhere
> between noticable and a showstopper.
After more playing around, I think this approach is pretty much
infeasible. Uploading even a 1.3MB PDF file causes Firefox3 to grind
to a halt.
Cheers,
--
Christopher Lenz
cmlenz at gmx.de
http://www.cmlenz.net/