rendered paste body<?php
/**************************
** COPYRIGHT 2006-2007 webuildspam.com
** This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Greece License
** http://creativecommons.org/licenses/by-nc-sa/3.0/gr/
**************************/
class CurlRequest {
public $url; // URL to connect to
public $options; // assoc array of curl options
public $parseHeaders = true; // set to true to parse headers
public $parseCookies = true; // set to true to parse cookies, needs an assoc array in $headers
public $cookies; // cookies assoc arrays
public $headers; // headers assoc arrays
public $body; // body string
public $head; // headers string
public $status; // HTTP status code
public $lastURL; // last effective url
public $totalTime; // total time for last transfer
public $error; // curl error
public $id; // index of the request in the curl object's $requests array
public $curl; // reference to the curl object
// set to true to keep curl handle alive
public $keep = false;
public function __construct($url, $opts=null) {
$this->url = $url;
if($opts)
$this->options = $opts;
}
/*
// If no curl error happens with the handle. If softfail is set and status>=400, success is not executed.
public function success() {
}
// If a curl error happens with the handle
public function failure() {
}
// If status>=400
public function softfail() {
}
// Before handle is initialised and options set
public function before() {
}
// After success/softfail/failure are executed
public function after() {
}
*/
public function cookie($str) {
$this->options[CURLOPT_COOKIE] = $str;
}
public function proxy($ip, $port, $user=null, $pwd=null) {
$this->options[CURLOPT_PROXYPORT] = $port;
$this->options[CURLOPT_PROXY] = $ip;
if($user)
$this->options[CURLOPT_PROXYUSERPWD] = $user.':'.$pwd;
}
public function ua($str) {
$this->options[CURLOPT_USERAGENT] = $str;
}
public function ip($str) {
$this->options[CURLOPT_INTERFACE] = $str;
}
}
class Curl {
/* VERY IMPORTANT
** MULTI MODE: true,false
** If you are having problems with curl_multi or you just don't need concurrent requests, change to false and it will work with
** non-multi curl. You will still be able to use perform() to execute multiple requests (however they won't be executed concurrently).
**
** Curl still blocks in the following operations even if multi is used:
** - Name resolves on non-windows unless c-ares is used
** - GnuTLS SSL connections
** - Active FTP connections
** - HTTP proxy CONNECT operations
** - TFTP transfers
** - file:// transfers
*/
public $multi = true;
// Max simultaneous requests, if there are more in the request pool it runs chunk()
public $maxParallelRequests = 50;
// Delay between requests in seconds, only works with $multi set to false.
public $delayBetweenSingle = 0;
// Delay between chunks in seconds, only works with $multi set to true.
public $delayBetweenChunks = 0;
// Request pool
public $requests = array();
// DEFAULT CURL OPTIONS
// Will override $curlOptions in make()
// DO NOT CHANGE 'CURLOPT_RETURNTRANSFER' and 'CURLOPT_HEADER' UNLESS YOU KNOW WHAT YOU ARE DOING
public $defaultOptions = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_AUTOREFERER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIEJAR => 'cookies.txt',
CURLOPT_COOKIEFILE => 'cookies.txt',
CURLOPT_HTTPHEADER => array("Expect:"),
CURLOPT_MAXREDIRS => 20);
// Curl Multi errors
public $multiErrors = array();
/*
** Internal variables
*/
// Pool of handles for the multihandle
protected $chPool;
// Multi curl handle
protected $mh;
protected $activeConnection =null;
protected $mrc;
// Request chunks
protected $chunks = false;
// Request count
protected $rCount = 0;
// Active requests
protected $active = array();
/*
** Constructor
*/
public function __construct() {
set_time_limit(0);
}
/*
** Single HTTP methods
*/
public function get($url, $curlOpts='') {
$r = new CurlRequest($url, $curlOpts);
$r->options[CURLOPT_HTTPGET] = true;
$id = $this->add($r);
$this->perform();
return $this->requests[$id];
}
public function post($url, $vars, $curlOpts='') {
$r = new CurlRequest($url, $curlOpts);
$r->options[CURLOPT_POST] = true;
$r->options[CURLOPT_POSTFIELDS] = $vars;
$id = $this->add($r);
$this->perform();
return $this->requests[$id];
}
/*
** Multiple HTTP methods
*/
public function add(&$request, $id=null) {
if(!isset($id)) {
$id = $this->rCount;
}
$this->active[$id] = '';
$this->requests[$id] = $request;
$this->requests[$id]->id = $id;
$this->requests[$id]->curl = &$this;
$this->rCount++;
return $id;
}
public function perform() {
if(($k = count($this->active)) > 0 ) {
//If there's only one request drop down to single mode
if($k == 1)
$this->multi = false;
// Initialise the multi-handle
if($this->multi) {
if(!($this->mh = curl_multi_init())) {
$this->multiErrors[] = "Failed to initialize multi handle";
return;
}
}
// Chunk and perform() once for each chunk
if($this->multi && $this->maxParallelRequests < $k)
{
$this->chunk();
foreach($this->chunks as $chunk) {
$this->active = $chunk;
// delay if needed
if($this->delayBetweenChunks > 0)
sleep($this->delayBetweenChunks);
while(count($this->active)>0) {
// initialise the single handles, stored in $this->chPool
$this->makeHandles();
// perform requests in the pool
$this->performMulti();
}
}
}
// Only one chunk
else
{
while(count($this->active)>0) {
$this->makeHandles();
$this->performMulti();
}
}
// Close the multi handle
if($this->multi)
curl_multi_close($this->mh);
}
}
/*
** Static methods
*/
public static function vars($vars) {
$str = '';
foreach( $vars as $k => $v)
$str .= urlencode($k).'='.urlencode($v).'&';
return substr($str, 0, -1);
}
public static function parseHeaders($str) {
//$str = str_replace("\r\n","\n",$str);
$h = array_filter(explode("\r\n",$str));
$a = array();
$c = -1;
foreach($h as $i) {
if(($p = strpos($i, ': ')) !== false) {
$type = trim(strtolower(substr($i,0,$p)));
$a[$c][$type] = trim(substr($i,$p+1));
} else {
$c++;
$parts = explode(' ', $i,3);
$a[$c]['http'] = array(
'version' => $parts[0],
'status' => $parts[1],
'string' => $parts[2]
);
}
}
return $a;
}
public static function parseCookies($arr,$other=false) {
$cookies = array();
foreach($arr as $i => $headers) {
if(!($str = $headers['set-cookie']))
continue;
if( strpos($str,';') === false) {
$c = explode('=',$str,2);
$c[0] = trim($c[0]);
$c[1] = trim($c[1]);
$cookies[$i][$c[0]] = $c[1];
} else {
$cookieparts = explode( ';', $str );
foreach($cookieparts as $data ) {
$c = explode( '=', $data, 2);
$c[0] = trim($c[0]);
$c[1] = trim($c[1]);
if(in_array( $c[0], array('domain', 'expires', 'path', 'secure', 'comment'))) {
if($other) {
switch($c[0]) {
case 'expires':
$c[1] = strtotime($c[1]);
break;
case 'secure':
$c[1] = true;
break;
}
$cookies[$i][$c[0]] = $c[1];
}
} else {
$cookies[$i][$c[0]] = $c[1];
}
}
}
}
return $cookies;
}
public static function discoverInterfaces() {
$a = shell_exec( 'ifconfig -a' );
//$a .= 'lala addr:127.123.123.123 addr:122.234.354.34 lala addr:10.10.10.10 addr:100.12.12.12 ';
preg_match_all( '@addr:(?=([0-9.]+))(?!(?:10\.|127\.|172\.[1-3][6-9_0]\.|192\.|169\.254\.[0-9.]+))@', $a, $m);
return $m[1];
}
/******
** Internal methods
******/
protected function chunk() {
$this->chunks = array_chunk($this->active, $this->maxParallelRequests, true);
}
protected function setOptions(&$ch, $curlOptions) {
if(!empty($curlOptions) && is_array($curlOptions))
curl_setopt_array($ch, $curlOptions);
}
protected function initHandle($k) {
if( ($this->chPool[$k] = curl_init()) !== false) {
$this->requests[$k]->options[CURLOPT_URL] = $this->requests[$k]->url;
$this->requests[$k]->options = $this->requests[$k]->options + $this->defaultOptions;
$this->setOptions($this->chPool[$k], $this->requests[$k]->options);
if($this->multi)
$this->addHandle($k);
} else {
unset($this->chPool[$k]);
unset($this->active[$k]);
$this->requests[$k]->error = array( 'n' => 99, 'msg' => 'Failed to initialize handle' );
}
}
protected function addHandle($k) {
if(($n = curl_multi_add_handle($this->mh,$this->chPool[$k])) !== 0) {
$this->multiErrors[] = 'Failed to add id:'.$k.' to multihandle. Err n:'.$n;
unset($this->chPool[$k]);
unset($this->active[$k]);
$this->requests[$k]->error = array( 'n' => 99, 'msg' => 'Failed to add to multihandle' );
}
}
protected function removeHandle($k) {
if(($n = curl_multi_add_handle($this->mh,$this->chPool[$k])) === false) {
$this->multiErrors[] = 'Failed to remove id:'.$k.' from multihandle';
}
}
protected function makeHandles() {
foreach($this->active as $k => $kk) {
if(method_exists($this->requests[$k],'before'))
$this->requests[$k]->before();
if(!$this->requests[$k]->keep) {
$this->initHandle($k);
} else {
$this->requests[$k]->options[CURLOPT_URL] = $this->requests[$k]->url;
$this->setOptions($this->chPool[$k], $this->requests[$k]->options);
if($this->multi)
$this->addHandle($k);
}
}
}
protected function performMulti() {
if($this->multi) {
// Start performing the requests
do { $this->mrc = curl_multi_exec($this->mh, $this->activeConnection); }
while($this->mrc == CURLM_CALL_MULTI_PERFORM);
while ($this->activeConnection && $this->mrc === CURLM_OK) {
// Wait for network
if (curl_multi_select($this->mh) != CURLM_CALL_MULTI_PERFORM) {
// pull in any new data, or at least handle timeouts
do { $this->mrc = curl_multi_exec($this->mh, $this->activeConnection); }
while( $this->mrc == CURLM_CALL_MULTI_PERFORM);
}
}
if ($this->mrc !== CURLM_OK) {
$this->multiErrors[] = "Curl multi read error: $this->mrc\n";
//return;
}
}
foreach($this->active as $i => $ii) {
$this->execute($i);
}
}
protected function execute($i) {
if(!$this->multi) {
if($this->delayBetweenSingle > 0)
sleep($this->delayBetweenSingle);
$response = curl_exec($this->chPool[$i]);
}
// No curl error
if ( ($ern = curl_errno($this->chPool[$i])) === 0 ) {
if($this->multi)
$response = curl_multi_getcontent($this->chPool[$i]);
$inf = curl_getinfo($this->chPool[$i]);
if($this->requests[$i]->options[CURLOPT_HEADER] && $this->requests[$i]->options[CURLOPT_RETURNTRANSFER]) {
$this->requests[$i]->head = substr($response,0,$inf['header_size']);
$this->requests[$i]->body = substr($response,$inf['header_size']);
} elseif($this->requests[$i]->options[CURLOPT_RETURNTRANSFER]) {
$this->requests[$i]->body = $response;
}
$this->requests[$i]->status = $inf['http_code'];
$this->requests[$i]->lastURL = $inf['url'];
$this->requests[$i]->totalTime = $inf['total_time'];
if($this->requests[$i]->head && $this->requests[$i]->parseHeaders)
$this->requests[$i]->headers = self::parseHeaders($this->requests[$i]->head);
if($this->requests[$i]->headers && $this->requests[$i]->parseCookies)
$this->requests[$i]->cookies = self::parseCookies($this->requests[$i]->headers);
if($this->requests[$i]->status >= 400 && method_exists($this->requests[$i],'softfail')) {
$this->requests[$i]->softfail();
} elseif(method_exists($this->requests[$i],'success')) {
$this->requests[$i]->success();
}
// Some curl error
} else {
$this->requests[$i]->error = array( 'n' => $ern, 'msg' => curl_error($this->chPool[$i]) );
if(method_exists($this->requests[$i],'failure'))
$this->requests[$i]->failure();
}
if(method_exists($this->requests[$i],'after'))
$this->requests[$i]->after();
if($this->multi)
curl_multi_remove_handle($this->mh, $this->chPool[$i]);
if(!$this->requests[$i]->keep) {
curl_close($this->chPool[$i]);
unset($this->active[$i]);
unset($this->chPool[$i]);
}
}
}
class CurlSingle
{
function setup()
{
$cookieJar = 'cookies.txt';
curl_setopt($this->curl,CURLOPT_COOKIEJAR, $cookieJar);
curl_setopt($this->curl,CURLOPT_COOKIEFILE, $cookieJar);
curl_setopt($this->curl,CURLOPT_AUTOREFERER, true);
curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->curl,CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl,CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11');
}
function get($url)
{
$this->curl = curl_init($url);
$this->setup();
return $this->request();
}
function getAll($reg,$str)
{
preg_match_all($reg,$str,$matches);
return $matches[1];
}
function post($url, $fields, $referer='')
{
$timeout = 0;
$this->curl = curl_init($url);
$this->setup();
curl_setopt($this->curl, CURLOPT_URL, $url);
curl_setopt($this->curl, CURLOPT_POST, 1);
curl_setopt($this->curl, CURLOPT_REFERER, $referer);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $fields);
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Expect:'));
return $this->request();
}
function getInfo($info)
{
$info = ($info == 'lasturl') ? curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL) : curl_getinfo($this->curl, $info);
$info = ($info == 'http_code') ? curl_getinfo($this->curl, CURLINFO_HTTP_CODE) : curl_getinfo($this->curl, $info);
return $info;
}
function request()
{
return curl_exec($this->curl);
}
}
?>