<?php
- /////////////////////////////////////////////////
- // PukiWiki - Yet another WikiWikiWeb clone.
- //
- // $Id: proxy.php,v 1.4 2003/10/01 05:38:47 arino Exp $
- //
- /*
- * http_request($url)
- * HTTPリクエストを発行し、データを取得する
- * $url : http://から始まるURL(http://user:pass@host:port/path?query)
- * $method : GET, POST, HEADのいずれか(デフォルトはGET)
- * $headers : 任意の追加ヘッダ
- * $post : POSTの時に送信するデータを格納した配列('変数名'=>'値')
- * $redirect_max : HTTP redirectの回数制限
- */
- // リダイレクト回数制限の初期値
- define('HTTP_REQUEST_URL_REDIRECT_MAX',10);
- function http_request($url,$method='GET',$headers='',$post=array(),
- $redirect_max=HTTP_REQUEST_URL_REDIRECT_MAX)
- {
- global $use_proxy,$proxy_host,$proxy_port;
- global $need_proxy_auth,$proxy_auth_user,$proxy_auth_pass;
-
- $rc = array();
- $arr = parse_url($url);
-
- $via_proxy = $use_proxy and via_proxy($arr['host']);
-
- // query
- $arr['query'] = isset($arr['query']) ? '?'.$arr['query'] : '';
- // port
- $arr['port'] = isset($arr['port']) ? $arr['port'] : 80;
-
- $url_base = $arr['scheme'].'://'.$arr['host'].':'.$arr['port'];
- $url_path = isset($arr['path']) ? $arr['path'] : '/';
- $url = ($via_proxy ? $url_base : '').$url_path.$arr['query'];
-
- $query = $method.' '.$url." HTTP/1.0\r\n";
- $query .= "Host: ".$arr['host']."\r\n";
- $query .= "User-Agent: PukiWiki/".S_VERSION."\r\n";
- // proxyのBasic認証
- if ($need_proxy_auth and isset($proxy_auth_user) and isset($proxy_auth_pass))
- {
- $query .= 'Proxy-Authorization: Basic '.
- base64_encode($proxy_auth_user.':'.$proxy_auth_pass)."\r\n";
- }
- // Basic 認証用
- if (isset($arr['user']) and isset($arr['pass']))
- {
- $query .= 'Authorization: Basic '.
- base64_encode($arr['user'].':'.$arr['pass'])."\r\n";
- }
-
- $query .= $headers;
-
- // POST 時は、urlencode したデータとする
- if (strtoupper($method) == 'POST')
- {
- $POST = array();
- foreach ($post as $name=>$val)
- {
- $POST[] = $name.'='.urlencode($val);
- }
- $data = join('&',$POST);
- $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
- $query .= 'Content-Length: '.strlen($data)."\r\n";
- $query .= "\r\n";
- $query .= $data;
- }
- else
- {
- $query .= "\r\n";
- }
-
- $fp = fsockopen(
- $via_proxy ? $proxy_host : $arr['host'],
- $via_proxy ? $proxy_port : $arr['port'],
- $errno,$errstr,30);
- if (!$fp)
- {
- return array(
- 'query' => $query, // Query String
- 'rc' => $errno, // エラー番号
- 'header' => '', // Header
- 'data' => $errstr // エラーメッセージ
- );
- }
-
- fputs($fp, $query);
-
- $response = '';
- while (!feof($fp))
- {
- $response .= fread($fp,4096);
- }
- fclose($fp);
-
- $resp = explode("\r\n\r\n",$response,2);
- $rccd = explode(' ',$resp[0],3); // array('HTTP/1.1','200','OK\r\n...')
- $rc = (integer)$rccd[1];
-
- // Redirect
- switch ($rc)
- {
- case 302: // Moved Temporarily
- case 301: // Moved Permanently
- if (preg_match('/^Location: (.+)$/m',$resp[0],$matches)
- and --$redirect_max > 0)
- {
- $url = trim($matches[1]);
- if (!preg_match('/^https?:\//',$url)) // no scheme
- {
- if ($url{0} != '/') // Relative path
- {
- // to Absolute path
- $url = substr($url_path,0,strrpos($url_path,'/')).'/'.$url;
- }
- // add sheme,host
- $url = $url_base.$url;
- }
- return http_request($url,$method,$headers,$post,$redirect_max);
- }
- }
-
- return array(
- 'query' => $query, // Query String
- 'rc' => $rc, // Response Code
- 'header' => $resp[0], // Header
- 'data' => $resp[1] // Data
- );
- }
- // プロキシを経由する必要があるかどうか判定
- function via_proxy($host)
- {
- global $use_proxy,$no_proxy;
- static $ip_pattern = '/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/(.+))?$/';
-
- if (!$use_proxy)
- {
- return FALSE;
- }
- $ip = gethostbyname($host);
- $l_ip = ip2long($ip);
- $valid = (is_long($l_ip) and long2ip($l_ip) == $ip); // valid ip address
-
- foreach ($no_proxy as $network)
- {
- if ($valid and preg_match($ip_pattern,$network,$matches))
- {
- $l_net = ip2long($matches[1]);
- $mask = array_key_exists(2,$matches) ? $matches[2] : 32;
- $mask = is_numeric($mask) ?
- pow(2,32) - pow(2,32 - $mask) : // "10.0.0.0/8"
- ip2long($mask); // "10.0.0.0/255.0.0.0"
- if (($l_ip & $mask) == $l_net)
- {
- return FALSE;
- }
- }
- else
- {
- if (preg_match('/'.preg_quote($network,'/').'/',$host))
- {
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- ?>
-