• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

XOOPS Cube Legacy base repository


Commit MetaInfo

Revisiónc3718b7bff6d64f103b7b7eb380852c1ee1cec8a (tree)
Tiempo2010-11-14 00:14:05
Autorkilica <kilica@704c...>
Commiterkilica

Log Message

- 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

Cambiar Resumen

Diferencia incremental

--- a/html/class/snoopy.php
+++ b/html/class/snoopy.php
@@ -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- "'&szlig;'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+ "'&szlig;'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+?>