The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. December 05, 2008, 10:39:08 AM

Login with username, password and session length


Pages: 1 2 3 [4]
  Print  
Author Topic: Perk's NEW WebRequest Class  (Read 3422 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5230


:sniffle: Humor was so much easier before.


View Profile
« Reply #45 on: April 08, 2008, 05:46:01 PM »

WebRequest 2.1

This version uses a substantially different server-pull set of functions. It has been beta tested but not fully tested, so if you have troubles with it please let me know. This code is strong enough for you to put into production systems (I have it in mine), but don't do it without a backup... it's not really well vetted yet.

The event pops, onSuccess and onFailure have been completely implemented.

Chunked downloads now work as they should.

Code:
<?php

class webRequest2
{
private $socket;

protected $finalURL;
protected $rawContent;
protected $rawHeader;
protected $rawResponse;

protected $caughtEarlyTerm;
protected $chunkedLength;
protected $chunkedTransfer;
protected $cookies;
protected $cookieStr;
protected $errorFlag;
protected $getList;
protected $headers;
protected $postList;
protected $postStr;

public $accept;
public $charSet;
public $domain;
public $debugLogFile;
public $debugLogClearOnDispatch;
public $debugMode;
public $earlyTermStr;
public $language;
public $manualPostContent;
public $method;
public $port;
public $postMode;
public $proxy;
public $redirect;
public $referer;
public $resultCode;
public $timeout;
public $url;
public $userAgent;
public $useSSL;

// Event Handlers
public $onFailure;
public $onProxyRetry;
public $onSuccess;

// Protected and special functions
function webRequest2()
{
$this->reset();
preg_match('/^([0-9])/'phpversion(), $parts);
$this->ancient = ($parts[1] < '5');
$this->userAgent 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/417.9 (KHTML, like Gecko) Safari/417.8';
$this->accept 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
$this->charSet 'ISO-8859-1,utf-8:q=0.7,*;q=0.7';
$this->language 'en-us,en;q=0.5';
$this->referer '';

if (!defined('WRD_OFF'))
{
define('WRD_OFF'0);
define('WRD_ECHO'1);
define('WRD_LOG'2);

define('WRM_GET'0);
define('WRM_POST'1);

define('WRP_NORMAL'0);
define('WRP_MULTIPART'1);
}

$this->debugMode WRD_OFF;
$this->postMode WRP_NORMAL;
$this->debugLogFile '';
$this->debugLogClearOnDispatch true;
$this->timeout 30;
$this->useSSL false;
$this->proxy '';
}

protected function buildCookieStr()
{
$cookieStr '';
$start true;
foreach($this->cookies as $name=>$value)
{
if (!$start) { $cookieStr .= '; '; }
$cookieStr .= "$name=$value";
$start false;
}
$this->debug("Built COOKIE String: $cookieStr");
return $cookieStr;
}

protected function buildGetStr()
{
$getStr '';
$getCount count($this->getList);
if ($getCount)
{
$sepStr '?';
foreach($this->getList as $name=>$value)
{
$value urlencode($value);
$getStr .= "$sepStr$name=$value";
$sepStr '&';
}
}
$this->debug("Built GET String: $getStr");
return $getStr;
}

protected function buildPostStr()
{
if ($this->manualPostContent)
return $this->manualPostContent;

$postStr '';
$postCount count($this->postList);
if ($postCount)
{
$sepStr '';
foreach($this->postList as $name=>$arr)
{
if ($arr['type'] == 'XML')
{
$value $arr['content'];
} else {
$value urlencode($arr['content']);
}
$postStr .= "$sepStr$name=$value";
$sepStr '&';
}
} else {
$postStr 'No Content';
}
$this->debug("Built POST String: $cookieStr");
return $postStr;
}

protected function buildHeader()
{

$header[0] = ''// place holder for first line of header
$header[] = "Host: {$this->domain}";
$header[] = "User-Agent: {$this->userAgent}";
$header[] = "Accept: {$this->accept}";
$header[] = "Accept-Language: {$this->language}";
$header[] = "Accept-Encoding: ";
$header[] = "Accept-Charset: {$this->charSet}";
if ($this->referer) { $header[] = "Referer: {$this->referer}"; }
if ($this->hasCookies()) { $header[] = "Cookie: {$this->buildCookieStr()}"; }
$header[] = "Connection: close";

$hostStr = ($this->proxy) ? "http://{$this->domain}" '';
switch($this->method)
{
case 'get':
case 'GET':
case WRM_GET:
$header[0] = "GET $hostStr{$this->finalURL} HTTP/1.1";
$header[] = '';
$header[] = "Content-Type: text/html";
$header[] = "Content-Length: 0";
$header[] = '';
break;

case 'post':
case 'POST':
case WRM_POST:
if (count($this->postList) == 0$this->postMode WRP_NORMAL;

$header[0] = "POST $hostStr{$this->finalURL} HTTP/1.1";
switch ($this->postMode)
{
case WRP_NORMAL:
$postData $this->buildPostStr();
$requestLen strlen($postData);
$header[] = "Content-Type: application/x-www-form-urlencoded";
$header[] = "Content-Length: $requestLen";
$header[] = '';
$header[] = $postData;
break;

case WRP_MULTIPART:
$boundary time() . time();
$postData $this->buildMultipartPostStr($boundary);
$requestLen strlen($postData);
$header[] = "Content-Type: multipart/form-data; boundary=$boundary";
$header[] = "Content-Length: $requestLen";
$header[] = '';
$header[] = "$postData";
break;

default:
$this->debug("buildHeader: Terminal failure - unknown postMode '{$this->postMode}'");
throw new Exception("buildHeader: Terminal failure - unknown postMode '{$this->postMode}'");
break;
}
break;

default:
$this->debug("buildHeader: Terminal failure - unknown method '{$this->method}'");
throw new Exception("buildHeader: Terminal failure - unknown method '{$this->method}'");
break;
}

$out implode("\r\n"$header);
$this->debug("Outbound Header:\n$out");
return $out;
}

protected function buildMultipartPostStr($boundary)
{
$out = array();
foreach($this->postList as $name=>$arr)
{
$value $arr['content'];
$type $arr['type'];
$out[] = "--$boundary";
$out[] = "Content-Disposition: form-data; name=\"$name\"";
$out[] = "Content-type: $type";
$out[] = '';
$out[] = "$value";
}

$out[] = "--$boundary--";

return implode("\r\n"$out);
}

protected function buildURL()
{
$this->finalURL "{$this->url}{$this->buildGetStr()}";
$this->debug("FinalURL: {$this->finalURL}");
}

protected function clearDebugLog()
{
if ($this->debugMode == WRD_LOG)
{
if (!$this->debugLogFile)
throw new Exception('webRequest2: Debug mode set to LOG, but debugLogFile property not set');
if (file_put_contents($this->debugLogFile'') === false)
throw new Exception('webRequest2: Debug mode set to LOG, but debugLogFile cannot be written to');
}
}

protected function debug($msg)
{
switch($this->debugMode)
{
case WRD_OFF
return;

case WRD_ECHO
echo "$msg\n";
break;

case WRD_LOG:
if (!$this->debugLogFile)
throw new Exception('webRequest2: Debug mode set to LOG, but debugLogFile property not set');
if (file_put_contents($this->debugLogFile"$msg\n\n"FILE_APPEND) == false)
throw new Exception('webRequest2: Debug mode set to LOG, but debugLogFile cannot be written to');
}
}

protected function exec_getContent($count)
{
$thisChunkLen 0;
$this->debug('exec_getContent: Starts');
while ((!feof($this->socket)) and ($count 0))
{
$thisBuff fread($this->socket$count);
$thisBuffLen += strlen($thisBuff);

if (!strlen($thisBuff))
{
$this->debug("exec_getContent: Timeout?");
$this->errorFlag true;
break;
}

$this->debug('exec_getContent: Packet Received ' strlen($thisBuff));
$count -= strlen($thisBuff);
$this->rawResponse .= $thisBuff;
$this->rawContent .= $thisBuff;

// New, 2008-02-13: If we see the existence of an earlyTermStr and it's found in what
// we've received so far, close and and go home...
if ($this->earlyTermStr)
{
$this->debug("exec_getContent: Evaluating content against early term string");
if (strpos($buff$this->rawContent))
{
$this->debug("exec_getContent: Sees an early termination string '{$this->earlyTermStr}'");
$this->caughtEarlyTerm true;
return $buff;
}
}
}

$this->debug("exec_getChunk Complete: $thisChunkLen bytes");
}

protected function exec_getHeader()
{
$lines = array();
$this->debug('exec_getHeader: Starts');
$thisLine trim(fgets($this->socket));
while ((!feof($this->socket)) and ($thisLine))
{
$this->debug("exec_getHeader: Received $thisLine");
$lines[] = $thisLine;
if (substr($thisLine04) == 'HTTP')
{
preg_match('~HTTP/([^ ]+) ([0-9]{1,4}) (.*)~'$thisLine$matches);
$this->resultVersion $matches[1];
$this->resultCode $matches[2];
$this->resultMessage $matches[3];
} else {
preg_match('/([^ ]+): (.*)/'$thisLine$matches);