web-dev-qa-db-ja.com

htaccess書き換えルールをApache2仮想ホストルールに変換する

Apache vhostsファイルに同じルールを使用できるという信念の下で、以前に正常に実装したいくつかの.htaccessルールを組み合わせて、ワイルドカードサブドメインRewriteRuleを設定しようとしています。

本質的に、example.comwww.example.comはルートパスに移動し、index.phpを探します。 abc.example.comなどのルートレベルの他のすべての(動的)サブドメインリクエストは、example.com/process.php?p=abcに書き換えられます(ブラウザには表示されません)。

次に、ベース/ルートレベル外のサブドメインからのファイルのリクエストは、サブドメインのない標準ドメインのルートパスから取得するように書き換える必要があります。したがって、abc.example.com/css/style.cssexample.com/css/style.cssから取得する必要があります

これが私の試みです。 Apacheエラーが発生します:

このサーバーで/index.phpにアクセスする権限がありません。

www以外のサブドメインの試行では、期待どおりに機能し、標準のexample.comでも問題なく機能します。

<VirtualHost *:80>

        ServerAdmin [email protected]
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/public_html

        ErrorLog ${Apache_LOG_DIR}/error.log
        CustomLog ${Apache_LOG_DIR}/access.log combined

</VirtualHost>

<VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html/

        <Directory /var/www/example.com/public_html/>
        Options FollowSymLinks
        AllowOverride all
        Require all granted

        RewriteCond %{HTTP_Host} !^www\.example\.com$ [NC]
                RewriteCond %{HTTP_Host} ^(www\.)?([^\.]+)\.example\.com$ [NC]
                RewriteRule ^$ /process.php?p=%2 [QSA,NC]
                RewriteCond %{REQUEST_FILENAME} !^$ [NC]
                RewriteRule ^(.*) http://www.example.com/$1 [P]
        </Directory>
</VirtualHost>

これは、このexample.comファイルを使用して別のドメインのルートディレクトリを.htaccessに正常にリダイレクトすることに基づいています。このファイルには、process.phpが組み込まれ、他のすべてのリクエストがexample.comのルートに送信されます。

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

# Check the request isn't an existing file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ http://www.example.com/process.php [P]
RewriteCond %{REQUEST_FILENAME} !^$ [NC]
RewriteRule ^(.*) http://www.example.com/$1 [P]

また、この.htaccessテストから、サブドメインを変数としてprocess.phpにリダイレクトするために実行しましたが、上記のcssの例など、他のファイル要求はキャッチされませんでした。

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_Host} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_Host} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /process.php?p=%2 [QSA,NC]

アップデート1

私は(一見)2番目の仮想ホストエントリの代わりに以下を使用することである程度の成功を収めました。サブドメインを使用すると、process.phpページが出力されます。パターンマッチングはその点で機能しているように見えますが、実際のprocess.phpは、予期されるサブドメインを文字列としてではなく、空の変数を受け取ります(process.php?p=%2の場合)。

<VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html

        <Directory /var/www/example.com/public_html>
        Options FollowSymLinks
        AllowOverride all
        Require all granted
        RewriteEngine on
        RewriteBase /

        RewriteCond %{HTTP_Host} !^www\.example\.com$ [NC]
        RewriteCond %{HTTP_Host} ^(www\.)?([^\.]+)\.example\.com$ [NC]
        RewriteCond %{REQUEST_URI} ^/$
        RewriteRule ^$ /process.php?p=%2 [NC,QSA]
        </Directory>
</VirtualHost>

アップデート2

私はこれを回りくどい方法で解決しましたが、それが最もエレガントな方法であるかどうかはわかりません。

上記のpdate 1コードを使用すると、クエリ文字列がまだ追加されているのに、%2ページのGETprocess.phpを受信して​​いないことがわかりました。私のコードの指示に従って、URLがブラウザへのURLにp=abc変数を表示しないにもかかわらず、内部URLがそれらを渡したと誤って想定した可能性があります。それでも、process.phpPHP$_SERVER['HTTP_X_FORWARDED_Host']を使用してサブドメインを文字列として判別し、最初のアイデアと同じようにページ上の変数として使用できることに気付きました。

3
biscuitstack
RewriteCond %{HTTP_Host} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_Host} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /process.php?p=%2 [NC,QSA]

%2後方参照は設定されていませんでした。これは、最後に一致した CondPattern(RewriteCondパターン)の2番目にキャプチャされたグループへの後方参照であるためです。最後に一致したCondPatternは^/$であり、キャプチャされたグループがないため、%2は常に空です。

その3番目のRewriteCondディレクティブは、とにかく不要に見えます。これはすでにRewriteRuleパターン^$によってチェックされています(ディレクトリごとのコンテキストでは、ディレクトリプレフィックスが削除されているため、これは正しいです)。

最初のRewriteCondディレクティブも不要に見えます。 www.example.comのリクエストは、最初のVirtualHostによってキャッチされるため、このVirtualHost内のhostnamewww.example.comになることはなく、このディレクティブは常にtrueと評価されます。

私はこれを次のように書き直します:

RewriteCond %{HTTP_Host} ^(?:www\.)?([^.]+)\.example\.com$ [NC]
RewriteRule ^$ process.php?p=%1 [QSA]

私は最初のgroup非キャプチャーを作成しました。 (?:www\.)-?:は、キャプチャしないようにします。したがって、実際のサブドメインに対してのみ%1を取得します。また、文字クラスでドットをエスケープする必要はありません(リテラルドットと一致させるため)。ここでは、NCRewriteRuleフラグは不要です。

RewriteRuleディレクティブでURLパスを指定したため、RewriteBasesubstitutionのスラッシュプレフィックスも削除しました。

これはabc.example.com/を書き換えるだけです。ドキュメントルートのリクエスト。

次に、ベース/ルートレベル外のサブドメインからのファイルのリクエストは、サブドメインのない標準ドメインのルートパスから取得するように書き換える必要があります。したがって、abc.example.com/css/style.cssexample.com/css/style.cssから取得する必要があります。

abc.example.com/example.com/はファイルシステム上の同じ場所を指しているので、ここで何かをする必要があるのでわかりませんか? example.com/css/style.cssは、abc.example.com/css/style.cssと同じファイルを指している必要があります。

ドキュメントルート内の他のファイルはどうですか?例えば。 abc.example.com/file。現時点では、これはCSSファイルの場合と同じように変更されません。

1
MrWhite