summaryrefslogtreecommitdiff
path: root/django/views/static.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/views/static.py')
-rw-r--r--django/views/static.py117
1 files changed, 9 insertions, 108 deletions
diff --git a/django/views/static.py b/django/views/static.py
index cc88211876..eee9885c02 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -9,6 +9,7 @@ import posixpath
import re
import stat
import urllib
+import warnings
from email.Utils import parsedate_tz, mktime_tz
from django.template import loader
@@ -16,6 +17,10 @@ from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpRespons
from django.template import Template, Context, TemplateDoesNotExist
from django.utils.http import http_date
+from django.contrib.staticfiles.views import \
+ directory_index, was_modified_since, serve as staticfiles_serve
+
+
def serve(request, path, document_root=None, show_indexes=False):
"""
Serve static files below a given point in the directory structure.
@@ -30,111 +35,7 @@ def serve(request, path, document_root=None, show_indexes=False):
but if you'd like to override it, you can create a template called
``static/directory_index.html``.
"""
-
- # Clean up given path to only allow serving files below document_root.
- path = posixpath.normpath(urllib.unquote(path))
- path = path.lstrip('/')
- newpath = ''
- for part in path.split('/'):
- if not part:
- # Strip empty path components.
- continue
- drive, part = os.path.splitdrive(part)
- head, part = os.path.split(part)
- if part in (os.curdir, os.pardir):
- # Strip '.' and '..' in path.
- continue
- newpath = os.path.join(newpath, part).replace('\\', '/')
- if newpath and path != newpath:
- return HttpResponseRedirect(newpath)
- fullpath = os.path.join(document_root, newpath)
- if os.path.isdir(fullpath):
- if show_indexes:
- return directory_index(newpath, fullpath)
- raise Http404("Directory indexes are not allowed here.")
- if not os.path.exists(fullpath):
- raise Http404('"%s" does not exist' % fullpath)
- # Respect the If-Modified-Since header.
- statobj = os.stat(fullpath)
- mimetype, encoding = mimetypes.guess_type(fullpath)
- mimetype = mimetype or 'application/octet-stream'
- if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
- statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
- return HttpResponseNotModified(mimetype=mimetype)
- contents = open(fullpath, 'rb').read()
- response = HttpResponse(contents, mimetype=mimetype)
- response["Last-Modified"] = http_date(statobj[stat.ST_MTIME])
- response["Content-Length"] = len(contents)
- if encoding:
- response["Content-Encoding"] = encoding
- return response
-
-DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
- <meta http-equiv="Content-Language" content="en-us" />
- <meta name="robots" content="NONE,NOARCHIVE" />
- <title>Index of {{ directory }}</title>
- </head>
- <body>
- <h1>Index of {{ directory }}</h1>
- <ul>
- {% ifnotequal directory "/" %}
- <li><a href="../">../</a></li>
- {% endifnotequal %}
- {% for f in file_list %}
- <li><a href="{{ f|urlencode }}">{{ f }}</a></li>
- {% endfor %}
- </ul>
- </body>
-</html>
-"""
-
-def directory_index(path, fullpath):
- try:
- t = loader.select_template(['static/directory_index.html',
- 'static/directory_index'])
- except TemplateDoesNotExist:
- t = Template(DEFAULT_DIRECTORY_INDEX_TEMPLATE, name='Default directory index template')
- files = []
- for f in os.listdir(fullpath):
- if not f.startswith('.'):
- if os.path.isdir(os.path.join(fullpath, f)):
- f += '/'
- files.append(f)
- c = Context({
- 'directory' : path + '/',
- 'file_list' : files,
- })
- return HttpResponse(t.render(c))
-
-def was_modified_since(header=None, mtime=0, size=0):
- """
- Was something modified since the user last downloaded it?
-
- header
- This is the value of the If-Modified-Since header. If this is None,
- I'll just return True.
-
- mtime
- This is the modification time of the item we're talking about.
-
- size
- This is the size of the item we're talking about.
- """
- try:
- if header is None:
- raise ValueError
- matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
- re.IGNORECASE)
- header_mtime = mktime_tz(parsedate_tz(matches.group(1)))
- header_len = matches.group(3)
- if header_len and int(header_len) != size:
- raise ValueError
- if mtime > header_mtime:
- raise ValueError
- except (AttributeError, ValueError, OverflowError):
- return True
- return False
+ warnings.warn("The view at `django.views.static.serve` is deprecated; "
+ "use the path `django.contrib.staticfiles.views.serve` "
+ "instead.", PendingDeprecationWarning)
+ return staticfiles_serve(request, path, document_root, show_indexes)