| 151 | | def get_dir(root, dir, match="", content_types=None, index=""): |
|---|
| 152 | | request = cherrypy.request |
|---|
| 153 | | path = request.object_path |
|---|
| 154 | | |
|---|
| 155 | | if match and not re.search(match, path): |
|---|
| 156 | | return False |
|---|
| 157 | | |
|---|
| 158 | | if root == 'global': |
|---|
| 159 | | root = "/" |
|---|
| 160 | | root = root.rstrip(r"\/") |
|---|
| 161 | | |
|---|
| 162 | | branch = urllib.unquote(path[len(root) + 1:].lstrip(r"\/")) |
|---|
| 163 | | |
|---|
| 164 | | # If branch is "", file will end in a slash |
|---|
| 165 | | file = os.path.join(dir, branch) |
|---|
| 166 | | |
|---|
| 167 | | # There's a chance that the branch pulled from the URL might |
|---|
| 168 | | # have ".." or similar uplevel attacks in it. Check that the final |
|---|
| 169 | | # file is a child of dir. |
|---|
| 170 | | if not os.path.normpath(file).startswith(os.path.normpath(dir)): |
|---|
| 171 | | raise cherrypy.HTTPError(403) # Forbidden |
|---|
| 172 | | |
|---|
| 173 | | if not os.path.isabs(file): |
|---|
| 174 | | msg = "static directory requires an absolute path (got '%s')." % file |
|---|
| 175 | | raise cherrypy.WrongConfigValue(msg) |
|---|
| 176 | | |
|---|
| 177 | | def attempt(fname): |
|---|
| | 151 | |
|---|
| | 152 | def _attempt(filename, content_types): |
|---|
| | 153 | try: |
|---|
| 182 | | r, ext = os.path.splitext(fname) |
|---|
| 183 | | content_type = content_types.get(ext[1:], None) |
|---|
| 184 | | serve_file(fname, contentType=content_type) |
|---|
| 185 | | |
|---|
| 186 | | try: |
|---|
| 187 | | attempt(file) |
|---|
| 188 | | return True |
|---|
| 189 | | except cherrypy.NotFound: |
|---|
| 190 | | # If we didn't find the static file, continue handling the |
|---|
| 191 | | # request. We might find a dynamic handler instead. |
|---|
| 192 | | |
|---|
| 193 | | # But first check for an index file if a folder was requested. |
|---|
| 194 | | if index and file[-1] in (r"\/"): |
|---|
| 195 | | try: |
|---|
| 196 | | attempt(os.path.join(file, index)) |
|---|
| 197 | | return True |
|---|
| 198 | | except cherrypy.NotFound: |
|---|
| 199 | | pass |
|---|
| 200 | | return False |
|---|
| 201 | | |
|---|
| 202 | | |
|---|
| 203 | | def get_file(filename, match="", content_types=None): |
|---|
| 204 | | if not os.path.isabs(filename): |
|---|
| 205 | | msg = "static file requires an absolute path." |
|---|
| 206 | | raise cherrypy.WrongConfigValue(msg) |
|---|
| 207 | | |
|---|
| 208 | | request = cherrypy.request |
|---|
| 209 | | path = request.object_path |
|---|
| 210 | | |
|---|
| 211 | | if match and not re.search(match, path): |
|---|
| 212 | | return False |
|---|
| 213 | | |
|---|
| 214 | | try: |
|---|
| 215 | | # you can set the content types for a complete directory per extension |
|---|
| 216 | | content_type = None |
|---|
| 217 | | if content_types: |
|---|
| 218 | | root, ext = os.path.splitext(filename) |
|---|
| | 158 | r, ext = os.path.splitext(filename) |
|---|
| | 166 | |
|---|
| | 167 | def get_dir(section, dir, root="", match="", content_types=None, index=""): |
|---|
| | 168 | if match and not re.search(match, cherrypy.request.object_path): |
|---|
| | 169 | return False |
|---|
| | 170 | |
|---|
| | 171 | # If dir is relative, make absolute using "root". |
|---|
| | 172 | if not os.path.isabs(dir): |
|---|
| | 173 | if not root: |
|---|
| | 174 | msg = "Static tool requires an absolute dir or root." |
|---|
| | 175 | raise cherrypy.WrongConfigValue(msg) |
|---|
| | 176 | dir = os.path.join(root, dir) |
|---|
| | 177 | |
|---|
| | 178 | # Determine where we are in the object tree relative to 'section' |
|---|
| | 179 | # (where the static tool was defined). |
|---|
| | 180 | if section == 'global': |
|---|
| | 181 | section = "/" |
|---|
| | 182 | section = section.rstrip(r"\/") |
|---|
| | 183 | branch = cherrypy.request.object_path[len(section) + 1:] |
|---|
| | 184 | branch = urllib.unquote(branch.lstrip(r"\/")) |
|---|
| | 185 | |
|---|
| | 186 | # If branch is "", filename will end in a slash |
|---|
| | 187 | filename = os.path.join(dir, branch) |
|---|
| | 188 | |
|---|
| | 189 | # There's a chance that the branch pulled from the URL might |
|---|
| | 190 | # have ".." or similar uplevel attacks in it. Check that the final |
|---|
| | 191 | # filename is a child of dir. |
|---|
| | 192 | if not os.path.normpath(filename).startswith(os.path.normpath(dir)): |
|---|
| | 193 | raise cherrypy.HTTPError(403) # Forbidden |
|---|
| | 194 | |
|---|
| | 195 | handled = _attempt(filename, content_types) |
|---|
| | 196 | if not handled: |
|---|
| | 197 | # Check for an index file if a folder was requested. |
|---|
| | 198 | if index and filename[-1] in (r"\/"): |
|---|
| | 199 | handled = _attempt(os.path.join(filename, index), content_types) |
|---|
| | 200 | return handled |
|---|
| | 201 | |
|---|
| | 202 | def get_file(filename, root=None, match="", content_types=None): |
|---|
| | 203 | if match and not re.search(match, cherrypy.request.object_path): |
|---|
| | 204 | return False |
|---|
| | 205 | |
|---|
| | 206 | # If filename is relative, make absolute using "root". |
|---|
| | 207 | if not os.path.isabs(filename): |
|---|
| | 208 | if not root: |
|---|
| | 209 | msg = "Static tool requires an absolute filename (got '%s')." % filename |
|---|
| | 210 | raise cherrypy.WrongConfigValue(msg) |
|---|
| | 211 | filename = os.path.join(root, filename) |
|---|
| | 212 | |
|---|
| | 213 | return _attempt(filename, content_types) |
|---|