some points for HTTP client on native applications (1)

はじめに

HTTP は利用頻度が高いネットワークプロトコルの一つだと思います。HTTP サーバを書くことはそんなに多くないと思いますが、HTTP クライアントは何らかの形で利用したり実装したりしたことがある人は多いのではないでしょうか。今回は、ネイティブアプリでの HTTP クライアントを利用・実装することに焦点を絞ります。


多少経験のあるプログラマなら、HTTP クライアントを自分で実装したいとはあまり思わないはずです*1。HTTP は、仕組みとしてはシンプルですがいざ実装しようとすると中々大変です。ソケットを使ってデータ転送をする処理や、HTTP リクエストの妥当性検証*2や生成、レスポンスの解析、ステータスコードの正しいハンドリング、データのバッファリング・・・。さらに、国際化ドメイン名、キープアライブ、リダイレクト、認証*3、プロキシ解決*4、プロキシ越え、HTTPS なんかも考え始めると頭が爆発しそうになるからです。フルスタックの HTTP クライアントを実装するのは非常に大変です。

ライブラリを使おう

そうなると、偉大なる先達が作ってきたものを利用しようという方向に頭が働きます。幸い、HTTP クライアントのライブラリは数多く存在します。

libcurl を使おう

大抵の場合、libcurl で事足ります。マルチプラットフォーム対応している優れものです。ただし、libcurl には以下の機能・問題がないので注意が必要です。


というわけで、プロキシに Digest 認証が必要な環境で HTTPS 通信がしたい、という場合、現状の libcurl を利用することはできません。上記で挙げたプラットフォーム標準搭載のライブラリは、どれもうまく処理してくれます。

プロキシ解決

プロキシ環境をサポートする場合、まず最初にやるべきことはプロキシ解決です。プロキシ解決は、どのプロキシサーバを利用するかを決定します。ないならないで利用しません。Internet ExplorerGoogle Chrome を利用している方なら、ステータスバーに「プロキシを解決しています」というメッセージが表示されていることに気づいている方もいると思いますが、あれのことですね。


プロキシ解決は、アプリケーション固有のプロキシ設定を用いる場合と、プラットフォームが持つ設定を踏襲する場合があります。前者はここでは特に触れず、後者に焦点を絞ります。


WindowsMac OS X では、プロキシ解決を以下の手順で行うことができます。

  1. プロキシの自動検出
  2. プロキシの自動構成


プロキシの自動検出は、Web Proxy Autodiscovery Protocol ( WPAD ) に基づいて行われます。大雑把にいうと、DHCP または DNS サーバに置いてある自動構成スクリプトファイルを持ってくる感じです。


WinINet なら、DetectAutoProxyUrl() を呼び出すことでこれが行えます。オプションとして、DHCP を用いるか、DNS の A レコードを用いるか、どちらもかを選択できます。呼び出すと、以下のような通信が発生します。

  • DHCP を用いる場合
    • DHCP INFORM パケットをクライアントから DHCP サーバに送信する
    • DHCP ACK パケットを DHCP サーバから DHCP クライアントに送信する
    • DHCP ACK パケットに含まれる URL のファイルをダウンロードする


DHCP サーバがこれに応答するように構成されていない場合、 この API の実行に10秒以上かかることがあります。エラーコードは ERROR_NO_TOKEN ( 1008 ) などです。また、1 秒程度で完了することもあります。

DNS サーバがこれに応答するように構成されていない場合、 この API の実行に 5 秒程度かかることがあります。エラーコードは WSAHOST_NOT_FOUND ( 11001 ) などです。


自力で実装するなら、ちょっとした DHCP クライアントを書く必要があるってことですね。また、自動構成スクリプトのダウンロード自体にも HTTP が必要という罠があります。


こうして、自動検出が完了したら次は自動構成スクリプトを解釈します。

次回へ続きます。

*1:ソケット覚えたての頃ならともかく

*2:正しく実装しなければ HTTP ヘッダインジェクションなどをまねきます

*3:Basic なら Base64、Digest なら MD5、NTLM なら DES が必要になります

*4:WPAD、自動構成スクリプトなど