Получение Drupal или Apache, чтобы попробовать прокси на 404

У меня есть старый (Tomcat) сайт, который раньше назывался host.domain и недавно развернул сайт Drupal. Новый сервер Drupal теперь называется host.domain, а старый сервер Tomcat - legacy.domain. Большая часть иерархии была реплицирована в Drupal, поэтому закладки и результаты поисковой системы все еще должны работать: запросите host.domain / dir / page.jsp и Drupal обрежет.jsp и найдет узел с именем dir / page. Часть контента еще не была перенесена, поэтому я использую модуль Drupal 'Redirects 404', чтобы проверить содержимое на старом сервере перед возвратом 404: запрос host.domain/legacy/oldpage.jsp, Drupal ищет наследие Узел / oldpage не находит ни одного, пробует legacy.domain/legacy/oldpage.jsp, находит его и прозрачно передает содержимое в браузер с помощью drupal_http_request() - URL клиента даже не меняется. Эта часть прекрасно работает.

Проблема заключается в файлах.js и.css - по какой-то причине запрос на host.domain/legacy/file.js или file.css не вызовет обработку 404 в Drupal, и поэтому Drupal никогда не запрашивает legacy.domain, если у него есть файл, Вместо этого 404 проваливается в Apache и отображает Apache 404 (не Drupal или Tomcat). Это означает, что контент на legacy.domain, обслуживаемый через Drupal на host.domain, если он включает локальные css или js, не получит эти стили или поведения

На мой взгляд, у меня есть три варианта:

  1. Скопируйте файлы css и js с сервера Tomcat и поместите их в корень Drupal при репликации старой иерархии каталогов. Это может работать, но может быть грязно, усложнять обновления ядра Drupal и может мешать поведению работающего прокси-контента 404.
  2. Получить Drupal для запуска 404 для файлов.js и.css, как это делает для файлов.jsp. Есть идеи, почему это не так?
  3. Если Drupal не выбросит 404 для файлов.js и.css, то попросите Apache выступить в качестве второго слоя для поведения прокси в Drupal. Если 404 проваливается в Apache, попробуйте вместо этого отправить его из legacy.domain.

Я думаю, что я мог бы также просмотреть весь контент на старом сервере Tomcat и заменить все относительные включения абсолютами, используя имя legacy.domain, но я уже пытаюсь переместить этот контент с этого хоста, и я действительно не Я не хочу прикладывать усилия к файлам, которые скоро будут заменены - я просто хочу, чтобы они работали правильно, пока я не смогу их перенести. У кого-нибудь есть какие-либо советы или руководства по реализации варианта 2 или 3?

Конфигурация Apache является стандартной Ubuntu 12.04.3 LTS..Htaccess в каталоге Drupal:

# Protect files and directories from prying eyes.                                           
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php
)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|
^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">                                              
  Order allow,deny                                                                          
</FilesMatch>                                                                               

# Don't show directory listings for URLs which map to a directory.                          
Options -Indexes                                                                            

# Follow symbolic links in this directory.                                                  
Options +FollowSymLinks                                                                     

# Make Drupal handle any 404 errors.                                                        
ErrorDocument 404 /index.php                                                                

# Set the default handler.                                                                  
DirectoryIndex index.php index.html index.htm                                               

# Override PHP settings that cannot be changed at runtime. See                              
# sites/default/default.settings.php and drupal_environment_initialize() in
# includes/bootstrap.inc for settings that can be changed at runtime.

# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
  php_flag magic_quotes_gpc                 off
  php_flag magic_quotes_sybase              off
  php_flag register_globals                 off
  php_flag session.auto_start               off
  php_value mbstring.http_input             pass
  php_value mbstring.http_output            pass
  php_flag mbstring.encoding_translation    off
</IfModule>

# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
  # Enable expirations.
  ExpiresActive On

  # Cache all files for 2 weeks after access (A).
  ExpiresDefault A1209600

  <FilesMatch \.php$>
    # Do not allow PHP scripts to be cached unless they explicitly send cache
    # headers themselves. Otherwise all scripts would have to overwrite the
    # headers set by mod_expires if they want another caching behavior. This may
    # fail if an error occurs early in the bootstrap process, and it may cause
    # problems if a non-Drupal PHP file is installed in a subdirectory.
    ExpiresActive Off
  </FilesMatch>
