XOOPS Cube Legacy base repository
Revisión | c3718b7bff6d64f103b7b7eb380852c1ee1cec8a (tree) |
---|---|
Tiempo | 2010-11-14 00:14:05 |
Autor | kilica <kilica@704c...> |
Commiter | kilica |
- Fix Bug #2666664 - /class/snoopy.php is susceptible to a remote command.
git-svn-id: https://xoopscube.svn.sourceforge.net/svnroot/xoopscube/Package_Legacy/trunk@832 704cf05f-ae62-4b0e-a484-234ee0250e75
@@ -1,1288 +1,1269 @@ | ||
1 | -<?php | |
2 | - | |
3 | -/************************************************* | |
4 | - | |
5 | -Snoopy - the PHP net client | |
6 | -Author: Monte Ohrt <monte@ispi.net> | |
7 | -Copyright (c): 1999-2000 ispi, all rights reserved | |
8 | -Version: 1.01 | |
9 | - | |
10 | - * This library is free software; you can redistribute it and/or | |
11 | - * modify it under the terms of the GNU Lesser General Public | |
12 | - * License as published by the Free Software Foundation; either | |
13 | - * version 2.1 of the License, or (at your option) any later version. | |
14 | - * | |
15 | - * This library is distributed in the hope that it will be useful, | |
16 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | - * Lesser General Public License for more details. | |
19 | - * | |
20 | - * You should have received a copy of the GNU Lesser General Public | |
21 | - * License along with this library; if not, write to the Free Software | |
22 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | - | |
24 | -You may contact the author of Snoopy by e-mail at: | |
25 | -monte@ispi.net | |
26 | - | |
27 | -Or, write to: | |
28 | -Monte Ohrt | |
29 | -CTO, ispi | |
30 | -237 S. 70th suite 220 | |
31 | -Lincoln, NE 68510 | |
32 | - | |
33 | -The latest version of Snoopy can be obtained from: | |
34 | -http://snoopy.sourceforge.net/ | |
35 | - | |
36 | -*************************************************/ | |
37 | - | |
38 | -class Snoopy | |
39 | -{ | |
40 | - /**** Public variables ****/ | |
41 | - | |
42 | - /* user definable vars */ | |
43 | - | |
44 | - var $host = "www.php.net"; // host name we are connecting to | |
45 | - var $port = 80; // port we are connecting to | |
46 | - var $host_port = ""; // port for Host Header | |
47 | - var $proxy_host = ""; // proxy host to use | |
48 | - var $proxy_port = ""; // proxy port to use | |
49 | - var $proxy_user = ""; // proxy user to use | |
50 | - var $proxy_pass = ""; // proxy password to use | |
51 | - | |
52 | - var $agent = "Snoopy v1.2.3"; // agent we masquerade as | |
53 | - var $referer = ""; // referer info to pass | |
54 | - var $cookies = array(); // array of cookies to pass | |
55 | - // $cookies["username"]="joe"; | |
56 | - var $rawheaders = array(); // array of raw headers to send | |
57 | - // $rawheaders["Content-type"]="text/html"; | |
58 | - | |
59 | - var $maxredirs = 5; // http redirection depth maximum. 0 = disallow | |
60 | - var $lastredirectaddr = ""; // contains address of last redirected address | |
61 | - var $offsiteok = true; // allows redirection off-site | |
62 | - var $maxframes = 0; // frame content depth maximum. 0 = disallow | |
63 | - var $expandlinks = true; // expand links to fully qualified URLs. | |
64 | - // this only applies to fetchlinks() | |
65 | - // submitlinks(), and submittext() | |
66 | - var $passcookies = true; // pass set cookies back through redirects | |
67 | - // NOTE: this currently does not respect | |
68 | - // dates, domains or paths. | |
69 | - | |
70 | - var $user = ""; // user for http authentication | |
71 | - var $pass = ""; // password for http authentication | |
72 | - | |
73 | - // http accept types | |
74 | - var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; | |
75 | - | |
76 | - var $results = ""; // where the content is put | |
77 | - | |
78 | - var $error = ""; // error messages sent here | |
79 | - var $response_code = ""; // response code returned from server | |
80 | - var $headers = array(); // headers returned from server sent here | |
81 | - var $maxlength = 500000; // max return data length (body) | |
82 | - var $read_timeout = 0; // timeout on read operations, in seconds | |
83 | - // supported only since PHP 4 Beta 4 | |
84 | - // set to 0 to disallow timeouts | |
85 | - var $timed_out = false; // if a read operation timed out | |
86 | - var $status = 0; // http request status | |
87 | - | |
88 | - var $temp_dir = "/tmp"; // temporary directory that the webserver | |
89 | - // has permission to write to. | |
90 | - // under Windows, this should be C:\temp | |
91 | - | |
92 | - var $curl_path = "/usr/local/bin/curl"; | |
93 | - // Snoopy will use cURL for fetching | |
94 | - // SSL content if a full system path to | |
95 | - // the cURL binary is supplied here. | |
96 | - // set to false if you do not have | |
97 | - // cURL installed. See http://curl.haxx.se | |
98 | - // for details on installing cURL. | |
99 | - // Snoopy does *not* use the cURL | |
100 | - // library functions built into php, | |
101 | - // as these functions are not stable | |
102 | - // as of this Snoopy release. | |
103 | - | |
104 | - /**** Private variables ****/ | |
105 | - | |
106 | - var $_maxlinelen = 4096; // max line length (headers) | |
107 | - | |
108 | - var $_httpmethod = "GET"; // default http request method | |
109 | - var $_httpversion = "HTTP/1.0"; // default http request version | |
110 | - var $_submit_method = "POST"; // default submit method | |
111 | - var $_submit_type = "application/x-www-form-urlencoded"; // default submit type | |
112 | - var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type | |
113 | - var $_redirectaddr = false; // will be set if page fetched is a redirect | |
114 | - var $_redirectdepth = 0; // increments on an http redirect | |
115 | - var $_frameurls = array(); // frame src urls | |
116 | - var $_framedepth = 0; // increments on frame depth | |
117 | - | |
118 | - var $_isproxy = false; // set if using a proxy server | |
119 | - var $_fp_timeout = 30; // timeout for socket connection | |
120 | - | |
121 | -/*======================================================================*\ | |
122 | - Function: fetch | |
123 | - Purpose: fetch the contents of a web page | |
124 | - (and possibly other protocols in the | |
125 | - future like ftp, nntp, gopher, etc.) | |
126 | - Input: $URI the location of the page to fetch | |
127 | - Output: $this->results the output text from the fetch | |
128 | -\*======================================================================*/ | |
129 | - | |
130 | - function fetch($URI) | |
131 | - { | |
132 | - | |
133 | - //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS); | |
134 | - $URI_PARTS = parse_url($URI); | |
135 | - if (!empty($URI_PARTS["user"])) | |
136 | - $this->user = $URI_PARTS["user"]; | |
137 | - if (!empty($URI_PARTS["pass"])) | |
138 | - $this->pass = $URI_PARTS["pass"]; | |
139 | - if (empty($URI_PARTS["query"])) | |
140 | - $URI_PARTS["query"] = ''; | |
141 | - if (empty($URI_PARTS["path"])) | |
142 | - $URI_PARTS["path"] = ''; | |
143 | - | |
144 | - switch(strtolower($URI_PARTS["scheme"])) | |
145 | - { | |
146 | - case "http": | |
147 | - $this->host = $URI_PARTS["host"]; | |
148 | - if(!empty($URI_PARTS["port"])) { | |
149 | - $this->port = $URI_PARTS["port"]; | |
150 | - $this->host_port = $URI_PARTS["port"]; | |
151 | - } | |
152 | - if($this->_connect($fp)) | |
153 | - { | |
154 | - if($this->_isproxy) | |
155 | - { | |
156 | - // using proxy, send entire URI | |
157 | - $this->_httprequest($URI,$fp,$URI,$this->_httpmethod); | |
158 | - } | |
159 | - else | |
160 | - { | |
161 | - $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
162 | - // no proxy, send only the path | |
163 | - $this->_httprequest($path, $fp, $URI, $this->_httpmethod); | |
164 | - } | |
165 | - | |
166 | - $this->_disconnect($fp); | |
167 | - | |
168 | - if($this->_redirectaddr) | |
169 | - { | |
170 | - /* url was redirected, check if we've hit the max depth */ | |
171 | - if($this->maxredirs > $this->_redirectdepth) | |
172 | - { | |
173 | - // only follow redirect if it's on this site, or offsiteok is true | |
174 | - if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
175 | - { | |
176 | - /* follow the redirect */ | |
177 | - $this->_redirectdepth++; | |
178 | - $this->lastredirectaddr=$this->_redirectaddr; | |
179 | - $this->fetch($this->_redirectaddr); | |
180 | - } | |
181 | - } | |
182 | - } | |
183 | - | |
184 | - if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
185 | - { | |
186 | - $frameurls = $this->_frameurls; | |
187 | - $this->_frameurls = array(); | |
188 | - | |
189 | - while(list(,$frameurl) = each($frameurls)) | |
190 | - { | |
191 | - if($this->_framedepth < $this->maxframes) | |
192 | - { | |
193 | - $this->fetch($frameurl); | |
194 | - $this->_framedepth++; | |
195 | - } | |
196 | - else | |
197 | - break; | |
198 | - } | |
199 | - } | |
200 | - } | |
201 | - else | |
202 | - { | |
203 | - return false; | |
204 | - } | |
205 | - return true; | |
206 | - break; | |
207 | - case "https": | |
208 | - if(!$this->curl_path) | |
209 | - return false; | |
210 | - if(function_exists("is_executable")) | |
211 | - if (!is_executable($this->curl_path)) | |
212 | - return false; | |
213 | - $this->host = $URI_PARTS["host"]; | |
214 | - if(!empty($URI_PARTS["port"])) { | |
215 | - $this->port = $URI_PARTS["port"]; | |
216 | - $this->host_port = $URI_PARTS["port"]; | |
217 | - } | |
218 | - if($this->_isproxy) | |
219 | - { | |
220 | - // using proxy, send entire URI | |
221 | - $this->_httpsrequest($URI,$URI,$this->_httpmethod); | |
222 | - } | |
223 | - else | |
224 | - { | |
225 | - $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
226 | - // no proxy, send only the path | |
227 | - $this->_httpsrequest($path, $URI, $this->_httpmethod); | |
228 | - } | |
229 | - | |
230 | - if($this->_redirectaddr) | |
231 | - { | |
232 | - /* url was redirected, check if we've hit the max depth */ | |
233 | - if($this->maxredirs > $this->_redirectdepth) | |
234 | - { | |
235 | - // only follow redirect if it's on this site, or offsiteok is true | |
236 | - if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
237 | - { | |
238 | - /* follow the redirect */ | |
239 | - $this->_redirectdepth++; | |
240 | - $this->lastredirectaddr=$this->_redirectaddr; | |
241 | - $this->fetch($this->_redirectaddr); | |
242 | - } | |
243 | - } | |
244 | - } | |
245 | - | |
246 | - if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
247 | - { | |
248 | - $frameurls = $this->_frameurls; | |
249 | - $this->_frameurls = array(); | |
250 | - | |
251 | - while(list(,$frameurl) = each($frameurls)) | |
252 | - { | |
253 | - if($this->_framedepth < $this->maxframes) | |
254 | - { | |
255 | - $this->fetch($frameurl); | |
256 | - $this->_framedepth++; | |
257 | - } | |
258 | - else | |
259 | - break; | |
260 | - } | |
261 | - } | |
262 | - return true; | |
263 | - break; | |
264 | - default: | |
265 | - // not a valid protocol | |
266 | - $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; | |
267 | - return false; | |
268 | - break; | |
269 | - } | |
270 | - return true; | |
271 | - } | |
272 | - | |
273 | -/*======================================================================*\ | |
274 | - Function: submit | |
275 | - Purpose: submit an http form | |
276 | - Input: $URI the location to post the data | |
277 | - $formvars the formvars to use. | |
278 | - format: $formvars["var"] = "val"; | |
279 | - $formfiles an array of files to submit | |
280 | - format: $formfiles["var"] = "/dir/filename.ext"; | |
281 | - Output: $this->results the text output from the post | |
282 | -\*======================================================================*/ | |
283 | - | |
284 | - function submit($URI, $formvars="", $formfiles="") | |
285 | - { | |
286 | - unset($postdata); | |
287 | - | |
288 | - $postdata = $this->_prepare_post_body($formvars, $formfiles); | |
289 | - | |
290 | - $URI_PARTS = parse_url($URI); | |
291 | - if (!empty($URI_PARTS["user"])) | |
292 | - $this->user = $URI_PARTS["user"]; | |
293 | - if (!empty($URI_PARTS["pass"])) | |
294 | - $this->pass = $URI_PARTS["pass"]; | |
295 | - if (empty($URI_PARTS["query"])) | |
296 | - $URI_PARTS["query"] = ''; | |
297 | - if (empty($URI_PARTS["path"])) | |
298 | - $URI_PARTS["path"] = ''; | |
299 | - | |
300 | - switch(strtolower($URI_PARTS["scheme"])) | |
301 | - { | |
302 | - case "http": | |
303 | - $this->host = $URI_PARTS["host"]; | |
304 | - if(!empty($URI_PARTS["port"])) { | |
305 | - $this->port = $URI_PARTS["port"]; | |
306 | - $this->host_port = $URI_PARTS["port"]; | |
307 | - } | |
308 | - if($this->_connect($fp)) | |
309 | - { | |
310 | - if($this->_isproxy) | |
311 | - { | |
312 | - // using proxy, send entire URI | |
313 | - $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata); | |
314 | - } | |
315 | - else | |
316 | - { | |
317 | - $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
318 | - // no proxy, send only the path | |
319 | - $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
320 | - } | |
321 | - | |
322 | - $this->_disconnect($fp); | |
323 | - | |
324 | - if($this->_redirectaddr) | |
325 | - { | |
326 | - /* url was redirected, check if we've hit the max depth */ | |
327 | - if($this->maxredirs > $this->_redirectdepth) | |
328 | - { | |
329 | - if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) | |
330 | - $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); | |
331 | - | |
332 | - // only follow redirect if it's on this site, or offsiteok is true | |
333 | - if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
334 | - { | |
335 | - /* follow the redirect */ | |
336 | - $this->_redirectdepth++; | |
337 | - $this->lastredirectaddr=$this->_redirectaddr; | |
338 | - if( strpos( $this->_redirectaddr, "?" ) > 0 ) | |
339 | - $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get | |
340 | - else | |
341 | - $this->submit($this->_redirectaddr,$formvars, $formfiles); | |
342 | - } | |
343 | - } | |
344 | - } | |
345 | - | |
346 | - if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
347 | - { | |
348 | - $frameurls = $this->_frameurls; | |
349 | - $this->_frameurls = array(); | |
350 | - | |
351 | - while(list(,$frameurl) = each($frameurls)) | |
352 | - { | |
353 | - if($this->_framedepth < $this->maxframes) | |
354 | - { | |
355 | - $this->fetch($frameurl); | |
356 | - $this->_framedepth++; | |
357 | - } | |
358 | - else | |
359 | - break; | |
360 | - } | |
361 | - } | |
362 | - | |
363 | - } | |
364 | - else | |
365 | - { | |
366 | - return false; | |
367 | - } | |
368 | - return true; | |
369 | - break; | |
370 | - case "https": | |
371 | - if(!$this->curl_path) | |
372 | - return false; | |
373 | - if(function_exists("is_executable")) | |
374 | - if (!is_executable($this->curl_path)) | |
375 | - return false; | |
376 | - $this->host = $URI_PARTS["host"]; | |
377 | - if(!empty($URI_PARTS["port"])) { | |
378 | - $this->port = $URI_PARTS["port"]; | |
379 | - $this->host_port = $URI_PARTS["port"]; | |
380 | - } | |
381 | - if($this->_isproxy) | |
382 | - { | |
383 | - // using proxy, send entire URI | |
384 | - $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
385 | - } | |
386 | - else | |
387 | - { | |
388 | - $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
389 | - // no proxy, send only the path | |
390 | - $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
391 | - } | |
392 | - | |
393 | - if($this->_redirectaddr) | |
394 | - { | |
395 | - /* url was redirected, check if we've hit the max depth */ | |
396 | - if($this->maxredirs > $this->_redirectdepth) | |
397 | - { | |
398 | - if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) | |
399 | - $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); | |
400 | - | |
401 | - // only follow redirect if it's on this site, or offsiteok is true | |
402 | - if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
403 | - { | |
404 | - /* follow the redirect */ | |
405 | - $this->_redirectdepth++; | |
406 | - $this->lastredirectaddr=$this->_redirectaddr; | |
407 | - if( strpos( $this->_redirectaddr, "?" ) > 0 ) | |
408 | - $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get | |
409 | - else | |
410 | - $this->submit($this->_redirectaddr,$formvars, $formfiles); | |
411 | - } | |
412 | - } | |
413 | - } | |
414 | - | |
415 | - if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
416 | - { | |
417 | - $frameurls = $this->_frameurls; | |
418 | - $this->_frameurls = array(); | |
419 | - | |
420 | - while(list(,$frameurl) = each($frameurls)) | |
421 | - { | |
422 | - if($this->_framedepth < $this->maxframes) | |
423 | - { | |
424 | - $this->fetch($frameurl); | |
425 | - $this->_framedepth++; | |
426 | - } | |
427 | - else | |
428 | - break; | |
429 | - } | |
430 | - } | |
431 | - return true; | |
432 | - break; | |
433 | - | |
434 | - default: | |
435 | - // not a valid protocol | |
436 | - $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; | |
437 | - return false; | |
438 | - break; | |
439 | - } | |
440 | - return true; | |
441 | - } | |
442 | - | |
443 | -/*======================================================================*\ | |
444 | - Function: fetchlinks | |
445 | - Purpose: fetch the links from a web page | |
446 | - Input: $URI where you are fetching from | |
447 | - Output: $this->results an array of the URLs | |
448 | -\*======================================================================*/ | |
449 | - | |
450 | - function fetchlinks($URI) | |
451 | - { | |
452 | - if ($this->fetch($URI)) | |
453 | - { | |
454 | - if($this->lastredirectaddr) | |
455 | - $URI = $this->lastredirectaddr; | |
456 | - if(is_array($this->results)) | |
457 | - { | |
458 | - for($x=0;$x<count($this->results);$x++) | |
459 | - $this->results[$x] = $this->_striplinks($this->results[$x]); | |
460 | - } | |
461 | - else | |
462 | - $this->results = $this->_striplinks($this->results); | |
463 | - | |
464 | - if($this->expandlinks) | |
465 | - $this->results = $this->_expandlinks($this->results, $URI); | |
466 | - return true; | |
467 | - } | |
468 | - else | |
469 | - return false; | |
470 | - } | |
471 | - | |
472 | -/*======================================================================*\ | |
473 | - Function: fetchform | |
474 | - Purpose: fetch the form elements from a web page | |
475 | - Input: $URI where you are fetching from | |
476 | - Output: $this->results the resulting html form | |
477 | -\*======================================================================*/ | |
478 | - | |
479 | - function fetchform($URI) | |
480 | - { | |
481 | - | |
482 | - if ($this->fetch($URI)) | |
483 | - { | |
484 | - | |
485 | - if(is_array($this->results)) | |
486 | - { | |
487 | - for($x=0;$x<count($this->results);$x++) | |
488 | - $this->results[$x] = $this->_stripform($this->results[$x]); | |
489 | - } | |
490 | - else | |
491 | - $this->results = $this->_stripform($this->results); | |
492 | - | |
493 | - return true; | |
494 | - } | |
495 | - else | |
496 | - return false; | |
497 | - } | |
498 | - | |
499 | - | |
500 | -/*======================================================================*\ | |
501 | - Function: fetchtext | |
502 | - Purpose: fetch the text from a web page, stripping the links | |
503 | - Input: $URI where you are fetching from | |
504 | - Output: $this->results the text from the web page | |
505 | -\*======================================================================*/ | |
506 | - | |
507 | - function fetchtext($URI) | |
508 | - { | |
509 | - if($this->fetch($URI)) | |
510 | - { | |
511 | - if(is_array($this->results)) | |
512 | - { | |
513 | - for($x=0;$x<count($this->results);$x++) | |
514 | - $this->results[$x] = $this->_striptext($this->results[$x]); | |
515 | - } | |
516 | - else | |
517 | - $this->results = $this->_striptext($this->results); | |
518 | - return true; | |
519 | - } | |
520 | - else | |
521 | - return false; | |
522 | - } | |
523 | - | |
524 | -/*======================================================================*\ | |
525 | - Function: submitlinks | |
526 | - Purpose: grab links from a form submission | |
527 | - Input: $URI where you are submitting from | |
528 | - Output: $this->results an array of the links from the post | |
529 | -\*======================================================================*/ | |
530 | - | |
531 | - function submitlinks($URI, $formvars="", $formfiles="") | |
532 | - { | |
533 | - if($this->submit($URI,$formvars, $formfiles)) | |
534 | - { | |
535 | - if($this->lastredirectaddr) | |
536 | - $URI = $this->lastredirectaddr; | |
537 | - if(is_array($this->results)) | |
538 | - { | |
539 | - for($x=0;$x<count($this->results);$x++) | |
540 | - { | |
541 | - $this->results[$x] = $this->_striplinks($this->results[$x]); | |
542 | - if($this->expandlinks) | |
543 | - $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); | |
544 | - } | |
545 | - } | |
546 | - else | |
547 | - { | |
548 | - $this->results = $this->_striplinks($this->results); | |
549 | - if($this->expandlinks) | |
550 | - $this->results = $this->_expandlinks($this->results,$URI); | |
551 | - } | |
552 | - return true; | |
553 | - } | |
554 | - else | |
555 | - return false; | |
556 | - } | |
557 | - | |
558 | -/*======================================================================*\ | |
559 | - Function: submittext | |
560 | - Purpose: grab text from a form submission | |
561 | - Input: $URI where you are submitting from | |
562 | - Output: $this->results the text from the web page | |
563 | -\*======================================================================*/ | |
564 | - | |
565 | - function submittext($URI, $formvars = "", $formfiles = "") | |
566 | - { | |
567 | - if($this->submit($URI,$formvars, $formfiles)) | |
568 | - { | |
569 | - if($this->lastredirectaddr) | |
570 | - $URI = $this->lastredirectaddr; | |
571 | - if(is_array($this->results)) | |
572 | - { | |
573 | - for($x=0;$x<count($this->results);$x++) | |
574 | - { | |
575 | - $this->results[$x] = $this->_striptext($this->results[$x]); | |
576 | - if($this->expandlinks) | |
577 | - $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); | |
578 | - } | |
579 | - } | |
580 | - else | |
581 | - { | |
582 | - $this->results = $this->_striptext($this->results); | |
583 | - if($this->expandlinks) | |
584 | - $this->results = $this->_expandlinks($this->results,$URI); | |
585 | - } | |
586 | - return true; | |
587 | - } | |
588 | - else | |
589 | - return false; | |
590 | - } | |
591 | - | |
592 | - | |
593 | - | |
594 | -/*======================================================================*\ | |
595 | - Function: set_submit_multipart | |
596 | - Purpose: Set the form submission content type to | |
597 | - multipart/form-data | |
598 | -\*======================================================================*/ | |
599 | - function set_submit_multipart() | |
600 | - { | |
601 | - $this->_submit_type = "multipart/form-data"; | |
602 | - } | |
603 | - | |
604 | - | |
605 | -/*======================================================================*\ | |
606 | - Function: set_submit_normal | |
607 | - Purpose: Set the form submission content type to | |
608 | - application/x-www-form-urlencoded | |
609 | -\*======================================================================*/ | |
610 | - function set_submit_normal() | |
611 | - { | |
612 | - $this->_submit_type = "application/x-www-form-urlencoded"; | |
613 | - } | |
614 | - | |
615 | - | |
616 | -// XOOPS2 Hack begin | |
617 | -// Added on March 4, 2003 by onokazu@xoops.org | |
618 | -/*======================================================================*\ | |
619 | - Function: set_submit_xml | |
620 | - Purpose: Set the submission content type to | |
621 | - text/xml | |
622 | -\*======================================================================*/ | |
623 | - function set_submit_xml() | |
624 | - { | |
625 | - $this->_submit_type = "text/xml"; | |
626 | - } | |
627 | -// XOOPS2 Hack end | |
628 | - | |
629 | - | |
630 | -/*======================================================================*\ | |
631 | - Private functions | |
632 | -\*======================================================================*/ | |
633 | - | |
634 | - | |
635 | -/*======================================================================*\ | |
636 | - Function: _striplinks | |
637 | - Purpose: strip the hyperlinks from an html document | |
638 | - Input: $document document to strip. | |
639 | - Output: $match an array of the links | |
640 | -\*======================================================================*/ | |
641 | - | |
642 | - function _striplinks($document) | |
643 | - { | |
644 | - preg_match_all("'<\s*a\s.*?href\s*=\s* # find <a href= | |
645 | - ([\"\'])? # find single or double quote | |
646 | - (?(1) (.*?)\\1 | ([^\s\>]+)) # if quote found, match up to next matching | |
647 | - # quote, otherwise match up to next space | |
648 | - 'isx",$document,$links); | |
649 | - | |
650 | - | |
651 | - // catenate the non-empty matches from the conditional subpattern | |
652 | - | |
653 | - while(list($key,$val) = each($links[2])) | |
654 | - { | |
655 | - if(!empty($val)) | |
656 | - $match[] = $val; | |
657 | - } | |
658 | - | |
659 | - while(list($key,$val) = each($links[3])) | |
660 | - { | |
661 | - if(!empty($val)) | |
662 | - $match[] = $val; | |
663 | - } | |
664 | - | |
665 | - // return the links | |
666 | - return $match; | |
667 | - } | |
668 | - | |
669 | -/*======================================================================*\ | |
670 | - Function: _stripform | |
671 | - Purpose: strip the form elements from an html document | |
672 | - Input: $document document to strip. | |
673 | - Output: $match an array of the links | |
674 | -\*======================================================================*/ | |
675 | - | |
676 | - function _stripform($document) | |
677 | - { | |
678 | - preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements); | |
679 | - | |
680 | - // catenate the matches | |
681 | - $match = implode("\r\n",$elements[0]); | |
682 | - | |
683 | - // return the links | |
684 | - return $match; | |
685 | - } | |
686 | - | |
687 | - | |
688 | - | |
689 | -/*======================================================================*\ | |
690 | - Function: _striptext | |
691 | - Purpose: strip the text from an html document | |
692 | - Input: $document document to strip. | |
693 | - Output: $text the resulting text | |
694 | -\*======================================================================*/ | |
695 | - | |
696 | - function _striptext($document) | |
697 | - { | |
698 | - | |
699 | - // I didn't use preg eval (//e) since that is only available in PHP 4.0. | |
700 | - // so, list your entities one by one here. I included some of the | |
701 | - // more common ones. | |
702 | - | |
703 | - $search = array("'<script[^>]*?>.*?</script>'si", // strip out javascript | |
704 | - "'<[\/\!]*?[^<>]*?>'si", // strip out html tags | |
705 | - "'([\r\n])[\s]+'", // strip out white space | |
706 | - "'&(quot|#34|#034|#x22);'i", // replace html entities | |
707 | - "'&(amp|#38|#038|#x26);'i", // added hexadecimal values | |
708 | - "'&(lt|#60|#060|#x3c);'i", | |
709 | - "'&(gt|#62|#062|#x3e);'i", | |
710 | - "'&(nbsp|#160|#xa0);'i", | |
711 | - "'&(iexcl|#161);'i", | |
712 | - "'&(cent|#162);'i", | |
713 | - "'&(pound|#163);'i", | |
714 | - "'&(copy|#169);'i", | |
715 | - "'&(reg|#174);'i", | |
716 | - "'&(deg|#176);'i", | |
717 | - "'&(#39|#039|#x27);'", | |
718 | - "'&(euro|#8364);'i", // europe | |
719 | - "'&a(uml|UML);'", // german | |
720 | - "'&o(uml|UML);'", | |
721 | - "'&u(uml|UML);'", | |
722 | - "'&A(uml|UML);'", | |
723 | - "'&O(uml|UML);'", | |
724 | - "'&U(uml|UML);'", | |
725 | - "'ß'i", | |
726 | - ); | |
727 | - $replace = array( "", | |
728 | - "", | |
729 | - "\\1", | |
730 | - "\"", | |
731 | - "&", | |
732 | - "<", | |
733 | - ">", | |
734 | - " ", | |
735 | - chr(161), | |
736 | - chr(162), | |
737 | - chr(163), | |
738 | - chr(169), | |
739 | - chr(174), | |
740 | - chr(176), | |
741 | - chr(39), | |
742 | - chr(128), | |
743 | - chr(228), | |
744 | - chr(246), | |
745 | - chr(252), | |
746 | - chr(196), | |
747 | - chr(214), | |
748 | - chr(220), | |
749 | - chr(223), | |
750 | - ); | |
751 | - | |
752 | - $text = preg_replace($search,$replace,$document); | |
753 | - | |
754 | - return $text; | |
755 | - } | |
756 | - | |
757 | -/*======================================================================*\ | |
758 | - Function: _expandlinks | |
759 | - Purpose: expand each link into a fully qualified URL | |
760 | - Input: $links the links to qualify | |
761 | - $URI the full URI to get the base from | |
762 | - Output: $expandedLinks the expanded links | |
763 | -\*======================================================================*/ | |
764 | - | |
765 | - function _expandlinks($links,$URI) | |
766 | - { | |
767 | - | |
768 | - preg_match("/^[^\?]+/",$URI,$match); | |
769 | - | |
770 | - $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]); | |
771 | - $match = preg_replace("|/$|","",$match); | |
772 | - $match_part = parse_url($match); | |
773 | - $match_root = | |
774 | - $match_part["scheme"]."://".$match_part["host"]; | |
775 | - | |
776 | - $search = array( "|^http://".preg_quote($this->host)."|i", | |
777 | - "|^(\/)|i", | |
778 | - "|^(?!http://)(?!mailto:)|i", | |
779 | - "|/\./|", | |
780 | - "|/[^\/]+/\.\./|" | |
781 | - ); | |
782 | - | |
783 | - $replace = array( "", | |
784 | - $match_root."/", | |
785 | - $match."/", | |
786 | - "/", | |
787 | - "/" | |
788 | - ); | |
789 | - | |
790 | - $expandedLinks = preg_replace($search,$replace,$links); | |
791 | - | |
792 | - return $expandedLinks; | |
793 | - } | |
794 | - | |
795 | -/*======================================================================*\ | |
796 | - Function: _httprequest | |
797 | - Purpose: go get the http data from the server | |
798 | - Input: $url the url to fetch | |
799 | - $fp the current open file pointer | |
800 | - $URI the full URI | |
801 | - $body body contents to send if any (POST) | |
802 | - Output: | |
803 | -\*======================================================================*/ | |
804 | - | |
805 | - function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="") | |
806 | - { | |
807 | - $cookie_headers = ''; | |
808 | - if($this->passcookies && $this->_redirectaddr) | |
809 | - $this->setcookies(); | |
810 | - | |
811 | - $URI_PARTS = parse_url($URI); | |
812 | - if(empty($url)) | |
813 | - $url = "/"; | |
814 | - $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; | |
815 | - if(!empty($this->agent)) | |
816 | - $headers .= "User-Agent: ".$this->agent."\r\n"; | |
817 | - if(!empty($this->host) && !isset($this->rawheaders['Host'])) { | |
818 | - $headers .= "Host: ".$this->host; | |
819 | - if(!empty($this->host_port)) | |
820 | - $headers .= ":".$this->host_port; | |
821 | - $headers .= "\r\n"; | |
822 | - } | |
823 | - if(!empty($this->accept)) | |
824 | - $headers .= "Accept: ".$this->accept."\r\n"; | |
825 | - if(!empty($this->referer)) | |
826 | - $headers .= "Referer: ".$this->referer."\r\n"; | |
827 | - if(!empty($this->cookies)) | |
828 | - { | |
829 | - if(!is_array($this->cookies)) | |
830 | - $this->cookies = (array)$this->cookies; | |
831 | - | |
832 | - reset($this->cookies); | |
833 | - if ( count($this->cookies) > 0 ) { | |
834 | - $cookie_headers .= 'Cookie: '; | |
835 | - foreach ( $this->cookies as $cookieKey => $cookieVal ) { | |
836 | - $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; "; | |
837 | - } | |
838 | - $headers .= substr($cookie_headers,0,-2) . "\r\n"; | |
839 | - } | |
840 | - } | |
841 | - if(!empty($this->rawheaders)) | |
842 | - { | |
843 | - if(!is_array($this->rawheaders)) | |
844 | - $this->rawheaders = (array)$this->rawheaders; | |
845 | - while(list($headerKey,$headerVal) = each($this->rawheaders)) | |
846 | - $headers .= $headerKey.": ".$headerVal."\r\n"; | |
847 | - } | |
848 | - if(!empty($content_type)) { | |
849 | - $headers .= "Content-type: $content_type"; | |
850 | - if ($content_type == "multipart/form-data") | |
851 | - $headers .= "; boundary=".$this->_mime_boundary; | |
852 | - $headers .= "\r\n"; | |
853 | - } | |
854 | - if(!empty($body)) | |
855 | - $headers .= "Content-length: ".strlen($body)."\r\n"; | |
856 | - if(!empty($this->user) || !empty($this->pass)) | |
857 | - $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n"; | |
858 | - | |
859 | - //add proxy auth headers | |
860 | - if(!empty($this->proxy_user)) | |
861 | - $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n"; | |
862 | - | |
863 | - | |
864 | - $headers .= "\r\n"; | |
865 | - | |
866 | - // set the read timeout if needed | |
867 | - if ($this->read_timeout > 0) | |
868 | - socket_set_timeout($fp, $this->read_timeout); | |
869 | - $this->timed_out = false; | |
870 | - | |
871 | - fwrite($fp,$headers.$body,strlen($headers.$body)); | |
872 | - | |
873 | - $this->_redirectaddr = false; | |
874 | - unset($this->headers); | |
875 | - | |
876 | - while($currentHeader = fgets($fp,$this->_maxlinelen)) | |
877 | - { | |
878 | - if ($this->read_timeout > 0 && $this->_check_timeout($fp)) | |
879 | - { | |
880 | - $this->status=-100; | |
881 | - return false; | |
882 | - } | |
883 | - | |
884 | - if($currentHeader == "\r\n") | |
885 | - break; | |
886 | - | |
887 | - // if a header begins with Location: or URI:, set the redirect | |
888 | - if(preg_match("/^(Location:|URI:)/i",$currentHeader)) | |
889 | - { | |
890 | - // get URL portion of the redirect | |
891 | - preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches); | |
892 | - // look for :// in the Location header to see if hostname is included | |
893 | - if(!preg_match("|\:\/\/|",$matches[2])) | |
894 | - { | |
895 | - // no host in the path, so prepend | |
896 | - $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host; | |
897 | - if(!empty($this->host_port)) | |
898 | - $this->_redirectaddr .= ":".$this->host_port; | |
899 | - // eliminate double slash | |
900 | - if(!preg_match("|^/|",$matches[2])) | |
901 | - $this->_redirectaddr .= "/".$matches[2]; | |
902 | - else | |
903 | - $this->_redirectaddr .= $matches[2]; | |
904 | - } | |
905 | - else | |
906 | - $this->_redirectaddr = $matches[2]; | |
907 | - } | |
908 | - | |
909 | - if(preg_match("|^HTTP/|",$currentHeader)) | |
910 | - { | |
911 | - if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status)) | |
912 | - { | |
913 | - $this->status= $status[1]; | |
914 | - } | |
915 | - $this->response_code = $currentHeader; | |
916 | - } | |
917 | - | |
918 | - $this->headers[] = $currentHeader; | |
919 | - } | |
920 | - | |
921 | - $results = ''; | |
922 | - do { | |
923 | - $_data = fread($fp, $this->maxlength); | |
924 | - if (strlen($_data) == 0) { | |
925 | - break; | |
926 | - } | |
927 | - $results .= $_data; | |
928 | - } while(true); | |
929 | - | |
930 | - if ($this->read_timeout > 0 && $this->_check_timeout($fp)) | |
931 | - { | |
932 | - $this->status=-100; | |
933 | - return false; | |
934 | - } | |
935 | - | |
936 | - // check if there is a a redirect meta tag | |
937 | - | |
938 | - if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) | |
939 | - | |
940 | - { | |
941 | - $this->_redirectaddr = $this->_expandlinks($match[1],$URI); | |
942 | - } | |
943 | - | |
944 | - // have we hit our frame depth and is there frame src to fetch? | |
945 | - if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match)) | |
946 | - { | |
947 | - $this->results[] = $results; | |
948 | - for($x=0; $x<count($match[1]); $x++) | |
949 | - $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); | |
950 | - } | |
951 | - // have we already fetched framed content? | |
952 | - elseif(is_array($this->results)) | |
953 | - $this->results[] = $results; | |
954 | - // no framed content | |
955 | - else | |
956 | - $this->results = $results; | |
957 | - | |
958 | - return true; | |
959 | - } | |
960 | - | |
961 | -/*======================================================================*\ | |
962 | - Function: _httpsrequest | |
963 | - Purpose: go get the https data from the server using curl | |
964 | - Input: $url the url to fetch | |
965 | - $URI the full URI | |
966 | - $body body contents to send if any (POST) | |
967 | - Output: | |
968 | -\*======================================================================*/ | |
969 | - | |
970 | - function _httpsrequest($url,$URI,$http_method,$content_type="",$body="") | |
971 | - { | |
972 | - if($this->passcookies && $this->_redirectaddr) | |
973 | - $this->setcookies(); | |
974 | - | |
975 | - $headers = array(); | |
976 | - | |
977 | - $URI_PARTS = parse_url($URI); | |
978 | - if(empty($url)) | |
979 | - $url = "/"; | |
980 | - // GET ... header not needed for curl | |
981 | - //$headers[] = $http_method." ".$url." ".$this->_httpversion; | |
982 | - if(!empty($this->agent)) | |
983 | - $headers[] = "User-Agent: ".$this->agent; | |
984 | - if(!empty($this->host)) | |
985 | - if(!empty($this->host_port)) | |
986 | - $headers[] = "Host: ".$this->host.":".$this->host_port; | |
987 | - else | |
988 | - $headers[] = "Host: ".$this->host; | |
989 | - if(!empty($this->accept)) | |
990 | - $headers[] = "Accept: ".$this->accept; | |
991 | - if(!empty($this->referer)) | |
992 | - $headers[] = "Referer: ".$this->referer; | |
993 | - if(!empty($this->cookies)) | |
994 | - { | |
995 | - if(!is_array($this->cookies)) | |
996 | - $this->cookies = (array)$this->cookies; | |
997 | - | |
998 | - reset($this->cookies); | |
999 | - if ( count($this->cookies) > 0 ) { | |
1000 | - $cookie_str = 'Cookie: '; | |
1001 | - foreach ( $this->cookies as $cookieKey => $cookieVal ) { | |
1002 | - $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; "; | |
1003 | - } | |
1004 | - $headers[] = substr($cookie_str,0,-2); | |
1005 | - } | |
1006 | - } | |
1007 | - if(!empty($this->rawheaders)) | |
1008 | - { | |
1009 | - if(!is_array($this->rawheaders)) | |
1010 | - $this->rawheaders = (array)$this->rawheaders; | |
1011 | - while(list($headerKey,$headerVal) = each($this->rawheaders)) | |
1012 | - $headers[] = $headerKey.": ".$headerVal; | |
1013 | - } | |
1014 | - if(!empty($content_type)) { | |
1015 | - if ($content_type == "multipart/form-data") | |
1016 | - $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary; | |
1017 | - else | |
1018 | - $headers[] = "Content-type: $content_type"; | |
1019 | - } | |
1020 | - if(!empty($body)) | |
1021 | - $headers[] = "Content-length: ".strlen($body); | |
1022 | - if(!empty($this->user) || !empty($this->pass)) | |
1023 | - $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass); | |
1024 | - | |
1025 | - for($curr_header = 0; $curr_header < count($headers); $curr_header++) { | |
1026 | - $safer_header = strtr( $headers[$curr_header], "\"", " " ); | |
1027 | - $cmdline_params .= " -H \"".$safer_header."\""; | |
1028 | - } | |
1029 | - | |
1030 | - if(!empty($body)) | |
1031 | - $cmdline_params .= " -d \"$body\""; | |
1032 | - | |
1033 | - if($this->read_timeout > 0) | |
1034 | - $cmdline_params .= " -m ".$this->read_timeout; | |
1035 | - | |
1036 | - $headerfile = tempnam($temp_dir, "sno"); | |
1037 | - | |
1038 | - exec($this->curl_path." -k -D \"$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return); | |
1039 | - | |
1040 | - if($return) | |
1041 | - { | |
1042 | - $this->error = "Error: cURL could not retrieve the document, error $return."; | |
1043 | - return false; | |
1044 | - } | |
1045 | - | |
1046 | - | |
1047 | - $results = implode("\r\n",$results); | |
1048 | - | |
1049 | - $result_headers = file("$headerfile"); | |
1050 | - | |
1051 | - $this->_redirectaddr = false; | |
1052 | - unset($this->headers); | |
1053 | - | |
1054 | - for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++) | |
1055 | - { | |
1056 | - | |
1057 | - // if a header begins with Location: or URI:, set the redirect | |
1058 | - if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader])) | |
1059 | - { | |
1060 | - // get URL portion of the redirect | |
1061 | - preg_match("/^(Location: |URI:)\s+(.*)/",chop($result_headers[$currentHeader]),$matches); | |
1062 | - // look for :// in the Location header to see if hostname is included | |
1063 | - if(!preg_match("|\:\/\/|",$matches[2])) | |
1064 | - { | |
1065 | - // no host in the path, so prepend | |
1066 | - $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host; | |
1067 | - if(!empty($this->host_port)) | |
1068 | - $this->_redirectaddr .= ":".$this->host_port; | |
1069 | - // eliminate double slash | |
1070 | - if(!preg_match("|^/|",$matches[2])) | |
1071 | - $this->_redirectaddr .= "/".$matches[2]; | |
1072 | - else | |
1073 | - $this->_redirectaddr .= $matches[2]; | |
1074 | - } | |
1075 | - else | |
1076 | - $this->_redirectaddr = $matches[2]; | |
1077 | - } | |
1078 | - | |
1079 | - if(preg_match("|^HTTP/|",$result_headers[$currentHeader])) | |
1080 | - $this->response_code = $result_headers[$currentHeader]; | |
1081 | - | |
1082 | - $this->headers[] = $result_headers[$currentHeader]; | |
1083 | - } | |
1084 | - | |
1085 | - // check if there is a a redirect meta tag | |
1086 | - | |
1087 | - if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) | |
1088 | - { | |
1089 | - $this->_redirectaddr = $this->_expandlinks($match[1],$URI); | |
1090 | - } | |
1091 | - | |
1092 | - // have we hit our frame depth and is there frame src to fetch? | |
1093 | - if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match)) | |
1094 | - { | |
1095 | - $this->results[] = $results; | |
1096 | - for($x=0; $x<count($match[1]); $x++) | |
1097 | - $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); | |
1098 | - } | |
1099 | - // have we already fetched framed content? | |
1100 | - elseif(is_array($this->results)) | |
1101 | - $this->results[] = $results; | |
1102 | - // no framed content | |
1103 | - else | |
1104 | - $this->results = $results; | |
1105 | - | |
1106 | - unlink("$headerfile"); | |
1107 | - | |
1108 | - return true; | |
1109 | - } | |
1110 | - | |
1111 | -/*======================================================================*\ | |
1112 | - Function: setcookies() | |
1113 | - Purpose: set cookies for a redirection | |
1114 | -\*======================================================================*/ | |
1115 | - | |
1116 | - function setcookies() | |
1117 | - { | |
1118 | - for($x=0; $x<count($this->headers); $x++) | |
1119 | - { | |
1120 | - if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match)) | |
1121 | - $this->cookies[$match[1]] = urldecode($match[2]); | |
1122 | - } | |
1123 | - } | |
1124 | - | |
1125 | - | |
1126 | -/*======================================================================*\ | |
1127 | - Function: _check_timeout | |
1128 | - Purpose: checks whether timeout has occurred | |
1129 | - Input: $fp file pointer | |
1130 | -\*======================================================================*/ | |
1131 | - | |
1132 | - function _check_timeout($fp) | |
1133 | - { | |
1134 | - if ($this->read_timeout > 0) { | |
1135 | - $fp_status = socket_get_status($fp); | |
1136 | - if ($fp_status["timed_out"]) { | |
1137 | - $this->timed_out = true; | |
1138 | - return true; | |
1139 | - } | |
1140 | - } | |
1141 | - return false; | |
1142 | - } | |
1143 | - | |
1144 | -/*======================================================================*\ | |
1145 | - Function: _connect | |
1146 | - Purpose: make a socket connection | |
1147 | - Input: $fp file pointer | |
1148 | -\*======================================================================*/ | |
1149 | - | |
1150 | - function _connect(&$fp) | |
1151 | - { | |
1152 | - if(!empty($this->proxy_host) && !empty($this->proxy_port)) | |
1153 | - { | |
1154 | - $this->_isproxy = true; | |
1155 | - | |
1156 | - $host = $this->proxy_host; | |
1157 | - $port = $this->proxy_port; | |
1158 | - } | |
1159 | - else | |
1160 | - { | |
1161 | - $host = $this->host; | |
1162 | - $port = $this->port; | |
1163 | - } | |
1164 | - | |
1165 | - $this->status = 0; | |
1166 | - | |
1167 | - if($fp = fsockopen( | |
1168 | - $host, | |
1169 | - $port, | |
1170 | - $errno, | |
1171 | - $errstr, | |
1172 | - $this->_fp_timeout | |
1173 | - )) | |
1174 | - { | |
1175 | - // socket connection succeeded | |
1176 | - | |
1177 | - return true; | |
1178 | - } | |
1179 | - else | |
1180 | - { | |
1181 | - // socket connection failed | |
1182 | - $this->status = $errno; | |
1183 | - switch($errno) | |
1184 | - { | |
1185 | - case -3: | |
1186 | - $this->error="socket creation failed (-3)"; | |
1187 | - case -4: | |
1188 | - $this->error="dns lookup failure (-4)"; | |
1189 | - case -5: | |
1190 | - $this->error="connection refused or timed out (-5)"; | |
1191 | - default: | |
1192 | - $this->error="connection failed (".$errno.")"; | |
1193 | - } | |
1194 | - return false; | |
1195 | - } | |
1196 | - } | |
1197 | -/*======================================================================*\ | |
1198 | - Function: _disconnect | |
1199 | - Purpose: disconnect a socket connection | |
1200 | - Input: $fp file pointer | |
1201 | -\*======================================================================*/ | |
1202 | - | |
1203 | - function _disconnect($fp) | |
1204 | - { | |
1205 | - return(fclose($fp)); | |
1206 | - } | |
1207 | - | |
1208 | - | |
1209 | -/*======================================================================*\ | |
1210 | - Function: _prepare_post_body | |
1211 | - Purpose: Prepare post body according to encoding type | |
1212 | - Input: $formvars - form variables | |
1213 | - $formfiles - form upload files | |
1214 | - Output: post body | |
1215 | -\*======================================================================*/ | |
1216 | - | |
1217 | - function _prepare_post_body($formvars, $formfiles) | |
1218 | - { | |
1219 | - settype($formvars, "array"); | |
1220 | - settype($formfiles, "array"); | |
1221 | - $postdata = ''; | |
1222 | - | |
1223 | - if (count($formvars) == 0 && count($formfiles) == 0) | |
1224 | - return; | |
1225 | - | |
1226 | - switch ($this->_submit_type) { | |
1227 | - case "application/x-www-form-urlencoded": | |
1228 | - reset($formvars); | |
1229 | - while(list($key,$val) = each($formvars)) { | |
1230 | - if (is_array($val) || is_object($val)) { | |
1231 | - while (list($cur_key, $cur_val) = each($val)) { | |
1232 | - $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&"; | |
1233 | - } | |
1234 | - } else | |
1235 | - $postdata .= urlencode($key)."=".urlencode($val)."&"; | |
1236 | - } | |
1237 | - break; | |
1238 | - | |
1239 | - case "multipart/form-data": | |
1240 | - $this->_mime_boundary = "Snoopy".md5(uniqid(microtime())); | |
1241 | - | |
1242 | - reset($formvars); | |
1243 | - while(list($key,$val) = each($formvars)) { | |
1244 | - if (is_array($val) || is_object($val)) { | |
1245 | - while (list($cur_key, $cur_val) = each($val)) { | |
1246 | - $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1247 | - $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n"; | |
1248 | - $postdata .= "$cur_val\r\n"; | |
1249 | - } | |
1250 | - } else { | |
1251 | - $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1252 | - $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n"; | |
1253 | - $postdata .= "$val\r\n"; | |
1254 | - } | |
1255 | - } | |
1256 | - | |
1257 | - reset($formfiles); | |
1258 | - while (list($field_name, $file_names) = each($formfiles)) { | |
1259 | - settype($file_names, "array"); | |
1260 | - while (list(, $file_name) = each($file_names)) { | |
1261 | - if (!is_readable($file_name)) continue; | |
1262 | - | |
1263 | - $fp = fopen($file_name, "r"); | |
1264 | - $file_content = fread($fp, filesize($file_name)); | |
1265 | - fclose($fp); | |
1266 | - $base_name = basename($file_name); | |
1267 | - | |
1268 | - $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1269 | - $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n"; | |
1270 | - $postdata .= "$file_content\r\n"; | |
1271 | - } | |
1272 | - } | |
1273 | - $postdata .= "--".$this->_mime_boundary."--\r\n"; | |
1274 | - break; | |
1275 | - // XOOPS2 Hack begin | |
1276 | - // Added on March 4, 2003 by onokazu@xoops.org | |
1277 | - case "text/xml": | |
1278 | - default: | |
1279 | - $postdata = $formvars[0]; | |
1280 | - break; | |
1281 | - // XOOPS2 Hack end | |
1282 | - } | |
1283 | - | |
1284 | - return $postdata; | |
1285 | - } | |
1286 | -} | |
1287 | - | |
1288 | -?> | |
1 | +<?php | |
2 | + | |
3 | +/************************************************* | |
4 | + | |
5 | +Snoopy - the PHP net client | |
6 | +Author: Monte Ohrt <monte@ispi.net> | |
7 | +Copyright (c): 1999-2008 New Digital Group, all rights reserved | |
8 | +Version: 1.2.4 | |
9 | + | |
10 | + * This library is free software; you can redistribute it and/or | |
11 | + * modify it under the terms of the GNU Lesser General Public | |
12 | + * License as published by the Free Software Foundation; either | |
13 | + * version 2.1 of the License, or (at your option) any later version. | |
14 | + * | |
15 | + * This library is distributed in the hope that it will be useful, | |
16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | + * Lesser General Public License for more details. | |
19 | + * | |
20 | + * You should have received a copy of the GNU Lesser General Public | |
21 | + * License along with this library; if not, write to the Free Software | |
22 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | + | |
24 | +You may contact the author of Snoopy by e-mail at: | |
25 | +monte@ohrt.com | |
26 | + | |
27 | +The latest version of Snoopy can be obtained from: | |
28 | +http://snoopy.sourceforge.net/ | |
29 | + | |
30 | +*************************************************/ | |
31 | + | |
32 | +class Snoopy | |
33 | +{ | |
34 | + /**** Public variables ****/ | |
35 | + | |
36 | + /* user definable vars */ | |
37 | + | |
38 | + var $host = "www.php.net"; // host name we are connecting to | |
39 | + var $port = 80; // port we are connecting to | |
40 | + var $proxy_host = ""; // proxy host to use | |
41 | + var $proxy_port = ""; // proxy port to use | |
42 | + var $proxy_user = ""; // proxy user to use | |
43 | + var $proxy_pass = ""; // proxy password to use | |
44 | + | |
45 | + var $agent = "Snoopy v1.2.4"; // agent we masquerade as | |
46 | + var $referer = ""; // referer info to pass | |
47 | + var $cookies = array(); // array of cookies to pass | |
48 | + // $cookies["username"]="joe"; | |
49 | + var $rawheaders = array(); // array of raw headers to send | |
50 | + // $rawheaders["Content-type"]="text/html"; | |
51 | + | |
52 | + var $maxredirs = 5; // http redirection depth maximum. 0 = disallow | |
53 | + var $lastredirectaddr = ""; // contains address of last redirected address | |
54 | + var $offsiteok = true; // allows redirection off-site | |
55 | + var $maxframes = 0; // frame content depth maximum. 0 = disallow | |
56 | + var $expandlinks = true; // expand links to fully qualified URLs. | |
57 | + // this only applies to fetchlinks() | |
58 | + // submitlinks(), and submittext() | |
59 | + var $passcookies = true; // pass set cookies back through redirects | |
60 | + // NOTE: this currently does not respect | |
61 | + // dates, domains or paths. | |
62 | + | |
63 | + var $user = ""; // user for http authentication | |
64 | + var $pass = ""; // password for http authentication | |
65 | + | |
66 | + // http accept types | |
67 | + var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; | |
68 | + | |
69 | + var $results = ""; // where the content is put | |
70 | + | |
71 | + var $error = ""; // error messages sent here | |
72 | + var $response_code = ""; // response code returned from server | |
73 | + var $headers = array(); // headers returned from server sent here | |
74 | + var $maxlength = 500000; // max return data length (body) | |
75 | + var $read_timeout = 0; // timeout on read operations, in seconds | |
76 | + // supported only since PHP 4 Beta 4 | |
77 | + // set to 0 to disallow timeouts | |
78 | + var $timed_out = false; // if a read operation timed out | |
79 | + var $status = 0; // http request status | |
80 | + | |
81 | + var $temp_dir = "/tmp"; // temporary directory that the webserver | |
82 | + // has permission to write to. | |
83 | + // under Windows, this should be C:\temp | |
84 | + | |
85 | + var $curl_path = "/usr/local/bin/curl"; | |
86 | + // Snoopy will use cURL for fetching | |
87 | + // SSL content if a full system path to | |
88 | + // the cURL binary is supplied here. | |
89 | + // set to false if you do not have | |
90 | + // cURL installed. See http://curl.haxx.se | |
91 | + // for details on installing cURL. | |
92 | + // Snoopy does *not* use the cURL | |
93 | + // library functions built into php, | |
94 | + // as these functions are not stable | |
95 | + // as of this Snoopy release. | |
96 | + | |
97 | + /**** Private variables ****/ | |
98 | + | |
99 | + var $_maxlinelen = 4096; // max line length (headers) | |
100 | + | |
101 | + var $_httpmethod = "GET"; // default http request method | |
102 | + var $_httpversion = "HTTP/1.0"; // default http request version | |
103 | + var $_submit_method = "POST"; // default submit method | |
104 | + var $_submit_type = "application/x-www-form-urlencoded"; // default submit type | |
105 | + var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type | |
106 | + var $_redirectaddr = false; // will be set if page fetched is a redirect | |
107 | + var $_redirectdepth = 0; // increments on an http redirect | |
108 | + var $_frameurls = array(); // frame src urls | |
109 | + var $_framedepth = 0; // increments on frame depth | |
110 | + | |
111 | + var $_isproxy = false; // set if using a proxy server | |
112 | + var $_fp_timeout = 30; // timeout for socket connection | |
113 | + | |
114 | +/*======================================================================*\ | |
115 | + Function: fetch | |
116 | + Purpose: fetch the contents of a web page | |
117 | + (and possibly other protocols in the | |
118 | + future like ftp, nntp, gopher, etc.) | |
119 | + Input: $URI the location of the page to fetch | |
120 | + Output: $this->results the output text from the fetch | |
121 | +\*======================================================================*/ | |
122 | + | |
123 | + function fetch($URI) | |
124 | + { | |
125 | + | |
126 | + //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS); | |
127 | + $URI_PARTS = parse_url($URI); | |
128 | + if (!empty($URI_PARTS["user"])) | |
129 | + $this->user = $URI_PARTS["user"]; | |
130 | + if (!empty($URI_PARTS["pass"])) | |
131 | + $this->pass = $URI_PARTS["pass"]; | |
132 | + if (empty($URI_PARTS["query"])) | |
133 | + $URI_PARTS["query"] = ''; | |
134 | + if (empty($URI_PARTS["path"])) | |
135 | + $URI_PARTS["path"] = ''; | |
136 | + | |
137 | + switch(strtolower($URI_PARTS["scheme"])) | |
138 | + { | |
139 | + case "http": | |
140 | + $this->host = $URI_PARTS["host"]; | |
141 | + if(!empty($URI_PARTS["port"])) | |
142 | + $this->port = $URI_PARTS["port"]; | |
143 | + if($this->_connect($fp)) | |
144 | + { | |
145 | + if($this->_isproxy) | |
146 | + { | |
147 | + // using proxy, send entire URI | |
148 | + $this->_httprequest($URI,$fp,$URI,$this->_httpmethod); | |
149 | + } | |
150 | + else | |
151 | + { | |
152 | + $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
153 | + // no proxy, send only the path | |
154 | + $this->_httprequest($path, $fp, $URI, $this->_httpmethod); | |
155 | + } | |
156 | + | |
157 | + $this->_disconnect($fp); | |
158 | + | |
159 | + if($this->_redirectaddr) | |
160 | + { | |
161 | + /* url was redirected, check if we've hit the max depth */ | |
162 | + if($this->maxredirs > $this->_redirectdepth) | |
163 | + { | |
164 | + // only follow redirect if it's on this site, or offsiteok is true | |
165 | + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
166 | + { | |
167 | + /* follow the redirect */ | |
168 | + $this->_redirectdepth++; | |
169 | + $this->lastredirectaddr=$this->_redirectaddr; | |
170 | + $this->fetch($this->_redirectaddr); | |
171 | + } | |
172 | + } | |
173 | + } | |
174 | + | |
175 | + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
176 | + { | |
177 | + $frameurls = $this->_frameurls; | |
178 | + $this->_frameurls = array(); | |
179 | + | |
180 | + while(list(,$frameurl) = each($frameurls)) | |
181 | + { | |
182 | + if($this->_framedepth < $this->maxframes) | |
183 | + { | |
184 | + $this->fetch($frameurl); | |
185 | + $this->_framedepth++; | |
186 | + } | |
187 | + else | |
188 | + break; | |
189 | + } | |
190 | + } | |
191 | + } | |
192 | + else | |
193 | + { | |
194 | + return false; | |
195 | + } | |
196 | + return true; | |
197 | + break; | |
198 | + case "https": | |
199 | + if(!$this->curl_path) | |
200 | + return false; | |
201 | + if(function_exists("is_executable")) | |
202 | + if (!is_executable($this->curl_path)) | |
203 | + return false; | |
204 | + $this->host = $URI_PARTS["host"]; | |
205 | + if(!empty($URI_PARTS["port"])) | |
206 | + $this->port = $URI_PARTS["port"]; | |
207 | + if($this->_isproxy) | |
208 | + { | |
209 | + // using proxy, send entire URI | |
210 | + $this->_httpsrequest($URI,$URI,$this->_httpmethod); | |
211 | + } | |
212 | + else | |
213 | + { | |
214 | + $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
215 | + // no proxy, send only the path | |
216 | + $this->_httpsrequest($path, $URI, $this->_httpmethod); | |
217 | + } | |
218 | + | |
219 | + if($this->_redirectaddr) | |
220 | + { | |
221 | + /* url was redirected, check if we've hit the max depth */ | |
222 | + if($this->maxredirs > $this->_redirectdepth) | |
223 | + { | |
224 | + // only follow redirect if it's on this site, or offsiteok is true | |
225 | + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
226 | + { | |
227 | + /* follow the redirect */ | |
228 | + $this->_redirectdepth++; | |
229 | + $this->lastredirectaddr=$this->_redirectaddr; | |
230 | + $this->fetch($this->_redirectaddr); | |
231 | + } | |
232 | + } | |
233 | + } | |
234 | + | |
235 | + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
236 | + { | |
237 | + $frameurls = $this->_frameurls; | |
238 | + $this->_frameurls = array(); | |
239 | + | |
240 | + while(list(,$frameurl) = each($frameurls)) | |
241 | + { | |
242 | + if($this->_framedepth < $this->maxframes) | |
243 | + { | |
244 | + $this->fetch($frameurl); | |
245 | + $this->_framedepth++; | |
246 | + } | |
247 | + else | |
248 | + break; | |
249 | + } | |
250 | + } | |
251 | + return true; | |
252 | + break; | |
253 | + default: | |
254 | + // not a valid protocol | |
255 | + $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; | |
256 | + return false; | |
257 | + break; | |
258 | + } | |
259 | + return true; | |
260 | + } | |
261 | + | |
262 | +/*======================================================================*\ | |
263 | + Function: submit | |
264 | + Purpose: submit an http form | |
265 | + Input: $URI the location to post the data | |
266 | + $formvars the formvars to use. | |
267 | + format: $formvars["var"] = "val"; | |
268 | + $formfiles an array of files to submit | |
269 | + format: $formfiles["var"] = "/dir/filename.ext"; | |
270 | + Output: $this->results the text output from the post | |
271 | +\*======================================================================*/ | |
272 | + | |
273 | + function submit($URI, $formvars="", $formfiles="") | |
274 | + { | |
275 | + unset($postdata); | |
276 | + | |
277 | + $postdata = $this->_prepare_post_body($formvars, $formfiles); | |
278 | + | |
279 | + $URI_PARTS = parse_url($URI); | |
280 | + if (!empty($URI_PARTS["user"])) | |
281 | + $this->user = $URI_PARTS["user"]; | |
282 | + if (!empty($URI_PARTS["pass"])) | |
283 | + $this->pass = $URI_PARTS["pass"]; | |
284 | + if (empty($URI_PARTS["query"])) | |
285 | + $URI_PARTS["query"] = ''; | |
286 | + if (empty($URI_PARTS["path"])) | |
287 | + $URI_PARTS["path"] = ''; | |
288 | + | |
289 | + switch(strtolower($URI_PARTS["scheme"])) | |
290 | + { | |
291 | + case "http": | |
292 | + $this->host = $URI_PARTS["host"]; | |
293 | + if(!empty($URI_PARTS["port"])) | |
294 | + $this->port = $URI_PARTS["port"]; | |
295 | + if($this->_connect($fp)) | |
296 | + { | |
297 | + if($this->_isproxy) | |
298 | + { | |
299 | + // using proxy, send entire URI | |
300 | + $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata); | |
301 | + } | |
302 | + else | |
303 | + { | |
304 | + $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
305 | + // no proxy, send only the path | |
306 | + $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
307 | + } | |
308 | + | |
309 | + $this->_disconnect($fp); | |
310 | + | |
311 | + if($this->_redirectaddr) | |
312 | + { | |
313 | + /* url was redirected, check if we've hit the max depth */ | |
314 | + if($this->maxredirs > $this->_redirectdepth) | |
315 | + { | |
316 | + if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) | |
317 | + $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); | |
318 | + | |
319 | + // only follow redirect if it's on this site, or offsiteok is true | |
320 | + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
321 | + { | |
322 | + /* follow the redirect */ | |
323 | + $this->_redirectdepth++; | |
324 | + $this->lastredirectaddr=$this->_redirectaddr; | |
325 | + if( strpos( $this->_redirectaddr, "?" ) > 0 ) | |
326 | + $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get | |
327 | + else | |
328 | + $this->submit($this->_redirectaddr,$formvars, $formfiles); | |
329 | + } | |
330 | + } | |
331 | + } | |
332 | + | |
333 | + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
334 | + { | |
335 | + $frameurls = $this->_frameurls; | |
336 | + $this->_frameurls = array(); | |
337 | + | |
338 | + while(list(,$frameurl) = each($frameurls)) | |
339 | + { | |
340 | + if($this->_framedepth < $this->maxframes) | |
341 | + { | |
342 | + $this->fetch($frameurl); | |
343 | + $this->_framedepth++; | |
344 | + } | |
345 | + else | |
346 | + break; | |
347 | + } | |
348 | + } | |
349 | + | |
350 | + } | |
351 | + else | |
352 | + { | |
353 | + return false; | |
354 | + } | |
355 | + return true; | |
356 | + break; | |
357 | + case "https": | |
358 | + if(!$this->curl_path) | |
359 | + return false; | |
360 | + if(function_exists("is_executable")) | |
361 | + if (!is_executable($this->curl_path)) | |
362 | + return false; | |
363 | + $this->host = $URI_PARTS["host"]; | |
364 | + if(!empty($URI_PARTS["port"])) | |
365 | + $this->port = $URI_PARTS["port"]; | |
366 | + if($this->_isproxy) | |
367 | + { | |
368 | + // using proxy, send entire URI | |
369 | + $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
370 | + } | |
371 | + else | |
372 | + { | |
373 | + $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); | |
374 | + // no proxy, send only the path | |
375 | + $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata); | |
376 | + } | |
377 | + | |
378 | + if($this->_redirectaddr) | |
379 | + { | |
380 | + /* url was redirected, check if we've hit the max depth */ | |
381 | + if($this->maxredirs > $this->_redirectdepth) | |
382 | + { | |
383 | + if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) | |
384 | + $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); | |
385 | + | |
386 | + // only follow redirect if it's on this site, or offsiteok is true | |
387 | + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) | |
388 | + { | |
389 | + /* follow the redirect */ | |
390 | + $this->_redirectdepth++; | |
391 | + $this->lastredirectaddr=$this->_redirectaddr; | |
392 | + if( strpos( $this->_redirectaddr, "?" ) > 0 ) | |
393 | + $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get | |
394 | + else | |
395 | + $this->submit($this->_redirectaddr,$formvars, $formfiles); | |
396 | + } | |
397 | + } | |
398 | + } | |
399 | + | |
400 | + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) | |
401 | + { | |
402 | + $frameurls = $this->_frameurls; | |
403 | + $this->_frameurls = array(); | |
404 | + | |
405 | + while(list(,$frameurl) = each($frameurls)) | |
406 | + { | |
407 | + if($this->_framedepth < $this->maxframes) | |
408 | + { | |
409 | + $this->fetch($frameurl); | |
410 | + $this->_framedepth++; | |
411 | + } | |
412 | + else | |
413 | + break; | |
414 | + } | |
415 | + } | |
416 | + return true; | |
417 | + break; | |
418 | + | |
419 | + default: | |
420 | + // not a valid protocol | |
421 | + $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; | |
422 | + return false; | |
423 | + break; | |
424 | + } | |
425 | + return true; | |
426 | + } | |
427 | + | |
428 | +/*======================================================================*\ | |
429 | + Function: fetchlinks | |
430 | + Purpose: fetch the links from a web page | |
431 | + Input: $URI where you are fetching from | |
432 | + Output: $this->results an array of the URLs | |
433 | +\*======================================================================*/ | |
434 | + | |
435 | + function fetchlinks($URI) | |
436 | + { | |
437 | + if ($this->fetch($URI)) | |
438 | + { | |
439 | + if($this->lastredirectaddr) | |
440 | + $URI = $this->lastredirectaddr; | |
441 | + if(is_array($this->results)) | |
442 | + { | |
443 | + for($x=0;$x<count($this->results);$x++) | |
444 | + $this->results[$x] = $this->_striplinks($this->results[$x]); | |
445 | + } | |
446 | + else | |
447 | + $this->results = $this->_striplinks($this->results); | |
448 | + | |
449 | + if($this->expandlinks) | |
450 | + $this->results = $this->_expandlinks($this->results, $URI); | |
451 | + return true; | |
452 | + } | |
453 | + else | |
454 | + return false; | |
455 | + } | |
456 | + | |
457 | +/*======================================================================*\ | |
458 | + Function: fetchform | |
459 | + Purpose: fetch the form elements from a web page | |
460 | + Input: $URI where you are fetching from | |
461 | + Output: $this->results the resulting html form | |
462 | +\*======================================================================*/ | |
463 | + | |
464 | + function fetchform($URI) | |
465 | + { | |
466 | + | |
467 | + if ($this->fetch($URI)) | |
468 | + { | |
469 | + | |
470 | + if(is_array($this->results)) | |
471 | + { | |
472 | + for($x=0;$x<count($this->results);$x++) | |
473 | + $this->results[$x] = $this->_stripform($this->results[$x]); | |
474 | + } | |
475 | + else | |
476 | + $this->results = $this->_stripform($this->results); | |
477 | + | |
478 | + return true; | |
479 | + } | |
480 | + else | |
481 | + return false; | |
482 | + } | |
483 | + | |
484 | + | |
485 | +/*======================================================================*\ | |
486 | + Function: fetchtext | |
487 | + Purpose: fetch the text from a web page, stripping the links | |
488 | + Input: $URI where you are fetching from | |
489 | + Output: $this->results the text from the web page | |
490 | +\*======================================================================*/ | |
491 | + | |
492 | + function fetchtext($URI) | |
493 | + { | |
494 | + if($this->fetch($URI)) | |
495 | + { | |
496 | + if(is_array($this->results)) | |
497 | + { | |
498 | + for($x=0;$x<count($this->results);$x++) | |
499 | + $this->results[$x] = $this->_striptext($this->results[$x]); | |
500 | + } | |
501 | + else | |
502 | + $this->results = $this->_striptext($this->results); | |
503 | + return true; | |
504 | + } | |
505 | + else | |
506 | + return false; | |
507 | + } | |
508 | + | |
509 | +/*======================================================================*\ | |
510 | + Function: submitlinks | |
511 | + Purpose: grab links from a form submission | |
512 | + Input: $URI where you are submitting from | |
513 | + Output: $this->results an array of the links from the post | |
514 | +\*======================================================================*/ | |
515 | + | |
516 | + function submitlinks($URI, $formvars="", $formfiles="") | |
517 | + { | |
518 | + if($this->submit($URI,$formvars, $formfiles)) | |
519 | + { | |
520 | + if($this->lastredirectaddr) | |
521 | + $URI = $this->lastredirectaddr; | |
522 | + if(is_array($this->results)) | |
523 | + { | |
524 | + for($x=0;$x<count($this->results);$x++) | |
525 | + { | |
526 | + $this->results[$x] = $this->_striplinks($this->results[$x]); | |
527 | + if($this->expandlinks) | |
528 | + $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); | |
529 | + } | |
530 | + } | |
531 | + else | |
532 | + { | |
533 | + $this->results = $this->_striplinks($this->results); | |
534 | + if($this->expandlinks) | |
535 | + $this->results = $this->_expandlinks($this->results,$URI); | |
536 | + } | |
537 | + return true; | |
538 | + } | |
539 | + else | |
540 | + return false; | |
541 | + } | |
542 | + | |
543 | +/*======================================================================*\ | |
544 | + Function: submittext | |
545 | + Purpose: grab text from a form submission | |
546 | + Input: $URI where you are submitting from | |
547 | + Output: $this->results the text from the web page | |
548 | +\*======================================================================*/ | |
549 | + | |
550 | + function submittext($URI, $formvars = "", $formfiles = "") | |
551 | + { | |
552 | + if($this->submit($URI,$formvars, $formfiles)) | |
553 | + { | |
554 | + if($this->lastredirectaddr) | |
555 | + $URI = $this->lastredirectaddr; | |
556 | + if(is_array($this->results)) | |
557 | + { | |
558 | + for($x=0;$x<count($this->results);$x++) | |
559 | + { | |
560 | + $this->results[$x] = $this->_striptext($this->results[$x]); | |
561 | + if($this->expandlinks) | |
562 | + $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); | |
563 | + } | |
564 | + } | |
565 | + else | |
566 | + { | |
567 | + $this->results = $this->_striptext($this->results); | |
568 | + if($this->expandlinks) | |
569 | + $this->results = $this->_expandlinks($this->results,$URI); | |
570 | + } | |
571 | + return true; | |
572 | + } | |
573 | + else | |
574 | + return false; | |
575 | + } | |
576 | + | |
577 | + | |
578 | + | |
579 | +/*======================================================================*\ | |
580 | + Function: set_submit_multipart | |
581 | + Purpose: Set the form submission content type to | |
582 | + multipart/form-data | |
583 | +\*======================================================================*/ | |
584 | + function set_submit_multipart() | |
585 | + { | |
586 | + $this->_submit_type = "multipart/form-data"; | |
587 | + } | |
588 | + | |
589 | + | |
590 | +/*======================================================================*\ | |
591 | + Function: set_submit_normal | |
592 | + Purpose: Set the form submission content type to | |
593 | + application/x-www-form-urlencoded | |
594 | +\*======================================================================*/ | |
595 | + function set_submit_normal() | |
596 | + { | |
597 | + $this->_submit_type = "application/x-www-form-urlencoded"; | |
598 | + } | |
599 | + | |
600 | + | |
601 | + | |
602 | + | |
603 | +/*======================================================================*\ | |
604 | + Private functions | |
605 | +\*======================================================================*/ | |
606 | + | |
607 | + | |
608 | +/*======================================================================*\ | |
609 | + Function: _striplinks | |
610 | + Purpose: strip the hyperlinks from an html document | |
611 | + Input: $document document to strip. | |
612 | + Output: $match an array of the links | |
613 | +\*======================================================================*/ | |
614 | + | |
615 | + function _striplinks($document) | |
616 | + { | |
617 | + preg_match_all("'<\s*a\s.*?href\s*=\s* # find <a href= | |
618 | + ([\"\'])? # find single or double quote | |
619 | + (?(1) (.*?)\\1 | ([^\s\>]+)) # if quote found, match up to next matching | |
620 | + # quote, otherwise match up to next space | |
621 | + 'isx",$document,$links); | |
622 | + | |
623 | + | |
624 | + // catenate the non-empty matches from the conditional subpattern | |
625 | + | |
626 | + while(list($key,$val) = each($links[2])) | |
627 | + { | |
628 | + if(!empty($val)) | |
629 | + $match[] = $val; | |
630 | + } | |
631 | + | |
632 | + while(list($key,$val) = each($links[3])) | |
633 | + { | |
634 | + if(!empty($val)) | |
635 | + $match[] = $val; | |
636 | + } | |
637 | + | |
638 | + // return the links | |
639 | + return $match; | |
640 | + } | |
641 | + | |
642 | +/*======================================================================*\ | |
643 | + Function: _stripform | |
644 | + Purpose: strip the form elements from an html document | |
645 | + Input: $document document to strip. | |
646 | + Output: $match an array of the links | |
647 | +\*======================================================================*/ | |
648 | + | |
649 | + function _stripform($document) | |
650 | + { | |
651 | + preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements); | |
652 | + | |
653 | + // catenate the matches | |
654 | + $match = implode("\r\n",$elements[0]); | |
655 | + | |
656 | + // return the links | |
657 | + return $match; | |
658 | + } | |
659 | + | |
660 | + | |
661 | + | |
662 | +/*======================================================================*\ | |
663 | + Function: _striptext | |
664 | + Purpose: strip the text from an html document | |
665 | + Input: $document document to strip. | |
666 | + Output: $text the resulting text | |
667 | +\*======================================================================*/ | |
668 | + | |
669 | + function _striptext($document) | |
670 | + { | |
671 | + | |
672 | + // I didn't use preg eval (//e) since that is only available in PHP 4.0. | |
673 | + // so, list your entities one by one here. I included some of the | |
674 | + // more common ones. | |
675 | + | |
676 | + $search = array("'<script[^>]*?>.*?</script>'si", // strip out javascript | |
677 | + "'<[\/\!]*?[^<>]*?>'si", // strip out html tags | |
678 | + "'([\r\n])[\s]+'", // strip out white space | |
679 | + "'&(quot|#34|#034|#x22);'i", // replace html entities | |
680 | + "'&(amp|#38|#038|#x26);'i", // added hexadecimal values | |
681 | + "'&(lt|#60|#060|#x3c);'i", | |
682 | + "'&(gt|#62|#062|#x3e);'i", | |
683 | + "'&(nbsp|#160|#xa0);'i", | |
684 | + "'&(iexcl|#161);'i", | |
685 | + "'&(cent|#162);'i", | |
686 | + "'&(pound|#163);'i", | |
687 | + "'&(copy|#169);'i", | |
688 | + "'&(reg|#174);'i", | |
689 | + "'&(deg|#176);'i", | |
690 | + "'&(#39|#039|#x27);'", | |
691 | + "'&(euro|#8364);'i", // europe | |
692 | + "'&a(uml|UML);'", // german | |
693 | + "'&o(uml|UML);'", | |
694 | + "'&u(uml|UML);'", | |
695 | + "'&A(uml|UML);'", | |
696 | + "'&O(uml|UML);'", | |
697 | + "'&U(uml|UML);'", | |
698 | + "'ß'i", | |
699 | + ); | |
700 | + $replace = array( "", | |
701 | + "", | |
702 | + "\\1", | |
703 | + "\"", | |
704 | + "&", | |
705 | + "<", | |
706 | + ">", | |
707 | + " ", | |
708 | + chr(161), | |
709 | + chr(162), | |
710 | + chr(163), | |
711 | + chr(169), | |
712 | + chr(174), | |
713 | + chr(176), | |
714 | + chr(39), | |
715 | + chr(128), | |
716 | + /* | |
717 | + * UTF8で表示出来ない文字をコードに変更 | |
718 | + * Marijuana | |
719 | + */ | |
720 | + chr(228), | |
721 | + chr(246), | |
722 | + chr(252), | |
723 | + chr(196), | |
724 | + chr(214), | |
725 | + chr(220), | |
726 | + chr(223), | |
727 | + ); | |
728 | + | |
729 | + $text = preg_replace($search,$replace,$document); | |
730 | + | |
731 | + return $text; | |
732 | + } | |
733 | + | |
734 | +/*======================================================================*\ | |
735 | + Function: _expandlinks | |
736 | + Purpose: expand each link into a fully qualified URL | |
737 | + Input: $links the links to qualify | |
738 | + $URI the full URI to get the base from | |
739 | + Output: $expandedLinks the expanded links | |
740 | +\*======================================================================*/ | |
741 | + | |
742 | + function _expandlinks($links,$URI) | |
743 | + { | |
744 | + | |
745 | + preg_match("/^[^\?]+/",$URI,$match); | |
746 | + | |
747 | + $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]); | |
748 | + $match = preg_replace("|/$|","",$match); | |
749 | + $match_part = parse_url($match); | |
750 | + $match_root = | |
751 | + $match_part["scheme"]."://".$match_part["host"]; | |
752 | + | |
753 | + $search = array( "|^http://".preg_quote($this->host)."|i", | |
754 | + "|^(\/)|i", | |
755 | + "|^(?!http://)(?!mailto:)|i", | |
756 | + "|/\./|", | |
757 | + "|/[^\/]+/\.\./|" | |
758 | + ); | |
759 | + | |
760 | + $replace = array( "", | |
761 | + $match_root."/", | |
762 | + $match."/", | |
763 | + "/", | |
764 | + "/" | |
765 | + ); | |
766 | + | |
767 | + $expandedLinks = preg_replace($search,$replace,$links); | |
768 | + | |
769 | + return $expandedLinks; | |
770 | + } | |
771 | + | |
772 | +/*======================================================================*\ | |
773 | + Function: _httprequest | |
774 | + Purpose: go get the http data from the server | |
775 | + Input: $url the url to fetch | |
776 | + $fp the current open file pointer | |
777 | + $URI the full URI | |
778 | + $body body contents to send if any (POST) | |
779 | + Output: | |
780 | +\*======================================================================*/ | |
781 | + | |
782 | + function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="") | |
783 | + { | |
784 | + $cookie_headers = ''; | |
785 | + if($this->passcookies && $this->_redirectaddr) | |
786 | + $this->setcookies(); | |
787 | + | |
788 | + $URI_PARTS = parse_url($URI); | |
789 | + if(empty($url)) | |
790 | + $url = "/"; | |
791 | + $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; | |
792 | + if(!empty($this->agent)) | |
793 | + $headers .= "User-Agent: ".$this->agent."\r\n"; | |
794 | + if(!empty($this->host) && !isset($this->rawheaders['Host'])) { | |
795 | + $headers .= "Host: ".$this->host; | |
796 | + /** | |
797 | + * 80のときはポート番号を付けない | |
798 | + * Marijuana | |
799 | + */ | |
800 | + if(!empty($this->port) && $this->port != 80) | |
801 | + $headers .= ":".$this->port; | |
802 | + $headers .= "\r\n"; | |
803 | + } | |
804 | + if(!empty($this->accept)) | |
805 | + $headers .= "Accept: ".$this->accept."\r\n"; | |
806 | + if(!empty($this->referer)) | |
807 | + $headers .= "Referer: ".$this->referer."\r\n"; | |
808 | + if(!empty($this->cookies)) | |
809 | + { | |
810 | + if(!is_array($this->cookies)) | |
811 | + $this->cookies = (array)$this->cookies; | |
812 | + | |
813 | + reset($this->cookies); | |
814 | + if ( count($this->cookies) > 0 ) { | |
815 | + $cookie_headers .= 'Cookie: '; | |
816 | + foreach ( $this->cookies as $cookieKey => $cookieVal ) { | |
817 | + $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; "; | |
818 | + } | |
819 | + $headers .= substr($cookie_headers,0,-2) . "\r\n"; | |
820 | + } | |
821 | + } | |
822 | + if(!empty($this->rawheaders)) | |
823 | + { | |
824 | + if(!is_array($this->rawheaders)) | |
825 | + $this->rawheaders = (array)$this->rawheaders; | |
826 | + while(list($headerKey,$headerVal) = each($this->rawheaders)) | |
827 | + $headers .= $headerKey.": ".$headerVal."\r\n"; | |
828 | + } | |
829 | + if(!empty($content_type)) { | |
830 | + $headers .= "Content-type: $content_type"; | |
831 | + if ($content_type == "multipart/form-data") | |
832 | + $headers .= "; boundary=".$this->_mime_boundary; | |
833 | + $headers .= "\r\n"; | |
834 | + } | |
835 | + if(!empty($body)) | |
836 | + $headers .= "Content-length: ".strlen($body)."\r\n"; | |
837 | + if(!empty($this->user) || !empty($this->pass)) | |
838 | + $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n"; | |
839 | + | |
840 | + //add proxy auth headers | |
841 | + if(!empty($this->proxy_user)) | |
842 | + $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n"; | |
843 | + | |
844 | + | |
845 | + $headers .= "\r\n"; | |
846 | + | |
847 | + // set the read timeout if needed | |
848 | + if ($this->read_timeout > 0) | |
849 | + socket_set_timeout($fp, $this->read_timeout); | |
850 | + $this->timed_out = false; | |
851 | + | |
852 | + fwrite($fp,$headers.$body,strlen($headers.$body)); | |
853 | + | |
854 | + $this->_redirectaddr = false; | |
855 | + unset($this->headers); | |
856 | + | |
857 | + while($currentHeader = fgets($fp,$this->_maxlinelen)) | |
858 | + { | |
859 | + if ($this->read_timeout > 0 && $this->_check_timeout($fp)) | |
860 | + { | |
861 | + $this->status=-100; | |
862 | + return false; | |
863 | + } | |
864 | + | |
865 | + if($currentHeader == "\r\n") | |
866 | + break; | |
867 | + | |
868 | + // if a header begins with Location: or URI:, set the redirect | |
869 | + if(preg_match("/^(Location:|URI:)/i",$currentHeader)) | |
870 | + { | |
871 | + // get URL portion of the redirect | |
872 | + preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches); | |
873 | + // look for :// in the Location header to see if hostname is included | |
874 | + if(!preg_match("|\:\/\/|",$matches[2])) | |
875 | + { | |
876 | + // no host in the path, so prepend | |
877 | + $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port; | |
878 | + // eliminate double slash | |
879 | + if(!preg_match("|^/|",$matches[2])) | |
880 | + $this->_redirectaddr .= "/".$matches[2]; | |
881 | + else | |
882 | + $this->_redirectaddr .= $matches[2]; | |
883 | + } | |
884 | + else | |
885 | + $this->_redirectaddr = $matches[2]; | |
886 | + } | |
887 | + | |
888 | + if(preg_match("|^HTTP/|",$currentHeader)) | |
889 | + { | |
890 | + if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status)) | |
891 | + { | |
892 | + $this->status= $status[1]; | |
893 | + } | |
894 | + $this->response_code = $currentHeader; | |
895 | + } | |
896 | + | |
897 | + $this->headers[] = $currentHeader; | |
898 | + } | |
899 | + | |
900 | + $results = ''; | |
901 | + do { | |
902 | + $_data = fread($fp, $this->maxlength); | |
903 | + if (strlen($_data) == 0) { | |
904 | + break; | |
905 | + } | |
906 | + $results .= $_data; | |
907 | + } while(true); | |
908 | + | |
909 | + if ($this->read_timeout > 0 && $this->_check_timeout($fp)) | |
910 | + { | |
911 | + $this->status=-100; | |
912 | + return false; | |
913 | + } | |
914 | + | |
915 | + // check if there is a a redirect meta tag | |
916 | + | |
917 | + if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) | |
918 | + | |
919 | + { | |
920 | + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); | |
921 | + } | |
922 | + | |
923 | + // have we hit our frame depth and is there frame src to fetch? | |
924 | + if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match)) | |
925 | + { | |
926 | + $this->results[] = $results; | |
927 | + for($x=0; $x<count($match[1]); $x++) | |
928 | + $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); | |
929 | + } | |
930 | + // have we already fetched framed content? | |
931 | + elseif(is_array($this->results)) | |
932 | + $this->results[] = $results; | |
933 | + // no framed content | |
934 | + else | |
935 | + $this->results = $results; | |
936 | + | |
937 | + return true; | |
938 | + } | |
939 | + | |
940 | +/*======================================================================*\ | |
941 | + Function: _httpsrequest | |
942 | + Purpose: go get the https data from the server using curl | |
943 | + Input: $url the url to fetch | |
944 | + $URI the full URI | |
945 | + $body body contents to send if any (POST) | |
946 | + Output: | |
947 | +\*======================================================================*/ | |
948 | + | |
949 | + function _httpsrequest($url,$URI,$http_method,$content_type="",$body="") | |
950 | + { | |
951 | + if($this->passcookies && $this->_redirectaddr) | |
952 | + $this->setcookies(); | |
953 | + | |
954 | + $headers = array(); | |
955 | + | |
956 | + $URI_PARTS = parse_url($URI); | |
957 | + if(empty($url)) | |
958 | + $url = "/"; | |
959 | + // GET ... header not needed for curl | |
960 | + //$headers[] = $http_method." ".$url." ".$this->_httpversion; | |
961 | + if(!empty($this->agent)) | |
962 | + $headers[] = "User-Agent: ".$this->agent; | |
963 | + if(!empty($this->host)) | |
964 | + /** | |
965 | + * 80のときはポート番号を付けない | |
966 | + * Marijuana | |
967 | + */ | |
968 | + if(!empty($this->port) && $this->port != 80) | |
969 | + $headers[] = "Host: ".$this->host.":".$this->port; | |
970 | + else | |
971 | + $headers[] = "Host: ".$this->host; | |
972 | + if(!empty($this->accept)) | |
973 | + $headers[] = "Accept: ".$this->accept; | |
974 | + if(!empty($this->referer)) | |
975 | + $headers[] = "Referer: ".$this->referer; | |
976 | + if(!empty($this->cookies)) | |
977 | + { | |
978 | + if(!is_array($this->cookies)) | |
979 | + $this->cookies = (array)$this->cookies; | |
980 | + | |
981 | + reset($this->cookies); | |
982 | + if ( count($this->cookies) > 0 ) { | |
983 | + $cookie_str = 'Cookie: '; | |
984 | + foreach ( $this->cookies as $cookieKey => $cookieVal ) { | |
985 | + $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; "; | |
986 | + } | |
987 | + $headers[] = substr($cookie_str,0,-2); | |
988 | + } | |
989 | + } | |
990 | + if(!empty($this->rawheaders)) | |
991 | + { | |
992 | + if(!is_array($this->rawheaders)) | |
993 | + $this->rawheaders = (array)$this->rawheaders; | |
994 | + while(list($headerKey,$headerVal) = each($this->rawheaders)) | |
995 | + $headers[] = $headerKey.": ".$headerVal; | |
996 | + } | |
997 | + if(!empty($content_type)) { | |
998 | + if ($content_type == "multipart/form-data") | |
999 | + $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary; | |
1000 | + else | |
1001 | + $headers[] = "Content-type: $content_type"; | |
1002 | + } | |
1003 | + if(!empty($body)) | |
1004 | + $headers[] = "Content-length: ".strlen($body); | |
1005 | + if(!empty($this->user) || !empty($this->pass)) | |
1006 | + $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass); | |
1007 | + | |
1008 | + for($curr_header = 0; $curr_header < count($headers); $curr_header++) { | |
1009 | + $safer_header = strtr( $headers[$curr_header], "\"", " " ); | |
1010 | + $cmdline_params .= " -H \"".$safer_header."\""; | |
1011 | + } | |
1012 | + | |
1013 | + if(!empty($body)) | |
1014 | + $cmdline_params .= " -d \"$body\""; | |
1015 | + | |
1016 | + if($this->read_timeout > 0) | |
1017 | + $cmdline_params .= " -m ".$this->read_timeout; | |
1018 | + | |
1019 | + $headerfile = tempnam($temp_dir, "sno"); | |
1020 | + | |
1021 | + exec($this->curl_path." -k -D \"$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return); | |
1022 | + | |
1023 | + if($return) | |
1024 | + { | |
1025 | + $this->error = "Error: cURL could not retrieve the document, error $return."; | |
1026 | + return false; | |
1027 | + } | |
1028 | + | |
1029 | + | |
1030 | + $results = implode("\r\n",$results); | |
1031 | + | |
1032 | + $result_headers = file("$headerfile"); | |
1033 | + | |
1034 | + $this->_redirectaddr = false; | |
1035 | + unset($this->headers); | |
1036 | + | |
1037 | + for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++) | |
1038 | + { | |
1039 | + | |
1040 | + // if a header begins with Location: or URI:, set the redirect | |
1041 | + if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader])) | |
1042 | + { | |
1043 | + // get URL portion of the redirect | |
1044 | + preg_match("/^(Location: |URI:)\s+(.*)/",chop($result_headers[$currentHeader]),$matches); | |
1045 | + // look for :// in the Location header to see if hostname is included | |
1046 | + if(!preg_match("|\:\/\/|",$matches[2])) | |
1047 | + { | |
1048 | + // no host in the path, so prepend | |
1049 | + $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port; | |
1050 | + // eliminate double slash | |
1051 | + if(!preg_match("|^/|",$matches[2])) | |
1052 | + $this->_redirectaddr .= "/".$matches[2]; | |
1053 | + else | |
1054 | + $this->_redirectaddr .= $matches[2]; | |
1055 | + } | |
1056 | + else | |
1057 | + $this->_redirectaddr = $matches[2]; | |
1058 | + } | |
1059 | + | |
1060 | + if(preg_match("|^HTTP/|",$result_headers[$currentHeader])) | |
1061 | + $this->response_code = $result_headers[$currentHeader]; | |
1062 | + | |
1063 | + $this->headers[] = $result_headers[$currentHeader]; | |
1064 | + } | |
1065 | + | |
1066 | + // check if there is a a redirect meta tag | |
1067 | + | |
1068 | + if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) | |
1069 | + { | |
1070 | + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); | |
1071 | + } | |
1072 | + | |
1073 | + // have we hit our frame depth and is there frame src to fetch? | |
1074 | + if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match)) | |
1075 | + { | |
1076 | + $this->results[] = $results; | |
1077 | + for($x=0; $x<count($match[1]); $x++) | |
1078 | + $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); | |
1079 | + } | |
1080 | + // have we already fetched framed content? | |
1081 | + elseif(is_array($this->results)) | |
1082 | + $this->results[] = $results; | |
1083 | + // no framed content | |
1084 | + else | |
1085 | + $this->results = $results; | |
1086 | + | |
1087 | + unlink("$headerfile"); | |
1088 | + | |
1089 | + return true; | |
1090 | + } | |
1091 | + | |
1092 | +/*======================================================================*\ | |
1093 | + Function: setcookies() | |
1094 | + Purpose: set cookies for a redirection | |
1095 | +\*======================================================================*/ | |
1096 | + | |
1097 | + function setcookies() | |
1098 | + { | |
1099 | + for($x=0; $x<count($this->headers); $x++) | |
1100 | + { | |
1101 | + if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match)) | |
1102 | + $this->cookies[$match[1]] = urldecode($match[2]); | |
1103 | + } | |
1104 | + } | |
1105 | + | |
1106 | + | |
1107 | +/*======================================================================*\ | |
1108 | + Function: _check_timeout | |
1109 | + Purpose: checks whether timeout has occurred | |
1110 | + Input: $fp file pointer | |
1111 | +\*======================================================================*/ | |
1112 | + | |
1113 | + function _check_timeout($fp) | |
1114 | + { | |
1115 | + if ($this->read_timeout > 0) { | |
1116 | + $fp_status = socket_get_status($fp); | |
1117 | + if ($fp_status["timed_out"]) { | |
1118 | + $this->timed_out = true; | |
1119 | + return true; | |
1120 | + } | |
1121 | + } | |
1122 | + return false; | |
1123 | + } | |
1124 | + | |
1125 | +/*======================================================================*\ | |
1126 | + Function: _connect | |
1127 | + Purpose: make a socket connection | |
1128 | + Input: $fp file pointer | |
1129 | +\*======================================================================*/ | |
1130 | + | |
1131 | + function _connect(&$fp) | |
1132 | + { | |
1133 | + if(!empty($this->proxy_host) && !empty($this->proxy_port)) | |
1134 | + { | |
1135 | + $this->_isproxy = true; | |
1136 | + | |
1137 | + $host = $this->proxy_host; | |
1138 | + $port = $this->proxy_port; | |
1139 | + } | |
1140 | + else | |
1141 | + { | |
1142 | + $host = $this->host; | |
1143 | + $port = $this->port; | |
1144 | + } | |
1145 | + | |
1146 | + $this->status = 0; | |
1147 | + | |
1148 | + if($fp = fsockopen( | |
1149 | + $host, | |
1150 | + $port, | |
1151 | + $errno, | |
1152 | + $errstr, | |
1153 | + $this->_fp_timeout | |
1154 | + )) | |
1155 | + { | |
1156 | + // socket connection succeeded | |
1157 | + | |
1158 | + return true; | |
1159 | + } | |
1160 | + else | |
1161 | + { | |
1162 | + // socket connection failed | |
1163 | + $this->status = $errno; | |
1164 | + switch($errno) | |
1165 | + { | |
1166 | + case -3: | |
1167 | + $this->error="socket creation failed (-3)"; | |
1168 | + case -4: | |
1169 | + $this->error="dns lookup failure (-4)"; | |
1170 | + case -5: | |
1171 | + $this->error="connection refused or timed out (-5)"; | |
1172 | + default: | |
1173 | + $this->error="connection failed (".$errno.")"; | |
1174 | + } | |
1175 | + return false; | |
1176 | + } | |
1177 | + } | |
1178 | +/*======================================================================*\ | |
1179 | + Function: _disconnect | |
1180 | + Purpose: disconnect a socket connection | |
1181 | + Input: $fp file pointer | |
1182 | +\*======================================================================*/ | |
1183 | + | |
1184 | + function _disconnect($fp) | |
1185 | + { | |
1186 | + return(fclose($fp)); | |
1187 | + } | |
1188 | + | |
1189 | + | |
1190 | +/*======================================================================*\ | |
1191 | + Function: _prepare_post_body | |
1192 | + Purpose: Prepare post body according to encoding type | |
1193 | + Input: $formvars - form variables | |
1194 | + $formfiles - form upload files | |
1195 | + Output: post body | |
1196 | +\*======================================================================*/ | |
1197 | + | |
1198 | + function _prepare_post_body($formvars, $formfiles) | |
1199 | + { | |
1200 | + settype($formvars, "array"); | |
1201 | + settype($formfiles, "array"); | |
1202 | + $postdata = ''; | |
1203 | + | |
1204 | + if (count($formvars) == 0 && count($formfiles) == 0) | |
1205 | + return; | |
1206 | + | |
1207 | + switch ($this->_submit_type) { | |
1208 | + case "application/x-www-form-urlencoded": | |
1209 | + reset($formvars); | |
1210 | + while(list($key,$val) = each($formvars)) { | |
1211 | + if (is_array($val) || is_object($val)) { | |
1212 | + while (list($cur_key, $cur_val) = each($val)) { | |
1213 | + $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&"; | |
1214 | + } | |
1215 | + } else | |
1216 | + $postdata .= urlencode($key)."=".urlencode($val)."&"; | |
1217 | + } | |
1218 | + break; | |
1219 | + | |
1220 | + case "multipart/form-data": | |
1221 | + $this->_mime_boundary = "Snoopy".md5(uniqid(microtime())); | |
1222 | + | |
1223 | + reset($formvars); | |
1224 | + while(list($key,$val) = each($formvars)) { | |
1225 | + if (is_array($val) || is_object($val)) { | |
1226 | + while (list($cur_key, $cur_val) = each($val)) { | |
1227 | + $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1228 | + $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n"; | |
1229 | + $postdata .= "$cur_val\r\n"; | |
1230 | + } | |
1231 | + } else { | |
1232 | + $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1233 | + $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n"; | |
1234 | + $postdata .= "$val\r\n"; | |
1235 | + } | |
1236 | + } | |
1237 | + | |
1238 | + reset($formfiles); | |
1239 | + while (list($field_name, $file_names) = each($formfiles)) { | |
1240 | + settype($file_names, "array"); | |
1241 | + while (list(, $file_name) = each($file_names)) { | |
1242 | + if (!is_readable($file_name)) continue; | |
1243 | + | |
1244 | + $fp = fopen($file_name, "r"); | |
1245 | + $file_content = fread($fp, filesize($file_name)); | |
1246 | + fclose($fp); | |
1247 | + $base_name = basename($file_name); | |
1248 | + | |
1249 | + $postdata .= "--".$this->_mime_boundary."\r\n"; | |
1250 | + $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n"; | |
1251 | + $postdata .= "$file_content\r\n"; | |
1252 | + } | |
1253 | + } | |
1254 | + $postdata .= "--".$this->_mime_boundary."--\r\n"; | |
1255 | + break; | |
1256 | + // XOOPS2 Hack begin | |
1257 | + // Added on March 4, 2003 by onokazu@xoops.org | |
1258 | + case "text/xml": | |
1259 | + default: | |
1260 | + $postdata = $formvars[0]; | |
1261 | + break; | |
1262 | + // XOOPS2 Hack end | |
1263 | + } | |
1264 | + | |
1265 | + return $postdata; | |
1266 | + } | |
1267 | +} | |
1268 | + | |
1269 | +?> |