OSDN Git Service

BugTrack/487: AutoLink対象のページ名がひとつもないときに、不正なパターンを生成していた
[pukiwiki/pukiwiki.git] / proxy.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: proxy.php,v 1.4 2003/10/01 05:38:47 arino Exp $
6 //
7
8 /*
9  * http_request($url)
10  *   HTTP¥ê¥¯¥¨¥¹¥È¤òȯ¹Ô¤·¡¢¥Ç¡¼¥¿¤ò¼èÆÀ¤¹¤ë
11  * $url     : http://¤«¤é»Ï¤Þ¤ëURL(http://user:pass@host:port/path?query)
12  * $method  : GET, POST, HEAD¤Î¤¤¤º¤ì¤«(¥Ç¥Õ¥©¥ë¥È¤ÏGET)
13  * $headers : Ç¤°Õ¤ÎÄɲåإåÀ
14  * $post    : POST¤Î»þ¤ËÁ÷¿®¤¹¤ë¥Ç¡¼¥¿¤ò³ÊǼ¤·¤¿ÇÛÎó('ÊÑ¿ô̾'=>'ÃÍ')
15  * $redirect_max : HTTP redirect¤Î²ó¿ôÀ©¸Â
16 */
17
18 // ¥ê¥À¥¤¥ì¥¯¥È²ó¿ôÀ©¸Â¤Î½é´üÃÍ
19 define('HTTP_REQUEST_URL_REDIRECT_MAX',10);
20
21 function http_request($url,$method='GET',$headers='',$post=array(),
22         $redirect_max=HTTP_REQUEST_URL_REDIRECT_MAX)
23 {
24         global $use_proxy,$proxy_host,$proxy_port;
25         global $need_proxy_auth,$proxy_auth_user,$proxy_auth_pass;
26         
27         $rc = array();
28         $arr = parse_url($url);
29         
30         $via_proxy = $use_proxy and via_proxy($arr['host']);
31         
32         // query
33         $arr['query'] = isset($arr['query']) ? '?'.$arr['query'] : '';
34         // port
35         $arr['port'] = isset($arr['port']) ? $arr['port'] : 80;
36         
37         $url_base = $arr['scheme'].'://'.$arr['host'].':'.$arr['port'];
38         $url_path = isset($arr['path']) ? $arr['path'] : '/';
39         $url = ($via_proxy ? $url_base : '').$url_path.$arr['query'];
40         
41         $query = $method.' '.$url." HTTP/1.0\r\n";
42         $query .= "Host: ".$arr['host']."\r\n";
43         $query .= "User-Agent: PukiWiki/".S_VERSION."\r\n";
44
45         // proxy¤ÎBasicǧ¾Ú
46         if ($need_proxy_auth and isset($proxy_auth_user) and isset($proxy_auth_pass))
47         {
48                 $query .= 'Proxy-Authorization: Basic '.
49                         base64_encode($proxy_auth_user.':'.$proxy_auth_pass)."\r\n";
50         }
51         // Basic Ç§¾ÚÍÑ
52         if (isset($arr['user']) and isset($arr['pass']))
53         {
54                 $query .= 'Authorization: Basic '.
55                         base64_encode($arr['user'].':'.$arr['pass'])."\r\n";
56         }
57         
58         $query .= $headers;
59         
60         // POST »þ¤Ï¡¢urlencode ¤·¤¿¥Ç¡¼¥¿¤È¤¹¤ë
61         if (strtoupper($method) == 'POST')
62         {
63                 $POST = array();
64                 foreach ($post as $name=>$val)
65                 {
66                         $POST[] = $name.'='.urlencode($val);
67                 }
68                 $data = join('&',$POST);
69                 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
70                 $query .= 'Content-Length: '.strlen($data)."\r\n";
71                 $query .= "\r\n";
72                 $query .= $data;
73         }
74         else
75         {
76                 $query .= "\r\n";
77         }
78         
79         $fp = fsockopen(
80                 $via_proxy ? $proxy_host : $arr['host'],
81                 $via_proxy ? $proxy_port : $arr['port'],
82                 $errno,$errstr,30);
83         if (!$fp)
84         {
85                 return array(
86                         'query'  => $query, // Query String
87                         'rc'     => $errno, // ¥¨¥é¡¼ÈÖ¹æ
88                         'header' => '',     // Header
89                         'data'   => $errstr // ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
90                 );
91         }
92         
93         fputs($fp, $query);
94         
95         $response = '';
96         while (!feof($fp))
97         {
98                 $response .= fread($fp,4096);
99         }
100         fclose($fp);
101         
102         $resp = explode("\r\n\r\n",$response,2);
103         $rccd = explode(' ',$resp[0],3); // array('HTTP/1.1','200','OK\r\n...')
104         $rc = (integer)$rccd[1];
105         
106         // Redirect
107         switch ($rc)
108         {
109                 case 302: // Moved Temporarily
110                 case 301: // Moved Permanently
111                         if (preg_match('/^Location: (.+)$/m',$resp[0],$matches)
112                                 and --$redirect_max > 0)
113                         {
114                                 $url = trim($matches[1]);
115                                 if (!preg_match('/^https?:\//',$url)) // no scheme
116                                 {
117                                         if ($url{0} != '/') // Relative path
118                                         {
119                                                 // to Absolute path
120                                                 $url = substr($url_path,0,strrpos($url_path,'/')).'/'.$url;
121                                         }
122                                         // add sheme,host
123                                         $url = $url_base.$url;
124                                 } 
125                                 return http_request($url,$method,$headers,$post,$redirect_max);
126                         }
127         }
128         
129         return array(
130                 'query'  => $query,   // Query String
131                 'rc'     => $rc,      // Response Code
132                 'header' => $resp[0], // Header
133                 'data'   => $resp[1]  // Data
134         );
135 }
136 // ¥×¥í¥­¥·¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ë¤«¤É¤¦¤«È½Äê
137 function via_proxy($host)
138 {
139         global $use_proxy,$no_proxy;
140         static $ip_pattern = '/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/(.+))?$/';
141         
142         if (!$use_proxy)
143         {
144                 return FALSE;
145         }
146         $ip = gethostbyname($host);
147         $l_ip = ip2long($ip);
148         $valid = (is_long($l_ip) and long2ip($l_ip) == $ip); // valid ip address
149         
150         foreach ($no_proxy as $network)
151         {
152                 if ($valid and preg_match($ip_pattern,$network,$matches))
153                 {
154                         $l_net = ip2long($matches[1]);
155                         $mask = array_key_exists(2,$matches) ? $matches[2] : 32;
156                         $mask = is_numeric($mask) ?
157                                 pow(2,32) - pow(2,32 - $mask) : // "10.0.0.0/8"
158                                 ip2long($mask);                 // "10.0.0.0/255.0.0.0"
159                         if (($l_ip & $mask) == $l_net)
160                         {
161                                 return FALSE;
162                         }
163                 }
164                 else
165                 {
166                         if (preg_match('/'.preg_quote($network,'/').'/',$host))
167                         {
168                                 return FALSE;
169                         }
170                 }
171         }
172         return TRUE;
173 }
174 ?>