web プロキシ http1.0 ヒント

33
CS-B3 ネネネネネネネネネネネネネ ネネネネネネネ I web ネネネネ HTTP1.0 ネネネ

Upload: veda-campos

Post on 30-Dec-2015

34 views

Category:

Documents


2 download

DESCRIPTION

web プロキシ HTTP1.0 ヒント. CS-B3  ネットワークプログラミング  &情報科学科実験 I. このスライドについて. このスライドでは皆さんがプログラムを書いたり,関数を調べたりする過程で行き詰ると予想される部分について簡単に解説します.. このスライドの目的は自主学習のサポートであり,説明が簡略化されています.完全な理解には自主学習が必要なので注意してください.. 目次. web プロキシとは 何を実装すればよいのか 実装方法の例 web サーバの特定方法 実装をする上での注意. web プロキシとは. 一般的な通信は直接通信. - PowerPoint PPT Presentation

TRANSCRIPT

CS-B3  ネットワークプログラミング &情報科学科実験 I

web プロキシ HTTP1.0 ヒント

このスライドについてこのスライドでは皆さんがプログラムを書いたり,関数を調べたりする過程で行き詰ると予想される部分について簡単に解説します.

このスライドの目的は自主学習のサポートであり,説明が簡略化されています.完全な理解には自主学習が必要なので注意してください.

目次web プロキシとは何を実装すればよいのか実装方法の例web サーバの特定方法実装をする上での注意

web プロキシとは一般的な通信は直接通信

ブラウザweb サーバ

web プロキシとは

web サーバとのデータのやりとりを中継する

ブラウザ

$./proxy

プロキシ

web サーバ

proxy = 「代理」

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

proxy 側listen()

web サーバlisten()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

ブラウザ側のconnect()

proxy 側listen()

web サーバlisten()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

プロキシ側でaccept()

web サーバlisten()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバブラウザからのリクエスト web サーバ

listen()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

リクエストからweb サーバを特定

web サーバlisten()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

web サーバへのconnect()

web サーバlisten()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

web サーバがaccept()

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバブラウザからのリクエストを転送

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

web サーバからのレスポンス

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

web サーバからのレスポンスを転送

何を実装すればよいのかプログラムの流れ

ブラウザ

$./proxy

プロキシ

web サーバ

ソケットクローズ

何を実装すればよいのか

1 リクエスト + 1 レスポンス = 1 コネクション

HTTP1.0 では

各リクエストごとに接続を確立します.

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

ブラウザ側のconnect()

proxy 側listen()

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

プロキシ側でaccept()

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

別スレッド,または別プロセス

listen 用ソケットは残しておく

accept() したら後は並列処理に任せる

proxy

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

別スレッド,または別プロセス

listen 用ソケットは残しておく

proxy

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

別スレッド,または別プロセス

proxy

ブラウザ側のconnect()

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

別スレッド,または別プロセス

proxy

プロキシ側でaccept()

web サーバlisten()

何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには

ブラウザ

$./proxy

プロキシ

web サーバ

別スレッド,または別プロセス

proxy

proxy

listen 用ソケットは残しておく

web サーバlisten()

実装方法の例main { listenSocket = listen 中のソケットを作成 ; sockaddr_in 変数の各種メンバの設定 ; bind(); listen();

while (1) { browserSocket = accept(listenSocket, …); /* ブラウザから listenSocket への接続要求を accept(); */ スレッド ( またはプロセス ) の作成 ; /* 子スレッド or 子プロセスに送受信処理を実行させる */ /*browserSocket をスレッド ( またはプロセス ) に渡す */ }/*main 関数は accept→ 子スレッド or プロセスの作成を繰り返す */}

※ あくまでも一例です.また,引数や実装方法が簡略化されています.

実装方法の例スレッド ( またはプロセス ) { recv(browserSocket からの文字列 → buffer); webserverSocket = socket(); hostName = buffer から web サーバのホスト名を抜き出す ; hostAddress = hostName から web サーバの IP アドレスを求める ; hostPort = web サーバならば通常は 80 を代入 ;(well-known port)  sockaddr_in 型変数のメンバへの設定 ; connect(); send(buffer の文字列 → webserverSocket)

while(1) { browserSocket または webserverSocket が読み取り可能になるまで待機 ;

if (browserSocket から recv() できるなら ) { recv(browserSocket からの文字列 → buffer); /* */① if (recv() が失敗したら ) break; send(buffer の文字列 → webserverSocket) /* リクエストの転送 */ if (① の recv() の結果, browserSocket がクーロズされていたとわかった ( つまり 0 バイト受信 )) { break; } } if (webserverSocket から recv() できるなら ) { recv(webserverSocket からの文字列 → buffer); /* */② if (recv() が失敗したら ) break; send(buffer の文字列 → browserSocket) /* レスポンスの転送 */ if (② の recv() の結果, webserverSocket がクーロズされていたとわかった ( つまり 0 バイト受信 )) { break; } } } close(browserSocket); close(webserverSocket); return 0;}

※ あくまでも一例です.また,引数や実装方法が簡略化されています.

スレッド or プロセスによって作成した子の中で

Select を用いればよい

web サーバの特定方法HTTP のリクエスト,レスポンスはテキストデータである.

GET http://www.inf.shizuoka.ac.jp/ HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

HTTP1.0 プロキシを用いたリクエスト

GET http://www.inf.shizuoka.ac.jp/ HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

web サーバの特定方法

HTTP1.0 プロキシを用いたリクエスト

ホスト名が特定できた= 名前解決で IP アドレスが分かる

※ 接続先ポート番号は今回は 80 番で固定で OK

GET http://www.inf.shizuoka.ac.jp/ HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

web サーバの特定方法

HTTP1.0 プロキシを用いたリクエスト

“Host: ” がないならば“GET” からホスト名を特定

※ 接続先ポート番号は今回は 80 番で固定で OK

実装上の注意web ブラウザによっては…

プロキシを使う場合と使わない場合ではリクエストが異なる!

プロキシ使用

GET http://www.inf.shizuoka.ac.jp/ HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

プロキシ未使用

GET / HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

リクエストを web サーバに転送するときは“ GET” メソッドから“http:// ホスト名”を削除しておこう !!

実装上の注意web ブラウザによっては…

プロキシを使う場合と使わない場合ではリクエストが異なる!

プロキシ使用

GET http://www.inf.shizuoka.ac.jp/ HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

プロキシ未使用

GET / HTTP/1.0\r\nHost: www.inf.shizuoka.ac.jp\r\n( 以下省略 )

※ メソッドは” GET” だけとは限りませんあくまでも“ http:// ホスト名”を削除するだけでそれ以外の部分をプロキシ側で書き換えてはいけません

まとめweb プロキシプログラムは

1. ブラウザからの connect() を accept() する

2. ブラウザとの通信用のソケットを並列処理に持っていく

1. ブラウザからリクエストを受け取る

2. ブラウザのリクエストから web サーバを特定する

3. web サーバとの通信用ソケットを作成し, connect() する

4. ブラウザのリクエスト, web サーバからのレスポンスを転送する ( このとき,リクエストはあらかじめ適切に変換しておく )

5. ソケットを閉じる

以下,並列処理