OSDN Git Service

BugTrack2/9: Remove all #freeze convert plugin
[pukiwiki/pukiwiki.git] / lib / proxy.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: proxy.php,v 1.2 2004/10/13 14:30:58 henoheno 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 $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 = 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 && isset($proxy_auth_user) && isset($proxy_auth_pass)) {
47                 $query .= 'Proxy-Authorization: Basic '.
48                         base64_encode($proxy_auth_user . ':' . $proxy_auth_pass) . "\r\n";
49         }
50
51         // Basic Ç§¾ÚÍÑ
52         if (isset($arr['user']) && isset($arr['pass'])) {
53                 $query .= 'Authorization: Basic '.
54                         base64_encode($arr['user'] . ':' . $arr['pass']) . "\r\n";
55         }
56
57         $query .= $headers;
58
59         // POST »þ¤Ï¡¢urlencode ¤·¤¿¥Ç¡¼¥¿¤È¤¹¤ë
60         if (strtoupper($method) == 'POST') {
61                 $POST = array();
62                 foreach ($post as $name=>$val) {
63                         $POST[] = $name . '=' . urlencode($val);
64                 }
65                 $data = join('&', $POST);
66                 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
67                 $query .= 'Content-Length: ' . strlen($data) . "\r\n";
68                 $query .= "\r\n";
69                 $query .= $data;
70         } else {
71                 $query .= "\r\n";
72         }
73
74         $errno = 0; $errstr = '';
75         $fp = fsockopen(
76                 $via_proxy ? $proxy_host : $arr['host'],
77                 $via_proxy ? $proxy_port : $arr['port'],
78                 $errno, $errstr, 30);
79         if ($fp === FALSE) {
80                 return array(
81                         'query'  => $query, // Query String
82                         'rc'     => $errno, // ¥¨¥é¡¼ÈÖ¹æ
83                         'header' => '',     // Header
84                         'data'   => $errstr // ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
85                 );
86         }
87
88         fputs($fp, $query);
89
90         $response = '';
91         while (! feof($fp))
92                 $response .= fread($fp, 4096);
93         fclose($fp);
94
95         $resp = explode("\r\n\r\n", $response, 2);
96         $rccd = explode(' ', $resp[0], 3); // array('HTTP/1.1', '200', 'OK\r\n...')
97         $rc = (integer)$rccd[1];
98
99         // Redirect
100         $matches = array();
101         switch ($rc) {
102         case 302: // Moved Temporarily
103         case 301: // Moved Permanently
104                 if (preg_match('/^Location: (.+)$/m', $resp[0], $matches)
105                         && --$redirect_max > 0)
106                 {
107                         $url = trim($matches[1]);
108                         if (! preg_match('/^https?:\//', $url)) {
109                                 // No scheme
110                                 if ($url{0} != '/') {
111                                         // Relative path to Absolute
112                                         $url = substr($url_path, 0, strrpos($url_path, '/')) . '/' . $url;
113                                 }
114                                 $url = $url_base . $url; // Add sheme, host
115                         }
116                         return http_request($url, $method, $headers, $post, $redirect_max);
117                 }
118         }
119
120         return array(
121                 'query'  => $query,   // Query String
122                 'rc'     => $rc,      // Response Code
123                 'header' => $resp[0], // Header
124                 'data'   => $resp[1]  // Data
125         );
126 }
127
128 // ¥×¥í¥­¥·¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ë¤«¤É¤¦¤«È½Äê
129 function via_proxy($host)
130 {
131         global $use_proxy, $no_proxy;
132         static $ip_pattern = '/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/(.+))?$/';
133
134         if (! $use_proxy) return FALSE;
135
136         $ip    = gethostbyname($host);
137         $l_ip  = ip2long($ip);
138         $valid = (is_long($l_ip) && long2ip($l_ip) == $ip); // valid ip address
139
140         $matches = array();
141         foreach ($no_proxy as $network) {
142                 if ($valid && preg_match($ip_pattern, $network, $matches)) {
143                         $l_net = ip2long($matches[1]);
144                         $mask  = isset($matches[2]) ? $matches[2] : 32;
145                         $mask  = is_numeric($mask) ?
146                                 pow(2, 32) - pow(2, 32 - $mask) : // "10.0.0.0/8"
147                                 ip2long($mask);                   // "10.0.0.0/255.0.0.0"
148
149                         if (($l_ip & $mask) == $l_net) return FALSE;
150                 } else {
151                         if (preg_match('/' . preg_quote($network, '/') . '/', $host))
152                                 return FALSE;
153                 }
154         }
155         return TRUE;
156 }
157 ?>