]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/web/unlinked.py
web/unlinked.py: don't use % operator to expand %(uri)s. fixes #1860.
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / web / unlinked.py
1
2 import urllib
3 from twisted.web import http
4 from twisted.internet import defer
5 from nevow import rend, url, tags as T
6 from allmydata.immutable.upload import FileHandle
7 from allmydata.mutable.publish import MutableFileHandle
8 from allmydata.web.common import getxmlfile, get_arg, boolean_of_arg, \
9      convert_children_json, WebError, get_format, get_mutable_type
10 from allmydata.web import status
11
12 def PUTUnlinkedCHK(req, client):
13     # "PUT /uri", to create an unlinked file.
14     uploadable = FileHandle(req.content, client.convergence)
15     d = client.upload(uploadable)
16     d.addCallback(lambda results: results.get_uri())
17     # that fires with the URI of the new file
18     return d
19
20 def PUTUnlinkedSSK(req, client, version):
21     # SDMF: files are small, and we can only upload data
22     req.content.seek(0)
23     data = MutableFileHandle(req.content)
24     d = client.create_mutable_file(data, version=version)
25     d.addCallback(lambda n: n.get_uri())
26     return d
27
28 def PUTUnlinkedCreateDirectory(req, client):
29     # "PUT /uri?t=mkdir", to create an unlinked directory.
30     file_format = get_format(req, None)
31     if file_format == "CHK":
32         raise WebError("format=CHK not accepted for PUT /uri?t=mkdir",
33                        http.BAD_REQUEST)
34     mt = None
35     if file_format:
36         mt = get_mutable_type(file_format)
37     d = client.create_dirnode(version=mt)
38     d.addCallback(lambda dirnode: dirnode.get_uri())
39     # XXX add redirect_to_result
40     return d
41
42
43 def POSTUnlinkedCHK(req, client):
44     fileobj = req.fields["file"].file
45     uploadable = FileHandle(fileobj, client.convergence)
46     d = client.upload(uploadable)
47     when_done = get_arg(req, "when_done", None)
48     if when_done:
49         # if when_done= is provided, return a redirect instead of our
50         # usual upload-results page
51         def _done(upload_results, redir_to):
52             if "%(uri)s" in redir_to:
53                 redir_to = redir_to.replace("%(uri)s", urllib.quote(upload_results.get_uri()))
54             return url.URL.fromString(redir_to)
55         d.addCallback(_done, when_done)
56     else:
57         # return the Upload Results page, which includes the URI
58         d.addCallback(UploadResultsPage)
59     return d
60
61
62 class UploadResultsPage(status.UploadResultsRendererMixin, rend.Page):
63     """'POST /uri', to create an unlinked file."""
64     docFactory = getxmlfile("upload-results.xhtml")
65
66     def __init__(self, upload_results):
67         rend.Page.__init__(self)
68         self.results = upload_results
69
70     def upload_results(self):
71         return defer.succeed(self.results)
72
73     def data_done(self, ctx, data):
74         d = self.upload_results()
75         d.addCallback(lambda res: "done!")
76         return d
77
78     def data_uri(self, ctx, data):
79         d = self.upload_results()
80         d.addCallback(lambda res: res.get_uri())
81         return d
82
83     def render_download_link(self, ctx, data):
84         d = self.upload_results()
85         d.addCallback(lambda res:
86                       T.a(href="/uri/" + urllib.quote(res.get_uri()))
87                       ["/uri/" + res.get_uri()])
88         return d
89
90 def POSTUnlinkedSSK(req, client, version):
91     # "POST /uri", to create an unlinked file.
92     # SDMF: files are small, and we can only upload data
93     contents = req.fields["file"].file
94     data = MutableFileHandle(contents)
95     d = client.create_mutable_file(data, version=version)
96     d.addCallback(lambda n: n.get_uri())
97     return d
98
99 def POSTUnlinkedCreateDirectory(req, client):
100     # "POST /uri?t=mkdir", to create an unlinked directory.
101     ct = req.getHeader("content-type") or ""
102     if not ct.startswith("multipart/form-data"):
103         # guard against accidental attempts to call t=mkdir as if it were
104         # t=mkdir-with-children, but make sure we tolerate the usual HTML
105         # create-directory form (in which the t=mkdir and redirect_to_result=
106         # and other arguments can be passed encoded as multipath/form-data,
107         # in the request body).
108         req.content.seek(0)
109         kids_json = req.content.read()
110         if kids_json:
111             raise WebError("t=mkdir does not accept children=, "
112                            "try t=mkdir-with-children instead",
113                            http.BAD_REQUEST)
114     file_format = get_format(req, None)
115     if file_format == "CHK":
116         raise WebError("format=CHK not currently accepted for POST /uri?t=mkdir",
117                        http.BAD_REQUEST)
118     mt = None
119     if file_format:
120         mt = get_mutable_type(file_format)
121     d = client.create_dirnode(version=mt)
122     redirect = get_arg(req, "redirect_to_result", "false")
123     if boolean_of_arg(redirect):
124         def _then_redir(res):
125             new_url = "uri/" + urllib.quote(res.get_uri())
126             req.setResponseCode(http.SEE_OTHER) # 303
127             req.setHeader('location', new_url)
128             req.finish()
129             return ''
130         d.addCallback(_then_redir)
131     else:
132         d.addCallback(lambda dirnode: dirnode.get_uri())
133     return d
134
135 def POSTUnlinkedCreateDirectoryWithChildren(req, client):
136     # "POST /uri?t=mkdir", to create an unlinked directory.
137     req.content.seek(0)
138     kids_json = req.content.read()
139     kids = convert_children_json(client.nodemaker, kids_json)
140     d = client.create_dirnode(initial_children=kids)
141     redirect = get_arg(req, "redirect_to_result", "false")
142     if boolean_of_arg(redirect):
143         def _then_redir(res):
144             new_url = "uri/" + urllib.quote(res.get_uri())
145             req.setResponseCode(http.SEE_OTHER) # 303
146             req.setHeader('location', new_url)
147             req.finish()
148             return ''
149         d.addCallback(_then_redir)
150     else:
151         d.addCallback(lambda dirnode: dirnode.get_uri())
152     return d
153
154 def POSTUnlinkedCreateImmutableDirectory(req, client):
155     # "POST /uri?t=mkdir", to create an unlinked directory.
156     req.content.seek(0)
157     kids_json = req.content.read()
158     kids = convert_children_json(client.nodemaker, kids_json)
159     d = client.create_immutable_dirnode(kids)
160     redirect = get_arg(req, "redirect_to_result", "false")
161     if boolean_of_arg(redirect):
162         def _then_redir(res):
163             new_url = "uri/" + urllib.quote(res.get_uri())
164             req.setResponseCode(http.SEE_OTHER) # 303
165             req.setHeader('location', new_url)
166             req.finish()
167             return ''
168         d.addCallback(_then_redir)
169     else:
170         d.addCallback(lambda dirnode: dirnode.get_uri())
171     return d