tl;dr
- リクエストURLのpathを
/foo///bar
のように設定した場合、そのレスポンスはサーバの実装によって異なり、面白い挙動をする実装もある - 連続した
/
をpathに含んだURLもRFC 3986に違反しない
URLとURI
URIは、URLとURNに分類される。
つまり、URLはURIの部分集合である。
URLを含む、URIの仕様はRFC 3986にある。
URIの構成
RFC 3986の3章には、以下のURI全体の構成図がある。
この記事ではpathに注目している。
foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment
URIのpath
pathについては3.3章に記述がある。
pathは、authorityの後の /
から始まり、queryの先頭である?
かfragment先頭である#
がくる直前までの部分のことである。
queryもfragmentもそのURIに含まれていない場合は、URIの終端がpathの終端である。
また、pathは空であることもありえる。(例: https://example.com#hoge)
本稿に関係のある部分だけ、pathについてのABNFを抜き出すと、次のようになる。
path = path-abempty / 省略
path-abempty = *( "/" segment )
segment = *pchar
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
pathは1つの/
で開始し、続くsegmentには/
は含まれていない。
segmentは空でもよいため/////
のようなpathも仕様に反してはいない。
その一方で、Linuxのpath探索のように、/path////to/file
を path/to/file
と解釈するといった規定はない。そのため、URIにおいて/
と //
は別物である。
実際の挙動
いくつかのサイトに対して、path連続した /
を含むリクエストを送って確認する。
正常なpathに対し、先頭と末尾に余分な /
を追加する。
Firefoxの開発者ツールのネットワークの項目を利用して実験する。
MDN Web Docs
URL | status code | location |
---|---|---|
https://developer.mozilla.org/ja/docs/Web | 200 | |
https://developer.mozilla.org////ja/docs/Web | 302 | /ja/docs/Web |
https://developer.mozilla.org/ja/docs/Web// | 301 | /ja/docs/Web_ |
https://developer.mozilla.org/ja/docs/Web/ | 302 | /ja/docs/Web |
IETF Datatracker
※ RFCのページ
Qiita
URL | status code | location |
---|---|---|
https://qiita.com/tags/url | 200 | |
https://qiita.com/tags/url/ | 301 | http://qiita.com/tags/url |
https://qiita.com/tags/url// | 301 | http://qiita.com/tags/url |
https://qiita.com///tags/url | 200 |
URL | status code | location |
---|---|---|
https://www.google.com/search?q=rfc3986 | 200 | |
https://www.google.com/search/?q=rfc3986 | 404 | |
https://www.google.com/search//?q=rfc3986 | 404 | |
https://www.google.com//search?q=rfc3986 | 200 |
GitHub
URL | status code | location |
---|---|---|
https://github.com/github/docs | 200 | |
https://github.com/github/docs/ | 200 | |
https://github.com/github/docs/// | 200 | |
https://github.com////github/docs | 200 |
まとめ
はじめに、RFC 3986の3章を参照しつつ、URIのpathについて仕様を確認した。
Linuxのpath探索とは異なり,複数連続した/
(例: /////
) を1つの/
とみなすと定まってはいなかった。
次に、現実のWebサービスのpathに対する処理を何件か調査した。
結果、全てStatus Code 200で同じコンテンツを返すサービス、1つでも余分に/
があると404を返すサービス、301や302で正規のURLへリダイレクトさせるサービスがあった。また、先頭に/
を挿入する場合と末尾に挿入する場合で挙動が異なるサービス多かった。
特徴的であったのがMDNで、pathに含まれていると//
を_
に置き換えてリダイレクトされる(リダイレクト先で404になる)。
多数の/
を加えた場合、末尾から4つずつ (////
を__
に)置き換え、連続した//
がpathからなくなるまで再帰的にリダイレクトし続ける。
今回はWebサービスを対象に実験をしたが、サーバアプリケーションを対象に実験をしてみると面白いかもしれないと思った。