PageRenderTime 60ms CodeModel.GetById 2ms app.highlight 50ms RepoModel.GetById 0ms app.codeStats 1ms

/libs/HTTPQuery.php

https://bitbucket.org/0xDB/text2speach
PHP | 922 lines | 481 code | 134 blank | 307 comment | 139 complexity | 689545d92b434bc7748248cec54cbef1 MD5 | raw file
  1<?php
  2
  3/**
  4 * @name: HTTPQuery.php
  5 * @description: Thing to work with HTTP protocol
  6 * @requires: WhoIS class by NULL_byte >= ver 1.1
  7 * @author: NULL_byte
  8 * @contacts: www.null-byte.info
  9 * @version: 2.1
 10 */
 11
 12# http://ru.php.net/manual/en/ref.url.php
 13# TODO: refactor HTTPSocket class using <http://ru.php.net/manual/en/ref.http.php>
 14#  & discover <http://ru.php.net/manual/en/class.httpresponse.php>
 15
 16# The better HTTP Client interface will always work via HTTPQuery class
 17# usage example:
 18#   $q = new HTTPQuery;
 19#   $q->Get('http://www.yandex.ru/');
 20
 21
 22# Import WhoIS class
 23if (!class_exists('WhoIS'))
 24	@require_once dirname(__FILE__).'/WhoIS.php';
 25if (!class_exists('WhoIS'))
 26	die("The required class `WhoIS` is not found!");
 27
 28abstract class HTTPClient extends WhoIS {
 29	# System operated variables
 30	public $URI          = 'http://localhost/';
 31	public $Scheme       = 'http';
 32	public $Host         = null;
 33	public $IDNA         = null; # Punycode
 34	public $Port         = '80';
 35	public $Path         = null;
 36	public $Method       = 'get';
 37	public $Query        = null;
 38	public $Cookies      = null;
 39	public $Engine       = null; # 'cURL' or 'Sockets'
 40	# Toggles
 41	public $Proxy        = false; # Proxy to use. Format: Array('proxy_host', 'port') or false or 'proxy:port', yeah
 42	#public $UserAgent    = 'Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4719; en; U; ssr)';
 43	public $UserAgent    = false;
 44	public $Referer      = null;
 45	public $AutoCookies  = true;
 46	public $AutoReferer  = true;
 47	public $AutoRedirect = true; # TODO: fix header('Location: /redirect.html');   # Fixed?
 48	public $FlushCookies = false; # WTF?!  will flush cookies after each request if $this->AutoCookies = false;
 49	public $Verbose      = false; # If true, would print many interesting messages
 50	public $Timeout      = 30; # Request timeout
 51	# Output
 52	public $Result       = null;  # Will contain result with page headers
 53	public $ResultClean  = null;  # Will contain result without page headers
 54	# Headers
 55	public $HTTPHeaders  = Array(); # Example:  $this->HTTPHeaders = Array('Location: /newpage.html', ...);
 56	public $PageHeaders  = Array(); # Example:  $this->PageHeaders['location'];
 57	# Aliases
 58	public $ResponseHeaders = Array(); # alias of $this->PageHeaders
 59	public $Headers         = Array(); # alias of $this->PageHeaders
 60	public $RequestHeaders  = Array(); # alias of $this->HTTPHeaders
 61	public $RawHeaders      = Array(); # alias of $this->HTTPHeaders
 62
 63	public $maxRedirects    = 20;
 64	public $maxRedirects_i  = 0;
 65
 66	public $Redirect_i      = 0; # should be reset manualy... (updates only on request!)
 67
 68	#private $gotCookies_    = null;
 69	public $gotCookies_    = null;
 70	public $gotCookies__    = null;
 71
 72	abstract public function Get($url);
 73	abstract public function Post($url);
 74	#abstract public function GetCookies();
 75	abstract protected function SendRequest();
 76	abstract protected function ConstructQuery();
 77
 78	public function __construct ($dump_engine = false) {
 79		$this->Engine = get_parent_class($this);
 80		#if (strtolower(substr($this->Engine, 0, 4)) == 'http')
 81		#	$this->Engine = substr($this->Engine, 4);
 82		if ($dump_engine)
 83			echo " # `".get_class($this)."` currently uses `<{$this->Engine}>` as HTTP engine\r\n";
 84	}
 85	
 86	public function rndUserAgent() { # needs to be improved
 87		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)';
 88		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/5.0 (compatible; Opera 9.80; Windows NT 6)';
 89		if(mt_rand(0,1)) $this->UserAgent = 'Safari Mozilla 4.6';
 90		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/3.0 Googlebot';
 91		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/5.0 (X11; U; Linux x86_64;) Gecko Ubuntu/9.04 (jaunty) Shiretoko/3.5';
 92		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/4.61 [en] (OS/2; U)';
 93		if(mt_rand(0,1)) $this->UserAgent = 'Mozilla/4.8 [en] (Windows NT 5.0; U)';
 94		if(mt_rand(0,1)) $this->UserAgent = 'Opera/8.0 (X11; Linux i686; U; cs)';
 95		if(mt_rand(0,1)) $this->UserAgent = 'Opera/10.00 (Windows NT 6.0; U; en) Presto/2.2.0';
 96		#if(mt_rand(0,1)) $this->UserAgent = 'Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4719; en; U; ssr)';
 97	}
 98
 99	protected function MakeAliases() {
100		if (!$this->PageHeaders && $this->ResponseHeaders) $this->PageHeaders = $this->ResponseHeaders;
101		if (!$this->PageHeaders && $this->Headers)         $this->PageHeaders = $this->Headers;
102		if (!$this->HTTPHeaders && $this->RequestHeaders)  $this->HTTPHeaders = $this->RequestHeaders;
103		if (!$this->HTTPHeaders && $this->RawHeaders)      $this->HTTPHeaders = $this->RawHeaders;
104	}
105
106	protected function PreConstructQuery() {
107		$this->getUrlParts();
108		list($this->IDNA, $this->Host) = $this->IDNA($this->Host);
109		if ($this->IDNA) $this->Host = $this->IDNA;
110	}
111
112	protected function getUrlParts($url = false) {
113		if (!$url && !$this->URI) return false;
114		if (!$url) $url = $this->URI;
115
116		$url_parts = parse_url($url);
117		if (!isset($url_parts['scheme'])) $url_parts['scheme'] = 'http';
118		if (!isset($url_parts['port']))
119			$url_parts['port'] = ($url_parts['scheme'] == 'https') ? 443 : 80;
120		if (!isset($url_parts['path'])) $url_parts['path'] = null;
121		if (!isset($url_parts['query']))
122			$url_parts['query'] = null;
123		else
124			$url_parts['query'] = "?{$url_parts['query']}";
125
126		$this->Scheme = strtolower($url_parts['scheme']);
127		$this->Host = strtolower($url_parts['host']);
128		$this->Port = $url_parts['port'];
129		$this->Path = $url_parts['path'];
130		$this->Query = $url_parts['query'];
131
132		return $url_parts;
133	}
134
135	protected function ParseHeaders() {
136		if (!$this->Result) return false;
137		$server_response = explode("\r\n\r\n", $this->Result);
138		$server_response = $server_response[0];
139		$server_response = str_replace("\r", '', $server_response);
140		$server_response = explode("\n", $server_response);
141
142		$this->ResponseStatus = $server_response[0];
143		preg_match('#\d{3}#', $this->ResponseStatus, $this->ResponseCode);
144		if (isset($this->ResponseCode[0]))
145			$this->ResponseCode = $this->ResponseCode[0];
146
147		$result = Array();
148		foreach($server_response as $mixed_headers) {
149			if ((strpos($mixed_headers, ': ') >= 0)) {
150				$header = explode(': ', trim($mixed_headers));
151				$result[$header[0]] = isset($header[1]) ? $header[1] : NULL;
152				$result[strtolower($header[0])] = isset($header[1]) ? $header[1] : NULL;
153			}
154		}
155		$this->ResponseHeaders = $result;
156		$this->PageHeaders = $result;
157		$this->Headers = $result;
158		return $result;
159	}
160
161	protected function CookiesToString($cookie = false) {
162		if (!$cookie) $cookie = $this->Cookies;
163		if (!$cookie) return $cookie;
164		if (is_string($cookie)) return $cookie;
165		#if (!is_array($cookie)) var_dump($cookie);
166		
167		$cookie_string = '';
168		foreach ($cookie as $key => $value)
169			$cookie_string .= " {$key}={$value};";
170		$cookie = trim($cookie_string, '; ');
171		return $cookie;
172	}
173
174	protected function CookiesToArray($cookie = false) {
175		if (!$cookie) $cookie = $this->Cookies;
176		if (is_array($cookie)) return $cookie;
177		$cookie = explode('; ', $cookie);
178		$cookie_array = Array();
179		for ($i = 0; $i < count($cookie); $i++) {
180			$c = explode('=', $cookie[$i]);
181			$cookie_array[$c[0]] = $c[1];
182		}
183		return $cookie_array;
184	}
185
186	public function GetCookies($as_string = false) {
187		if (!$this->Result && $as_string) return null;
188		if (!$this->Result) return Array();
189		$data = explode("\r\n\r\n", $this->Result);
190		$data = $data[0];
191		$data = str_replace("\r", '', $data);
192		$data = explode("\n", $data);
193		$raw_cookies = Array();
194		foreach ($data as $d) {
195			$d = explode(' ', $d);
196			if (strtolower($d[0]) == 'set-cookie:') {
197				$raw_cookies[] = $d[1];
198			}
199		}
200		$cookies = Array();
201		foreach ($raw_cookies as $cookie) {
202			$cookie_name = substr($cookie, 0, strpos($cookie, '='));
203			$cookie_value = substr($cookie, strpos($cookie, '=')+1, strpos($cookie, ';')-2);
204			$cookies[$cookie_name] = trim($cookie_value, '; ');
205		}
206		if ($as_string)
207			$cookies = $this->CookiesToString($cookies);
208		#$this->Cookies = $cookies;
209		return $cookies;
210	}
211
212	public function ClearCookies() {
213		$this->Cookies = null;
214	}
215
216
217	# Pa-paa-ram!
218	# Checks if string is UTF-8 encoded
219	function is_utf8($string, $utf8_split = 5000) { // v1.01
220		if (strlen($string) > $utf8_split) {
221			for ($i=0,$s=$utf8_split,$j=ceil(strlen($string)/$utf8_split);$i < $j;$i++,$s+=$utf8_split) {
222				if ($this->is_utf8(substr($string,$s,$utf8_split)))
223					return true;
224			}
225			return false;
226		} else {
227			return preg_match('%^(?:
228				[\x09\x0A\x0D\x20-\x7E]              # ASCII
229				| [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
230				|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
231				| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
232				|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
233				|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
234				| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
235				|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
236			)*$%xs', $string);
237		}
238	}
239}
240
241
242# If cURL  extension is available, we will use it...
243# else we'll be lived without HTTP/1.1 & HTTPS support
244
245#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
246#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
247
248#####     #####     #####     #####     #####     #####
249
250#####     Working with HTTP via cURL...           #####
251
252#####     #####     #####     #####     #####     #####
253
254#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
255#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
256
257
258# cURL based interface
259class HTTPcURL extends HTTPClient {
260	var $cURLHandler = null;
261
262	function ConstructQuery() {
263		if ($this->Verbose) {
264			file_put_contents("./_request_#{$this->Redirect_i}.log", null);
265			echo  " # Client request log created (`./_request_#{$this->Redirect_i}.log`)\n";
266		}
267		$this->MakeAliases();
268
269		$this->cURLHandler = curl_init();
270		curl_setopt($this->cURLHandler, CURLOPT_FRESH_CONNECT, true);
271		curl_setopt($this->cURLHandler, CURLOPT_FORBID_REUSE, true);
272		curl_setopt($this->cURLHandler, CURLOPT_USERAGENT, $this->UserAgent);
273		if ($this->Verbose) {
274			file_put_contents("./_request_#{$this->Redirect_i}.log", 
275				"UserAgent: `".print_r($this->UserAgent, true)."`\r\n", FILE_APPEND);
276			echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `UserAgent`\r\n";
277		}
278		curl_setopt($this->cURLHandler, CURLOPT_TIMEOUT, $this->Timeout);
279		curl_setopt($this->cURLHandler, CURLOPT_HEADER, true);
280		#curl_setopt($this->cURLHandler, CURLINFO_HEADER_OUT, true);
281		curl_setopt($this->cURLHandler, CURLOPT_SSL_VERIFYPEER, false);
282		curl_setopt($this->cURLHandler, CURLOPT_SSL_VERIFYHOST, false);
283		curl_setopt($this->cURLHandler, CURLOPT_AUTOREFERER, $this->AutoReferer);
284		#curl_setopt($this->cURLHandler, CURLOPT_COOKIESESSION, true);
285		curl_setopt($this->cURLHandler, CURLOPT_FOLLOWLOCATION, false);
286		curl_setopt($this->cURLHandler, CURLOPT_VERBOSE, $this->Verbose);
287		curl_setopt($this->cURLHandler, CURLOPT_NOPROGRESS, !$this->Verbose);
288		curl_setopt($this->cURLHandler, CURLOPT_FAILONERROR, false);
289		if ($this->Proxy) {
290			if (is_string($this->Proxy))
291				$this->Proxy = explode(':', $this->Proxy);
292			curl_setopt($this->cURLHandler, CURLOPT_PROXY, $this->Proxy[0]);
293			curl_setopt($this->cURLHandler, CURLOPT_PROXYPORT, $this->Proxy[1]);
294			curl_setopt($this->cURLHandler, CURLOPT_HTTPPROXYTUNNEL, true);
295			if ($this->Verbose) {
296				file_put_contents("./_request_#{$this->Redirect_i}.log", 
297					"Proxy: `".trim(print_r($this->Proxy, true))."`\r\n", FILE_APPEND);
298				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `Proxy`\r\n";
299			}
300		} else {
301			curl_setopt($this->cURLHandler, CURLOPT_HTTPPROXYTUNNEL, false);
302		}
303		
304		
305
306		# CURLOPT_COOKIE
307
308
309		if ($this->AutoReferer && !$this->Referer && $this->Host)
310			$this->Referer = "{$this->Scheme}://{$this->Host}/";
311
312
313		if ($this->Referer) {
314			curl_setopt($this->cURLHandler, CURLOPT_REFERER, $this->Referer);
315			if ($this->Verbose) {
316				file_put_contents("./_request_#{$this->Redirect_i}.log", 
317					"Referer: `".trim(print_r($this->Referer, true))."`\r\n", FILE_APPEND);
318				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `Referer`\r\n";
319			}
320		}
321
322		#if ($this->AutoCookies && $this->Cookies) {
323		if ($this->Cookies) {
324			curl_setopt($this->cURLHandler, CURLOPT_COOKIE, $this->CookiesToString());
325			if ($this->Verbose) {
326				file_put_contents("./_request_#{$this->Redirect_i}.log", 
327					"Cookies: `".$this->CookiesToString()."`\r\n", FILE_APPEND);
328				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `Cookies`\r\n";
329			}
330		}
331
332		if ($this->HTTPHeaders) {
333			curl_setopt($this->cURLHandler, CURLOPT_HTTPHEADER, $this->HTTPHeaders);
334			if ($this->Verbose) {
335				file_put_contents("./_request_#{$this->Redirect_i}.log", 
336					"HTTP Headers: `".trim(print_r($this->HTTPHeaders, true))."`\r\n", FILE_APPEND);
337				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `HTTPHeaders`\r\n";
338			}
339		}
340		#curl_setopt($this->cURLHandler, CURLOPT_POST, true);
341		#curl_setopt($this->cURLHandler, CURLOPT_HTTPGET, false);
342		#curl_setopt($this->cURLHandler, CURLOPT_POSTFIELDS, $this->Query);
343
344		if ($this->Verbose) {
345			file_put_contents("./_request_#{$this->Redirect_i}.log", "\r\n", FILE_APPEND);
346				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `new line (".'\r\n'.")`\r\n";
347		}
348		return $this->cURLHandler;
349	}
350
351
352	function SendRequest($url = false, $ch = false) {
353		if (!$url && !$this->URI) return false;
354		if (!$url) $url = $this->URI;
355		else $this->URI = $url;
356
357		$this->PreConstructQuery();
358		if (!$ch) $this->cURLHandler = $this->ConstructQuery();
359		else $this->cURLHandler = $ch;
360		
361		#var_dump("{$this->Scheme}://{$this->Host}{$this->Path}{$this->Query}");
362		#var_dump($this);
363
364		curl_setopt($this->cURLHandler, CURLOPT_URL,
365			"{$this->Scheme}://{$this->Host}{$this->Path}{$this->Query}");
366
367		curl_setopt($this->cURLHandler, CURLOPT_PORT, $this->Port);
368		curl_setopt($this->cURLHandler, CURLOPT_RETURNTRANSFER, true);
369
370		$this->Result = curl_exec($this->cURLHandler);
371		curl_close($this->cURLHandler);
372
373		# clean 100 continue waste
374		while (preg_match('#^http/1\.[01] [^\r\n]+\r?\n\r?\n#si', $this->Result))
375			$this->Result = preg_replace("#^http/1\.[01] [^\r\n]+\r?\n\r?\n#si", '', $this->Result);
376		#if (preg_match('#^http/1\.[01] [^\r\n]+\r\n\r\n#i', $this->Result))
377		#	$this->Result = preg_replace("#^http/1\.[01] [^\r\n]+\r\n\r\n#i", '', $this->Result);
378
379
380		if ($this->Verbose) {
381			file_put_contents("./_responce_#{$this->Redirect_i}.log", null);
382			echo  " # Server responce log created (`./_responce_#{$this->Redirect_i}.log`)\n";
383#var_dump($this->Cookies);
384#var_dump($this->GetCookies());
385		}
386
387		$this->ParseHeaders();
388		$this->gotCookies_ = $this->GetCookies();
389		if ($this->AutoCookies) {
390			if ($this->Verbose) {
391				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
392					"HTTP Page request (source) Cookies: `".trim($this->CookiesToString())."`\r\n", FILE_APPEND);
393				echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page request (source) Cookies`\r\n";
394
395				echo "Trying to set AutoCookies, responce Cookies are: \n";
396				var_dump(trim($this->CookiesToString($this->gotCookies_)));
397				echo "\n";
398			}
399
400			if (!$this->Cookies) $this->Cookies = $this->gotCookies_; #mad_cow O_o
401			elseif (is_array($this->Cookies)) $this->Cookies = array_merge($this->Cookies, $this->gotCookies_);
402			elseif (is_string($this->Cookies)) $this->Cookies .= $this->CookiesToString($this->gotCookies_);
403
404			if ($this->Verbose) {
405				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
406					"HTTP Page responce (current) Cookies: `".trim(print_r($this->gotCookies_, true))."`\r\n", FILE_APPEND);
407				echo  " # Server total log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page total (current) Cookies`\r\n";
408
409				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
410					"HTTP Page total (result) Cookies: `".trim($this->CookiesToString($this->Cookies))."`\r\n", FILE_APPEND);
411				echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page total (result) Cookies`\r\n";
412				echo "\n";
413
414			}
415		}
416
417
418		if ($this->Verbose) {
419			file_put_contents("./_responce_#{$this->Redirect_i}.log", 
420				"HTTP Page Headers: `".trim(print_r($this->PageHeaders, true))."`\r\n", FILE_APPEND);
421			echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page Headers`\r\n";
422		}
423/*
424			if (!$this->Cookies) $this->Cookies = $this->gotCookies_; #mad_cow O_o
425			elseif (is_array($this->Cookies)) $this->Cookies = array_merge($this->Cookies, $this->gotCookies_);
426			elseif (is_string($this->Cookies)) $this->Cookies .= $this->CookiesToString($this->gotCookies_);
427			if ($this->Verbose) {
428				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
429					"HTTP Page total Cookies: `".trim(print_r($this->Cookies, true))."`\r\n", FILE_APPEND);
430				echo  " # Server total log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page total (current) Cookies`\r\n";
431				#echo "So, resulting Cookies are: \n";
432				#var_dump($this->Cookies);
433			}
434#		}
435*/
436
437
438/*
439		
440		#curl_setopt($ch, CURLOPT_ENCODING, '');
441		#if ($this->gotCookies_) {
442		if ($this->Cookies) {
443var_dump($this->CookiesToString());
444			curl_setopt($this->cURLHandler, CURLOPT_COOKIE, $this->CookiesToString());
445			if ($this->Verbose) {
446				file_put_contents("./_request_#{$this->Redirect_i}.log", 
447					"Cookies: `".trim(print_r($this->CookiesToString()), true)."`\r\n", FILE_APPEND);
448var_dump($this->CookiesToString());
449				echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `Cookies`\r\n";
450			}
451		}
452*/
453
454
455
456/*
457		#$this->gotCookies__ = $this->Cookies;
458		$this->gotCookies_ = $this->GetCookies();
459		if ($this->AutoCookies) {
460			if ($this->Verbose) {
461				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
462					#"HTTP Page request Cookies: `".trim(print_r($this->gotCookies__, true))."`\r\n", FILE_APPEND);
463					"HTTP Page request Cookies: `".trim(print_r($this->Cookies, true))."`\r\n", FILE_APPEND);
464				echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page request (source) Cookies`\r\n";
465				#echo "Trying to set AutoCookies, source Cookies are: \n";
466				#var_dump($this->Cookies);
467
468				file_put_contents("./_responce_#{$this->Redirect_i}.log", 
469					"HTTP Page responce Cookies: `".trim(print_r($this->gotCookies_, true))."`\r\n", FILE_APPEND);
470				echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page responce (current) Cookies`\r\n";
471				#echo "Trying to set AutoCookies, current Cookies are: \n";
472				#var_dump($this->gotCookies_);
473			}
474*/
475
476			
477			
478/*
479			if ($this->Verbose) {
480				echo "Current Cookies are: \n";
481				var_dump($this->gotCookies_);
482			}
483			if (!$this->Cookies) $this->Cookies = $this->gotCookies_; #mad_cow O_o
484			elseif (is_array($this->Cookies)) $this->Cookies = array_merge($this->Cookies, $this->gotCookies_);
485			elseif (is_string($this->Cookies)) $this->Cookies .= $this->CookiesToString($this->gotCookies_);
486			if ($this->Verbose) {
487				echo "So, resulting Cookies are: \n";
488				var_dump($this->Cookies);
489			}
490
491
492			#if (is_array($this->Cookies)) $this->Cookies += $this->GetCookies();
493			#$gotCookies = $this->GetCookies();
494/*
495			$gotCookies = $this->Cookies;
496			if ($this->Verbose)
497				echo "Above page Cookies: \n".print_r($gotCookies, true)."\n";
498*/
499#		}
500
501
502
503
504		#$this->GetCookies();
505		#$this->gotCookies_ = $this->GetCookies(); # should be declared as `private`
506		#}
507/*
508		if ($this->Verbose && $this->Cookies) {
509			file_put_contents("./_responce_#{$this->Redirect_i}.log", 
510				"HTTP Page total Cookies: `".trim(print_r($this->Cookies, true))."`\r\n", FILE_APPEND);
511			echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page total Cookies`\r\n";
512		}
513*/
514
515
516		if ($this->Verbose && $this->AutoRedirect && isset($this->Headers['location']) && 
517			$this->maxRedirects_i < $this->maxRedirects) {
518			file_put_contents("./_responce_#{$this->Redirect_i}.log", 
519				"HTTP is now redirecting us: ({$this->maxRedirects_i}/{$this->maxRedirects}) to `{$this->Headers['location']}`\r\n", FILE_APPEND);
520			echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Redirect`\r\n";
521		}
522
523
524		if ($this->Verbose) {
525			file_put_contents("./_responce_#{$this->Redirect_i}.log", 
526				"HTTP Page Contents: `".trim(print_r($this->Result, true))."`\r\n", FILE_APPEND);
527			echo  " # Server responce log [`./_responce_#{$this->Redirect_i}.log`] updated with `HTTP Page Contents`\r\n";
528		}
529
530
531
532		#while (preg_match('#^http/1\.[01] [^\r\n]+\r\n\r\n#i', $this->Result)) {
533		#if (preg_match('#^http/1\.[01] [^\r\n]+\r\n\r\n#i', $this->Result))
534		#	$this->Result = preg_replace("#^http/1\.[01] [^\r\n]+\r\n\r\n#i", '', $this->Result);
535
536/*
537		if (!preg_match('#^HTTP/1\.[01] 100#', $this->Result)) {
538			if ($this->Verbose)
539				echo "Above page Headers: ".print_r($this->PageHeaders, true)."\n";
540			if ($this->Verbose) echo "\n\n";
541		}
542*/
543		if (preg_match('#^HTTP/1\.[01] 100#', $this->Result)) {
544			if ($this->Verbose)
545				echo "Above page Headers: ".print_r($this->PageHeaders, true)."\n";
546			if ($this->Verbose) echo "\n\n";
547		}
548#var_dump("Loc\n");
549#var_dump($this->Headers);
550#var_dump("{$this->maxRedirects_i} < {$this->maxRedirects}");
551		#if ($this->Verbose && $this->AutoRedirect && isset($this->Headers['location']))
552		#	echo " Redirect {$this->maxRedirects_i}/{$this->maxRedirects} -> \n";
553		if ($this->AutoRedirect && isset($this->Headers['location']) && 
554			$this->maxRedirects_i < $this->maxRedirects) {
555			$this->maxRedirects_i++;
556			#if (substr($this->Headers['location'],0,7) == 'http://') {
557			if ($this->Verbose)
558				echo "Above page redirected ({$this->maxRedirects_i}/{$this->maxRedirects}) to <{$this->Headers['location']}>\n";
559
560			if (preg_match('#^https?://#i', $this->Headers['location'])) {
561				return $this->SendRequest("{$this->Headers['location']}");
562			} elseif ($this->Headers['location'][0] == '/') {
563				return $this->SendRequest("{$this->Scheme}://{$this->Host}{$this->Headers['location']}");
564			} else {
565				return $this->SendRequest("{$this->Scheme}://{$this->Host}".
566					substr($this->Path,0,strrpos($this->Path,'/')+1)."{$this->Headers['location']}");
567			}
568		}
569		#$this->ResultClean = ltrim(substr($this->Result, strrpos($this->Result, "\r\n\r\n")));
570		#$this->ResultClean = preg_match("#Content-Length: [0-9]+\r\n\r\n(.*?)$#si", $this->Result, $clean);
571		#preg_match("#[^<>]+:[^<>]+\r\n\r\n(.*?)$#si", $this->Result, $clean);
572		#$this->ResultClean = isset($clean[1]) ? $clean[1] : $this->Result;
573		$this->ResultClean = ltrim(substr($this->Result, strpos($this->Result, "\r\n\r\n")));
574		$this->Referer = false;
575		$this->Query = Array();
576		$this->Redirect_i++;
577
578		#var_dump($this->Cookies);
579
580		return $this->Result;
581	}
582
583	function Get($url) {
584		$this->Method = 'get';
585		$this->cURLHandler = $this->ConstructQuery();
586		curl_setopt($this->cURLHandler, CURLOPT_HTTPGET, true);
587		return $this->SendRequest($url, $this->cURLHandler);
588	}
589
590	function Post($url, $postfields = false, $force_fields_str = false) {
591		$this->Method = 'post';
592		if (!$postfields) $postfields = $this->Query;
593
594
595		if ($force_fields_str) {
596			#if (is_array($postfields))
597			#	$postfields = http_build_query($postfields);
598			#	$postfields = str_replace('+', '%20', $postfields);
599				
600			if (is_array($postfields)) {
601				$postfields_ = '';
602				if (is_array($postfields))
603					foreach ($postfields as $key => $value) {
604						if (isset($value[0]) && $value[0] != '@')
605							$value = urlencode($value);
606						#var_dump("{$key}={$value}&");
607						$postfields_ .= "{$key}={$value}&";
608					}
609				$postfields_ = rtrim($postfields_, '&');
610				$postfields = $postfields_;
611			}
612				
613		}
614
615		#if (is_array($postfields))
616		#	$postfields = http_build_query($postfields);
617		#	$postfields = str_replace('+', '%20', $postfields);
618
619		# a-la http_build_query()
620		/*
621			if (is_array($postfields))
622				foreach ($postfields as &$field)
623					if ($field[0] != '@')
624						$field = urlencode(($field));
625			$postfields_ = '';
626			if (is_array($postfields))
627				foreach ($postfields as $key => $value)
628					$postfields_ .= "{$key}={$value}&";
629			$postfields_ = trim($postfields_, '&');
630			$postfields = $postfields_;
631		#*#/
632
633		echo "\n\n------------------\n\n";var_dump($postfields);
634		if (is_array($postfields))
635			foreach ($postfields as &$field)
636				if ($field[0] != '@')
637					$field = rawurlencode($field);
638				#$field = str_replace('+', '%2B', $field);
639		echo "\n\n------------------\n\n";var_dump($postfields);
640		*/
641
642		$this->cURLHandler = $this->ConstructQuery();
643		if ($this->Verbose) {
644			echo "Below Post data: ".print_r($postfields, true)."\n";
645			file_put_contents("./_request_#{$this->Redirect_i}.log", 
646				"Post Vars: `".trim(print_r($postfields, true))."`\r\n", FILE_APPEND);
647			echo  " # Client request log [`./_request_#{$this->Redirect_i}.log`] updated with `Post Vars`\r\n";
648		}
649		curl_setopt($this->cURLHandler, CURLOPT_POST, true);
650		curl_setopt($this->cURLHandler, CURLOPT_HTTPGET, false);
651		curl_setopt($this->cURLHandler, CURLOPT_POSTFIELDS, $postfields);
652		return $this->SendRequest($url, $this->cURLHandler);
653	}
654
655	/*
656	function GetCookies() {
657		#return true;
658		preg_match_all('#\sSet-Cookie: *([^ ]+); #si', $this->Result, $cookies, PREG_SET_ORDER);
659		foreach ($cookies as $cookie) {
660			if ($this->AutoCookies) $this->Cookies .= " {$cookie[1]};";
661			#elseif ($this->FlushCookies) $this->Cookies = "{$cookie[1]};";
662		}
663	}
664	*/
665
666}
667
668
669
670# If the above methods are not available, but we still need to do the work...
671
672#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
673#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
674
675#####     #####     #####     #####     #####     #####
676
677#####     Working with HTTP via sockets...        #####
678
679#####     #####     #####     #####     #####     #####
680
681#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
682#####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####     #####
683
684
685# Socket based interface
686class HTTPSockets extends HTTPClient {
687	var $ContentType  = null;
688	var $Boundary     = '-----NULL-BYTE----NULL-BYTE----NULL-BYTE';
689
690	var $Silent       = false; # If it true, wouldn't print any messages
691
692	var $ResponseStatus = false; # First line of the response header
693	var $ResponseCode = 0; # Response HTTP code
694
695	var $Retries = 3; # Max number of request retries
696
697	function ConstructQuery() {
698		$this->MakeAliases();
699
700		if (is_array($this->Query)) {
701			if (strtolower($this->ContentType) != 'multipart/form-data') {
702				$query_string = '';
703				foreach ($this->Query as $key => $value) {
704					$query_string .= "$key=$value&";
705					//$query_string .= $key.'='.urlencode($value);
706				}
707				$this->Query = trim($query_string, '&');
708			} else {
709				$query_string = '';
710				foreach ($this->Query as $key => $value) {
711					$query_string .= "--{$this->Boundary}\r\n";
712					if (!is_array($value)) {
713						$query_string .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n$value\r\n";
714					} else {
715						/*
716						if (!isset($value[1]) && !isset($value[2])) {
717							$value[1] = $value[0];
718							if (!is_file($value[1])) {
719								echo "HTTPQuery: No such file!\n";
720								//return false;
721							}
722							$value[0] = @file_get_contents($value[1]);
723							file_put_contents("./!!!{$value[1]}", '');
724						}*/
725						if (!isset($value[1])) $value[1] = 'somefile';
726						if (!isset($value[2])) $value[2] = 'application/octet-stream';
727						//if (!isset($value[2])) $value[2] = 'undefined/undefined';
728						$query_string .= "Content-Disposition: form-data; name=\"$key\"; ";
729						$query_string .= "filename=\"{$value[1]}\"\r\n";
730						$query_string .= "Content-Type: {$value[2]}\r\n\r\n{$value[0]}\r\n";
731					}
732				}
733				$query_string .= "--{$this->Boundary}--\r\n";
734				$this->Query = $query_string;
735			}
736		}
737	}
738
739	function Filter() {
740		$this->Result = null;
741		$this->ResultClean = null;
742
743		$this->Method = strtolower($this->Method);
744		$this->URI = preg_replace('#^https?://#', '', $this->URI);
745		//$this->URI = preg_replace('#[\\]]#', '/', $this->URI);
746		//$this->URI = preg_replace('#/{2,}#', '/', $this->URI);
747		if (is_string($this->Proxy)) $this->Proxy = explode(':', $this->Proxy);
748
749		$this->ConstructQuery();
750
751		# Erasing data from old request (if current will fail)
752		$this->ResponseStatus = false;
753		$this->ResponseCode = 0;
754	}
755
756	function SendRequest($url = false) {
757		if (!$url && !$this->URI) return false;
758		if (!$url) $url = $this->URI;
759		else $this->URI = $url;
760		$this->Filter();
761
762		$url_parts = explode('/', $this->URI);
763		$url_parts[0] = explode(':', $url_parts[0]);
764		$this->Host = $url_parts[0][0];
765		if (isset($url_parts[0][1]) && is_numeric($url_parts[0][1]))
766			$this->Port = $url_parts[0][1];
767		$this->Path = '';
768		for ($i = 1; $i < count($url_parts); $i++)
769			$this->Path .= '/'.$url_parts[$i];
770		if ($this->Path == '') $this->Path = '/';
771
772		// Creating socket
773		$cur_try = 0; // Current try
774		$max_tries = $this->Retries; // Max allowed tries
775		while (true) {
776			if ($this->Proxy) {
777				if (is_string($this->Proxy))
778					$this->Proxy = explode(':', $this->Proxy);
779				$fp = @fsockopen($this->Proxy[0], $this->Proxy[1], $errno, $errstr, $this->Timeout);
780			} else {
781				$fp = @fsockopen($this->Host, $this->Port, $errno, $errstr, $this->Timeout);
782			}
783			if ($fp) break; // If everything is ok, going on without stopping
784
785			// Else retrying...
786			$cur_try++;
787			if (!$this->Silent) echo "Cannot create socket, will now try again ({$cur_try}/{$max_tries})...\n";
788			if ($cur_try >= $max_tries) {
789				if (!$this->Silent) echo "Too many errors, please check your internet connection!\n";
790				return false;
791			}
792			sleep(0);
793		}
794
795		if (($this->Method == 'get') && (substr(0, 1, $this->Query) != '?') && ($this->Query != null))
796			$this->Query = '?'.$this->Query;
797
798		$query_length = strlen($this->Query);
799
800		if (!$this->UserAgent)
801			$this->UserAgent = 'NULL_byte\'s PHP Browser Mozilla/4.0 (compatible; MSIE 3.0; Windows NT 4.0)';
802		if ($this->AutoReferer && !$this->Referer)
803			$this->Referer = $this->URI;
804
805		$_cookies = $this->CookiesToString($this->Cookies);
806
807		$PostContentType = 'application/x-www-form-urlencoded';
808		if (strtolower($this->ContentType) == 'multipart/form-data')
809			$PostContentType = "multipart/form-data; boundary={$this->Boundary}";
810
811		$HTTP_Version = 'HTTP/1.0';
812		$out = Array();
813		switch ($this->Method) {
814			case 'get':
815				$out[] = "GET {$this->Path}{$this->Query} {$HTTP_Version}";
816				break;
817			case 'post':
818				$out[] = "POST {$this->Path} {$HTTP_Version}";
819				if (isset($this->ContentType))
820					$out[] = "Content-Type: {$PostContentType}";
821				$out[] = "Content-Length: {$query_length}";
822				break;
823			default:
824				$out[] = strtoupper($this->Method)." {$this->Path}{$this->Query} {$HTTP_Version}";
825				break;
826		}
827		$out[] = "Host: {$this->Host}:{$this->Port}";
828		$out[] = "Accept: text/html;q=0.9,application/xhtml+xml;q=0.8,*/*;q=0.5";
829		$out[] = "Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7";
830		$out[] = "User-Agent: {$this->UserAgent}";
831		if ($this->Cookies) $out[] = "Cookie: {$_cookies}";
832		if ($this->Referer) $out[] = "Referer: {$this->Referer}";
833		$out = array_merge($out, $this->HTTPHeaders);
834		$out[] = "Connection: Close";
835		//$out[] = "Connection: Keep-Alive";
836		$out = implode("\r\n", $out);
837
838		$out = str_replace("\n", "\r\n", $out);
839		$out = preg_replace("#[\n]+#", "\n", $out);
840		$out = preg_replace("#[\r]+#", "\r", $out);
841		$out .= "\r\n\r\n";
842		if ($this->Method == 'post') $out .= $this->Query;
843
844		fwrite($fp, $out);
845		$this->Result = '';
846		while (!feof($fp))
847			$this->Result .= fgets($fp, 1024);
848		fclose($fp);
849		$this->ResultClean = ltrim(substr($this->Result, strpos($this->Result, "\r\n\r\n")));
850		$this->ParseHeaders();
851
852		if ($this->Verbose) {
853			echo "----->\n$out\n\n";
854			echo "<-----\n{$this->Result}\n\n";
855		}
856		if ($this->AutoCookies) {
857			#if (is_array($this->Cookies)) $this->Cookies += $this->GetCookies();
858			if (!$this->Cookies) $this->Cookies = $this->GetCookies();
859			elseif (is_array($this->Cookies)) $this->Cookies = array_merge($this->Cookies, $this->GetCookies());
860			elseif (is_string($this->Cookies)) $this->Cookies .= $this->GetCookies(true);
861		}
862		if ($this->AutoRedirect && isset($this->Headers['location']) && 
863			$this->maxRedirects_i < $this->maxRedirects) {
864			$this->maxRedirects_i++;
865			if (substr($this->Headers['location'],0,7) == 'http://') {
866				return $this->SendRequest("{$this->Headers['location']}");
867			} elseif ($this->Headers['location'][0] == '/') {
868				return $this->SendRequest("http://{$this->Host}{$this->Headers['location']}");
869			} else {
870				return $this->SendRequest("http://{$this->Host}".
871					substr($this->Path,0,strrpos($this->Path,'/')+1)."{$this->Headers['location']}");
872			}
873		}
874		$this->Query = NULL;
875		$this->Referer = $url;
876		$this->ContentType = NULL;
877		$this->RawHeaders = Array();
878		$this->HTTPHeaders = Array();
879		$this->RequestHeaders = Array();
880
881		$this->Redirect_i++;
882		return $this->Result;
883	}
884
885	function Get($url, $vars = false) {
886		if ($vars)
887			$this->Query = $vars;
888		$this->Method = 'get';
889		return $this->SendRequest($url);
890	}
891
892	function Post($url, $vars = false, $force_fields_str = false) {
893		if ($vars)
894			$this->Query = $vars;
895		$this->Method = 'post';
896		return $this->SendRequest($url);
897	}
898
899
900}
901
902
903/*
904if (!function_exists('class_alias')) {
905function class_alias($from, $to) {
906	eval("class {$to} extends {$from} {}");
907	#eval("abstract class {$to} extends {$from} {}");
908}}
909
910if (function_exists('curl_init')) {
911	class_alias('HTTPcURL', 'HTTPQuery');
912} else {
913	class_alias('HTTPSockets', 'HTTPQuery');
914}
915*/
916
917eval('class HTTPQuery extends '.
918	(function_exists('curl_init') ? 'HTTPcURL' : 'HTTPSockets').' {}');
919
920
921
922?>