携帯端末は端末が移動することを前提としているため主に無線ネットワークを使用する。そのため電波が届かなくなり、通信が切断されることがある。一方で、現在のWeb技術は常時接続を前提としているため、通信が切断される無線ネットワークについて考慮されていない。
よって、本研究では図1のように端末内にキャッシュを保有することで無線ネットワーク切断時でもWebコンテンツの閲覧を可能にし、通信を安定化させるシステムを提案する。加えて、ネットワーク切断時に閲覧可能なWebコンテンツをWebコンテンツの制作者がコントロール可能にする。これにより、ユーザが無線ネットワーク切断時に閲覧するWebコンテンツを事前に提供するサービスや、属性によってユーザにキャッシュさせるWebコンテンツを変化させるサービスを行うことが可能となる。
本研究では通信が不安定である無線ネットワークにおいてネットワークアプリケーションサービスの安定化を目的とする。例えば、通信が切断された時に携帯端末が特定のWebコンテンツを安定して閲覧可能となるようにする。ここで、無線ネットワークの切断時には携帯端末はインターネットにアクセスできないが、端末内にキャッシュを保有していればキャッシュを元にWebコンテンツを表示出来る。つまり、キャッシュを保有することでWebコンテンツの閲覧をより安定化できる。
端末内にキャッシュを保有すれば無線ネットワーク切断時でもWebコンテンツの閲覧が可能になる。本研究ではWebコンテンツの制作者がキャッシュさせるWebコンテンツをコントロールできるようなシステムとして、ローカルProxyサーバを利用し、さらにWebコンテンツにパラメータを付加してキャッシュコントロールを実現する。これにより、Webコンテンツの制作者側では各Webコンテンツにパラメータを付加することでユーザの携帯端末にキャッシュさせるWebコンテンツを指定させることができ、ユーザ側ではローカルProxyサーバを利用することで無線ネットワーク切断時でも接続時と同じようにWebコンテンツの閲覧が可能となる。
本研究で提案するキャッシュコントロールは従来のキャッシュと様々な違いがある。従来のキャッシュコントロールとしてはHTTP/1.1で実装されているHTTPヘッダに付加できるCache-Control要素がある。このCache-Control要素をHTTPヘッダに付加する方法として、HTMLによるmetaタグの利用があるが、全てのサーバがこのmetaタグからHTTPヘッダを生成する保証は無い。また、metaタグでは参照先のコンテンツに対するHTTPヘッダを生成することは不可能である。加えて、参照先コンテンツのキャッシュコントロール実現のためにHTTPヘッダ生成をHTTPサーバの設定から行うことができるが、コンテンツの制作者が簡単に設定できるとは限らない。よって、本研究で提案する方式はHTMLにパラメータを付加することで各コンテンツに対してのキャッシュコントロールが可能となり、制作者にとっても簡単にキャッシュコントロールを設定できる方式となっている。
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="有効期限">
本研究では携帯端末上にローカルProxyサーバを設置する。こうすることで従来は直接ネットワークの通信を行っていたWebブラウザにおいてネットワークの通信がローカルProxyサーバとの通信に置き換わる。このようにすると、無線ネットワーク切断時はこのローカルProxyサーバの保有するキャッシュにアクセスすることができるため、WebブラウザによるネットワークアクセスがローカルProxyからのディスクアクセスに置き換わる。これにより、ネットワークを仮想ストレージ化されたサービスと見なせれば、ローカルProxyを導入するだけで、仮想ストレージを実現できる。
コンテンツによっては、キャッシュの効果があまり無いと思われる状況が考えられる。一つ目は変化度が高いコンテンツ(株価情報など更新頻度が高い時)、二つ目は閲覧しているコンテンツとは関連性の無いコンテンツ(経済コンテンツ閲覧中のスポーツコンテンツなど)、三つ目は重要度が低いコンテンツ(背景の装飾や広告など)である。これらに対してはキャッシュをするべきかどうかのコントロールが必要であると考えられる。ここで、キャッシュコントロールのパラメータとして次の3つを用いることとする。一つ目は変化度を表すパラメータ「variability」、二つ目は属性を表すパラメータ「keyword」、三つ目は重要度を表すパラメータ「priority」、これらのパラメータを使用してキャッシュするコンテンツのコントロールを行う。それぞれのパラメータは次の様になる。
キーワードを指定する。各キーワードに対して「0.1~1.0」までの値を付ける事が出来る。値を指定するときは「キーワード=」の後に指定する。未指定時は「0.1」となり、キーワードはカンマで区切ることにより複数指定可能である。
重要度を指定する。範囲は「1~5」となり、未指定時は「1」となる。
変化の度合いを指定するが、数値と単語で指定する2通りの指定方法がある。値の範囲は「1~5」となり、単語では値の低い順に「constant, stable, variable,kaleidoscopic, throwaway」となる。未指定時は「variable及び3」の値と同値となる。
keyword | priority | variability | ||
---|---|---|---|---|
数値 | 単語 | |||
範囲 | 0~1.0 | 1, 2, 3, 4, 5 | 1 | constant |
2 | stable | |||
3 | variable | |||
4 | kaleidoscopic | |||
5 | throwaway | |||
未指定時 | 0.1 | 1 | 3 | variable |
使用例 | keyword:東京=0.5 | priority:3 | variability:3 | variability:variable |
HTMLドキュメントにコンテンツのキャッシュコントロールパラメータを付加するが、コンテンツにはHTMLコンテンツそのものとリンク要素として関連付けられたコンテンツの2種類がある。ここで、HTMLコンテンツそのものに対してはMETAタグを用いたパラメータの付加を行う。一方、リンク要素として関連付けられたコンテンツはURLに情報を付加する。具体的にはクエリの形式を用いたパラメータの付加を行う。このクエリの形式においてパラメータの付加を明確化する識別文字を使用する。これにより、Webサーバにこのクエリの形式のパラメータが送信されてもWebサーバ側では理解できないクエリとして無視されることが期待できるため、通信に影響は無いと考えることができる。
METAタグ、URLクエリに付加するパラメータ書式及び記入例は図の様になる。
<meta name="要素" content="値">
METAタグに付加するときはname要素には「keyword, priority, variability」のパラメータ要素を、content要素には「東京=0.3, 3, stable」などの値要素が入る。
(例)
<meta name="keyword" content="東京=0.6,秋葉原=0.9">
<meta name="priority" content="3">
<meta name="variability" content="stable">
<a href="images/logo.gif?tdu-cache-control=要素:値>リンク</a>
上記のようにURL クエリに識別文字として「tdu-cache-control=」を付加した上で、要素と値はコロンで区切る。また、セミコロンで区切ることにより、複数のパラメータ要素を連続して指定することが出来る。
(例)
<a href="images/logo.gif?tdu-cache-control=keyword:大学=0.7,電気=0.5;priority:2;variability:5">TDU(先読みリンク画像)</a>
URLクエリ | METAタグ | ||
---|---|---|---|
name | content | ||
keyword要素 | keyword:東京=0.6 | keyword | 東京=0.6 |
priority要素 | priority:3 | priority | 3 |
variability要素 | variability:3 | variability | 3 |
パラメータが付加されたHTML ドキュメントをローカルProxyが読み取る際に、このHTML ドキュメントにリンクとして関連付けられているコンテンツをあらかじめ先読みしてキャッシュとして保存しておくことが出来る。これにより、無線ネットワークの切断時にキャッシュから読み込むことで未閲覧のコンテンツをスムーズに閲覧できる。また、切断時にWebブラウザが要求するキャッシュを保有していない場合は通常エラーとなるが、重要度が低いコンテンツは無くても困らないためダミーコンテンツに置き換える。よって、ローカルProxyサーバがする動作は次の様に「キャッシュ、先読み、ダミー」の3つの動作を行う。
これから閲覧する | 閲覧したい | 非重要 | |
---|---|---|---|
動作 | 先読み | キャッシュ | ダミー |
「キャッシュ、先読み、ダミー」の動作を行うために「keyword, priority, variability」の各パラメータ値の組み合わせと動作を対応付ける必要がある。まず、関連性の高いコンテンツはkeyword値が高くなるため、これから閲覧する可能性が高い。そのためkeyword値が0.6以上の時はコンテンツの先読みと関連付けることとする。次に、非重要なコンテンツはpriority値が低いため、2以下のときはダミーと関連付けることとする。最後に、切断時に閲覧したいコンテンツは変化度が低いことが前提となるため、variabilityは2以下とする。また、この時重要度が高いコンテンツ、又は関連性の高いコンテンツが閲覧したいコンテンツとなるため、priorityが3以上、又はkeyword値が0.6以上のコンテンツをキャッシュと関連付けることにする。以上により、パラメータと動作の関係は次の様になる。
先読み | キャッシュ | ダミー | ||
---|---|---|---|---|
keyword | 0.6以上 | 0.6以上 | 任意 | 任意 |
priority | 任意 | 任意 | 3以上 | 2以下 |
variability | 任意 | 2以下 | 任意 |
本研究ではパラメータによるキャッシュコントロールを実装したProxyサーバをJava言語を用いて開発する。開発における基礎知識を以下に記述する。
ProxyサーバはWebブラウザとWebサーバ間で代理の働きをするので、HTTPサーバとHTTPクライアントの機能がある。よって、それぞれを作成して結合すればProxyサーバを作成できる。
HTTPサーバ、及びHTTPクライアントを作成する上でHTTP(Hypertext TransferProtocol)の通信について知る必要がある。HTTPはヘッダー、ボディーで組になったデータを転送してやりとりする。ヘッダーには要求のリクエストヘッダーと応答のレスポンスヘッダーがある。それぞれのヘッダー内容は多少異なるが、主に「要求(応答)、転送するデータサイズ、コンテンツの種類、環境情報」などがやりとりされる。
「http://www.google.co.jp/firefox」におけるリクエストヘッダー及びレスポンスヘッダーを実際にキャプチャした例は次の様になる。
次に、ボディーは実際にやりとりするコンテンツそのものとなる。つまり、画像なら画像データ、HTML ドキュメントならHTML ドキュメントデータがボディーとなる。このヘッダーとボディーはヘッダーの最後にヘッダーの終端を表すCRLF(キャリッジリターン、ラインフィード)のみの空行を挿入することにより分けられる。HTTP通信ではボディーは必須ではないが、ヘッダーは必須である。HTTPの通信は主に次の様になる。
この時、実際に「http://www.google.co.jp/firefox」接続時におけるリクエスト、及びレスポンスの通信内容はそれぞれ次の様になる。
リクエストヘッダはHTTPサーバに取得したいコンテンツを要求するためにHTTPクライアントが送信する。ここで、Webブラウザが直接Webサーバにリクエストを送信する時と、Proxyサーバを通してWebサーバにリクエストを送信する時ではリクエストヘッダが異なってくる。実際に「http://www.google.com/firefox」接続時において、Proxyサーバを通したときのリクエストヘッダは変化して次の様になる。
Proxyサーバを使用しない図10と使用する図12のリクエストヘッダを比較すると、主に初めのGET文のパス、及びConnectionがProxy-Connectionに変化していことが分かる
GET文
図12のGET文はURLが絶対パスとなっている。この絶対パスはProxyサーバに接続先のホストを伝達するために使用される。よって、Proxyサーバが接続先ホストを理解すればURLの絶対パスは必要なくなるため、Proxyサーバがホストを省いた図10の様な相対パスに変更する。
ProxyConnection要素
Proxy-ConnectionはConnection: Keep-Aliveの代わりに使用され、持続的接続をProxyサーバに伝達している。これも同様にProxyサーバが理解した後に元の形式であるConnection: Keep-Aliveに変更する。
よって、Proxyサーバのみが理解すればよい情報は取り除き、Proxyサーバ未使用時にWebブラウザが出すリクエストと同じリクエストをProxyサーバが送信する。リクエストヘッダの初めの1行はメソッドとなり、HTTPサーバに対して要求する動作となる。ここで、リクエストにおける主なメソッド次に示す。
GET | HEAD | POST |
---|---|---|
指定したコンテンツを要求する | レスポンスヘッダのみを要求する | データ送信(メッセージの投稿などに使用) |
リクエストボディはHTTPクライアントからデータを送信する時に使用する。リクエストボディの存在はメソッドで判別が出来る。ボディが存在する条件はPOST メソッドの時だけであり、図12の例ではGET メソッドのため、リクエストボディーが存在しないことが分かる。もし、POST メソッドの時はリクエストボディのデータサイズがリクエストヘッダに記述される。
レスポンスヘッダはHTTPクライアントから受け取った要求に対して、HTTPサーバがHTTPクライアントに送信する応答である。このレスポンスヘッダはHTTPクライアントがWebブラウザ、又はProxyサーバであっても変化しない。
また、レスポンスヘッダの初めの1行はステータスコードとなり、エラーが起きたかどうかなどがこのコード番号により判別できる。ステータスコードは3桁の数となるが、初めの数で主に次の様に分けられる。
ステータスコード | 1xx | 2xx | 3xx | 4xx | 5xx |
---|---|---|---|---|---|
内容 | Information 情報 |
Succeed 成功 |
Redirection 転送 |
Client Error クライアントエラー |
Server Error サーバエラー |
レスポンスボディはHTTPクライアントが要求したコンテンツそのものとなるが、Webサーバからコンテンツが削除された時やHTTPクライアントがコンテンツを要求しない時などはレスポンスボディを送信しない。ここで、あらかじめレスポンスボディーが存在しないと判別できる条件が有り、この条件を次に示す。
リクエストメソッド | HEAD |
---|---|
ステータスコード | 100, 101, 204, 304 |
Content-Length (レスポンスヘッダ) |
0 |
リクエストボディ、及びレスポンスボディの送信において、送信するサイズを指定してから一度に全て送信する方式と、ボディを分割して送信するサイズを指定しながらそれぞれ送信する2つの方式がある。
全てのボディを送信する時は、ヘッダの「Content-Length」要素に送信するボディサイズが記述され、ボディと一緒に送信される。基本的に、この一括送信でボディが送信されることが多い。実際の記述例は次の様になる。
ボディの分割送信はチャンク形式として送信される。チャンク形式ではヘッダの「Transfer-Encoding」要素に「chunked」が指定され、ボディサイズはボディの先頭に16進数で記述される。このボディサイズの終端にはCRLFがあり、サイズとボディが交互に複数回繰り返される。ボディの終わりはボディサイズ0が指定された時となる。また、このチャンク形式による送信方式でも一括してボディ全てを転送することが可能である。
一括送信 | 分割送信 | |
---|---|---|
ボディサイズ指定方法 | ヘッダ | ボディ |
Content-Length要素 | 先頭行 | |
サイズの値 | 10進数 | 16進数 |
ProxyサーバはHTTP クライアントとHTTPサーバを組み合わせることで作成できるため、始めにこれらを作成する。また、主な動作についてのプログラム作成方法を記述し、細かい動作については省略する。
HTTPサーバのクラスとしてProxyServer クラスを作成する。これは主にWebブラウザとのやりとりを行うため、このクラスで実装すべき機能はリクエストヘッダ及びリクエストボディの受信、レスポンスヘッダ及びレスポンスボディの送信となる。リクエストはデータが少ないのでメモリ上に格納し、レスポンスはデータが大きくなることが予想されるので保存されたファイルから送信することにする。また、メモリ上に保存する時にはProxyParameter クラスのオブジェクトに格納することにする。
ヘッダはCRLFのみの空行で終わるので、これを検出するまではヘッダとして読み込む。また、ここで「Proxy-Connection」を「Connection」に書き換える。
ボディはヘッダにContent-Lengthがあれば指定されたデータサイズ分ボディを読み込み、Transfer-Encodingでchunkedがあればボディの先頭で16進数により指定されたデータサイズ分ボディを読み込む。ただし、ボディを読み込む必要がある時は、ヘッダに「POST」メソッドがある時だけとなる。
保存されたレスポンスヘッダのファイルからデータを読み込み、そのままWebブラウザに送信する。ただし、ボディがある時はボディと一緒に送信する。
保存されたレスポンスボディのファイルからデータを読み込み、ヘッダの直後にボディを付加してそのままWebブラウザに送信する。
以上の主な動作を満たすProxyServerクラスを作成することでHTTPサーバが完成する。作成したHTTPサーバの詳細については付録2のProxyServerクラスを参照。
HTTP クライアントのクラスとしてProxyClientクラスを作成する。これは主にWebサーバとのやりとりを行うため、このクラスで実装すべき機能はリクエストヘッダ及びリクエストボディの送信、レスポンスヘッダ及びレスポンスボディの受信となる。また、受信したレスポンスヘッダ及びボディをProxyCacheクラスを使用することでファイルとして保存する。
ProxyServer クラスによってProxyParameter オブジェクトに格納されたリクエストヘッダを読み込み、Webサーバにそのまま送信する。ただし、ボディがある時はボディと一緒に送信する。
これもヘッダと同様にProxyParameter オブジェクトから読み込んでヘッダの直後に付加してWebサーバにそのまま送信する。
ヘッダの終端であるCRLFのみの行まで読み込み、ファイルとして保存する。
ヘッダにContent-Lengthがあれば指定されたデータサイズ分ボディを読み込み、Transfer-Encodingでchunkedがあればボディの先頭で16進数により指定されたデータサイズ分ボディを読み込み、ファイルとして保存する。
以上の主な動作を満たすProxyClientクラスを作成することでHTTPクライアントが完成する。作成したHTTPクライアントの詳細については付録3のProxyClientクラスを参照。また、ProxyParameterクラスについては付録4を参照。
上記で作成したProxyServer とProxyClientクラスを結びつけることでProxyサーバが作成できる。よって、これらを結びつけるためのLaunchProxy クラスを作成する。このクラスではWebブラウザとHTTPサーバ、HTTPサーバとHTTPクライアント、HTTPクライアントとWebサーバ、それぞれの接続をコントロールする。
リクエスト時
HTTPサーバはWeb ブラウザからの接続を常に待つようにする。Web ブラウザからの接続が来たら、その接続に対するHTTP クライアントのオブジェクトを生成して実行する。
レスポンス時
レスポンスヘッダ及びボディをWebサーバに送信する。Web ブラウザとHTTPサーバの接続はWeb ブラウザから切断されるまで維持する。
リクエスト時
HTTPサーバが受信したリクエストヘッダ及びボディが格納されているProxyParameter オブジェクトの参照をHTTP クライアントに渡し、HTTPサーバは一時的に停止する。ただし、新たなリクエストの待ち受けは継続して行う。
レスポンス時
HTTPサーバの動作が再開し、HTTPクライアントが保存したレスポンスヘッダ及びボディのファイルをHTTPサーバが読み込む。
リクエスト時
Webサーバにリクエストヘッダ及びボディを送信する。
レスポンス時
レスポンスヘッダ及びボディを受信後、レスポンスヘッダのConnection要素がkeep-alive以外の時はWebサーバとHTTPクライアントとの接続を切断する。
作成したLaunchProxyクラスの詳細については付録5のLaunchProxyクラスを参照。また、HTTPサーバのコントロールは付録6のLaunchServerクラスを、HTTPクライアントのコントロールは付録7のLaunchClientクラスを参照。
キャッシュを取り扱う機能はProxyCacheクラスで実現するように作成する。
キャッシュ化する対象がヘッダかボディかで書き込み方を異なるようにする。ボディの場合はそのままファイル化してキャッシュとして書き込むが、ヘッダの場合はキャッシュコントロールを行うための情報を付加できるようにオブジェクトのままシリアライズ化してキャッシュとして書き込むようにする。
キャッシュを読み込む際にボディはそのまま読み込むが、ヘッダはオブジェクトとしてファイル化されているのでオブジェクトとして読み込む。この時、このオブジェクトから付加された情報を読み取り、この情報によりキャッシュコントロールを行う。
本研究ではHTMLに付加されたパラメータによるキャッシュコントロールを実装したProxyサーバを作成するので、基本的にパラメータが付加されていないファイルは削除する。これにより、キャッシュ化の有無を操作する。
作成したProxyCacheクラスについては付録8を参照。
上記で作成したProxyサーバはWebブラウザとWebサーバを中継するだけで何の機能もない。よって、これにキャッシュコントロール機能を付加する。キャッシュコントロールを行うためのパラメータはHTML ファイルに書き込まれているので、まずはこのHTMLを解析するパーサーを作成する。
HTMLコンテンツそのものに対するパラメータはMETAタグに、参照先のコンテンツはリンク要素に付加されている。よって、まずはHTMLドキュメントのすべてのパラメータを解析する。全てのパラメータを解析した後に、先読みコンテンツであるならば先読みリストを作成する。パラメータの解析に当たってはjavax.swing.text.html.parser.ParserDelegatorクラスを使用してMETAタグ、及びアンカータグを検出し、付加されたパラメータ値を読み込むように実装する。
先読みクライアントは基本的にHTTPクライアントと同じであるが、Webブラウザからリクエストが来る前にあらかじめコンテンツを取得するので、リクエストヘッダーを作成する必要がある。ここで、Webブラウザからのリクエストを初めの通信時にあらかじめ保存しておけば基本的な部分を使い回すことが出来る。リクエストヘッダは図10の例のようになるので、書き換える部分は初めのGET文と、もし接続先ホストが変わったならばHost要素を書き換えることで作成出来る。これは、HTTPクライアントとは別に独立して動作するようにし、先読みしたコンテンツをファイル化する。
キャッシュを行うかどうかはHTML ドキュメント解析時に判別出来るため、ヘッダファイルにこの情報を付加する。これにより、Webブラウザにコンテンツを送信後にキャッシュ化するコンテンツはそのままに、しないコンテンツはファイルを削除することでキャッシュ化の有無が実装出来る。
まずHTML ドキュメントパース時にダミーコンテンツのリストを作成する。次に、Webブラウザからのリクエストが来た時に通信が切断していた場合はダミーリストと照合し、このリストに一致するコンテンツの場合はダミーコンテンツを送信する。ただし、このダミーコンテンツはあらかじめファイルとして用意する。また、これに対応するレスポンスヘッダーもあらかじめ準備することでダミーコンテンツの表示を実装できる。
作成したHtmlParser クラスは付録9を参照。また、HTMLを解析するにあたって解析に使用するための文字コードを検出するDetectEncodingクラスは付録10を、検出したタグから要素を取り出すためのDetectElementsクラスは付録11を参照。先読み機能においてはPreReadクラスは付録12を、PreReadClientクラスは付録13を、PreReadCacheクラスは付録14を、PreReadParameterクラスは付録15を参照。
初めに、パラメータを付加したHTMLドキュメントのサンプルとしては付録1を使用した。キャッシュコントロールを実装したHTMLドキュメントを表示すると次のようになる。
この時、ファイルのキャッシュ状態は次のようになっている。
図15,16よりHTML ドキュメント読み込み直後に先読みコンテンツがキャッシュ化されていることが分かる。この時、通信を切断して再読み込みすると次のようになる。
図17より重要度の高い電車の画像は表示されず、重要度の低いFireFoxのロゴはダミーコンテンツとして表示されていること分かる。これにより、通信が切断してもリンクをクリックした時にコンテンツを閲覧することができ、切断時でもある程度安定したコンテンツの閲覧が可能となる。
本研究で作成したローカルProxyキャッシュを携帯端末に搭載したところで、現状ではキャッシュを全く行わない。これは、HTMLに本研究で提案したパラメータが全く付加されていないからである。ここで、キャッシュ、先読み、ダミー表示などの動作を行うためにはユーザが自らそれぞれのコンテンツURLに対してパラメータを付加し、HTMLのリンク集を作成することでこれらの動作を現状でも行うことが可能となる。
本研究では携帯端末上にローカルProxyキャッシュを設置することを提案した。これにより、携帯端末上のWebサービスにおいてネットワークが不調な時にこのローカルProxyキャッシュを利用することでネットワークの不調を吸収し、端末内で安定した通信を行う。よって、このローカルProxyキャッシュは単なるキャッシュではなくネットワークの仮想ストレージ化を行っていると言える。
また、本研究ではProxyサーバによりローカルキャッシュのコントロールを行ったが、Webブラウザがこの機能を取り込めば、ローカルキャッシュのコントロールをユーザが全く意識せずに行うことが可能となるため、将来的にはこちらの方が好ましいと考えられる。
今回作成したプログラムではHTMLドキュメントに記述されているパラメータをローカルProxyサーバが解析するため、HTMLドキュメントがgzipなどで圧縮されているときはこのgzipを展開出来ないため解析することが出来ないという問題が生じる。これを回避するためにはリクエストヘッダーのAccept-Encoding要素からgzipを取り除きdeflateのみにすることでボディーの圧縮を無効化してHTMLを解析できるようになる。しかし、圧縮を無効化することにより転送するボディーのデータサイズが増加し、ネットワークの効率が悪くなる問題点が有る。
また、キャッシュコントロールはコンテンツの製作者が行うため、ユーザが自分の好みに合わせたキャッシュを行うことが出来ない。ここで、ユーザが望むコンテンツのキーワードをProxyサーバに設定することでこのキーワードとHTMLドキュメントのキーワードを比較し、キャッシュを行う条件を調整することで、ユーザが望むコンテンツのキャッシュを優先的に行えると考えられる。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head>
<META HTTP-EQUIV=CONTENT-TYPE CONTENT="text/html; charset=utf-8">
<meta name="keyword" content="東京=0.6,秋葉原=0.9">
<META NAME="keyword" content="大阪,日本橋=0.5">
<meta NAME="priority" CONTENT="3">
<META name="variability" content="stable">
<title>たいとる<title>
</head>
<body>
<h1>てすてすてすと(UTF-8)</h1>
<ul>
<li><a href="./html/test2.html?tdu-cache-control=keyword:電大=0.6,日記=0.3,研究=0.1">test2</a></li>
<li>地球(キャッシュ)<img src="/globe.png?tdu-cache-control=keyword:地球=0.1,自然=0.3;priority:4;variability:1"></li>
<li>電車(エラー)<img src="./shinkansen.gif?tdu-cache-control=keyword:電車=0.4,交通=0.3;priority:4;variability:4"></li>
<li>FireFox(ダミー)<img src="./images/firefox.png?tdu-cachecontrol=keyword:Browser=0.2,速度=0.4;priority:1;variability:2"></li>
<li><a href="images/logo.gif?tdu-cache-control=keyword:大学=0.7,電気=0.5;priority:2;variability:5">TDU(先読み)</a></li>
<li><a href="./test/nav_logo3.png?tdu-cachecontrol=keyword:search=0.7,google=0.5;priority:4;variability:1">Google(先読みキャッシュ)</a></li>
</ul>
</body>
</html>
このクラスでは主にWebブラウザとのやりとりを行う。
コンストラクタ
ProxyServer(Socket socket)
引数のソケットに対して入出力ストリームを構成してフィールド変数に設定してインスタンスを生成する
フィールド変数
Socket server_socket
Webブラウザとの通信に使用する
BufferedInputStream server_in
Webブラウザからの入力ストリーム
BufferedOutputStream server_out
Webブラウザへの出力ストリーム
ProxyParameter pp
各種設定のProxyParameterオブジェクトを格納する
ProxyCache pcache
キャッシュを扱うProxyCacheオブジェクトを格納する
フィールド変数
void setProxyParameter(ProxyParameter pp)
ProxyParameterオブジェクトをフィールド変数にセットする
ProxyParameter getProxyParameter()
フィールド変数のProxyParameterオブジェクトを取得する
ProxyCache getProxyCache()
フィールド変数のProxyCacheオブジェクトを取得する
void disconnect()
Webブラウザとの通信を切断する
boolean receiveRequestHeader()
Webブラウザのリクエストヘッダを受信する
byte[] receiveRequestBody()
Webブラウザのリクエストボディーを受信するための動作の振り分けを行う
byte[] readContendLengthMode()
Content-Lengthで指定されたデータサイズのリクエストボディを受信する
byte[] readChunkMode()
Chunk形式で指定されたデータサイズのリクエストボディを受信する
boolean transmitResponseHeaderCached()
キャッシュされたレスポンスヘッダをセットして送信準備をする
boolean transmitResponseBodyCached()
キャッシュされたレスポンスヘッダとボディをまとめてWebブラウザに送信する
void transmitDummyHeader(File dummy_file)
ダミーヘッダをセットして送信準備をする
void transmitDummyBody(File dummy_file)
ダミーヘッダとボディをまとめてWebブラウザに送信する
このクラスでは主にWebサーバとのやりとりを行う。
コンストラクタ
ProxyClient(ProxyParameter pp, ProxyCache pcache)
引数のProxyParameter, ProxyCacheをフィールド変数に代入してインスタンスを生成する
フィールド変数
Socket client_socket
Webサーバとの通信に使用する
BufferedOutputStream client_out
Webサーバへの出力ストリーム
BufferedInputStream client_in
Webサーバからの入力ストリーム
ProxyParameter pp
各種設定のProxyParameterオブジェクトを格納する
ProxyCache pcache
キャッシュを扱うProxyCacheオブジェクトを格納する
メソッド
void setProxyParameter(ProxyParameter pp)
引数のProxyParameterをフィールド変数に代入する
ProxyParameter getProxyParameter()
フィールド変数のProxyParameterオブジェクトを取得する
boolean connect(URL url)
引数のURLのホストに接続する
void disconnect()
Webサーバとの通信を切断する
void transmitRequestHeader(LinkedHashMap<String, String> header)
引数のリクエストヘッダをセットして送信準備をする
void transmitRequestBody(byte[] request_body)
リクエストヘッダと引数のリクエストボディをまとめて送信する
boolean receiveResponseHeaderCaching()
Webサーバのレスポンスヘッダを受信してキャッシュ化する
boolean receiveResponseBodyCaching()
Webサーバのレスポンスボディを受信するための動作の振り分けを行う
int readContentLengthMode()
Content-Lengthで指定されたデータサイズのレスポンスボディを受信する
int readChunkMode()
Chunk形式で指定されたデータサイズのレスポンスボディを受信する
このクラスは各種設定を保存、及び変更する。
フィールド変数
String CONNECTION
文字列「Connection」
String CONTENT_LENGTH
文字列「Content-Length」
String CONTENT_ENCODING
文字列「Content-Encoding」
String CONTENT_TYPE
文字列「Content-Type」
String CRLF
文字列「\r\n」
String HEAD
文字列「HEAD」
String SP
スペースの文字列「 」
String SLASH
文字列「/」
String ASTERISK
文字列「*」
String QUESTION
文字列「?」
String COLON
文字列「:」
String SEMICOLON
文字列「;」
String TRANSFER_ENCODING
文字列「Transfer-Encoding」
String TDU_PROXY_NAME
文字列「TDU-LOCAL-PROXY」
String TDU_CACHE_CONTROL
文字列「?tdu-cache-control=」
File cd
カレントディレクトリのファイルオブジェクト、初期状態は「現在のカレントディレクトリ+Cache」
int buff_size
通信に使用するバッファサイズ、初期状態は「1024」
int data_size
データのサイズ
boolean browser_status
ブラウザとの接続状態
int browser_port
ブラウザとの通信に使用するポート番号
int host_port
Webサーバとの通信に使用するポート番号
boolean response_body
レスポンスボディの状態
boolean keep_alive
持続的接続の状態
boolean head
「HEAD」メソッドのフラグ
URL url
接続先URL
File header_file
ヘッダファイルのファイルオブジェクト
File body_file
ボディファイルのファイルオブジェクト
LinkedHashMap<String, String> request_header
リクエストヘッダを格納する
LinkedHashMap<String, String> response_header
レスポンスヘッダを格納する
HashMap<String, Boolean> host_list
接続先ホスト一覧を格納する
boolean cache_status
キャッシュがあるかどうかの状態
HashMap<URL, String> url_list
パラメータが付加されているURLのリスト
HashMap<URL, Boolean> pre_list
先読みを行うURLのリスト
HashMap<URL, Boolean> dummy_list
ダミーコンテンツ可のURL リスト
LinkedHashMap<String, String> pre_request_header
先読みリクエストヘッダ
boolean pre_read_flag
先読みフラグ
boolean cache_flag
キャッシュフラグ
File dummy_file
ダミーファイルのファイルオブジェクト
メソッド
File getCurrentDirectory()
現在のカレントディレクトリを返す
void setBrowserConnection(boolean browser_status)
ブラウザとの接続状態を設定する
boolean getBrowserConnection()
ブラウザとの接続状態を返す
void setBrowserPort(int browser_port)
ブラウザとの接続に使用しているポート番号を設定する
int getBrowserPort()
ブラウザとの接続に使用しているポート番号を返す
void setHeadMethod(boolean head)
「HEAD」メソッドかどうかを設定する
boolean getHeadMethod()
「HEAD」メソッドかどうかを返す
void setHostPort(int host_port)
Webサーバとの接続に使用しているポートを設定する
int getHostPort()
Webサーバとの接続に使用しているポートを返す
void setBufferSize(int buff_size)
通信に使用するバッファサイズを設定する
int getBufferSize()
通信に使用するバッファサイズを返す
void setDirectorySize(File root)
ディレクトリ内のデータサイズを設定する
void setSubDirectorySize(File root)
サブディレクトリ内のデータサイズを設定する
int getDirectorySize()
ディレクトリ内のデータサイズを返す
void setKeepAlive(boolean keep_alive)
持続的接続の設定をする
boolean getKeepAlive()
持続的接続かどうかを返す
void setURL(String url)
URLを設定する
URL getURL()
URLを返す
void setResponseBodyExists(String code)
レスポンスボディの存在を文字列により設定する
void setResponseBodyExists(int length)
レスポンスボディの存在をボディサイズにより設定する
boolean getResponseBodyExists()
レスポンスボディが存在するかどうかを返す
void setHeaderFile(int hashcode)
hashcodeをファイル名にしてヘッダファイルを設定する
File getHeaderFile()
ヘッダファイルを返す
void setBodyFile(int hashcode)
hashcodeをファイル名にしてボディファイルを設定する
File getBodyFile()
ボディファイルを返す
void setDummyFile(String file)
fileをファイル名としたダミーファイルを設定する
File getDummyFile()
ダミーファイルを返す
void setRequestHeader(LinkedHashMap<String, String> request_header)
リクエストヘッダを設定する
LinkedHashMap<String, String> getRequestHeader()
リクエストヘッダを返す
void setResponseHeader(LinkedHashMap<String, String> response_header)
レスポンスヘッダを設定する
LinkedHashMap<String, String> getResponseHeader()
レスポンスヘッダを返す
void setHostStatus(String host, Boolean status)
Webサーバとの接続状態を設定する
boolean getHostStatus(String host)
Webサーバとの接続状態を返す
boolean isAllHostClosed()
すべてのWebサーバとの接続が閉じているかどうかを返す
boolean isTextHtml()
コンテンツがHTML ドキュメントかどうかを返す
void setCacheFlag(boolean cache_flag)
キャッシュフラグを設定する
boolean getCacheFlag()
キャッシュフラグを返す
void setCacheStatus(boolean cache_status)
キャッシュステータスを設定する
void setCacheStatus(URL key_url)
キャッシュステータスをパラメータにより設定する
String getTDUQueryElement(String regex, String query)
付加されたパラメータ要素を返す
boolean isCachingEnabled(int get_priority, Object get_variability)
パラメータによりキャッシュ条件返す
boolean getCacheStatus()
キャッシュステータスを返す
URL getParentURL(URL url)
親URLを返す
void setURLList(HashMap<URL, String> url_list)
パラメータが付加されているURLのリストを設定する
HashMap<URL, String> getURLList()
URL リストを返す
void setPreURLList(HashMap<URL, Boolean> pre_list)
先読みURL リストを設定する
HashMap<URL, Boolean> getPreURLList()
先読みURL リストを返す
boolean cacheExists()
キャッシュが存在するかどうかを返す
void setPreRequestHeader(URL pre_url)
pre_urlに対する先読みリクエストヘッダを設定する
LinkedHashMap<String, String> getPreRequestHeader()
先読みリクエストヘッダを返す
void setPreReadFlag(boolean a)
先読みフラグを設定する
boolean getPreReadFlag()
先読みフラグを返す
このクラスでは主にHTTPサーバとHTTPクライアントのコントロールを行い、Proxyサーバとしての機能を確立する。
フィールド変数
ServerSocket s_socket
Webブラウザの接続を待ち受ける
ArrayList<LaunchServer> server_list
LaunchServerオブジェクトを格納する
メソッド
void launch()
Webブラウザからの接続を受けて生成されたソケットを引数としてLaunchServerオブジェクトを次々に生成して実行する。
このクラスはThread クラスのサブクラスである。
コンストラクタ
LaunchServer(Socket getsocket)
HTTPサーバであるProxyServerのインスタンスを生成し、LaunchServerインスタンスを生成する
フィールド変数
ProxyServer ps
HTTPサーバであるProxyServerオブジェクトを格納する
LaunchClient client
HTTPクライアントのコントロールを行うLaunchClientオブジェクトを格納する
LaunchServer server
HTTPサーバのコントロールを行うLaunchClientオブジェクトを格納する
ProxyParameter pp
各種のパラメータを持つProxyParameterオブジェクトを格納する
ProxyCache pc
キャッシュ操作を行うProxyCacheオブジェクトを格納する
byte[] data
一時的なデータを格納する
PreReader pr
先読みを行うPreReaderオブジェクトを格納する
boolean error
エラーが起こったかどうかを判別する
boolean next
次のステップに進むかどうかを判別する
メソッド
void run()
このオブジェクトのスレッドを実行するメソッドである。以下の動作をクライアントとの接続が切れるまで繰り返す。
1. リクエストを受け取る
2. キャッシュがあればキャッシュよりレスポンスを返す
3. ホスト接続エラーの時はダミーレスポンスをクライアントに送信する
4. 先読みコンテンツがある場合はpreRead()メソッドを実行する
5. 一時キャッシュされたレスポンスをクライアントに返す
6. 不要な一時キャッシュは削除する
void preRead()
先読みリストに基づいてコンテンツの先読みを行う
void dummyRead()
ダミーコンテンツのレスポンスをクライアントに送信する
void restart()
待機中のスレッドを再開する
このクラスはLaunchServer クラスの内部クラスである。そのため、LaunchServer クラスのフールド変数を参照できる。また、Thread クラスのサブクラスである。
コンストラクタ
LaunchClient()
ProxyClient インスタンスを生成し、フィールド変数に格納したLaunchClientインスタンスを生成する
フィールド変数
ProxyClient pc
HTTPクライアントオブジェクトのProxyClientオブジェクトを格納する
メソッド
void run()
このオブジェクトのスレッドを実行するメソッドである。以下の動作をクライアントとの接続が切れるまで繰り返す。
1. ホストとの接続が無ければ接続する
2. リクエストをWebサーバに送信する
3. レスポンスを受信して一時的にキャッシュする
4. 持続的接続でないときは切断する
このクラスはキャッシュに関する動作を行う。
コンストラクタ
ProxyCache(ProxyParameter pp)
引数のProxyParameterオブジェクトの参照をフィールドに設定してインスタンスを生成する
フィールド変数
ProxyParameter pp
各種設定のProxyParameterオブジェクトを格納する
LinkedHashMap<String, String> response_header
レスポンスヘッダを格納する
String encoding
文字エンコーディング名を格納する
HashMap<String, Double> keyword
キーワードを格納する
int priority
重要度を格納する
Object variability
変化度を格納する
boolean cache_status
キャッシュのステータスフラグ
HashMap<URL, Boolean> dummy_list
ダミーURL リスト
メソッド
void setProxyParameter(ProxyParameter pp)
ProxyParameterオブジェクトをフィールド変数に設定する
void setEncoding(String encoding)
文字エンコーディングを設定する
String getEncoding()
文字エンコーディングを返す
LinkedHashMap<String, String> getResponseHeader()
レスポンスヘッダを返す
void setResponseHeader(LinkedHashMap<String, String> response_header)
レスポンスヘッダを設定する
HashMap<String, Double> getKeyword()
キーワードを返す
int getPriority()
重要度を返す
Object getVariability()
変化度を返す
Object readSerializedData(File file)
レスポンスのヘッダファイルを読み込む
void readResponseBody(BufferedOutputStream out)
レスポンスのボディファイルを読み込む
void writeSerializedData()
レスポンスヘッダをファイルとして書き込む
boolean makeHostDirectory()
ホスト名のディレクトリを作成する
boolean removeHostDirectory()
ホスト名のディレクトリを削除する
void deleteCache()
キャッシュを削除する
void cleanFiles(File root)
ディレクトリ内のファイルを全て削除する
boolean detectEncoding()
HTTPヘッダ内で指定されている文字エンコーディングを検出する
void detectElements()
HTMLに付加された各種パラメータ要素を検出する
void writeDummyList(HashMap<URL, Boolean> dummy_list)
ダミーリストをファイルとして書き込む
HashMap<URL, Boolean> readDummyList()
ダミーリストをファイルから読み込む
boolean isCachingEnabled()
パラメータよりキャッシュ可能かどうか判断する
void setCacheStatus(boolean cache_status)
キャッシュ状態を設定する
boolean getCacheStatus()
キャッシュ状態を返す
このクラスはHTMLを解析して付加されたパラメータを読み取る。
コンストラクタ
HtmlParser(File file, String encoding)
指定されたエンコーディングでHtmlParserのインスタンスを生成する
フィールド変数
String CONTENT
小文字の文字列「content」
String HTTP_EQUIV
小文字の文字列「http-equiv」
String NAME
小文字の文字列「name」
String EQUAL
文字「=」
String CONMA
文字「,」
String PERIOD
文字「.」
String SEMICOLON
文字「;」
String TDU_QUERY
小文字の文字列「?tdu-cache-control=」
ParserDelegator parser
HTMLを解析するParserDelegatorオブジェクトを格納する
HTMLEditorKit.ParserCallback callback
タグ検出時に呼び出されるHTMLEditorKit.ParserCallbackオブジェクトを格納する
String encoding
文字エンコーディング名を格納する
File file
解析対象ファイルのオブジェクトを格納する
HashMap<String, Double> keyword
付加されたキーワードを格納する
int priority
付加された重要度を格納する
Object variability
変化度を格納する
HashMap<URL, String> url_list
パラメータが付加されているURLのリストを格納する
HashMap<URL, Boolean> pre_list
先読みを行うURLのリストを格納する
HashMap<URL, Boolean> dummy_list
ダミーコンテンツを返すURLのリストを格納する
ProxyParameter pp
ProxyParameterオブジェクトを格納する
メソッド
String getEncoding()
HTML ドキュメントのエンコーディングをMeta タグから検出する
void parseElements()
HTMLに付加された各種パラメータを解析する
HashMap<String, Double> getKeyword()
キーワードの参照を返す
int getPriority()
重要度を返す
Object getVariability()
変化度の参照を返す
HashMap<URL, Boolean> getPreURLList()
先読みURL リストの参照を返す
HashMap<URL, String> getURLList()
パラメータが付加されているURL リストの参照を返す
HashMap<URL, Boolean> getDummyList()
ダミーコンテンツを使用しても良いURL リストの参照を返す
void setProxyParameter(ProxyParameter pp)
ProxyParameterを設定する
このクラスはHTMLEditorKit.ParserCallbackクラスのサブクラスであり、HtmlParserクラスによって検出されたMeta タグ内の文字エンコーディング分析を行う。また、これはHtmlParserクラスの内部クラスであるため、フィールド変数にアクセスすることが出来る。
メソッド
void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos)
Meta タグを検出したらその内容を読み取り、「http-equiv」属性に「Content-Type」があればsetEncodingメソッドを実行する。
void setEncoding(String content)
文字コードが指定されていれば、それを検出してencodingオブジェクトに格納する。
このクラスはDetectEncodingクラスと同様にHtmlクラスによって検出されたタグを分析する。また、これはHtmlParserクラスの内部クラスであるため、フィールド変数にアクセスすることが出来る。
メソッド
void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos)
Meta タグ及び、Img タグの各種パラメータを解析する
void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos)
アンカータグを解析する
void setKeyword(String str)
キーワードを設定する
void setPriority(String str)
重要度を設定する
void setVariability(String str)
変化度を設定する
boolean setPreReadList(String str)
先読みリストを作成する
void setURLList(String str)
パラメータが付加されているURLのリストを作成する
URL setURL(String str)
引数のStringオブジェクトからURLオブジェクトを作成する
void setDummyList(String str)
ダミーリストを作成する
String getTDUQueryElement(String regex, String query)
TDU クエリ「?tdu-cache-control=」があるかどうかを検出し、ある場合その要素を返す
このクラスはLaunchServerクラスの内部クラスである。そのため、LaunchServerクラスのフィールド変数を参照できる。また、Threadクラスのサブクラスである。
コンストラクタ
PreReader(URL url, boolean cache_status, LinkedHashMap<String, String> request)
PreReadClient, PreReadParameterのインスタンスを生成し、フィールド変数に格納したPreReaderインスタンスを生成する。
フィールド変数
PreReadClient pc
先読みHTTPクライアントのPreReadClientオブジェクトを格納する
PreReadParameter prp
先読みにおける各種設定のPreReadParameterオブジェクトを格納する
メソッド
void run()
このオブジェクトのスレッドを実行するメソッドである。以下の動作をクライアントとの接続が切れるまで繰り返す。
1. ホストと接続する
2. リクエストを送信する
3. レスポンスを受信する
4. 切断する
このクラスは先読みを行うHTTPクライアントである。
コンストラクタ
PreReadClient(PreReadParameter prp)
引数のオブジェクトをフィールド変数に格納してPreReadClientのインスタンスを生成する
フィールド変数
PreReadParameter prp
各種設定のオブジェクトであるPreReadParameterを格納する
メソッド
void connect()
Webサーバと接続する
void disconnect()
Webサーバから切断する
void transmitRequest()
先読みコンテンツ用のリクエストヘッダを送信する
boolean receiveResponseHeader()
レスポンスヘッダを受信してキャッシュ化する
boolean receiveResponseBody()
レスポンスボディを受信するための動作の振り分けを行う
int readContentLengthMode()
Content-Lengthで指定されたサイズ分ボディを受信する
int readChunkMode()
Chunk形式で指定されたデータサイズのレスポンスボディを受信する
このクラスは先読みクライアントにおけるキャッシュ機能を扱う
フィールド変数
LinkedHashMap<String, String> response_header
レスポンスヘッダを格納する
boolean cache_status
キャッシュするべきかどうかのステータスフラグ
メソッド
void setHeader(LinkedHashMap<String, String> response_header)
レスポンスヘッダの参照をフィールドに渡す
LinkedHashMap<String, String> getHeader()
レスポンスヘッダへの参照を返す
mkdirs(URL url)
ホスト名のディレクトリを作成する
void setCacheStatus(boolean cache_status)
キャッシュステータスフラグを変更する
boolean getCacheStatus()
キャッシュステータスフラグを返す
void writeHeaderFile(URL url)
レスポンスヘッダをファイルとして書き込む
Object readHeaderFile(URL url)
レスポンスヘッダをファイルから読み込む
このクラスは先読みクライアントにおける各種設定を取り扱う
フィールド変数
Socket client_socket
クライアントとの接続に使用
BufferedOutputStream client_out
クライアントへの出力ストリーム
BufferedInputStream client_in
クライアントからの入力ストリーム
URL url
接続先URL
LinkedHashMap<String, String> request_header
リクエストヘッダを格納する
LinkedHashMap<String, String> response_header
レスポンスヘッダを格納する
boolean body_exists
ボディがあるかどうかのフラグ
boolean keep_alive
持続的接続をするかどうかのフラグ
int buff_size
通信に使用するバッファのサイズ
boolean cache_status
キャッシュするかどうかのステータスフラグ
メソッド
void setURL(URL url)
接続先URLを設定する
URL getURL()
URLを返す
void setSocket(String host, int port)
Webサーバとの接続ソケットを設定する
Socket getSocket()
ソケットの参照を返す
void setInputStream(InputStream in)
入力ストリームを設定する
BufferedInputStream getInputStream()
入力ストリームの参照を返す
void setOutputStream(OutputStream out)
出力ストリームを設定する
BufferedOutputStream getOutputStream()
出力ストリームの参照を返す
void setRequestHeader(LinkedHashMap<String, String> request_header)
リクエストヘッダを設定する
LinkedHashMap<String, String> getRequestHeader()
リクエストヘッダの参照を返す
void setResponseHeader(LinkedHashMap<String, String> response_header)
レスポンスヘッダを設定する
LinkedHashMap<String, String> getResponseHeader()
レスポンスヘッダの参照を返す
void setCacheStatus(boolean cache_status)
キャッシュステータスを設定する
boolean getCacheStatus()
キャッシュステータスを返す
File getBodyFile()
ボディファイルの参照を返す
void setBufferSize(int buff_size)
通信に使用するバッファサイズを設定する
int getBufferSize()
バッファサイズを返す
void setResponseBodyExists(String code)
レスポンスボディが存在することを設定する
boolean getResponseBodyExists()
レスポンスボディが存在することを返す
void setNoResponseBody()
レスポンスボディが存在しないことを設定する
void setKeepAlive(boolean keep_alive)
持続的接続を設定する
void writeSerializedHeader()
レスポンスヘッダをファイルとして書き込む