🐥
[備忘録14]作って学ぶブラウザのしくみ / HTTPを実装する/ ホスト名からIPアドレスへの変換
DNSを使用してドメイン名からIPアドレスに変換することを名前解決という。特に、ドメイン名からIPアドレスへの変換は正引きと呼ばれ、IPアドレスからドメイン名への変換は逆引きと呼ばれる。
HTTPリクエストではIPアドレスをもとに送り先を特定する。
DNSによる正引きによって、URLに含まれているホストからIPアドレスを知ることができる。ホストやIPアドレスの対応は、DNSサーバによって提供される。Webサイトやnslookupコマンドなどのツールを使うことによってDNSサーバにアクセスし、IPアドレスを知ることができる。
※DNSはRFC1035,1034の仕様に基づいて実装されている。
WasabiOSではIPアドレスを知るためにlookup_hostというAPIを提供している。ブラウザ側の実装では、単にこのAPIを使用するだけでいい。
HttpClient構造体のget関数は以下のようになる
impl HttpClient {
pub fn get (&self, host: String, port : u16, path: String) -> Result<HttpResponse, Error> {
let ips = match lookup_host(&host) {
Ok(ips) => ips,
Err(e) => {
return Err(Error::Network(format!("Failed to find IP addresses: {:#?}",e)))
}
};
if ips.len() < 1 {
return Err(Error::Network("No IP addresses found".to_string()))
}
}
}
ソケットアドレスの定義
ソケットアドレスとはTCP/IPネットワーク上で通信する際に、送信元や送信先を認識するために使用されるアドレス。通常IPアドレスとポート番号の組み合わせで表される。例えばブラウザがwebサーバにHTTPリクエストを送信する際に、ソケットアドレスはwebサーバのIPアドレスやHTTPにおける標準ポート番号である80番ポートとなる。
SOcketAddr構造体はnoliライブラリで定義されている。
#[derive(Debug)]
pub struct SocketAddr {
addr: IpV4Addr,
port: u16,
}
httpClient構造体のフィールドでSocketAddrの変数を定義する。
httpClient構造体は以下のような実装になる
impl HttpClient {
pub fn get (&self, host: String, port : u16, path: String) -> Result<HttpResponse, Error> {
let ips = match lookup_host(&host) {
Ok(ips) => ips,
Err(e) => {
return Err(Error::Network(format!("Failed to find IP addresses: {:#?}",e)))
}
};
if ips.len() < 1 {
return Err(Error::Network("No IP addresses found".to_string()))
}
let socket_addr: SocketAddr = (ips[0], port).into();
}
}
Discussion