Редакция 69 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 69 | Редакция 87 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | /**
|
2 | /**
|
3 | * PEAR_REST
|
3 | * PEAR_REST
|
4 | *
|
4 | *
|
5 | * PHP versions 4 and 5
|
5 | * PHP versions 4 and 5
|
6 | *
|
6 | *
|
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
8 | * that is available through the world-wide-web at the following URI:
|
8 | * that is available through the world-wide-web at the following URI:
|
9 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
9 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
10 | * the PHP License and are unable to obtain it through the web, please
|
10 | * the PHP License and are unable to obtain it through the web, please
|
11 | * send a note to license@php.net so we can mail you a copy immediately.
|
11 | * send a note to license@php.net so we can mail you a copy immediately.
|
12 | *
|
12 | *
|
13 | * @category pear
|
13 | * @category pear
|
14 | * @package PEAR
|
14 | * @package PEAR
|
15 | * @author Greg Beaver <cellog@php.net>
|
15 | * @author Greg Beaver <cellog@php.net>
|
16 | * @copyright 1997-2008 The PHP Group
|
16 | * @copyright 1997-2008 The PHP Group
|
17 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
17 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
18 | * @version CVS: $Id: REST.php,v 1.31 2008/05/13 18:03:36 cellog Exp $
|
18 | * @version CVS: $Id: REST.php,v 1.31 2008/05/13 18:03:36 cellog Exp $
|
19 | * @link http://pear.php.net/package/PEAR
|
19 | * @link http://pear.php.net/package/PEAR
|
20 | * @since File available since Release 1.4.0a1
|
20 | * @since File available since Release 1.4.0a1
|
21 | */
|
21 | */
|
22 | 22 | ||
23 | /**
|
23 | /**
|
24 | * For downloading xml files
|
24 | * For downloading xml files
|
25 | */
|
25 | */
|
26 | require_once 'PEAR.php'; |
26 | require_once 'PEAR.php'; |
27 | require_once 'PEAR/XMLParser.php'; |
27 | require_once 'PEAR/XMLParser.php'; |
28 | 28 | ||
29 | /**
|
29 | /**
|
30 | * Intelligently retrieve data, following hyperlinks if necessary, and re-directing
|
30 | * Intelligently retrieve data, following hyperlinks if necessary, and re-directing
|
31 | * as well
|
31 | * as well
|
32 | * @category pear
|
32 | * @category pear
|
33 | * @package PEAR
|
33 | * @package PEAR
|
34 | * @author Greg Beaver <cellog@php.net>
|
34 | * @author Greg Beaver <cellog@php.net>
|
35 | * @copyright 1997-2008 The PHP Group
|
35 | * @copyright 1997-2008 The PHP Group
|
36 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
36 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
37 | * @version Release: 1.7.2
|
37 | * @version Release: 1.7.2
|
38 | * @link http://pear.php.net/package/PEAR
|
38 | * @link http://pear.php.net/package/PEAR
|
39 | * @since Class available since Release 1.4.0a1
|
39 | * @since Class available since Release 1.4.0a1
|
40 | */
|
40 | */
|
41 | class PEAR_REST
|
41 | class PEAR_REST
|
42 | {
|
42 | {
|
43 | var $config; |
43 | var $config; |
44 | var $_options; |
44 | var $_options; |
45 | function PEAR_REST(&$config, $options = array()) |
45 | function PEAR_REST(&$config, $options = array()) |
46 | {
|
46 | {
|
47 | $this->config = &$config; |
47 | $this->config = &$config; |
48 | $this->_options = $options; |
48 | $this->_options = $options; |
49 | }
|
49 | }
|
50 | 50 | ||
51 | /**
|
51 | /**
|
52 | * Retrieve REST data, but always retrieve the local cache if it is available.
|
52 | * Retrieve REST data, but always retrieve the local cache if it is available.
|
53 | *
|
53 | *
|
54 | * This is useful for elements that should never change, such as information on a particular
|
54 | * This is useful for elements that should never change, such as information on a particular
|
55 | * release
|
55 | * release
|
56 | * @param string full URL to this resource
|
56 | * @param string full URL to this resource
|
57 | * @param array|false contents of the accept-encoding header
|
57 | * @param array|false contents of the accept-encoding header
|
58 | * @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
58 | * @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
59 | * parsed using PEAR_XMLParser
|
59 | * parsed using PEAR_XMLParser
|
60 | * @return string|array
|
60 | * @return string|array
|
61 | */
|
61 | */
|
62 | function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) |
62 | function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) |
63 | {
|
63 | {
|
64 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
64 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
65 | md5($url) . 'rest.cachefile'; |
65 | md5($url) . 'rest.cachefile'; |
66 | if (file_exists($cachefile)) { |
66 | if (file_exists($cachefile)) { |
67 | return unserialize(implode('', file($cachefile))); |
67 | return unserialize(implode('', file($cachefile))); |
68 | }
|
68 | }
|
69 | return $this->retrieveData($url, $accept, $forcestring, $channel); |
69 | return $this->retrieveData($url, $accept, $forcestring, $channel); |
70 | }
|
70 | }
|
71 | 71 | ||
72 | /**
|
72 | /**
|
73 | * Retrieve a remote REST resource
|
73 | * Retrieve a remote REST resource
|
74 | * @param string full URL to this resource
|
74 | * @param string full URL to this resource
|
75 | * @param array|false contents of the accept-encoding header
|
75 | * @param array|false contents of the accept-encoding header
|
76 | * @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
76 | * @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
77 | * parsed using PEAR_XMLParser
|
77 | * parsed using PEAR_XMLParser
|
78 | * @return string|array
|
78 | * @return string|array
|
79 | */
|
79 | */
|
80 | function retrieveData($url, $accept = false, $forcestring = false, $channel = false) |
80 | function retrieveData($url, $accept = false, $forcestring = false, $channel = false) |
81 | {
|
81 | {
|
82 | $cacheId = $this->getCacheId($url); |
82 | $cacheId = $this->getCacheId($url); |
83 | if ($ret = $this->useLocalCache($url, $cacheId)) { |
83 | if ($ret = $this->useLocalCache($url, $cacheId)) { |
84 | return $ret; |
84 | return $ret; |
85 | }
|
85 | }
|
86 | if (!isset($this->_options['offline'])) { |
86 | if (!isset($this->_options['offline'])) { |
87 | $trieddownload = true; |
87 | $trieddownload = true; |
88 | $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); |
88 | $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); |
89 | } else { |
89 | } else { |
90 | $trieddownload = false; |
90 | $trieddownload = false; |
91 | $file = false; |
91 | $file = false; |
92 | }
|
92 | }
|
93 | if (PEAR::isError($file)) { |
93 | if (PEAR::isError($file)) { |
94 | if ($file->getCode() == -9276) { |
94 | if ($file->getCode() == -9276) { |
95 | $trieddownload = false; |
95 | $trieddownload = false; |
96 | $file = false; // use local copy if available on socket connect error |
96 | $file = false; // use local copy if available on socket connect error |
97 | } else { |
97 | } else { |
98 | return $file; |
98 | return $file; |
99 | }
|
99 | }
|
100 | }
|
100 | }
|
101 | if (!$file) { |
101 | if (!$file) { |
102 | $ret = $this->getCache($url); |
102 | $ret = $this->getCache($url); |
103 | if (!PEAR::isError($ret) && $trieddownload) { |
103 | if (!PEAR::isError($ret) && $trieddownload) { |
104 | // reset the age of the cache if the server says it was unmodified
|
104 | // reset the age of the cache if the server says it was unmodified
|
105 | $this->saveCache($url, $ret, null, true, $cacheId); |
105 | $this->saveCache($url, $ret, null, true, $cacheId); |
106 | }
|
106 | }
|
107 | return $ret; |
107 | return $ret; |
108 | }
|
108 | }
|
109 | if (is_array($file)) { |
109 | if (is_array($file)) { |
110 | $headers = $file[2]; |
110 | $headers = $file[2]; |
111 | $lastmodified = $file[1]; |
111 | $lastmodified = $file[1]; |
112 | $content = $file[0]; |
112 | $content = $file[0]; |
113 | } else { |
113 | } else { |
114 | $content = $file; |
114 | $content = $file; |
115 | $lastmodified = false; |
115 | $lastmodified = false; |
116 | $headers = array(); |
116 | $headers = array(); |
117 | }
|
117 | }
|
118 | if ($forcestring) { |
118 | if ($forcestring) { |
119 | $this->saveCache($url, $content, $lastmodified, false, $cacheId); |
119 | $this->saveCache($url, $content, $lastmodified, false, $cacheId); |
120 | return $content; |
120 | return $content; |
121 | }
|
121 | }
|
122 | if (isset($headers['content-type'])) { |
122 | if (isset($headers['content-type'])) { |
123 | switch ($headers['content-type']) { |
123 | switch ($headers['content-type']) { |
124 | case 'text/xml' : |
124 | case 'text/xml' : |
125 | case 'application/xml' : |
125 | case 'application/xml' : |
126 | $parser = new PEAR_XMLParser; |
126 | $parser = new PEAR_XMLParser; |
127 | PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
127 | PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
128 | $err = $parser->parse($content); |
128 | $err = $parser->parse($content); |
129 | PEAR::popErrorHandling(); |
129 | PEAR::popErrorHandling(); |
130 | if (PEAR::isError($err)) { |
130 | if (PEAR::isError($err)) { |
131 | return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . |
131 | return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . |
132 | $err->getMessage()); |
132 | $err->getMessage()); |
133 | }
|
133 | }
|
134 | $content = $parser->getData(); |
134 | $content = $parser->getData(); |
135 | case 'text/html' : |
135 | case 'text/html' : |
136 | default : |
136 | default : |
137 | // use it as a string
|
137 | // use it as a string
|
138 | }
|
138 | }
|
139 | } else { |
139 | } else { |
140 | // assume XML
|
140 | // assume XML
|
141 | $parser = new PEAR_XMLParser; |
141 | $parser = new PEAR_XMLParser; |
142 | $parser->parse($content); |
142 | $parser->parse($content); |
143 | $content = $parser->getData(); |
143 | $content = $parser->getData(); |
144 | }
|
144 | }
|
145 | $this->saveCache($url, $content, $lastmodified, false, $cacheId); |
145 | $this->saveCache($url, $content, $lastmodified, false, $cacheId); |
146 | return $content; |
146 | return $content; |
147 | }
|
147 | }
|
148 | 148 | ||
149 | function useLocalCache($url, $cacheid = null) |
149 | function useLocalCache($url, $cacheid = null) |
150 | {
|
150 | {
|
151 | if ($cacheid === null) { |
151 | if ($cacheid === null) { |
152 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
152 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
153 | md5($url) . 'rest.cacheid'; |
153 | md5($url) . 'rest.cacheid'; |
154 | if (file_exists($cacheidfile)) { |
154 | if (file_exists($cacheidfile)) { |
155 | $cacheid = unserialize(implode('', file($cacheidfile))); |
155 | $cacheid = unserialize(implode('', file($cacheidfile))); |
156 | } else { |
156 | } else { |
157 | return false; |
157 | return false; |
158 | }
|
158 | }
|
159 | }
|
159 | }
|
160 | $cachettl = $this->config->get('cache_ttl'); |
160 | $cachettl = $this->config->get('cache_ttl'); |
161 | // If cache is newer than $cachettl seconds, we use the cache!
|
161 | // If cache is newer than $cachettl seconds, we use the cache!
|
162 | if (time() - $cacheid['age'] < $cachettl) { |
162 | if (time() - $cacheid['age'] < $cachettl) { |
163 | return $this->getCache($url); |
163 | return $this->getCache($url); |
164 | }
|
164 | }
|
165 | return false; |
165 | return false; |
166 | }
|
166 | }
|
167 | 167 | ||
168 | function getCacheId($url) |
168 | function getCacheId($url) |
169 | {
|
169 | {
|
170 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
170 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
171 | md5($url) . 'rest.cacheid'; |
171 | md5($url) . 'rest.cacheid'; |
172 | if (file_exists($cacheidfile)) { |
172 | if (file_exists($cacheidfile)) { |
173 | $ret = unserialize(implode('', file($cacheidfile))); |
173 | $ret = unserialize(implode('', file($cacheidfile))); |
174 | return $ret; |
174 | return $ret; |
175 | } else { |
175 | } else { |
176 | return false; |
176 | return false; |
177 | }
|
177 | }
|
178 | }
|
178 | }
|
179 | 179 | ||
180 | function getCache($url) |
180 | function getCache($url) |
181 | {
|
181 | {
|
182 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
182 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
183 | md5($url) . 'rest.cachefile'; |
183 | md5($url) . 'rest.cachefile'; |
184 | if (file_exists($cachefile)) { |
184 | if (file_exists($cachefile)) { |
185 | return unserialize(implode('', file($cachefile))); |
185 | return unserialize(implode('', file($cachefile))); |
186 | } else { |
186 | } else { |
187 | return PEAR::raiseError('No cached content available for "' . $url . '"'); |
187 | return PEAR::raiseError('No cached content available for "' . $url . '"'); |
188 | }
|
188 | }
|
189 | }
|
189 | }
|
190 | 190 | ||
191 | /**
|
191 | /**
|
192 | * @param string full URL to REST resource
|
192 | * @param string full URL to REST resource
|
193 | * @param string original contents of the REST resource
|
193 | * @param string original contents of the REST resource
|
194 | * @param array HTTP Last-Modified and ETag headers
|
194 | * @param array HTTP Last-Modified and ETag headers
|
195 | * @param bool if true, then the cache id file should be regenerated to
|
195 | * @param bool if true, then the cache id file should be regenerated to
|
196 | * trigger a new time-to-live value
|
196 | * trigger a new time-to-live value
|
197 | */
|
197 | */
|
198 | function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) |
198 | function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) |
199 | {
|
199 | {
|
200 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
200 | $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
201 | md5($url) . 'rest.cacheid'; |
201 | md5($url) . 'rest.cacheid'; |
202 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
202 | $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . |
203 | md5($url) . 'rest.cachefile'; |
203 | md5($url) . 'rest.cachefile'; |
204 | if ($cacheid === null && $nochange) { |
204 | if ($cacheid === null && $nochange) { |
205 | $cacheid = unserialize(implode('', file($cacheidfile))); |
205 | $cacheid = unserialize(implode('', file($cacheidfile))); |
206 | }
|
206 | }
|
207 | 207 | ||
208 | $fp = @fopen($cacheidfile, 'wb'); |
208 | $fp = @fopen($cacheidfile, 'wb'); |
209 | if (!$fp) { |
209 | if (!$fp) { |
210 | $cache_dir = $this->config->get('cache_dir'); |
210 | $cache_dir = $this->config->get('cache_dir'); |
211 | if (!is_dir($cache_dir)) { |
211 | if (!is_dir($cache_dir)) { |
212 | System::mkdir(array('-p', $cache_dir)); |
212 | System::mkdir(array('-p', $cache_dir)); |
213 | $fp = @fopen($cacheidfile, 'wb'); |
213 | $fp = @fopen($cacheidfile, 'wb'); |
214 | if (!$fp) { |
214 | if (!$fp) { |
215 | return false; |
215 | return false; |
216 | }
|
216 | }
|
217 | } else { |
217 | } else { |
218 | return false; |
218 | return false; |
219 | }
|
219 | }
|
220 | }
|
220 | }
|
221 | 221 | ||
222 | if ($nochange) { |
222 | if ($nochange) { |
223 | fwrite($fp, serialize(array( |
223 | fwrite($fp, serialize(array( |
224 | 'age' => time(), |
224 | 'age' => time(), |
225 | 'lastChange' => $cacheid['lastChange'], |
225 | 'lastChange' => $cacheid['lastChange'], |
226 | ))); |
226 | ))); |
227 | fclose($fp); |
227 | fclose($fp); |
228 | return true; |
228 | return true; |
229 | } else { |
229 | } else { |
230 | fwrite($fp, serialize(array( |
230 | fwrite($fp, serialize(array( |
231 | 'age' => time(), |
231 | 'age' => time(), |
232 | 'lastChange' => $lastmodified, |
232 | 'lastChange' => $lastmodified, |
233 | ))); |
233 | ))); |
234 | }
|
234 | }
|
235 | fclose($fp); |
235 | fclose($fp); |
236 | $fp = @fopen($cachefile, 'wb'); |
236 | $fp = @fopen($cachefile, 'wb'); |
237 | if (!$fp) { |
237 | if (!$fp) { |
238 | if (file_exists($cacheidfile)) { |
238 | if (file_exists($cacheidfile)) { |
239 | @unlink($cacheidfile); |
239 | @unlink($cacheidfile); |
240 | }
|
240 | }
|
241 | return false; |
241 | return false; |
242 | }
|
242 | }
|
243 | fwrite($fp, serialize($contents)); |
243 | fwrite($fp, serialize($contents)); |
244 | fclose($fp); |
244 | fclose($fp); |
245 | return true; |
245 | return true; |
246 | }
|
246 | }
|
247 | 247 | ||
248 | /**
|
248 | /**
|
249 | * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory
|
249 | * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory
|
250 | * This is best used for small files
|
250 | * This is best used for small files
|
251 | *
|
251 | *
|
252 | * If an HTTP proxy has been configured (http_proxy PEAR_Config
|
252 | * If an HTTP proxy has been configured (http_proxy PEAR_Config
|
253 | * setting), the proxy will be used.
|
253 | * setting), the proxy will be used.
|
254 | *
|
254 | *
|
255 | * @param string $url the URL to download
|
255 | * @param string $url the URL to download
|
256 | * @param string $save_dir directory to save file in
|
256 | * @param string $save_dir directory to save file in
|
257 | * @param false|string|array $lastmodified header values to check against for caching
|
257 | * @param false|string|array $lastmodified header values to check against for caching
|
258 | * use false to return the header values from this download
|
258 | * use false to return the header values from this download
|
259 | * @param false|array $accept Accept headers to send
|
259 | * @param false|array $accept Accept headers to send
|
260 | * @return string|array Returns the contents of the downloaded file or a PEAR
|
260 | * @return string|array Returns the contents of the downloaded file or a PEAR
|
261 | * error on failure. If the error is caused by
|
261 | * error on failure. If the error is caused by
|
262 | * socket-related errors, the error object will
|
262 | * socket-related errors, the error object will
|
263 | * have the fsockopen error code available through
|
263 | * have the fsockopen error code available through
|
264 | * getCode(). If caching is requested, then return the header
|
264 | * getCode(). If caching is requested, then return the header
|
265 | * values.
|
265 | * values.
|
266 | *
|
266 | *
|
267 | * @access public
|
267 | * @access public
|
268 | */
|
268 | */
|
269 | function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) |
269 | function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) |
270 | {
|
270 | {
|
271 | $info = parse_url($url); |
271 | $info = parse_url($url); |
272 | if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { |
272 | if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { |
273 | return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); |
273 | return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); |
274 | }
|
274 | }
|
275 | if (!isset($info['host'])) { |
275 | if (!isset($info['host'])) { |
276 | return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); |
276 | return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); |
277 | } else { |
277 | } else { |
278 | $host = $info['host']; |
278 | $host = $info['host']; |
279 | if (!array_key_exists('port', $info)) { |
279 | if (!array_key_exists('port', $info)) { |
280 | $info['port'] = null; |
280 | $info['port'] = null; |
281 | }
|
281 | }
|
282 | if (!array_key_exists('path', $info)) { |
282 | if (!array_key_exists('path', $info)) { |
283 | $info['path'] = null; |
283 | $info['path'] = null; |
284 | }
|
284 | }
|
285 | $port = $info['port']; |
285 | $port = $info['port']; |
286 | $path = $info['path']; |
286 | $path = $info['path']; |
287 | }
|
287 | }
|
288 | $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; |
288 | $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; |
289 | if ($this->config->get('http_proxy')&& |
289 | if ($this->config->get('http_proxy')&& |
290 | $proxy = parse_url($this->config->get('http_proxy'))) { |
290 | $proxy = parse_url($this->config->get('http_proxy'))) { |
291 | $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; |
291 | $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; |
292 | if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { |
292 | if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { |
293 | $proxy_host = 'ssl://' . $proxy_host; |
293 | $proxy_host = 'ssl://' . $proxy_host; |
294 | }
|
294 | }
|
295 | $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; |
295 | $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; |
296 | $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; |
296 | $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; |
297 | $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; |
297 | $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; |
298 | }
|
298 | }
|
299 | if (empty($port)) { |
299 | if (empty($port)) { |
300 | if (isset($info['scheme']) && $info['scheme'] == 'https') { |
300 | if (isset($info['scheme']) && $info['scheme'] == 'https') { |
301 | $port = 443; |
301 | $port = 443; |
302 | } else { |
302 | } else { |
303 | $port = 80; |
303 | $port = 80; |
304 | }
|
304 | }
|
305 | }
|
305 | }
|
306 | If (isset($proxy['host'])) { |
306 | If (isset($proxy['host'])) { |
307 | $request = "GET $url HTTP/1.1\r\n"; |
307 | $request = "GET $url HTTP/1.1\r\n"; |
308 | } else { |
308 | } else { |
309 | $request = "GET $path HTTP/1.1\r\n"; |
309 | $request = "GET $path HTTP/1.1\r\n"; |
310 | }
|
310 | }
|
311 | $request .= "Host: $host:$port\r\n"; |
311 | $request .= "Host: $host:$port\r\n"; |
312 | 312 | ||
313 | $ifmodifiedsince = ''; |
313 | $ifmodifiedsince = ''; |
314 | if (is_array($lastmodified)) { |
314 | if (is_array($lastmodified)) { |
315 | if (isset($lastmodified['Last-Modified'])) { |
315 | if (isset($lastmodified['Last-Modified'])) { |
316 | $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; |
316 | $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; |
317 | }
|
317 | }
|
318 | if (isset($lastmodified['ETag'])) { |
318 | if (isset($lastmodified['ETag'])) { |
319 | $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; |
319 | $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; |
320 | }
|
320 | }
|
321 | } else { |
321 | } else { |
322 | $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); |
322 | $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); |
323 | }
|
323 | }
|
324 | $request .= $ifmodifiedsince . |
324 | $request .= $ifmodifiedsince . |
325 | "User-Agent: PEAR/1.7.2/PHP/" . PHP_VERSION . "\r\n"; |
325 | "User-Agent: PEAR/1.7.2/PHP/" . PHP_VERSION . "\r\n"; |
326 | $username = $this->config->get('username', null, $channel); |
326 | $username = $this->config->get('username', null, $channel); |
327 | $password = $this->config->get('password', null, $channel); |
327 | $password = $this->config->get('password', null, $channel); |
328 | if ($username && $password) { |
328 | if ($username && $password) { |
329 | $tmp = base64_encode("$username:$password"); |
329 | $tmp = base64_encode("$username:$password"); |
330 | $request .= "Authorization: Basic $tmp\r\n"; |
330 | $request .= "Authorization: Basic $tmp\r\n"; |
331 | }
|
331 | }
|
332 | if ($proxy_host != '' && $proxy_user != '') { |
332 | if ($proxy_host != '' && $proxy_user != '') { |
333 | $request .= 'Proxy-Authorization: Basic ' . |
333 | $request .= 'Proxy-Authorization: Basic ' . |
334 | base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; |
334 | base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; |
335 | }
|
335 | }
|
336 | if ($accept) { |
336 | if ($accept) { |
337 | $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; |
337 | $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; |
338 | }
|
338 | }
|
339 | $request .= "Accept-Encoding:\r\n"; |
339 | $request .= "Accept-Encoding:\r\n"; |
340 | $request .= "Connection: close\r\n"; |
340 | $request .= "Connection: close\r\n"; |
341 | $request .= "\r\n"; |
341 | $request .= "\r\n"; |
342 | if ($proxy_host != '') { |
342 | if ($proxy_host != '') { |
343 | $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15); |
343 | $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15); |
344 | if (!$fp) { |
344 | if (!$fp) { |
345 | return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", |
345 | return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", |
346 | -9276); |
346 | -9276); |
347 | }
|
347 | }
|
348 | } else { |
348 | } else { |
349 | if (isset($info['scheme']) && $info['scheme'] == 'https') { |
349 | if (isset($info['scheme']) && $info['scheme'] == 'https') { |
350 | $host = 'ssl://' . $host; |
350 | $host = 'ssl://' . $host; |
351 | }
|
351 | }
|
352 | $fp = @fsockopen($host, $port, $errno, $errstr); |
352 | $fp = @fsockopen($host, $port, $errno, $errstr); |
353 | if (!$fp) { |
353 | if (!$fp) { |
354 | return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); |
354 | return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); |
355 | }
|
355 | }
|
356 | }
|
356 | }
|
357 | fwrite($fp, $request); |
357 | fwrite($fp, $request); |
358 | $headers = array(); |
358 | $headers = array(); |
359 | while (trim($line = fgets($fp, 1024))) { |
359 | while (trim($line = fgets($fp, 1024))) { |
360 | if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { |
360 | if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { |
361 | $headers[strtolower($matches[1])] = trim($matches[2]); |
361 | $headers[strtolower($matches[1])] = trim($matches[2]); |
362 | } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { |
362 | } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { |
363 | if ($matches[1] == 304 && ($lastmodified || ($lastmodified === false))) { |
363 | if ($matches[1] == 304 && ($lastmodified || ($lastmodified === false))) { |
364 | return false; |
364 | return false; |
365 | }
|
365 | }
|
366 | if ($matches[1] != 200) { |
366 | if ($matches[1] != 200) { |
367 | return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)", (int) $matches[1]); |
367 | return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)", (int) $matches[1]); |
368 | }
|
368 | }
|
369 | }
|
369 | }
|
370 | }
|
370 | }
|
371 | if (isset($headers['content-length'])) { |
371 | if (isset($headers['content-length'])) { |
372 | $length = $headers['content-length']; |
372 | $length = $headers['content-length']; |
373 | } else { |
373 | } else { |
374 | $length = -1; |
374 | $length = -1; |
375 | }
|
375 | }
|
376 | $data = ''; |
376 | $data = ''; |
377 | while ($chunk = @fread($fp, 8192)) { |
377 | while ($chunk = @fread($fp, 8192)) { |
378 | $data .= $chunk; |
378 | $data .= $chunk; |
379 | }
|
379 | }
|
380 | fclose($fp); |
380 | fclose($fp); |
381 | if ($lastmodified === false || $lastmodified) { |
381 | if ($lastmodified === false || $lastmodified) { |
382 | if (isset($headers['etag'])) { |
382 | if (isset($headers['etag'])) { |
383 | $lastmodified = array('ETag' => $headers['etag']); |
383 | $lastmodified = array('ETag' => $headers['etag']); |
384 | }
|
384 | }
|
385 | if (isset($headers['last-modified'])) { |
385 | if (isset($headers['last-modified'])) { |
386 | if (is_array($lastmodified)) { |
386 | if (is_array($lastmodified)) { |
387 | $lastmodified['Last-Modified'] = $headers['last-modified']; |
387 | $lastmodified['Last-Modified'] = $headers['last-modified']; |
388 | } else { |
388 | } else { |
389 | $lastmodified = $headers['last-modified']; |
389 | $lastmodified = $headers['last-modified']; |
390 | }
|
390 | }
|
391 | }
|
391 | }
|
392 | return array($data, $lastmodified, $headers); |
392 | return array($data, $lastmodified, $headers); |
393 | }
|
393 | }
|
394 | return $data; |
394 | return $data; |
395 | }
|
395 | }
|
396 | }
|
396 | }
|
397 | ?>
|
397 | ?>
|
398 | 398 |