- PR -

クライアントから URL がディレクトリかどうかを知る方法

投稿者投稿内容
Shane
大ベテラン
会議室デビュー日: 2003/06/06
投稿数: 132
お住まい・勤務地: Vancouver, BC
投稿日時: 2005-01-08 03:42
クライアントから URL がディレクトリかどうかを知る方法を探しています。

例えば、
http://www.abc.com/hoge
とアクセスしたとき、
・hoge はディレクトリで実際は http://www.abc.com/hoge/index.html にアクセスしているのか
・hoge はファイルで実際に http://www.abc.com/hoge にアクセスしているのか
をクライアント側で知る方法はありますでしょうか?

よろしくお願いします。
Mattun
ぬし
会議室デビュー日: 2004/08/10
投稿数: 1391
投稿日時: 2005-01-08 08:26
引用:

例えば、
http://www.abc.com/hoge
とアクセスしたとき、
・hoge はディレクトリで実際は http://www.abc.com/hoge/index.html にアクセスしているのか
・hoge はファイルで実際に http://www.abc.com/hoge にアクセスしているのか
をクライアント側で知る方法はありますでしょうか?


WebサーバのHTTPレスポンス内で、Content-Locationを返してくる場合、
「このデータの場所はindex.htmlである」みたいな情報が含まれていることになるので
判別可能ですが、そういう情報をWebサーバが送ってくれない限り、判別しようがありません。

そして、大抵のWebサイトにおいて、Content-Locationは送信してくれません。
http://www.debian.org/
あたりが、意図的にContent-Locationを返してたと記憶してますし、
今見てみたらやっぱり返してくれました。
ここはコンテントネゴシエーションを使っており、HTTPリクエストの中のAccept-Languageを
元に、提供するコンテンツの言語を切り替えてます。
例えば、
http://www.debian.org/
に対してAccept-Language: ja
ってリクエストを送った場合、実際に返されるデータは
http://www.debian.org/index.ja.html
のものであり、HTTPレスポンスヘッダにも
Content-Location: index.ja.html
ってのが含まれますので、判別可能です。


あとは、実際のWebサーバとのやり取りを、スニファなんかで覗いてみれば
違いが分かるんじゃないかと。

[ メッセージ編集済み 編集者: Mattun 編集日時 2005-01-08 08:30 ]
Shane
大ベテラン
会議室デビュー日: 2003/06/06
投稿数: 132
お住まい・勤務地: Vancouver, BC
投稿日時: 2005-01-08 08:49
書き込みありがとうございます。
つまりたいていのサーバにおいてその判別は無理ということですね。

今、指定ウェブページのリンク(<a href> <img src> <form action> など)を
取得するアプリを書いているのですが、
ユーザが上記のようにディレクトリに / をつけずに URL 指定した際、
そのページから相対指定しているリンクがあった場合、
そこがディレクトリなのかファイルなのかがわからなく
そのリンクの絶対パスが取れなく困っていました。

クライアントには事情を説明し、ディレクトリの際は明示的に
/ をつけて貰うようにします。
Mattun
ぬし
会議室デビュー日: 2004/08/10
投稿数: 1391
投稿日時: 2005-01-08 09:09
引用:

今、指定ウェブページのリンク(<a href> <img src> <form action> など)を
取得するアプリを書いているのですが、
ユーザが上記のようにディレクトリに / をつけずに URL 指定した際、
そのページから相対指定しているリンクがあった場合、
そこがディレクトリなのかファイルなのかがわからなく
そのリンクの絶対パスが取れなく困っていました。



ただ、
引用:

・hogeはファイルで実際に http://www.abc.com/hoge にアクセスしているのか


ってケース自体が稀なんじゃないかと思います。
大抵のWebサイトでは、各ファイルに拡張子つけてますし。
あえてつけてないところは見たことがあるけど、1個所だけしか記憶にありません。
http://www.ne.jp/asahi/minazuki/bakera/html/hatomaru

大きな選択肢としては、http://www.example.com/hogeに対し、
1. hogeを問答無用でファイルと見なす
2. hogeを問答無用でディレクトリと見なす(または勝手に/を補完する)
3. hogeをディレクトリとみなすかファイルと見なすかユーザに確認させる(ソフトのオプションとして実装する)
  (または/を補完するか確認させる)
あたりになるかと思います。
3.が無難でしょうが、多くのWebサイトの現状を見る限りだと、2.でもほとんど
問題でないんじゃないかと思います。

あと、理屈だけで言ってしまえば、
http://www.example.com/hoge.html
ってURLに対し、hoge.htmlがディレクトリであり、
http://www.example.com/hoge.html/index.html
が返される可能性すら否定できません。

