http://http://http://@http://http://?http://#http:// を理解する
少し前に話題になっていた、http://http://http://@http://http://?http://#http://
が有効な URL であるというツイートに対して、各パーサーによって解釈されるのか等が解説されている記事。
Wikipedia の Uniform Resource Locator によると、HTTP や FTP のように IP 接続が行われるプロトコルでは //<user>:<password>@<host>:<port>/<url-path>?<query-string>
のような形式が用いられる。
そのため http://http://http://@http://http://?http://#http://
は、最初の http:
がプロトコルで、次の //
から @
までが認証に使われる <user>:<password>
に当たり、 http
が ID で //http://
がパスワードに当たる。
残りの http://http://?http://#http://
は、<query-string>
に当たる ?
以降の ?http://
が search で、#
から後ろの #http://
が hash に該当する。
残った http://http://
が <host>:<port>/<url-path>
に該当するので、http
が <host>
で ://http://
が <url-path>
に該当するはずである。
理論上はこちらのように振る舞うはずだが、実際の URL パーサーの挙動は少々異なるようで、IETF RFC 3986 や WHATWG URL Specification とも微妙なズレがある。
Python’s urllib の挙動
ParseResult(scheme='http',
netloc='http:',
path='//http://@http://http://',
params='',
query='http://',
fragment='http://')
URL
の挙動
JavaScript の {
hash: "#http://",
host: "http",
hostname: "http",
href: "http://http//http://@http://http://?http://#http://",
origin: "http://http",
password: "",
pathname: "//http://@http://http://",
port: "",
protocol: "http:",
search: "?http://",
searchParams: URLSearchParams {},
username: ""
}
Firefox および Chrome のアドレスバーに入力したときの挙動
/etc/hosts
に 127.0.0.1 http
を入力した上で、 http://http://http://@http://http://?http://#http://
をアドレスバーに入力すると、Firefox と Chrome いずれも http://http//http://@http://http://?http://#http://
に書き換えられた。2番目のセミコロンが取り除かれた以外は全く同じである。