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://')
JavaScript の URL の挙動
{
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番目のセミコロンが取り除かれた以外は全く同じである。