-
Notifications
You must be signed in to change notification settings - Fork 0
/
RATIONALES.txt
93 lines (82 loc) · 5.76 KB
/
RATIONALES.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
Rationale for Using a Content-Disposition header
------------------------------------------------
``sdexternaledit`` returns a response when the pencil icon is clicked with a
mimetype of ``application/x-external-edit`` with a URL that has a final path
segment with the same name as the resource being edited, and a
Content-Disposition header that has a filename with a ``.zem`` extension. Why?
Chromium delegates to the operating system to choose which application to open
when a file cannot be handled by the browser itself, and is downloaded as a
result. The fun part: the mimetype provided by in the response from the server
is simply thrown away when Chromium figures out it can't handle the mimetype
all by itself, and that it needs to punt to the OS. It's not even set as an
extended attribute of the downloaded file. It's just gone.
After downloading the file and throwing the mimetype away, Chromium punts to
the operating system to figure out which application should be used to open the
downloaded file. Which, on Ubuntu or probably any other recent Linux OS means
the "xdg-open" program. xdg-open uses the "Shared Mime Info" specification
(http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html)
to choose which application to open given a file. xdg-open cannot be given a
hint about the file's mimetype because clearly that would make life far too
easy. And Chromium *does not* set the ``user.mime_type`` attribute on the
downloaded file (not that it would matter, because the version of xdg-open on
Ubuntu 12.04 doesn't take it into account anyway, even though the spec says it
should). Instead, it only takes a filename or a URL as a single argument, and
then attempts to divine the mimetype from that argument. xdg-open on Ubuntu
(really gvfs-open, because xdg-open is just a wrapper around it) will first
consult the mime database using the file extension of the file. If a mimetype
is associated with the extension, it's game over. In practice, this means that
if the downloaded file extension is ``.txt``, gedit is going to be used to open
the file, full stop.
However, we don't *want* gedit to be used to open the file, we want zopeedit to
be used to open the file. This means that we either have to manufacture a
phony extension that isn't associated with any mimetype in the shared mime
database, so that the *magic* computation of the shared mimeinfo database will
begin to come into play or we need to tack on an extension that is known to be
associated with zopeedit. Once the magic computation comes into play or the
extension is ``.zem`` "application/x-zope-edit" will always be found as the
mimetype due to the magic/glob rules in the "zopeedit.xml" file. Good enough.
So assume we've decided to use ``.zem`` as an extension to every downloaded
file that is destined for zopeedit by adding a view name of ``edit.zem`` to
each server-side view. We're able to download the file as a ``.zem`` file and
zopeedit gets launched. However, collective.zopeedit will copy the file to a
tempfile using the filename in the URL (which ends with .zem), and if
``editor`` is not set *it* wants to use gvfs-open to figure out which
application to use to open the file. And since the filename ends in ``.zem``
it chooses zopeedit, which ends in a total clusterfuck.
So we can't do that. Instead we have to tack on a ``.zem`` extension in the
content-disposition of the downloaded file using ``attachment;
filename="realfilename.txt.zem". Once we do that, zopeedit is unaware of the
.zem extension and copies the tempfile over without using it. The tempfile
will have the same name as the original resource (due to the "url" zopeedit
header in the body of the downloaded file), which means if zopeedit tries to
use xdg-open against it, if glob computation is used, something that can handle
the file will be used.
There is similar weirdness using Firefox, although Firefox has some sort of way
of associating a mimetype with an external program, so it may behave slightly
better. In particular, I think when it downloads a file of a particular
mimetype that it doesn't yet know about, it asks you which program to use to
open the file (with a sensible deafult based on the response mimetype) instead
of just downloading it and letting the OS take over.
Windows and MacOS are completely different animals. No idea there.
You might think an option would be to cause the client to accept a *URL*
instead of a filename. The URL can have a custom scheme
(e.g. ``zopeedit://localhost:6543/foo/bar.txt``). Then we can associate the
scheme with an application, which will be fed the URL. But this has problems
too because the program that is fed the URL wont have the proper credentials to
download the file.
Another option would be to use views with the name ``edit.zem`` and change
collective.zopeedit to munge the filename it uses to create a copy of the
downloaded file in a temp location to get rid of /edit.zem or at least tack on
the original extension of the downloaded file. But this would mean we have to
fork the client.
The remaining problem: when xdg-open is used by zopeedit to figure out which
editor to launch (instead of editor= being assigned manually), it will
generally find one and launch it ok, but the zopeedit process usually loses
track of the editor and assumes it has closed, because most programs like gedit
spawn a small process which feeds a new file to an already-open program
(e.g. something like emacsclient). It looks like ``collective.zopeedit``
actually has some code in place that tries to continually ask the user if the
file is still being edited in this case, but it doesn't actually appear to
work. So in practice, setting ``editor`` in ZopeEdit.ini to a static value (or
on a per content-type basis) is the only practical thing to do, at least on
Linux systems that use xdg-utils.