</IfModule>

# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on

# This forces all drupal links to end in a trailing slash.
# Companion rules to trailing slash module.
# https://drupal.org/project/trailing_slash
RewriteBase /
RewriteCond %{REQUEST_METHOD} !=post [NC]
RewriteRule ^(.*(?:^|/)[^/\.]+)$ $1/ [L,R=301]

  # Set "protossl" to "s" if we were accessed via https://.  This is used later
  # if you enable "www." stripping or enforcement, in order to ensure that
  # you don't bounce between http and https.
  RewriteRule ^ - [E=protossl]
  RewriteCond %{HTTPS} on
  RewriteRule ^ - [E=protossl:s]

  # Make sure Authorization HTTP header is available to PHP
  # even when running as CGI or FastCGI.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Block access to "hidden" directories whose names begin with a period.
  RewriteRule "(^|/)\." - [F]

  # Pass all requests not referring directly to files in the filesystem to
  # index.php. Clean URLs are handled in drupal_environment_initialize().
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]

  # Rules to correctly serve gzip compressed CSS and JS files.
  # Requires both mod_rewrite and mod_headers to be enabled.
  <IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.css $1\.css\.gz [QSA]

    # Serve gzip compressed JS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.js $1\.js\.gz [QSA]

    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
    RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]

    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Serve correct encoding type.
      Header set Content-Encoding gzip
      # Force proxies to cache gzipped & non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
  </IfModule>
</IfModule>

ОБНОВИТЬ

В соответствии с рекомендацией Шейна Мэддена, приведенной ниже, я добавил это в начало раздела mod_rewrite корня.htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} \.(css|js)$
RewriteRule ^(.*)$ http://legacy.domain/$1 [L]

Это работает, если я запрашиваю host.domain / oldfile.css: даже если oldfile.css не существует на устаревшем хосте, я получаю Tomcat 404, поэтому я знаю, что перезапись работает. Проблема в каталогах, которые не существуют в каталогах, которые не существуют.

Если у меня есть файл в устаревшей системе:

http://legacy.domain/root.css

и попросить об этом в

http://host.domain/root.css

файл появится, потому что он соответствует трем правилам RewriteCond. Однако, если я попрошу

http://host.domain/long/path/to/file.css

тогда я получаю Apache (не Tomcat) 404, с записью в error.log:

File does not exist: /var/www/long

Похоже, что правило перезаписи вступает в силу только в том случае, если запрошенный документ находится (или будет) в том же каталоге, что и.htaccess, содержащий это правило. Если запрошенный файл находится внутри каталога, каталог запускает 404, что не соответствует условиям, потому что он не заканчивается на.css или.js, и Apache сразу же прекращает обработку. Есть ли способ применить правило для любого 404, независимо от того, насколько далеко оно может находиться в иерархии каталогов, которая не существует локально?

1 ответ

Решение

Как насчет прямого проксирования файлов css и js, которые не существуют в файловой системе, поскольку файлы для сайта drupal должны попадать в реальные файлы в /sites каталог?

В пределах <Directory> блок для вашей установки Drupal, что-то вроде этого:

RewriteCond %{REQUEST_FILENAME} \.(css|js)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ http://proxy-target/$1 [P,L]

Редактировать:

Поскольку сопоставление файловой системы задыхается, прежде чем она сможет проверить существование, вместо этого давайте сделаем проверку без необходимости сопоставления файловой системы.

Поместите это в свой <VirtualHost> блокировать напрямую (или в конфигурации основного сервера, если вы не используете виртуальные хосты):

RewriteCond %{REQUEST_URI} \.(css|js)$
RewriteCond /path/to/your/docroot%{REQUEST_URI} !-f
RewriteRule ^/(.*)$ http://proxy-target/$1 [P,L]
Другие вопросы по тегам