Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/httpdrop/__init__.py

Revision 117 (checked in by fumanchu, 6 years ago)

HTTPDrop: New mount(path, script_name) function.

  • Property svn:eol-style set to native
Line 
1 from operator import attrgetter
2 import os
3 localDir = os.path.dirname(__file__)
4 absDir = os.path.join(os.getcwd(), localDir)
5 import re
6
7 import cherrypy
8 from cherrypy import tools
9
10
11 lcase_sort = lambda x,y: cmp(x.lower(), y.lower())
12
13
14 def mount(filepath, script_name):
15     """Mount a new HTTP drop box at the given path and URL."""
16     box = HTTPDrop(path=filepath)
17     return cherrypy.tree.mount(box, script_name=script_name)
18
19
20 class HTTPDrop:
21     """HTTPDrop, a CherryPy 3 controller for file management via HTTP.
22     
23     To use as a "standalone" application:
24         
25         mount(filepath, script_name)
26     
27     To include within another CherryPy 3 application:
28         
29         root.path.to.box = HTTPDrop(path=filepath, section="/path/to/box")
30         cherrypy.tree.mount(root)
31     """
32    
33     def __init__(self, path, section="", html_index=None):
34         self.section = section.strip(r"\/")
35         self.icons = tools.staticdir.handler(section="%s/icons" % self.section,
36                                              dir=os.path.join(absDir, "icons"))
37        
38         # Normalize the path so we can test for uplevel attacks in abspath().
39         self.path = os.path.normpath(path)
40         self.root = tools.staticdir.handler(section="%s/root" % self.section,
41                                             dir=self.path)
42        
43         if html_index is None:
44             html_index = os.path.join(absDir, "httpdrop.html")
45         self.html_index = html_index
46    
47     def abspath(self, *path):
48         """Join path to self.path and verify."""
49         path = [x.lstrip(r"\/") for x in path]
50         newpath = os.path.normpath(os.path.join(self.path, *path))
51         if not newpath.startswith(self.path):
52             cherrypy.log("Uplevel attack to: %s" % repr(path))
53             raise cherrypy.HTTPError(403, "Don't even *think* about trying "
54                                      "to walk MY tree.")
55         return newpath
56    
57     ajax_js = tools.staticfile.handler(os.path.join(absDir, "ajax.js"))
58    
59     def index(self, path=None):
60         tools.staticfile.callable(self.html_index)
61         return cherrypy.response.body
62     index.exposed = True
63    
64     def dirs(self, path):
65         """Return a JSON list of the path's subdirectories."""
66         cherrypy.response.headers["Content-Type"] = "application/x-json"
67         path = self.abspath(path)
68         for root, dirs, files in os.walk(path):
69             dirs.sort(lcase_sort)
70             return repr(dirs)
71         else:
72             # Something went wrong in os.walk.
73             raise IOError("The path %s could not be accessed." % repr(path))
74     dirs.exposed = True
75    
76     def files(self, path):
77         """Return a JSON list of the path's files."""
78         cherrypy.response.headers["Content-Type"] = "application/x-json"
79         path = self.abspath(path)
80         for root, dirs, files in os.walk(path):
81             files.sort(lcase_sort)
82             return repr(files)
83         else:
84             # Something went wrong in os.walk.
85             raise IOError("The path %s could not be accessed." % repr(path))
86     files.exposed = True
87    
88     def upload(self, path, payload, unzip=False):
89         # IE passes the full path in payload.filename, so split off the tail.
90         tail = os.path.split(payload.filename)[1]
91         fname = self.abspath(path, tail)
92         outfile = open(fname, 'wb')
93         while True:
94             data = payload.file.read(8192)
95             if not data:
96                 break
97             outfile.write(data)
98         outfile.close()
99        
100         if unzip:
101             try:
102                 import zipfile
103                 f = zipfile.ZipFile(fname)
104                 for name in f.namelist():
105                      open(self.abspath(path, name), "wb").write(f.read(name))
106             except:
107                 cherrypy.log(traceback=True)
108        
109         raise cherrypy.HTTPRedirect("./?path=%s" % path)
110     upload.exposed = True
111    
112     def move(self, oldname, newname):
113         """Move/rename the file at 'oldname' to 'newname'."""
114         oldname = self.abspath(oldname)
115         newname = self.abspath(newname)
116         os.rename(oldname, newname)
117         cherrypy.response.status = "204 No Content"
118     move.exposed = True
119    
120     def delete(self, path):
121         path = self.abspath(path)
122         os.remove(path)
123         cherrypy.response.status = "204 No Content"
124     delete.exposed = True
125
126
127
Note: See TracBrowser for help on using the browser.