Как обслуживать статические файлы Django через HTTPS?

Я получаю ошибку 404 при доступе к статическим файлам через HTTPS, но через HTTP статические файлы работают нормально.

Чтобы было ясно, я могу получить доступ к определенной странице в обоих направлениях, например. http://domain.com/page и https://domain.com/page, но в случае HTTPS изображения не загрузятся.

Кроме того, прямой доступ к изображению http://domain.com/static/image.png работает, но https://domain.com/static/image.png возвращает 404.

Я использую Ubuntu 10.04 с Django 1.3, используя mod_wsgi на apache2.

Вот соответствующие файлы (wsgi и prod.conf и secure_prod.conf и settings.py):

django.wsgi

import os
import sys
import site

sys.stdout = sys.stderr # Allows use of print statements

PROJECT_ROOT = '/home/code/domain/src/domain-project/'
site_packages = '/home/code/domain/lib/python2.6/site-packages'

site.addsitedir(os.path.abspath(site_packages))
sys.path.insert(0, PROJECT_ROOT)
sys.path.insert(1, os.path.join(PROJECT_ROOT, "domain"))
sys.path.insert(2, site_packages)
os.environ['DJANGO_SETTINGS_MODULE'] = 'domain.settings'
os.environ['PYTHON_EGG_CACHE'] = '/home/administrator/.python-eggs'
os.environ["CELERY_LOADER"] = "django"

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

# Load a monitor to automatically reload apache when files change
import domain.monitor
domain.monitor.start(interval=1.0)

производство.conf

<VirtualHost *:80>

  # Admin email, Server Name (domain name) and any aliases
  ServerAdmin [email protected]
  ServerName domain.com
    ServerAlias *.domain.com

  DocumentRoot /home/code/domain/src/domain-project/domain
  LogLevel warn
  WSGIDaemonProcess domain-production processes=5 maximum-requests=500 threads=100
  WSGIProcessGroup domain-production
  WSGIScriptAlias / /home/code/domain/src/domain-project/apache/production.wsgi

  SetEnv PYTHON_EGG_CACHE /home/apache/.python_eggs

    Alias /admin/media /home/code/domain/lib/python2.6/site-packages/django/contrib/admin/media
    Alias /site_media /home/code/domain/src/domain-project/static
    Alias /static /home/code/domain/src/domain-project/static
    Alias /robots.txt /home/code/domain/src/domain-project/static/robots.txt
    Alias /favicon.ico /home/code/domain/src/domain-project/static/favicon.ico

  <Location /admin/media>
    SetHandler None
    Order allow,deny
    Allow from all
  </Location>

  <Location /site_media>
    SetHandler None
    Order allow,deny
    Allow from all
  </Location>

  <LocationMatch "\.(jpg|gif|png|mp4)$">
    SetHandler None
  </LocationMatch>

  <LocationMatch "^/(robots\.txt|favicon\.ico|crossdomain\.xml)$">
    SetHandler none
  </LocationMatch>

  ErrorLog /var/log/apache2/domain/production_error.log
  LogLevel info
  CustomLog /var/log/apache2/domain/production_access.log combined

</VirtualHost>

secure_production.conf

<VirtualHost *:443>

    ServerAdmin [email protected]
    ServerName domain.com
    ServerAlias *.domain.com

    DocumentRoot /home/code/domain/src/domain-project/domain 
    LogLevel warn
    WSGIDaemonProcess domain-production processes=5 maximum-requests=500 threads=100
    WSGIProcessGroup domain_production_secure
    WSGIScriptAlias / /home/code/domain/src/domain-project/apache/production.wsgi

    SSLEngine on
    SSLOptions +StrictRequire

    <Directory />
        SSLRequireSSL
    </Directory>

    SSLProtocol -all +TLSv1 +SSLv3
    SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM

    SSLCertificateFile /home/code/domain/src/domain-project/apache/key/domain.COM.crt
    SSLCertificateKeyFile /home/code/domain/src/domain-project/apache/key/domain.com.key
    SSLCertificateChainFile /home/code/domain/src/domain-project/apache/key/Apache_Plesk_Install.txt
    SSLVerifyClient none
    SSLProxyEngine off

    <IfModule mime.c>
        AddType application/x-x509-ca-cert      .crt
        AddType application/x-pkcs7-crl         .crl
    </IfModule>


    SetEnv PYTHON_EGG_CACHE /home/apache/.python_eggs


    Alias /admin/media /home/code/domain/lib/python2.6/site-packages/django/contrib/admin/media
    Alias /site_media /home/code/domain/src/domain-project/static
    Alias /static /home/code/domain/src/domain-project/static
    Alias /robots.txt /home/code/domain/src/domain-project/static/robots.txt
    Alias /favicon.ico /home/code/domain/src/domain-project/static/favicon.ico


    <Location /admin/media>
      SetHandler None
      Order allow,deny
      Allow from all
    </Location>

    <Location /site_media>
      SetHandler None
      Order allow,deny
      Allow from all
    </Location>

    <LocationMatch "\.(jpg|gif|png|mp4)$">
      SetHandler None
    </LocationMatch>

    <LocationMatch "^/(robots\.txt|favicon\.ico|crossdomain\.xml)$">
      SetHandler none
    </LocationMatch>

    ErrorLog /var/log/apache2/domain/production_secure_error.log
    LogLevel info
    CustomLog /var/log/apache2/domain/production_secure_access.log combined