そういや、同様の動作をするプログラムは他にも存在すると思うんですけど、
どういう実装になってるんですかね。wgetとか。

[ メッセージ編集済み 編集者: Mattun 編集日時 2005-01-08 09:23 ]
Shane
大ベテラン
会議室デビュー日: 2003/06/06
投稿数: 132
お住まい・勤務地: Vancouver, BC
投稿日時: 2005-01-08 09:54
引用:

Mattunさんの書き込み (2005-01-08 09:09) より:

あと、理屈だけで言ってしまえば、
http://www.example.com/hoge.html
ってURLに対し、hoge.htmlがディレクトリであり、
http://www.example.com/hoge.html/index.html
が返される可能性すら否定できません。



そこが懸念のポイントで、Mattun さんのおっしゃった選択肢「2」が取れない理由でもあります。
(hoge がディレクトリだと決めるルールが拡張子があるかないかぐらいだが、拡張子のあるディレクトリは実際に存在する)

ちいにぃ
大ベテラン
会議室デビュー日: 2002/05/28
投稿数: 244
投稿日時: 2005-01-08 10:29
ブラウザもおなじことをやってるはずなので、ブラウザの挙動を見てみました。
(Webアクセスをモニタする)

ディレクトリの末尾に / をつけないでHTTPリクエストを行うと、
レスポンスでコード 301 と Location が返って来るので、
これで判断できないでしょうか?

1) ディレクトリらしきものに / をつけないでHTTPリクエストする。
 GET /somewhere/unknown HTTP/1.1

2) unknownがディレクトリであれば、次のレスポンスが返ってくる
 HTTP/1.x 301 Moved Permanently
 Location: http://example.jp/somewhere/unknown/

3) Location で示されたURL (/付加されたもの) に再度HTTPリクエストする
 GET /somewhere/unknown/ HTTP/1.1
Shane
大ベテラン
会議室デビュー日: 2003/06/06
投稿数: 132
お住まい・勤務地: Vancouver, BC
投稿日時: 2005-01-12 08:01
引用:

ちいにぃさんの書き込み (2005-01-08 10:29) より:
ディレクトリの末尾に / をつけないでHTTPリクエストを行うと、
レスポンスでコード 301 と Location が返って来るので、
これで判断できないでしょうか?



レスありがとうございます。

現在 Java でコードを書いていて、java.net.URL:penConnection() で
HTTP 接続すると、その辺りを自動的に処理してしまうようで、
301 を拾うことができないようでした。

そこで Socket で HTTP を自分で話すのはめんどいと思いましたが、
java.net.HttpURLConnection::setFollowRedirects() で、
301 の際に自動リダイレクトしないように設定できることを知り、
試してみました。

結果は、
http://www.yahoo.com → 200: OK
http://www.yahoo.com/ → 200: OK

だめでした。
サーバエイリアスや https へのリダイレクトは止まってくれて
301 を返すようなんですが。。。イマイチ中途半端な実装ですね。

少し Java に話がそれてしまいましたが、
IP Network 板的な結論は、ちいにぃさんのおっしゃる通り、

・URLアクセスし、レスポンスコードで 301 が帰った際は、
 クライアント側で実はディレクトリではないかと疑い、
 "/" を末尾に(元々付いていない場合)付けてリトライする。
A:うまくいった=URLはディレクトリだった
B:うまくいかなかった=本当に301だった
(うまくいったの解釈があいまいですがそこは適当に読んでください)

といったところでしょうか?
ちなみに今回はそこまでする必要はなかったので、
ディレクトリ(サイトトップ以外)には / を入れてください
ということでお客さんに納得してもらいました。

[ メッセージ編集済み 編集者: Shin 編集日時 2005-01-12 08:07 ]

[ メッセージ編集済み 編集者: Shin 編集日時 2005-01-12 08:16 ]
okutin
ベテラン
会議室デビュー日: 2003/12/11
投稿数: 98
お住まい・勤務地: 広島
投稿日時: 2005-01-12 09:23
こんにちは。

引用:

Shinさんの書き込み (2005-01-12 08:01) より:

・URLアクセスし、レスポンスコードで 301 が帰った際は、
 クライアント側で実はディレクトリではないかと疑い、
 "/" を末尾に(元々付いていない場合)付けてリトライする。
A:うまくいった=URLはディレクトリだった
B:うまくいかなかった=本当に301だった
(うまくいったの解釈があいまいですがそこは適当に読んでください)




コード301などは正しいURLが返されますので、それを使用する(実際にアクセスするなり、初回アクセス時のURLと比較を行うなり)のが良いと思います。
とりあえず"/"をつけてみるというのはよろしくないと思います。

スキルアップ/キャリアアップ(JOB@IT)