「Apache mod rewriteメモ」の版間の差分

提供:雑廉堂Wiki
編集の要約なし
 
(同じ利用者による、間の25版が非表示)
1行目: 1行目:
== mod_rewrite ==
=== ロギング ===
<code>httpd.conf</code>に追加
LogLevel alert rewrite:trace4
ログは<code>error.log</code>に吐かれる。
sed -e 's/^\(.*\)\(\[perdir.*\)$/\2/'
== RewriteBaseとは ==
== RewriteBaseとは ==


24行目: 36行目:
  RewriteBase /abc
  RewriteBase /abc
  RewriteRule ^abc/hoge\.html piyo.html [L]
  RewriteRule ^abc/hoge\.html piyo.html [L]
```


* 例: URLを<nowiki>http://server/abc/hoge.html</nowiki>と指定した場合、表示されているURLはそのままで、<code>${DOCUMENT_ROOT}${REWRITE_BASE}/piyo.html</code>の内容が表示される。
* 例: URLを<code><nowiki>http://server/abc/hoge.html</nowiki></code>と指定した場合、表示されているURLはそのままで、<code>${DOCUMENT_ROOT}${REWRITE_BASE}/piyo.html</code>の内容が表示される。<br />この場合、URL表示は<code><nowiki>http://server/abc/hoge.html</nowiki></code>で、実際には<code>/var/www/site/abc/piyo.html</code>が表示される。
 
=== Rewriteのメカニズム ===
 
==== Aliasがない場合 ====
 
'''httpd.conf'''
 
DocumentRoot '''/var/www/html'''
 
'''/var/www/html/ore/sandbox/.htaccess'''
 
RewriteEngine On
 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
 
'''リクエストパス:<nowiki>http://example.com/ore/sandbox/aaa/zzz</nowiki>'''
:* URLのパス部分: '''ore/sandbox/aaa/zzz'''
 
# <code>mod_rewrite</code>には、<code>${DocumentRoot}+${URLのパス}</code>が渡される:
#* <code>'''/var/www/html/ore/sandbox/aaa/zzz'''</code>
# <code>.htaccess</code>のあるディレクトリまでのパスを削除
#* <code>'''<span style="color:red;">/var/www/html/ore/sandbox/</span>aaa/zzz'''</code> -> <code>'''aaa/zzz'''</code>
# <code>RewriteRule</code>条件のチェック
#* <code>^.*$</code>なのでマッチ
# パスの書き換え
#* <code>'''<span style="color:red;">aaa/zzz</span>'''</code> -> <code>'''index.php'''</code>
# 2. で除去したパスをくっつける。
#* <code>'''index.php'''</code> -> <code>'''<span style="color:blue;">/var/www/html/ore/sandbox/</span>index.php'''</code>
# ドキュメントルートを削除
#* <code>'''<span style="color:red;">/var/www/html/</span>ore/sandbox/index.php'''</code> -> <code>'''/ore/sandbox/index.php'''</code>
# 書き換えられたパスに内部リダイレクト
#* <code>'''/ore/sandbox/index.php'''</code>


## RewriteRuleとは
==== Aliasを使った時 ====


### 書式
'''httpd.conf'''


```
DocumentRoot '''/var/www/html'''
RewriteRule 置換前のパターン 置換後の文字列
Alias '''/ore/sandbox''' '''/home/ore/sandbox/html'''
```


- 置換前のパターン:リクエストされたURLとは限らず、書き換えされてきたURLも指す。
'''/home/ore/sandbox/.htaccess'''


### 説明
RewriteEngine On
 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]


- DocumentRoot
'''リクエストパス:<nowiki>http://example.com/ore/sandbox/aaa/zzz</nowiki>'''
:* URLのパス部分: '''ore/sandbox/aaa/zzz'''


```
# <code>mod_rewrite</code>には、<code>${Aliasで指定したパス}+${URLのパス}</code>が渡される:
/var/www/site/
#* <code>'''/home/ore/sandbox/html/aaa/zzz'''</code>
```
# <code>.htaccess</code>のあるディレクトリまでのパスを削除
#* <code>'''<span style="color:red;">/home/ore/sandbox/html/</span>aaa/zzz'''</code> -> <code>'''aaa/zzz'''</code>
# <code>RewriteRule</code>条件のチェック
#* <code>^.*$</code>なのでマッチ
# パスの書き換え
#* <code>'''<span style="color:red;">aaa/zzz</span>'''</code> -> <code>'''index.php'''</code>
# 2. で除去したパスをくっつける。
#* <code>'''index.php'''</code> -> <code>'''<span style="color:blue;">/home/ore/sandbox/html/</span>index.php'''</code>
# ドキュメントルートを削除
#* <code>'''/home/ore/sandbox/html/index.php'''</code> -> <code>'''<span style="color:red">/home/ore/sandbox/html/index.php</span>'''</code>
#** ところが、パスのプレフィックスが違うために取り除けない。
# 書き換えられたパスに内部リダイレクト
#* <code>'''/home/ore/sandbox/html/index.php'''</code>
#** しかしながら、<code>'''<nowiki>http://example.com/home/ore/sandbox/html/index.php</nowiki>'''</code>というパスは存在しないため、<code>'''404 Not Found'''</code>を返す。


- htmlの配置
== RewriteRuleとは ==


```
=== 書式 ===
/var/www/site/hoge.html
/var/www/site/piyo.html
```


- ルール
RewriteRule 置換前のパターン 置換後の文字列


```
* 置換前のパターン:リクエストされたURLとは限らず、書き換えされてきたURLも指す。
RewriteEngine On
RewriteRule ^/?hoge\.html$ piyo.html [L]
```


`^/?hoge\.html$`:渡ってきたURL(正規表現)を`piyo.html`で置換。`[L]`は個々で書き換えを終了するという意味。
=== 説明 ===


- URLが`hoge.html`と渡ってくるか、`/hoge.html`と渡ってくるかの違い
* DocumentRoot
  - `VirtualHost`ディレクティブの場合は、URLのパスが対象となり、先頭に`/`が付く
  - `Directory`ディレクティブや`.htaccess`の場合は、そのディレクトリからの相対パスが対象となり、先頭に`/`が付かない。


`(.*)`パターンをグループ化
/var/www/site/


```
* htmlの配置
RewriteEngine On
RewriteRule (.*) http://server/$1 [R]
```


- `(.*)`を変数`$1`で展開
/var/www/site/hoge.html
/var/www/site/piyo.html


```
* ルール
http://server1/hoge.html -> http://server/hoge.html
```


```
RewriteEngine On
RewriteEngine ON
RewriteRule ^/?hoge\.html$ piyo.html [L]
RewriteRule ^/旧ディレクトリ/(.*) /新ディレクトリ/$1
```


```
<code>^/?hoge\.html$</code>:渡ってきたURL(正規表現)を<code>piyo.html</code>で置換。<code>[L]</code>はここで書き換えを終了するという意味。
RewriteEngine On
RewriteRule ^(/somedir/.*) http://newserver/$1 [R]
```


* URLが<code>hoge.html</code>と渡ってくるか、<code>/hoge.html</code>と渡ってくるかの違い
** <code><VirtualHost></code>ディレクティブの場合は、URLのパスが対象となり、先頭に<code>/</code>が付く
** `Directory`ディレクティブや`.htaccess`の場合は、そのディレクトリからの相対パスが対象となり、先頭に`/`が付かない。


<code>(.*)</code>パターンをグループ化
RewriteEngine On
RewriteRule (.*) <nowiki>http://server/</nowiki>$1 [R]
* <code>(.*)</code>を変数<code>$1</code>で展開
<nowiki>http://server1/hoge.html -> http://server/hoge.html</nowiki>
RewriteEngine ON
RewriteRule ^/旧ディレクトリ/'''(.*)''' /新ディレクトリ/'''$1'''
RewriteEngine On
RewriteRule ^'''(/somedir/.*)''' <nowiki>http://newserver/</nowiki>'''$1''' [R]


## RwriteRuleのフラグ
== RwriteRuleのフラグ ==


^フラグ ^意味 ^説明 ^
{| class="wikitable"
|C |Chain |このルールにマッチしたら、次のルールを評価 |
|+ RewriteRuleのフラグ
|F |Forbidden |アクセス禁止(403-Forbidden)。[L]フラグと同様、以降のルールは無視。 |
!フラグ
|G |Gone |削除(410-GOne) |
!意味
|L |Last |マッチしたらRewriteを辞めます。以降のルールは無視。 |
!説明
|NC |No Case |大文字小文字を無視   |
|-
|NE |No Escape |"."、"?"、"%"などの特殊文字が"%25"のようにエンコードされるのを防ぐ |
|C
|OR |Or |RewriteCondを複数指定する場合のOr指定。指定なしならAND |
|Chain
|PT |Path Through |Rewriteを終了し、それ以外の処理に移行 |
|このルールにマッチしたら、次のルールを評価
|R |Redirect |指定したURLにリダイレクト。[R=303]のようにリダイレクトコードも付加できる。[L]同様、以降のルールは無視。 |
|-
|F
|Forbidden
|アクセス禁止(403-Forbidden)。[L]フラグと同様、以降のルールは無視。
|-
|G
|Gone
|削除(410-GOne)
|-
|L
|Last
|マッチしたらRewriteを辞めます。以降のルールは無視。
|-
|NC
|No Case
|大文字小文字を無視
|-
|NE
|No Escape
|"."、"?"、"%"などの特殊文字が"%25"のようにエンコードされるのを防ぐ
|-
|OR
|Or
|RewriteCondを複数指定する場合のOr指定。指定なしならAND
|-
|PT
|Path Through
|Rewriteを終了し、それ以外の処理に移行
|-
|R
|Redirect
|指定したURLにリダイレクト。[R=303]のようにリダイレクトコードも付加できる。[L]同様、以降のルールは無視。
|}

2018年3月20日 (火) 20:35時点における最新版

mod_rewrite

ロギング

httpd.confに追加

LogLevel alert rewrite:trace4

ログはerror.logに吐かれる。

sed -e 's/^\(.*\)\(\[perdir.*\)$/\2/'

RewriteBaseとは

書式

RewriteBase URL上のディレクトリパス


説明

  • DocumentRoot
/var/www/site/


  • htmlの配置
/var/www/site/abc/hoge.html
/var/www/site/abc/piyo.html
  • ルール
RewriteEngine On
RewriteBase /abc
RewriteRule ^abc/hoge\.html piyo.html [L]
  • 例: URLをhttp://server/abc/hoge.htmlと指定した場合、表示されているURLはそのままで、${DOCUMENT_ROOT}${REWRITE_BASE}/piyo.htmlの内容が表示される。
    この場合、URL表示はhttp://server/abc/hoge.htmlで、実際には/var/www/site/abc/piyo.htmlが表示される。

Rewriteのメカニズム

Aliasがない場合

httpd.conf

DocumentRoot /var/www/html

/var/www/html/ore/sandbox/.htaccess

RewriteEngine On
 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^.*$ index.php [NC,L]

リクエストパス:http://example.com/ore/sandbox/aaa/zzz

  • URLのパス部分: ore/sandbox/aaa/zzz
  1. mod_rewriteには、${DocumentRoot}+${URLのパス}が渡される:
    • /var/www/html/ore/sandbox/aaa/zzz
  2. .htaccessのあるディレクトリまでのパスを削除
    • /var/www/html/ore/sandbox/aaa/zzz -> aaa/zzz
  3. RewriteRule条件のチェック
    • ^.*$なのでマッチ
  4. パスの書き換え
    • aaa/zzz -> index.php
  5. 2. で除去したパスをくっつける。
    • index.php -> /var/www/html/ore/sandbox/index.php
  6. ドキュメントルートを削除
    • /var/www/html/ore/sandbox/index.php -> /ore/sandbox/index.php
  7. 書き換えられたパスに内部リダイレクト
    • /ore/sandbox/index.php

Aliasを使った時

httpd.conf

DocumentRoot /var/www/html
Alias /ore/sandbox /home/ore/sandbox/html

/home/ore/sandbox/.htaccess

RewriteEngine On
 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^.*$ index.php [NC,L]

リクエストパス:http://example.com/ore/sandbox/aaa/zzz

  • URLのパス部分: ore/sandbox/aaa/zzz
  1. mod_rewriteには、${Aliasで指定したパス}+${URLのパス}が渡される:
    • /home/ore/sandbox/html/aaa/zzz
  2. .htaccessのあるディレクトリまでのパスを削除
    • /home/ore/sandbox/html/aaa/zzz -> aaa/zzz
  3. RewriteRule条件のチェック
    • ^.*$なのでマッチ
  4. パスの書き換え
    • aaa/zzz -> index.php
  5. 2. で除去したパスをくっつける。
    • index.php -> /home/ore/sandbox/html/index.php
  6. ドキュメントルートを削除
    • /home/ore/sandbox/html/index.php -> /home/ore/sandbox/html/index.php
      • ところが、パスのプレフィックスが違うために取り除けない。
  7. 書き換えられたパスに内部リダイレクト
    • /home/ore/sandbox/html/index.php
      • しかしながら、http://example.com/home/ore/sandbox/html/index.phpというパスは存在しないため、404 Not Foundを返す。

RewriteRuleとは

書式

RewriteRule 置換前のパターン 置換後の文字列
  • 置換前のパターン:リクエストされたURLとは限らず、書き換えされてきたURLも指す。

説明

  • DocumentRoot
/var/www/site/
  • htmlの配置
/var/www/site/hoge.html
/var/www/site/piyo.html
  • ルール
RewriteEngine On
RewriteRule ^/?hoge\.html$ piyo.html [L]

^/?hoge\.html$:渡ってきたURL(正規表現)をpiyo.htmlで置換。[L]はここで書き換えを終了するという意味。

  • URLがhoge.htmlと渡ってくるか、/hoge.htmlと渡ってくるかの違い
    • <VirtualHost>ディレクティブの場合は、URLのパスが対象となり、先頭に/が付く
    • `Directory`ディレクティブや`.htaccess`の場合は、そのディレクトリからの相対パスが対象となり、先頭に`/`が付かない。

(.*)パターンをグループ化

RewriteEngine On
RewriteRule (.*) http://server/$1 [R]
  • (.*)を変数$1で展開
http://server1/hoge.html -> http://server/hoge.html
RewriteEngine ON
RewriteRule ^/旧ディレクトリ/(.*) /新ディレクトリ/$1
RewriteEngine On
RewriteRule ^(/somedir/.*) http://newserver/$1 [R]

RwriteRuleのフラグ

RewriteRuleのフラグ
フラグ 意味 説明
C Chain このルールにマッチしたら、次のルールを評価
F Forbidden アクセス禁止(403-Forbidden)。[L]フラグと同様、以降のルールは無視。
G Gone 削除(410-GOne)
L Last マッチしたらRewriteを辞めます。以降のルールは無視。
NC No Case 大文字小文字を無視
NE No Escape "."、"?"、"%"などの特殊文字が"%25"のようにエンコードされるのを防ぐ
OR Or RewriteCondを複数指定する場合のOr指定。指定なしならAND
PT Path Through Rewriteを終了し、それ以外の処理に移行
R Redirect 指定したURLにリダイレクト。[R=303]のようにリダイレクトコードも付加できる。[L]同様、以降のルールは無視。