</VirtualHost>

settings.py

# Django settings for domain project.
import os

DEBUG = False
TEMPLATE_DEBUG = DEBUG 

# create a relative path to anything on the project from the PROJECT PATH
SETTINGS_PATH = os.path.dirname(os.path.abspath(__file__))
PROJECT_PATH = os.path.join(*os.path.split(SETTINGS_PATH)[:-1])
rel = lambda * args: os.path.join(PROJECT_PATH, *args)

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = rel('..', 'static')

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.request',
    'django.core.context_processors.static',
)


MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

ROOT_URLCONF = 'domain.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    rel('..', 'templates'),
)

DJANGO_APPS= [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
]

THIRDPARTY_APPS = [
    'djcelery',
    'djkombu',
    #'sentry',
    #'sentry.client',
    #'south',
]

domain_APPS= []

INSTALLED_APPS = DJANGO_APPS + THIRDPARTY_APPS + domain_APPS

person Jordan    schedule 05.08.2011    source источник
comment
У вас есть django 404 или apacho 404? Если вы получаете apache 404, то, вероятно, виновата ваша безопасная производственная конфигурация. Если вы получите django 404, то сопоставление будет неправильным.   -  person leech    schedule 23.09.2011


Ответы (2)


Вам также необходимо использовать псевдонимы для всех ваших статических носителей и файлов администратора.

На данный момент вы, кажется, обслуживаете django на портах 80 и 443, но сайт-медиа только на порту 80. Просто скопируйте правила псевдонимов и разделы местоположения в secure_production.conf

person timc3    schedule 26.09.2011
comment
Итак, у меня была та же проблема, что и у Джордана, и я сбился с толку на два-три часа. Я пробовал mysite.com и не видел статических файлов. Наконец, когда я удалил автоматическое перенаправление на https, а затем проверил http... все статические файлы работали с http. Итак, благодаря вашему решению. Мне просто нужно было добавить псевдоним /static /path/to/my/static также на сайт по умолчанию-ssl в Ubuntu, и он начал работать! - person harijay; 24.04.2014

Ваш виртуальный хост 443 не может привыкнуть, потому что, если бы это был mod_wsgi, он бы жаловался по нескольким причинам. Первая причина заключается в том, что «производство домена» используется несколько раз для WSGIDaemonProcess, чего mod_wsgi не допустит, поскольку имя должно быть уникальным для всего экземпляра Apache. Во-вторых, WSGIProcessGroup в 443 ссылается на «domain_production_secure», для которого нет групповой директивы WSGIDaemonProcess.

Вам нужно проверить, какие файлы на самом деле читаются. Вы можете сделать это, введя синтаксическую ошибку в файлы и посмотреть, жалуется ли Apache при запуске или выполнить configtest.

Если вы изменяете то, что вы публикуете, постарайтесь не делать этого, так как любые сделанные вами изменения, которые изменяют смысл, затрудняют отладку.

Кстати, ваш конфиг унаследовал некоторые вещи, которые не нужны для mod_wsgi и нужны только для mod_python. Вы должны вернуться и пересмотреть документацию mod_wsgi и очистить эти вещи. В частности, SetEnv для кэша яиц Python не работает для mod_wsgi, а SetHandler None не требуется для mod_wsgi. Также плохой практикой является использование директив Location вместе с директивами управления доступом Apache. Вместо этого примените их к физическим каталогам, используя директиву Directory.

person Graham Dumpleton    schedule 26.09.2011