web プロキシ HTTP1.0 ヒント
-
Upload
veda-campos -
Category
Documents
-
view
34 -
download
2
description
Transcript of web プロキシ HTTP1.0 ヒント
このスライドについてこのスライドでは皆さんがプログラムを書いたり,関数を調べたりする過程で行き詰ると予想される部分について簡単に解説します.
このスライドの目的は自主学習のサポートであり,説明が簡略化されています.完全な理解には自主学習が必要なので注意してください.
何を実装すればよいのかさらに,ブラウザからの connect を複数受け付けるには
ブラウザ
$./proxy
プロキシ
web サーバ
ブラウザ側のconnect()
proxy 側listen()
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:// ホスト名”を削除するだけでそれ以外の部分をプロキシ側で書き換えてはいけません