mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-03 08:41:39 +09:00
Merge pull request #68 from kijin/pr/remove-libs
libs 폴더 내의 오래된 라이브러리들 정리
This commit is contained in:
commit
66a6edeffb
458 changed files with 52458 additions and 30848 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,6 +4,7 @@ Thumbs.db
|
|||
config.user.inc.php
|
||||
/files/
|
||||
/build/
|
||||
/libs/
|
||||
|
||||
codeception.yml
|
||||
/tests/_output/
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ module.exports = function(grunt) {
|
|||
"!files/**",
|
||||
"!tests/**",
|
||||
"!tools/**",
|
||||
"!node_modules/**",
|
||||
"!libs/**",
|
||||
"!common/libraries/**",
|
||||
"!vendor/**",
|
||||
"!tests/_output/**"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1198,16 +1198,42 @@ class Context
|
|||
return $obj->str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode UTF-8 domain into IDNA (punycode)
|
||||
*
|
||||
* @param string $domain Domain to convert
|
||||
* @return string Converted string
|
||||
*/
|
||||
public static function encodeIdna($domain)
|
||||
{
|
||||
if(function_exists('idn_to_ascii'))
|
||||
{
|
||||
return idn_to_ascii($domain);
|
||||
}
|
||||
else
|
||||
{
|
||||
$encoder = new TrueBV\Punycode();
|
||||
return $encoder->encode($domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert IDNA (punycode) domain into UTF-8
|
||||
*
|
||||
* @param string $domain Domain to convert
|
||||
* @return string Converted string
|
||||
*/
|
||||
public static function decodeIdna($domain)
|
||||
{
|
||||
if(strpos($domain, 'xn--') !== FALSE)
|
||||
if(function_exists('idn_to_utf8'))
|
||||
{
|
||||
require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
|
||||
$IDN = new idna_convert(array('idn_version' => 2008));
|
||||
$domain = $IDN->decode($domain);
|
||||
return idn_to_utf8($domain);
|
||||
}
|
||||
else
|
||||
{
|
||||
$decoder = new TrueBV\Punycode();
|
||||
return $decoder->decode($domain);
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -315,7 +315,6 @@ class FileHandler
|
|||
return;
|
||||
}
|
||||
|
||||
require_once(_XE_PATH_ . 'libs/ftp.class.php');
|
||||
$oFtp = new ftp();
|
||||
if(!$ftp_info->ftp_host)
|
||||
{
|
||||
|
|
@ -516,8 +515,6 @@ class FileHandler
|
|||
/**
|
||||
* Return remote file's content via HTTP
|
||||
*
|
||||
* If the target is moved (when return code is 300~399), this function follows the location specified response header.
|
||||
*
|
||||
* @param string $url The address of the target file
|
||||
* @param string $body HTTP request body
|
||||
* @param int $timeout Connection timeout
|
||||
|
|
@ -532,89 +529,66 @@ class FileHandler
|
|||
{
|
||||
try
|
||||
{
|
||||
requirePear();
|
||||
if(!class_exists('HTTP_Request')) require_once('HTTP/Request.php');
|
||||
|
||||
$parsed_url = parse_url(__PROXY_SERVER__);
|
||||
if($parsed_url["host"])
|
||||
$request_headers = array();
|
||||
$request_cookies = array();
|
||||
$request_options = array('timeout' => $timeout);
|
||||
|
||||
foreach($headers as $key => $val)
|
||||
{
|
||||
$oRequest = new HTTP_Request(__PROXY_SERVER__);
|
||||
$oRequest->setMethod('POST');
|
||||
$oRequest->addPostData('arg', serialize(array('Destination' => $url, 'method' => $method, 'body' => $body, 'content_type' => $content_type, "headers" => $headers, "post_data" => $post_data)));
|
||||
$request_headers[$key] = $val;
|
||||
}
|
||||
|
||||
if(isset($cookies[$host]) && is_array($cookies[$host]))
|
||||
{
|
||||
foreach($cookies[$host] as $key => $val)
|
||||
{
|
||||
$request_cookies[] = rawurlencode($key) . '=' . rawurlencode($val);
|
||||
}
|
||||
}
|
||||
if(count($request_cookies))
|
||||
{
|
||||
$request_headers['Cookie'] = implode('; ', $request_cookies);
|
||||
}
|
||||
|
||||
foreach($request_config as $key => $val)
|
||||
{
|
||||
$request_options[$key] = $val;
|
||||
}
|
||||
|
||||
if($content_type)
|
||||
{
|
||||
$request_headers['Content-Type'] = $content_type;
|
||||
}
|
||||
|
||||
$proxy = parse_url(__PROXY_SERVER__);
|
||||
if($proxy["host"])
|
||||
{
|
||||
$request_options['proxy'] = array($proxy['host'] . ($proxy['port'] ? (':' . $proxy['port']) : ''));
|
||||
if($proxy['user'] && $proxy['pass'])
|
||||
{
|
||||
$request_options['proxy'][] = $proxy['user'];
|
||||
$request_options['proxy'][] = $proxy['pass'];
|
||||
}
|
||||
}
|
||||
|
||||
$response = Requests::request($url, $request_headers, $body ?: $post_data, $method, $request_options);
|
||||
|
||||
if(count($response->cookies))
|
||||
{
|
||||
foreach($response->cookies as $cookie)
|
||||
{
|
||||
$cookies[$host][$cookie->name] = $cookie->value;
|
||||
}
|
||||
}
|
||||
|
||||
if($response->success)
|
||||
{
|
||||
return $response->body;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oRequest = new HTTP_Request($url);
|
||||
|
||||
if(count($request_config) && method_exists($oRequest, 'setConfig'))
|
||||
{
|
||||
foreach($request_config as $key=>$val)
|
||||
{
|
||||
$oRequest->setConfig($key, $val);
|
||||
}
|
||||
}
|
||||
|
||||
if(count($headers) > 0)
|
||||
{
|
||||
foreach($headers as $key => $val)
|
||||
{
|
||||
$oRequest->addHeader($key, $val);
|
||||
}
|
||||
}
|
||||
if($cookies[$host])
|
||||
{
|
||||
foreach($cookies[$host] as $key => $val)
|
||||
{
|
||||
$oRequest->addCookie($key, $val);
|
||||
}
|
||||
}
|
||||
if(count($post_data) > 0)
|
||||
{
|
||||
foreach($post_data as $key => $val)
|
||||
{
|
||||
$oRequest->addPostData($key, $val);
|
||||
}
|
||||
}
|
||||
if(!$content_type)
|
||||
$oRequest->addHeader('Content-Type', 'text/html');
|
||||
else
|
||||
$oRequest->addHeader('Content-Type', $content_type);
|
||||
$oRequest->setMethod($method);
|
||||
if($body)
|
||||
$oRequest->setBody($body);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(method_exists($oRequest, 'setConfig'))
|
||||
{
|
||||
$oRequest->setConfig('timeout', $timeout);
|
||||
}
|
||||
elseif(property_exists($oRequest, '_timeout'))
|
||||
{
|
||||
$oRequest->_timeout = $timeout;
|
||||
}
|
||||
|
||||
$oResponse = $oRequest->sendRequest();
|
||||
|
||||
$code = $oRequest->getResponseCode();
|
||||
$header = $oRequest->getResponseHeader();
|
||||
$response = $oRequest->getResponseBody();
|
||||
if($c = $oRequest->getResponseCookies())
|
||||
{
|
||||
foreach($c as $k => $v)
|
||||
{
|
||||
$cookies[$host][$v['name']] = $v['value'];
|
||||
}
|
||||
}
|
||||
|
||||
if($code > 300 && $code < 399 && $header['location'])
|
||||
{
|
||||
return self::getRemoteResource($header['location'], $body, $timeout, $method, $content_type, $headers, $cookies, $post_data);
|
||||
}
|
||||
|
||||
if($code != 200)
|
||||
return;
|
||||
|
||||
return $response;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,165 +1,53 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
require_once _XE_PATH_ . "libs/phpmailer/phpmailer.php";
|
||||
|
||||
/**
|
||||
* Mailing class for XpressEngine
|
||||
*
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* Mail class
|
||||
*
|
||||
* This class was originally written for the Advanced Mailer module.
|
||||
* Advanced Mailer is licensed under GPLv2, but the author hereby relicenses
|
||||
* this class under the same license as the remainder of RhymiX.
|
||||
* All other parts of the Advanced Mailer module remain under GPLv2.
|
||||
*
|
||||
* @author Kijin Sung <kijin@kijinsung.com>
|
||||
*/
|
||||
class Mail extends PHPMailer
|
||||
class Mail
|
||||
{
|
||||
|
||||
/**
|
||||
* Sender name
|
||||
* @var string
|
||||
* Properties for compatibility with XE Mail class
|
||||
*/
|
||||
var $sender_name = '';
|
||||
|
||||
public $content = '';
|
||||
public $content_type = 'html';
|
||||
public $attachments = array();
|
||||
public $cidAttachments = array();
|
||||
|
||||
/**
|
||||
* Sender email address
|
||||
* @var string
|
||||
* Properties used by Advanced Mailer
|
||||
*/
|
||||
var $sender_email = '';
|
||||
|
||||
public $error = null;
|
||||
public $caller = null;
|
||||
public $message = null;
|
||||
public static $transport = null;
|
||||
|
||||
/**
|
||||
* Receiptor name
|
||||
* @var string
|
||||
* Constructor
|
||||
*/
|
||||
var $receiptor_name = '';
|
||||
|
||||
/**
|
||||
* Receiptor email address
|
||||
* @var string
|
||||
*/
|
||||
var $receiptor_email = '';
|
||||
|
||||
/**
|
||||
* Title of email
|
||||
* @var string
|
||||
*/
|
||||
var $title = '';
|
||||
|
||||
/**
|
||||
* Content of email
|
||||
* @var string
|
||||
*/
|
||||
var $content = '';
|
||||
|
||||
/**
|
||||
* Content type
|
||||
* @var string
|
||||
*/
|
||||
var $content_type = 'html';
|
||||
|
||||
/**
|
||||
* Message id
|
||||
* @var string
|
||||
*/
|
||||
var $messageId = NULL;
|
||||
|
||||
/**
|
||||
* Reply to
|
||||
* @var string
|
||||
*/
|
||||
var $replyTo = NULL;
|
||||
|
||||
/**
|
||||
* BCC (Blind carbon copy)
|
||||
* @var string
|
||||
*/
|
||||
var $bcc = NULL;
|
||||
|
||||
/**
|
||||
* Attachments
|
||||
* @var array
|
||||
*/
|
||||
var $attachments = array();
|
||||
|
||||
/**
|
||||
* Content attachements
|
||||
* @var array
|
||||
*/
|
||||
var $cidAttachments = array();
|
||||
|
||||
/**
|
||||
* ???
|
||||
* @var ???
|
||||
*/
|
||||
var $mainMailPart = NULL;
|
||||
|
||||
/**
|
||||
* Raw body
|
||||
* @var string
|
||||
*/
|
||||
var $body = '';
|
||||
|
||||
/**
|
||||
* Raw header
|
||||
* @var string
|
||||
*/
|
||||
var $header = '';
|
||||
|
||||
/**
|
||||
* End of line
|
||||
* @var string
|
||||
*/
|
||||
var $eol = '';
|
||||
|
||||
/**
|
||||
* Reference
|
||||
* @var string
|
||||
*/
|
||||
var $references = '';
|
||||
|
||||
/**
|
||||
* Additional parameters
|
||||
* @var string
|
||||
*/
|
||||
var $additional_params = NULL;
|
||||
|
||||
/**
|
||||
* Whether use or not use stmp
|
||||
* @var bool
|
||||
*/
|
||||
var $use_smtp = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
$this->message = \Swift_Message::newInstance();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set parameters for using Gmail
|
||||
*
|
||||
* @param string $account_name Password
|
||||
* @param string $account_passwd Secure method ('ssl','tls')
|
||||
* @param string $account_name Email address
|
||||
* @param string $account_passwd Email password
|
||||
* @return void
|
||||
*/
|
||||
function useGmailAccount($account_name, $account_passwd)
|
||||
public static function useGmailAccount($account_name, $account_passwd)
|
||||
{
|
||||
$this->SMTPAuth = TRUE;
|
||||
$this->SMTPSecure = "tls";
|
||||
$this->Host = 'smtp.gmail.com';
|
||||
$this->Port = '587';
|
||||
if($this->isVaildMailAddress($account_name))
|
||||
{
|
||||
$this->Username = $account_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Username = $account_name . '@gmail.com';
|
||||
}
|
||||
$this->Password = $account_passwd;
|
||||
$this->IsSMTP();
|
||||
self::useSMTP(null, 'smtp.gmail.com', $account_name, $account_passwd, 'ssl', 465);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set parameters for using SMTP protocol
|
||||
*
|
||||
|
|
@ -172,67 +60,26 @@ class Mail extends PHPMailer
|
|||
*
|
||||
* @return bool TRUE if SMTP is set correct, otherwise return FALSE
|
||||
*/
|
||||
function useSMTP($auth = NULL, $host = NULL, $user = NULL, $pass = NULL, $secure = NULL, $port = 25)
|
||||
public static function useSMTP($auth = null, $host = null, $user = null, $pass = null, $secure = null, $port = 25)
|
||||
{
|
||||
$this->SMTPAuth = $auth;
|
||||
$this->Host = $host;
|
||||
$this->Username = $user;
|
||||
$this->Password = $pass;
|
||||
$this->Port = $port;
|
||||
|
||||
if($secure == 'ssl' || $secure == 'tls')
|
||||
self::$transport = \Swift_SmtpTransport::newInstance($host, $port, $secure);
|
||||
self::$transport->setUsername($user);
|
||||
self::$transport->setPassword($pass);
|
||||
$local_domain = self::$transport->getLocalDomain();
|
||||
if (preg_match('/^\*\.(.+)$/', $local_domain, $matches))
|
||||
{
|
||||
$this->SMTPSecure = $secure;
|
||||
}
|
||||
|
||||
if(($this->SMTPAuth !== NULL && $this->Host !== NULL && $this->Username !== NULL && $this->Password !== NULL) || ($this->SMTPAuth === NULL && $this->Host !== NULL))
|
||||
{
|
||||
$this->IsSMTP();
|
||||
$this->AltBody = "To view the message, please use an HTML compatible email viewer!";
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->IsMail();
|
||||
return FALSE;
|
||||
self::$transport->setLocalDomain($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set additional parameters
|
||||
*
|
||||
* @param string $additional_params Additional parameters
|
||||
* @return void
|
||||
*/
|
||||
function setAdditionalParams($additional_params)
|
||||
public function setAdditionalParams($additional_params)
|
||||
{
|
||||
$this->additional_params = $additional_params;
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file attachment
|
||||
*
|
||||
* @param string $filename File name to attach
|
||||
* @param string $orgfilename Real path of file to attach
|
||||
* @return void
|
||||
*/
|
||||
function addAttachment($filename, $orgfilename)
|
||||
{
|
||||
$this->attachments[$orgfilename] = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content attachment
|
||||
*
|
||||
* @param string $filename Real path of file to attach
|
||||
* @param string $cid Content-CID
|
||||
* @return void
|
||||
*/
|
||||
function addCidAttachment($filename, $cid)
|
||||
{
|
||||
$this->cidAttachments[$cid] = $filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Sender (From:)
|
||||
*
|
||||
|
|
@ -240,172 +87,246 @@ class Mail extends PHPMailer
|
|||
* @param string $email Sender email address
|
||||
* @return void
|
||||
*/
|
||||
function setSender($name, $email)
|
||||
public function setSender($name, $email)
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
try
|
||||
{
|
||||
$this->sender_name = $name;
|
||||
$this->sender_email = $email;
|
||||
$this->message->setFrom(array($email => $name));
|
||||
}
|
||||
else
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$this->SetFrom($email, $name);
|
||||
$this->errors[] = array($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Sender (From:)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getSender()
|
||||
public function getSender()
|
||||
{
|
||||
if(!stristr(PHP_OS, 'win') && $this->sender_name)
|
||||
$from = $this->message->getFrom();
|
||||
foreach($from as $email => $name)
|
||||
{
|
||||
return sprintf("%s <%s>", '=?utf-8?b?' . base64_encode($this->sender_name) . '?=', $this->sender_email);
|
||||
if($name === '')
|
||||
{
|
||||
return $email;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $name . ' <' . $email . '>';
|
||||
}
|
||||
}
|
||||
return $this->sender_email;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Receiptor (TO:)
|
||||
* Set Recipient (To:)
|
||||
*
|
||||
* @param string $name Receiptor name
|
||||
* @param string $email Receiptor email address
|
||||
* @param string $name Recipient name
|
||||
* @param string $email Recipient email address
|
||||
* @return void
|
||||
*/
|
||||
function setReceiptor($name, $email)
|
||||
public function setReceiptor($name, $email)
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
try
|
||||
{
|
||||
$this->receiptor_name = $name;
|
||||
$this->receiptor_email = $email;
|
||||
$this->message->setTo(array($email => $name));
|
||||
}
|
||||
else
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$this->AddAddress($email, $name);
|
||||
$this->errors[] = array($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Receiptor (TO:)
|
||||
* Get Recipient (To:)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getReceiptor()
|
||||
public function getReceiptor()
|
||||
{
|
||||
if(!stristr(PHP_OS, 'win') && $this->receiptor_name && $this->receiptor_name != $this->receiptor_email)
|
||||
$to = $this->message->getTo();
|
||||
foreach($to as $email => $name)
|
||||
{
|
||||
return sprintf("%s <%s>", '=?utf-8?b?' . base64_encode($this->receiptor_name) . '?=', $this->receiptor_email);
|
||||
if($name === '')
|
||||
{
|
||||
return $email;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $name . ' <' . $email . '>';
|
||||
}
|
||||
}
|
||||
return $this->receiptor_email;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Email's Title
|
||||
* Set Subject
|
||||
*
|
||||
* @param string $title Title to set
|
||||
* @param string $subject The subject
|
||||
* @return void
|
||||
*/
|
||||
function setTitle($title)
|
||||
public function setTitle($subject)
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Subject = $title;
|
||||
}
|
||||
$this->message->setSubject(strval($subject));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Email's Title
|
||||
* Get Subject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getTitle()
|
||||
public function getTitle()
|
||||
{
|
||||
return '=?utf-8?b?' . base64_encode($this->title) . '?=';
|
||||
return $this->message->getSubject();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set BCC
|
||||
*
|
||||
* @param string $bcc
|
||||
* @return void
|
||||
*/
|
||||
function setBCC($bcc)
|
||||
public function setBCC($bcc)
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
try
|
||||
{
|
||||
$this->bcc = $bcc;
|
||||
$this->message->setBcc(array($bcc));
|
||||
}
|
||||
else
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$this->AddBCC($bcc);
|
||||
$this->errors[] = array($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set ReplyTo
|
||||
*
|
||||
* @param string $replyTo
|
||||
* @return void
|
||||
*/
|
||||
public function setReplyTo($replyTo)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->message->setReplyTo(array($replyTo));
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$this->errors[] = array($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Return Path
|
||||
*
|
||||
* @param string $returnPath
|
||||
* @return void
|
||||
*/
|
||||
public function setReturnPath($returnPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->message->setReturnPath($returnPath);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$this->errors[] = array($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Message ID
|
||||
*
|
||||
* @param string $messageId
|
||||
* @return void
|
||||
*/
|
||||
function setMessageID($messageId)
|
||||
public function setMessageID($messageId)
|
||||
{
|
||||
$this->messageId = $messageId;
|
||||
$this->message->getHeaders()->get('Message-ID')->setId($messageId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set references
|
||||
*
|
||||
* @param string $references
|
||||
* @return void
|
||||
*/
|
||||
function setReferences($references)
|
||||
public function setReferences($references)
|
||||
{
|
||||
$this->references = $references;
|
||||
$headers = $this->message->getHeaders();
|
||||
$headers->addTextHeader('References', $references);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ReplyTo param
|
||||
*
|
||||
* @param string $replyTo
|
||||
* @return void
|
||||
*/
|
||||
function setReplyTo($replyTo)
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
{
|
||||
$this->replyTo = $replyTo;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->AddReplyTo($replyTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set message content
|
||||
*
|
||||
* @param string $content Content
|
||||
* @return void
|
||||
*/
|
||||
function setContent($content)
|
||||
public function setContent($content)
|
||||
{
|
||||
$content = preg_replace_callback('/<img([^>]+)>/i', array($this, 'replaceResourceRealPath'), $content);
|
||||
if($this->Mailer == "mail")
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->MsgHTML($content);
|
||||
}
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the type of message content (html or plain text)
|
||||
*
|
||||
* @param string $mode The type
|
||||
* @return void
|
||||
*/
|
||||
public function setContentType($type = 'html')
|
||||
{
|
||||
$this->content_type = $type === 'html' ? 'html' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Plain content of body message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPlainContent()
|
||||
{
|
||||
return chunk_split(base64_encode(str_replace(array("<", ">", "&"), array("<", ">", "&"), $this->content)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML content of body message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHTMLContent()
|
||||
{
|
||||
return chunk_split(base64_encode($this->content_type != 'html' ? nl2br($this->content) : $this->content));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file attachment
|
||||
*
|
||||
* @param string $filename File name to attach
|
||||
* @param string $original_filename Real path of file to attach
|
||||
* @return void
|
||||
*/
|
||||
public function addAttachment($filename, $original_filename)
|
||||
{
|
||||
$this->attachments[$original_filename] = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content attachment
|
||||
*
|
||||
* @param string $original_filename Real path of file to attach
|
||||
* @param string $cid Content-CID
|
||||
* @return void
|
||||
*/
|
||||
public function addCidAttachment($original_filename, $cid)
|
||||
{
|
||||
$this->cidAttachments[$cid] = $original_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace resourse path of the files
|
||||
*
|
||||
|
|
@ -413,188 +334,93 @@ class Mail extends PHPMailer
|
|||
* @param array $matches Match info.
|
||||
* @return string
|
||||
*/
|
||||
function replaceResourceRealPath($matches)
|
||||
public function replaceResourceRealPath($matches)
|
||||
{
|
||||
return preg_replace('/src=(["\']?)files/i', 'src=$1' . Context::getRequestUri() . 'files', $matches[0]);
|
||||
return preg_replace('/src=(["\']?)files/i', 'src=$1' . \Context::getRequestUri() . 'files', $matches[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Plain content of body message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPlainContent()
|
||||
{
|
||||
return chunk_split(base64_encode(str_replace(array("<", ">", "&"), array("<", ">", "&"), $this->content)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML content of body message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getHTMLContent()
|
||||
{
|
||||
return chunk_split(base64_encode($this->content_type != 'html' ? nl2br($this->content) : $this->content));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of body's content
|
||||
*
|
||||
* @param string $mode
|
||||
* @return void
|
||||
*/
|
||||
function setContentType($mode = 'html')
|
||||
{
|
||||
$this->content_type = $mode == 'html' ? 'html' : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the images from attachments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function procAttachments()
|
||||
public function procAttachments()
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
{
|
||||
if(count($this->attachments) > 0)
|
||||
{
|
||||
$this->body = $this->header . $this->body;
|
||||
$boundary = '----==' . uniqid(rand(), TRUE);
|
||||
$this->header = "Content-Type: multipart/mixed;" . $this->eol . "\tboundary=\"" . $boundary . "\"" . $this->eol . $this->eol;
|
||||
$this->body = "--" . $boundary . $this->eol . $this->body . $this->eol . $this->eol;
|
||||
$res = array();
|
||||
$res[] = $this->body;
|
||||
foreach($this->attachments as $filename => $attachment)
|
||||
{
|
||||
$type = $this->returnMIMEType($filename);
|
||||
$file_handler = new FileHandler();
|
||||
$file_str = $file_handler->readFile($attachment);
|
||||
$chunks = chunk_split(base64_encode($file_str));
|
||||
$tempBody = sprintf(
|
||||
"--" . $boundary . $this->eol .
|
||||
"Content-Type: %s;" . $this->eol .
|
||||
"\tname=\"%s\"" . $this->eol .
|
||||
"Content-Transfer-Encoding: base64" . $this->eol .
|
||||
"Content-Description: %s" . $this->eol .
|
||||
"Content-Disposition: attachment;" . $this->eol .
|
||||
"\tfilename=\"%s\"" . $this->eol . $this->eol .
|
||||
"%s" . $this->eol . $this->eol, $type, $filename, $filename, $filename, $chunks);
|
||||
$res[] = $tempBody;
|
||||
}
|
||||
$this->body = implode("", $res);
|
||||
$this->body .= "--" . $boundary . "--";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count($this->attachments) > 0)
|
||||
{
|
||||
foreach($this->attachments as $filename => $attachment)
|
||||
{
|
||||
parent::AddAttachment($attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the images from body content. This functions is used if Mailer is set as mail not as SMTP
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function procCidAttachments()
|
||||
public function procCidAttachments()
|
||||
{
|
||||
if(count($this->cidAttachments) > 0)
|
||||
{
|
||||
$this->body = $this->header . $this->body;
|
||||
$boundary = '----==' . uniqid(rand(), TRUE);
|
||||
$this->header = "Content-Type: multipart/relative;" . $this->eol . "\ttype=\"multipart/alternative\";" . $this->eol . "\tboundary=\"" . $boundary . "\"" . $this->eol . $this->eol;
|
||||
$this->body = "--" . $boundary . $this->eol . $this->body . $this->eol . $this->eol;
|
||||
$res = array();
|
||||
$res[] = $this->body;
|
||||
foreach($this->cidAttachments as $cid => $attachment)
|
||||
{
|
||||
$filename = basename($attachment);
|
||||
$type = $this->returnMIMEType(FileHandler::getRealPath($attachment));
|
||||
$file_str = FileHandler::readFile($attachment);
|
||||
$chunks = chunk_split(base64_encode($file_str));
|
||||
$tempBody = sprintf(
|
||||
"--" . $boundary . $this->eol .
|
||||
"Content-Type: %s;" . $this->eol .
|
||||
"\tname=\"%s\"" . $this->eol .
|
||||
"Content-Transfer-Encoding: base64" . $this->eol .
|
||||
"Content-ID: <%s>" . $this->eol .
|
||||
"Content-Description: %s" . $this->eol .
|
||||
"Content-Location: %s" . $this->eol . $this->eol .
|
||||
"%s" . $this->eol . $this->eol, $type, $filename, $cid, $filename, $filename, $chunks);
|
||||
$res[] = $tempBody;
|
||||
}
|
||||
$this->body = implode("", $res);
|
||||
$this->body .= "--" . $boundary . "--";
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the message before sending
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function procAssembleMessage()
|
||||
{
|
||||
// Add all attachments
|
||||
foreach($this->attachments as $original_filename => $filename)
|
||||
{
|
||||
$attachment = \Swift_Attachment::fromPath($original_filename);
|
||||
$attachment->setFilename($filename);
|
||||
$this->message->attach($attachment);
|
||||
}
|
||||
|
||||
// Add all CID attachments
|
||||
foreach($this->cidAttachments as $cid => $original_filename)
|
||||
{
|
||||
$embedded = \Swift_EmbeddedFile::fromPath($original_filename);
|
||||
$newcid = $this->message->embed($embedded);
|
||||
$this->content = str_replace(array("cid:$cid", $cid), $newcid, $this->content);
|
||||
}
|
||||
|
||||
// Set content type
|
||||
$content_type = $this->content_type === 'html' ? 'text/html' : 'text/plain';
|
||||
$this->message->setBody($this->content, $content_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email
|
||||
*
|
||||
* @return bool TRUE in case of success, FALSE if sending fails
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function send()
|
||||
public function send()
|
||||
{
|
||||
if($this->Mailer == "mail")
|
||||
try
|
||||
{
|
||||
$boundary = '----==' . uniqid(rand(), TRUE);
|
||||
$this->eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n";
|
||||
$this->header = "Content-Type: multipart/alternative;" . $this->eol . "\tboundary=\"" . $boundary . "\"" . $this->eol . $this->eol;
|
||||
$this->body = sprintf(
|
||||
"--%s" . $this->eol .
|
||||
"Content-Type: text/plain; charset=utf-8; format=flowed" . $this->eol .
|
||||
"Content-Transfer-Encoding: base64" . $this->eol .
|
||||
"Content-Disposition: inline" . $this->eol . $this->eol .
|
||||
"%s" .
|
||||
"--%s" . $this->eol .
|
||||
"Content-Type: text/html; charset=utf-8" . $this->eol .
|
||||
"Content-Transfer-Encoding: base64" . $this->eol .
|
||||
"Content-Disposition: inline" . $this->eol . $this->eol .
|
||||
"%s" .
|
||||
"--%s--" .
|
||||
"", $boundary, $this->getPlainContent(), $boundary, $this->getHTMLContent(), $boundary
|
||||
);
|
||||
$this->procCidAttachments();
|
||||
$this->procAttachments();
|
||||
$headers = sprintf(
|
||||
"From: %s" . $this->eol .
|
||||
"%s" .
|
||||
"%s" .
|
||||
"%s" .
|
||||
"%s" .
|
||||
"MIME-Version: 1.0" . $this->eol . "", $this->getSender(), $this->messageId ? ("Message-ID: <" . $this->messageId . ">" . $this->eol) : "", $this->replyTo ? ("Reply-To: <" . $this->replyTo . ">" . $this->eol) : "", $this->bcc ? ("Bcc: " . $this->bcc . $this->eol) : "", $this->references ? ("References: <" . $this->references . ">" . $this->eol . "In-Reply-To: <" . $this->references . ">" . $this->eol) : ""
|
||||
);
|
||||
$headers .= $this->header;
|
||||
if($this->additional_params)
|
||||
$this->procAssembleMessage();
|
||||
if(!self::$transport)
|
||||
{
|
||||
return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers, $this->additional_params);
|
||||
self::$transport = \Swift_MailTransport::newInstance();
|
||||
}
|
||||
return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers);
|
||||
$mailer = \Swift_Mailer::newInstance(self::$transport);
|
||||
$result = $mailer->send($this->message, $this->errors);
|
||||
return (bool)$result;
|
||||
}
|
||||
else
|
||||
catch(\Exception $e)
|
||||
{
|
||||
$this->procAttachments();
|
||||
return parent::Send();
|
||||
$this->error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if DNS of param is real or fake
|
||||
*
|
||||
* @param string $email_address Email address
|
||||
* @return boolean TRUE if param is valid DNS otherwise FALSE
|
||||
*
|
||||
* @param string $email_address Email address to check
|
||||
* @return bool
|
||||
*/
|
||||
function checkMailMX($email_address)
|
||||
public function checkMailMX($email_address)
|
||||
{
|
||||
if(!Mail::isVaildMailAddress($email_address))
|
||||
if(!self::isVaildMailAddress($email_address))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -612,14 +438,14 @@ class Mail extends PHPMailer
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if param is a valid email or not
|
||||
*
|
||||
* @param string $email_address Email address
|
||||
* @return string email address if param is valid email address otherwise blank string
|
||||
*
|
||||
* @param string $email_address Email address to check
|
||||
* @return string
|
||||
*/
|
||||
function isVaildMailAddress($email_address)
|
||||
public function isVaildMailAddress($email_address)
|
||||
{
|
||||
if(preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@
|
|||
"ext-xml": "*",
|
||||
"defuse/php-encryption": "1.2.1",
|
||||
"ezyang/htmlpurifier": "4.7.*",
|
||||
"firephp/firephp-core": "0.4.0",
|
||||
"matthiasmullie/minify": "1.3.*",
|
||||
"michelf/php-markdown": "1.5.*",
|
||||
"rmccue/requests": "1.6.*",
|
||||
"sunra/php-simple-html-dom-parser": "1.5.*"
|
||||
"sunra/php-simple-html-dom-parser": "1.5.*",
|
||||
"swiftmailer/swiftmailer": "5.4.*",
|
||||
"true/punycode": "2.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"php": ">=5.4.0",
|
||||
|
|
|
|||
163
composer.lock
generated
163
composer.lock
generated
|
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "8649ea9e0951fe7dd685f9bb14e4a17d",
|
||||
"content-hash": "0276b439721108d097fff978f7ee1c93",
|
||||
"hash": "a35061b94658a2dbdafe943dddcdc898",
|
||||
"content-hash": "1a71937e1cbc600f8a237c6445d6a69f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "defuse/php-encryption",
|
||||
|
|
@ -97,17 +97,53 @@
|
|||
"time": "2015-08-05 01:03:42"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
"version": "1.3.30",
|
||||
"name": "firephp/firephp-core",
|
||||
"version": "v0.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/minify.git",
|
||||
"reference": "0cd5108683e7376e795555ced56229c4c16597aa"
|
||||
"url": "https://github.com/firephp/firephp-core.git",
|
||||
"reference": "fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/0cd5108683e7376e795555ced56229c4c16597aa",
|
||||
"reference": "0cd5108683e7376e795555ced56229c4c16597aa",
|
||||
"url": "https://api.github.com/repos/firephp/firephp-core/zipball/fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf",
|
||||
"reference": "fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"lib/FirePHPCore/FirePHP.class.php",
|
||||
"lib/FirePHPCore/fb.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christoph Dorn",
|
||||
"email": "christoph@christophdorn.com",
|
||||
"homepage": "http://christophdorn.com"
|
||||
}
|
||||
],
|
||||
"description": "Traditional FirePHPCore library for sending PHP variables to the browser.",
|
||||
"homepage": "https://github.com/firephp/firephp-core",
|
||||
"time": "2013-04-23 15:28:20"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
"version": "1.3.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/minify.git",
|
||||
"reference": "140c714688908afcecde87338c8309233bdc2519"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/140c714688908afcecde87338c8309233bdc2519",
|
||||
"reference": "140c714688908afcecde87338c8309233bdc2519",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -151,20 +187,20 @@
|
|||
"minifier",
|
||||
"minify"
|
||||
],
|
||||
"time": "2016-01-05 07:43:18"
|
||||
"time": "2016-01-11 02:10:11"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/path-converter",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/path-converter.git",
|
||||
"reference": "9f83d0c398dbe70f45f5840d95ffad73d5efd35f"
|
||||
"reference": "83609c1bb251b2540eba912615571a501a0a06a6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/9f83d0c398dbe70f45f5840d95ffad73d5efd35f",
|
||||
"reference": "9f83d0c398dbe70f45f5840d95ffad73d5efd35f",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/83609c1bb251b2540eba912615571a501a0a06a6",
|
||||
"reference": "83609c1bb251b2540eba912615571a501a0a06a6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -201,7 +237,7 @@
|
|||
"paths",
|
||||
"relative"
|
||||
],
|
||||
"time": "2016-01-05 07:45:30"
|
||||
"time": "2016-01-07 00:41:13"
|
||||
},
|
||||
{
|
||||
"name": "michelf/php-markdown",
|
||||
|
|
@ -345,6 +381,105 @@
|
|||
"parser"
|
||||
],
|
||||
"time": "2013-05-04 14:32:03"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v5.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421",
|
||||
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~0.9.1,<0.9.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/swift_required.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Corbyn"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Swiftmailer, free feature-rich PHP mailer",
|
||||
"homepage": "http://swiftmailer.org",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2015-06-06 14:19:39"
|
||||
},
|
||||
{
|
||||
"name": "true/punycode",
|
||||
"version": "v2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/true/php-punycode.git",
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.7",
|
||||
"squizlabs/php_codesniffer": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TrueBV\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Renan Gonçalves",
|
||||
"email": "renan.saddam@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)",
|
||||
"homepage": "https://github.com/true/php-punycode",
|
||||
"keywords": [
|
||||
"idna",
|
||||
"punycode"
|
||||
],
|
||||
"time": "2016-01-07 17:12:58"
|
||||
}
|
||||
],
|
||||
"packages-dev": null,
|
||||
|
|
|
|||
|
|
@ -289,12 +289,6 @@ if(!defined('__PROXY_SERVER__'))
|
|||
define('__PROXY_SERVER__', NULL);
|
||||
}
|
||||
|
||||
// Require specific files when using Firebug console output
|
||||
if((__DEBUG_OUTPUT__ == 2) && version_compare(PHP_VERSION, '6.0.0') === -1)
|
||||
{
|
||||
require _XE_PATH_ . 'libs/FirePHPCore/FirePHP.class.php';
|
||||
}
|
||||
|
||||
// Set Timezone as server time
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
|
|
@ -404,6 +398,8 @@ $GLOBALS['__xe_autoload_file_map'] = array_change_key_case(array(
|
|||
'HintTableTag' => 'classes/xml/xmlquery/tags/table/HintTableTag.class.php',
|
||||
'TableTag' => 'classes/xml/xmlquery/tags/table/TableTag.class.php',
|
||||
'TablesTag' => 'classes/xml/xmlquery/tags/table/TablesTag.class.php',
|
||||
'Ftp' => 'common/libraries/ftp.php',
|
||||
'Tar' => 'common/libraries/tar.php',
|
||||
), CASE_LOWER);
|
||||
|
||||
function __xe_autoload($class_name)
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,7 @@ function stripEmbedTagForAdmin(&$content, $writer_member_srl)
|
|||
*/
|
||||
function requirePear()
|
||||
{
|
||||
set_include_path(_XE_PATH_ . "libs/PEAR.1.9.5" . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1468,9 +1468,7 @@ function checkCSRF()
|
|||
|
||||
if(strpos($default_url, 'xn--') !== FALSE && strpos($referer, 'xn--') === FALSE)
|
||||
{
|
||||
require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
|
||||
$IDN = new idna_convert(array('idn_version' => 2008));
|
||||
$referer = $IDN->encode($referer);
|
||||
$referer = Context::encodeIdna($referer);
|
||||
}
|
||||
|
||||
$default_url = parse_url($default_url);
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
|
||||
2008-06-14 - Release Version: 0.3.1
|
||||
|
||||
- (Issue 108) ignore class name case in object filter
|
||||
|
||||
2009-05-11 - Release Version: 0.3
|
||||
2009-05-01 - Release Version: 0.3.rc.1
|
||||
|
||||
- (Issue 90) PHP4 compatible version of FirePHPCore
|
||||
- (Issue 98) Thrown exceptions don't send an HTTP 500 if the FirePHP exception handler is enabled
|
||||
- (Issue 85) Support associative arrays in encodeTable method in FirePHP.class.php
|
||||
- (Issue 66) Add a new getOptions() public method in API
|
||||
- (Issue 82) Define $this->options outside of __construct
|
||||
- (Issue 72) Message error if group name is null
|
||||
- (Issue 68) registerErrorHandler() and registerExceptionHandler() should returns previous handlers defined
|
||||
- (Issue 69) Add the missing register handler in the triumvirate (error, exception, assert)
|
||||
- (Issue 75) [Error & Exception Handling] Option to not exit script execution
|
||||
- (Issue 83) Exception handler can't throw exceptions
|
||||
- (Issue 80) Auto/Pre collapsing groups AND Custom group row colors
|
||||
|
||||
2008-11-09 - Release Version: 0.2.1
|
||||
|
||||
- (Issue 70) Problem when logging resources
|
||||
|
||||
2008-10-21 - Release Version: 0.2.0
|
||||
|
||||
- Updated version to 0.2.0
|
||||
- Switched to using __sleep instead of __wakeup
|
||||
- Added support to exclude object members when encoding
|
||||
- Add support to enable/disable logging
|
||||
|
||||
2008-10-17 - Release Version: 0.2.b.8
|
||||
|
||||
- New implementation for is_utf8()
|
||||
- (Issue 55) maxObjectDepth Option not working correctly when using TABLE and EXCEPTION Type
|
||||
- Bugfix for max[Object|Array]Depth when encoding nested array/object graphs
|
||||
- Bugfix for FB::setOptions()
|
||||
|
||||
2008-10-16 - Release Version: 0.2.b.7
|
||||
|
||||
- (Issue 45) Truncate dump when string have non utf8 cars
|
||||
- (Issue 52) logging will not work when firephp object gets stored in the session.
|
||||
|
||||
2008-10-16 - Release Version: 0.2.b.6
|
||||
|
||||
- (Issue 37) Display file and line information for each log message
|
||||
- (Issue 51) Limit output of object graphs
|
||||
- Bugfix for encoding object members set to NULL|false|''
|
||||
|
||||
2008-10-14 - Release Version: 0.2.b.5
|
||||
|
||||
- Updated JsonStream wildfire protocol to be more robust
|
||||
- (Issue 33) PHP error notices running demos
|
||||
- (Issue 48) Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given
|
||||
|
||||
2008-10-08 - Release Version: 0.2.b.4
|
||||
|
||||
- Bugfix for logging objects with recursion
|
||||
|
||||
2008-10-08 - Release Version: 0.2.b.3
|
||||
|
||||
- (Issue 43) Notice message in 0.2b2
|
||||
- Added support for PHP's native json_encode() if available
|
||||
- Revised object encoder to detect object recursion
|
||||
|
||||
2008-10-07 - Release Version: 0.2.b.2
|
||||
|
||||
- (Issue 28) Need solution for logging private and protected object variables
|
||||
- Added trace() and table() aliases in FirePHP class
|
||||
- (Issue 41) Use PHP doc in FirePHP
|
||||
- (Issue 39) Static logging method for object oriented API
|
||||
|
||||
2008-10-01 - Release Version: 0.2.b.1
|
||||
|
||||
- Added support for error and exception handling
|
||||
- Updated min PHP version for PEAR package to 5.2
|
||||
- Added version constant for library
|
||||
- Gave server library it's own wildfire plugin namespace
|
||||
- Migrated communication protocol to Wildfire JsonStream
|
||||
- Added support for console groups using "group" and "groupEnd"
|
||||
- Added support for log, info, warn and error logging aliases
|
||||
- (Issue 29) problem with TRACE when using with error_handler
|
||||
- (Issue 33) PHP error notices running demos
|
||||
- (Issue 12) undefined index php notice
|
||||
- Removed closing ?> php tags
|
||||
- (Issue 13) the code in the fb() function has a second return statement that will never be reached
|
||||
|
||||
2008-07-30 - Release Version: 0.1.1.3
|
||||
|
||||
- Include __className property in JSON string if variable was an object
|
||||
- Bugfix - Mis-spelt "Exception" in JSON encoding code
|
||||
|
||||
2008-06-13 - Release Version: 0.1.1.1
|
||||
|
||||
- Bugfix - Standardize windows paths in stack traces
|
||||
- Bugfix - Display correct stack trace info in windows environments
|
||||
- Bugfix - Check $_SERVER['HTTP_USER_AGENT'] before returning
|
||||
|
||||
2008-06-13 - Release Version: 0.1.1
|
||||
|
||||
- Added support for FirePHP::TRACE log style
|
||||
- Changed license to New BSD License
|
||||
|
||||
2008-06-06 - Release Version: 0.0.2
|
||||
|
||||
- Bugfix - Added usleep() to header writing loop to ensure unique index
|
||||
- Bugfix - Ensure chunk_split does not generate trailing "\n" with empty data header
|
||||
- Added support for FirePHP::TABLE log style
|
||||
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
_______________________________
|
||||
F i r e P H P C o r e
|
||||
|
||||
Current Development
|
||||
-------------------
|
||||
|
||||
Christoph Dorn <christoph@christophdorn.com>
|
||||
Michael Day <manveru.alma@gmail.com>
|
||||
|
||||
If you've done work on FirePHPCore and you are not listed here,
|
||||
please feel free to add yourself.
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
Software License Agreement (New BSD License)
|
||||
|
||||
Copyright (c) 2006-2009, Christoph Dorn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Christoph Dorn nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
Version: 0.3.1
|
||||
|
||||
------------------------------------------------------
|
||||
Requirements
|
||||
------------------------------------------------------
|
||||
|
||||
Client Side:
|
||||
|
||||
- Firefox - http://www.getfirefox.com/
|
||||
- Firebug - http://www.getfirebug.com/
|
||||
- FirePHP - http://www.firephp.org/
|
||||
|
||||
Server Side:
|
||||
|
||||
- PHP 5 (complete functionality)
|
||||
- PHP 4 (most functionality)
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
Install Tutorial
|
||||
------------------------------------------------------
|
||||
|
||||
http://www.firephp.org/HQ/Install.htm
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
Support
|
||||
------------------------------------------------------
|
||||
|
||||
http://forum.firephp.org/
|
||||
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* This file is part of FirePHP (http://www.firephp.org/).
|
||||
*
|
||||
* Software License Agreement (New BSD License)
|
||||
*
|
||||
* Copyright (c) 2006-2009, Christoph Dorn
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Christoph Dorn nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* @copyright Copyright (C) 2007-2009 Christoph Dorn
|
||||
* @author Christoph Dorn <christoph@christophdorn.com>
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @package FirePHP
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/FirePHP.class.php';
|
||||
|
||||
/**
|
||||
* Sends the given data to the FirePHP Firefox Extension.
|
||||
* The data can be displayed in the Firebug Console or in the
|
||||
* "Server" request tab.
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
function fb()
|
||||
{
|
||||
$instance = FirePHP::getInstance(true);
|
||||
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($instance,'fb'),$args);
|
||||
}
|
||||
|
||||
|
||||
class FB
|
||||
{
|
||||
/**
|
||||
* Enable and disable logging to Firebug
|
||||
*
|
||||
* @see FirePHP->setEnabled()
|
||||
* @param boolean $Enabled TRUE to enable, FALSE to disable
|
||||
* @return void
|
||||
*/
|
||||
public static function setEnabled($Enabled) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setEnabled($Enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logging is enabled
|
||||
*
|
||||
* @see FirePHP->getEnabled()
|
||||
* @return boolean TRUE if enabled
|
||||
*/
|
||||
public static function getEnabled() {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
return $instance->getEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a filter to be used when encoding an object
|
||||
*
|
||||
* Filters are used to exclude object members.
|
||||
*
|
||||
* @see FirePHP->setObjectFilter()
|
||||
* @param string $Class The class name of the object
|
||||
* @param array $Filter An array or members to exclude
|
||||
* @return void
|
||||
*/
|
||||
public static function setObjectFilter($Class, $Filter) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setObjectFilter($Class, $Filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some options for the library
|
||||
*
|
||||
* @see FirePHP->setOptions()
|
||||
* @param array $Options The options to be set
|
||||
* @return void
|
||||
*/
|
||||
public static function setOptions($Options) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$instance->setOptions($Options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options for the library
|
||||
*
|
||||
* @see FirePHP->getOptions()
|
||||
* @return array The options
|
||||
*/
|
||||
public static function getOptions() {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
return $instance->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object to firebug
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function send()
|
||||
{
|
||||
$instance = FirePHP::getInstance(true);
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($instance,'fb'),$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a group for following messages
|
||||
*
|
||||
* Options:
|
||||
* Collapsed: [true|false]
|
||||
* Color: [#RRGGBB|ColorName]
|
||||
*
|
||||
* @param string $Name
|
||||
* @param array $Options OPTIONAL Instructions on how to log the group
|
||||
* @return true
|
||||
*/
|
||||
public static function group($Name, $Options=null) {
|
||||
$instance = FirePHP::getInstance(true);
|
||||
return $instance->group($Name, $Options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a group you have started before
|
||||
*
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function groupEnd() {
|
||||
return self::send(null, null, FirePHP::GROUP_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::LOG
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function log($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::INFO
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function info($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::WARN
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function warn($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::ERROR
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function error($Object, $Label=null) {
|
||||
return self::send($Object, $Label, FirePHP::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps key and variable to firebug server panel
|
||||
*
|
||||
* @see FirePHP::DUMP
|
||||
* @param string $Key
|
||||
* @param mixed $Variable
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function dump($Key, $Variable) {
|
||||
return self::send($Variable, $Key, FirePHP::DUMP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a trace in the firebug console
|
||||
*
|
||||
* @see FirePHP::TRACE
|
||||
* @param string $Label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function trace($Label) {
|
||||
return self::send($Label, FirePHP::TRACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a table in the firebug console
|
||||
*
|
||||
* @see FirePHP::TABLE
|
||||
* @param string $Label
|
||||
* @param string $Table
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function table($Label, $Table) {
|
||||
return self::send($Table, $Label, FirePHP::TABLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
class HTTP_Request extends HTTP_Request2
|
||||
{
|
||||
private $reponse = null;
|
||||
|
||||
public function addHeader($name, $value)
|
||||
{
|
||||
$this->setHeader($name, $value);
|
||||
}
|
||||
|
||||
public function sendRequest($saveBody = true)
|
||||
{
|
||||
$response = $this->send();
|
||||
$this->response = $response;
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getResponseCode() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseHeader() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getHeader();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseBody() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getBody();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseCookies() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getCookies();
|
||||
}
|
||||
}
|
||||
|
||||
public function addPostData($name, $value, $preencoded = false)
|
||||
{
|
||||
$this->addPostParameter($name, $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,137 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*/
|
||||
require_once 'HTTP/Request2/Response.php';
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* HTTP_Request2 class itself only defines methods for aggregating the request
|
||||
* data, all actual work of sending the request to the remote server and
|
||||
* receiving its response is performed by adapters.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
abstract class HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A list of methods that MUST NOT have a request body, per RFC 2616
|
||||
* @var array
|
||||
*/
|
||||
protected static $bodyDisallowed = array('TRACE');
|
||||
|
||||
/**
|
||||
* Methods having defined semantics for request body
|
||||
*
|
||||
* Content-Length header (indicating that the body follows, section 4.3 of
|
||||
* RFC 2616) will be sent for these methods even if no body was added
|
||||
*
|
||||
* @var array
|
||||
* @link http://pear.php.net/bugs/bug.php?id=12900
|
||||
* @link http://pear.php.net/bugs/bug.php?id=14740
|
||||
*/
|
||||
protected static $bodyRequired = array('POST', 'PUT');
|
||||
|
||||
/**
|
||||
* Request being sent
|
||||
* @var HTTP_Request2
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Request body
|
||||
* @var string|resource|HTTP_Request2_MultipartBody
|
||||
* @see HTTP_Request2::getBody()
|
||||
*/
|
||||
protected $requestBody;
|
||||
|
||||
/**
|
||||
* Length of the request body
|
||||
* @var integer
|
||||
*/
|
||||
protected $contentLength;
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
abstract public function sendRequest(HTTP_Request2 $request);
|
||||
|
||||
/**
|
||||
* Calculates length of the request body, adds proper headers
|
||||
*
|
||||
* @param array &$headers associative array of request headers, this method
|
||||
* will add proper 'Content-Length' and 'Content-Type'
|
||||
* headers to this array (or remove them if not needed)
|
||||
*/
|
||||
protected function calculateRequestLength(&$headers)
|
||||
{
|
||||
$this->requestBody = $this->request->getBody();
|
||||
|
||||
if (is_string($this->requestBody)) {
|
||||
$this->contentLength = strlen($this->requestBody);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$stat = fstat($this->requestBody);
|
||||
$this->contentLength = $stat['size'];
|
||||
rewind($this->requestBody);
|
||||
} else {
|
||||
$this->contentLength = $this->requestBody->getLength();
|
||||
$headers['content-type'] = 'multipart/form-data; boundary=' .
|
||||
$this->requestBody->getBoundary();
|
||||
$this->requestBody->rewind();
|
||||
}
|
||||
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed)
|
||||
|| 0 == $this->contentLength
|
||||
) {
|
||||
// No body: send a Content-Length header nonetheless (request #12900),
|
||||
// but do that only for methods that require a body (bug #14740)
|
||||
if (in_array($this->request->getMethod(), self::$bodyRequired)) {
|
||||
$headers['content-length'] = 0;
|
||||
} else {
|
||||
unset($headers['content-length']);
|
||||
// if the method doesn't require a body and doesn't have a
|
||||
// body, don't send a Content-Type header. (request #16799)
|
||||
unset($headers['content-type']);
|
||||
}
|
||||
} else {
|
||||
if (empty($headers['content-type'])) {
|
||||
$headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
// Content-Length should not be sent for chunked Transfer-Encoding (bug #20125)
|
||||
if (!isset($headers['transfer-encoding'])) {
|
||||
$headers['content-length'] = $this->contentLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,567 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* Mapping of header names to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $headerMap = array(
|
||||
'accept-encoding' => CURLOPT_ENCODING,
|
||||
'cookie' => CURLOPT_COOKIE,
|
||||
'referer' => CURLOPT_REFERER,
|
||||
'user-agent' => CURLOPT_USERAGENT
|
||||
);
|
||||
|
||||
/**
|
||||
* Mapping of SSL context options to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $sslContextMap = array(
|
||||
'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
|
||||
'ssl_cafile' => CURLOPT_CAINFO,
|
||||
'ssl_capath' => CURLOPT_CAPATH,
|
||||
'ssl_local_cert' => CURLOPT_SSLCERT,
|
||||
'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
|
||||
);
|
||||
|
||||
/**
|
||||
* Mapping of CURLE_* constants to Exception subclasses and error codes
|
||||
* @var array
|
||||
*/
|
||||
protected static $errorMap = array(
|
||||
CURLE_UNSUPPORTED_PROTOCOL => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_COULDNT_RESOLVE_PROXY => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_COULDNT_RESOLVE_HOST => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_COULDNT_CONNECT => array('HTTP_Request2_ConnectionException'),
|
||||
// error returned from write callback
|
||||
CURLE_WRITE_ERROR => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_OPERATION_TIMEOUTED => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::TIMEOUT),
|
||||
CURLE_HTTP_RANGE_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_CONNECT_ERROR => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_LIBRARY_NOT_FOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_FUNCTION_NOT_FOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_ABORTED_BY_CALLBACK => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_TOO_MANY_REDIRECTS => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::TOO_MANY_REDIRECTS),
|
||||
CURLE_SSL_PEER_CERTIFICATE => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_GOT_NOTHING => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_ENGINE_NOTFOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_SSL_ENGINE_SETFAILED => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_SEND_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_RECV_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_CERTPROBLEM => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT),
|
||||
CURLE_SSL_CIPHER => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_SSL_CACERT => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_BAD_CONTENT_ENCODING => array('HTTP_Request2_MessageException'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Response being received
|
||||
* @var HTTP_Request2_Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Whether 'sentHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventSentHeaders = false;
|
||||
|
||||
/**
|
||||
* Whether 'receivedHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventReceivedHeaders = false;
|
||||
|
||||
/**
|
||||
* Position within request body
|
||||
* @var integer
|
||||
* @see callbackReadBody()
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Information about last transfer, as returned by curl_getinfo()
|
||||
* @var array
|
||||
*/
|
||||
protected $lastInfo;
|
||||
|
||||
/**
|
||||
* Creates a subclass of HTTP_Request2_Exception from curl error data
|
||||
*
|
||||
* @param resource $ch curl handle
|
||||
*
|
||||
* @return HTTP_Request2_Exception
|
||||
*/
|
||||
protected static function wrapCurlError($ch)
|
||||
{
|
||||
$nativeCode = curl_errno($ch);
|
||||
$message = 'Curl error: ' . curl_error($ch);
|
||||
if (!isset(self::$errorMap[$nativeCode])) {
|
||||
return new HTTP_Request2_Exception($message, 0, $nativeCode);
|
||||
} else {
|
||||
$class = self::$errorMap[$nativeCode][0];
|
||||
$code = empty(self::$errorMap[$nativeCode][1])
|
||||
? 0 : self::$errorMap[$nativeCode][1];
|
||||
return new $class($message, $code, $nativeCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'cURL extension not available', HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->response = null;
|
||||
$this->position = 0;
|
||||
$this->eventSentHeaders = false;
|
||||
$this->eventReceivedHeaders = false;
|
||||
|
||||
try {
|
||||
if (false === curl_exec($ch = $this->createCurlHandle())) {
|
||||
$e = self::wrapCurlError($ch);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
if (isset($ch)) {
|
||||
$this->lastInfo = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
$response = $this->response;
|
||||
unset($this->request, $this->requestBody, $this->response);
|
||||
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($jar = $request->getCookieJar()) {
|
||||
$jar->addCookiesFromResponse($response, $request->getUrl());
|
||||
}
|
||||
|
||||
if (0 < $this->lastInfo['size_download']) {
|
||||
$request->setLastEvent('receivedBody', $response);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about last transfer
|
||||
*
|
||||
* @return array associative array as returned by curl_getinfo()
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->lastInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cURL handle and populates it with data from the request
|
||||
*
|
||||
* @return resource a cURL handle, as created by curl_init()
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_NotImplementedException
|
||||
*/
|
||||
protected function createCurlHandle()
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
// setup write callbacks
|
||||
CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
|
||||
CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
|
||||
// buffer size
|
||||
CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
|
||||
// connection timeout
|
||||
CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
|
||||
// save full outgoing headers, in case someone is interested
|
||||
CURLINFO_HEADER_OUT => true,
|
||||
// request url
|
||||
CURLOPT_URL => $this->request->getUrl()->getUrl()
|
||||
));
|
||||
|
||||
// set up redirects
|
||||
if (!$this->request->getConfig('follow_redirects')) {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
||||
} else {
|
||||
if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Redirect support in curl is unavailable due to open_basedir or safe_mode setting',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects'));
|
||||
// limit redirects to http(s), works in 5.2.10+
|
||||
if (defined('CURLOPT_REDIR_PROTOCOLS')) {
|
||||
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
// works in 5.3.2+, http://bugs.php.net/bug.php?id=49571
|
||||
if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR')) {
|
||||
curl_setopt($ch, CURLOPT_POSTREDIR, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// set local IP via CURLOPT_INTERFACE (request #19515)
|
||||
if ($ip = $this->request->getConfig('local_ip')) {
|
||||
curl_setopt($ch, CURLOPT_INTERFACE, $ip);
|
||||
}
|
||||
|
||||
// request timeout
|
||||
if ($timeout = $this->request->getConfig('timeout')) {
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
}
|
||||
|
||||
// set HTTP version
|
||||
switch ($this->request->getConfig('protocol_version')) {
|
||||
case '1.0':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
break;
|
||||
case '1.1':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
}
|
||||
|
||||
// set request method
|
||||
switch ($this->request->getMethod()) {
|
||||
case HTTP_Request2::METHOD_GET:
|
||||
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_POST:
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_HEAD:
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_PUT:
|
||||
curl_setopt($ch, CURLOPT_UPLOAD, true);
|
||||
break;
|
||||
default:
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
|
||||
}
|
||||
|
||||
// set proxy, if needed
|
||||
if ($host = $this->request->getConfig('proxy_host')) {
|
||||
if (!($port = $this->request->getConfig('proxy_port'))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
|
||||
if ($user = $this->request->getConfig('proxy_user')) {
|
||||
curl_setopt(
|
||||
$ch, CURLOPT_PROXYUSERPWD,
|
||||
$user . ':' . $this->request->getConfig('proxy_password')
|
||||
);
|
||||
switch ($this->request->getConfig('proxy_auth_scheme')) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
if ($type = $this->request->getConfig('proxy_type')) {
|
||||
switch ($type) {
|
||||
case 'http':
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
break;
|
||||
case 'socks5':
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
break;
|
||||
default:
|
||||
throw new HTTP_Request2_NotImplementedException(
|
||||
"Proxy type '{$type}' is not supported"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set authentication data
|
||||
if ($auth = $this->request->getAuth()) {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
|
||||
switch ($auth['scheme']) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
|
||||
// set SSL options
|
||||
foreach ($this->request->getConfig() as $name => $value) {
|
||||
if ('ssl_verify_host' == $name && null !== $value) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
|
||||
} elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
|
||||
curl_setopt($ch, self::$sslContextMap[$name], $value);
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->request->getHeaders();
|
||||
// make cURL automagically send proper header
|
||||
if (!isset($headers['accept-encoding'])) {
|
||||
$headers['accept-encoding'] = '';
|
||||
}
|
||||
|
||||
if (($jar = $this->request->getCookieJar())
|
||||
&& ($cookies = $jar->getMatching($this->request->getUrl(), true))
|
||||
) {
|
||||
$headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies;
|
||||
}
|
||||
|
||||
// set headers having special cURL keys
|
||||
foreach (self::$headerMap as $name => $option) {
|
||||
if (isset($headers[$name])) {
|
||||
curl_setopt($ch, $option, $headers[$name]);
|
||||
unset($headers[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->calculateRequestLength($headers);
|
||||
if (isset($headers['content-length']) || isset($headers['transfer-encoding'])) {
|
||||
$this->workaroundPhpBug47204($ch, $headers);
|
||||
}
|
||||
|
||||
// set headers not having special keys
|
||||
$headersFmt = array();
|
||||
foreach ($headers as $name => $value) {
|
||||
$canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
|
||||
$headersFmt[] = $canonicalName . ': ' . $value;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
|
||||
|
||||
return $ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for PHP bug #47204 that prevents rewinding request body
|
||||
*
|
||||
* The workaround consists of reading the entire request body into memory
|
||||
* and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large
|
||||
* file uploads, use Socket adapter instead.
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param array &$headers Request headers
|
||||
*/
|
||||
protected function workaroundPhpBug47204($ch, &$headers)
|
||||
{
|
||||
// no redirects, no digest auth -> probably no rewind needed
|
||||
if (!$this->request->getConfig('follow_redirects')
|
||||
&& (!($auth = $this->request->getAuth())
|
||||
|| HTTP_Request2::AUTH_DIGEST != $auth['scheme'])
|
||||
) {
|
||||
curl_setopt($ch, CURLOPT_READFUNCTION, array($this, 'callbackReadBody'));
|
||||
|
||||
} else {
|
||||
// rewind may be needed, read the whole body into memory
|
||||
if ($this->requestBody instanceof HTTP_Request2_MultipartBody) {
|
||||
$this->requestBody = $this->requestBody->__toString();
|
||||
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$fp = $this->requestBody;
|
||||
$this->requestBody = '';
|
||||
while (!feof($fp)) {
|
||||
$this->requestBody .= fread($fp, 16384);
|
||||
}
|
||||
}
|
||||
// curl hangs up if content-length is present
|
||||
unset($headers['content-length']);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for reading the request body
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param resource $fd file descriptor (not used)
|
||||
* @param integer $length maximum length of data to return
|
||||
*
|
||||
* @return string part of the request body, up to $length bytes
|
||||
*/
|
||||
protected function callbackReadBody($ch, $fd, $length)
|
||||
{
|
||||
if (!$this->eventSentHeaders) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
$this->eventSentHeaders = true;
|
||||
}
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed)
|
||||
|| 0 == $this->contentLength || $this->position >= $this->contentLength
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($this->requestBody)) {
|
||||
$string = substr($this->requestBody, $this->position, $length);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$string = fread($this->requestBody, $length);
|
||||
} else {
|
||||
$string = $this->requestBody->read($length);
|
||||
}
|
||||
$this->request->setLastEvent('sentBodyPart', strlen($string));
|
||||
$this->position += strlen($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response headers
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param string $string response header (with trailing CRLF)
|
||||
*
|
||||
* @return integer number of bytes saved
|
||||
* @see HTTP_Request2_Response::parseHeaderLine()
|
||||
*/
|
||||
protected function callbackWriteHeader($ch, $string)
|
||||
{
|
||||
// we may receive a second set of headers if doing e.g. digest auth
|
||||
if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
|
||||
// don't bother with 100-Continue responses (bug #15785)
|
||||
if (!$this->eventSentHeaders
|
||||
|| $this->response->getStatus() >= 200
|
||||
) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
}
|
||||
$upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
|
||||
// if body wasn't read by a callback, send event with total body size
|
||||
if ($upload > $this->position) {
|
||||
$this->request->setLastEvent(
|
||||
'sentBodyPart', $upload - $this->position
|
||||
);
|
||||
$this->position = $upload;
|
||||
}
|
||||
if ($upload && (!$this->eventSentHeaders
|
||||
|| $this->response->getStatus() >= 200)
|
||||
) {
|
||||
$this->request->setLastEvent('sentBody', $upload);
|
||||
}
|
||||
$this->eventSentHeaders = true;
|
||||
// we'll need a new response object
|
||||
if ($this->eventReceivedHeaders) {
|
||||
$this->eventReceivedHeaders = false;
|
||||
$this->response = null;
|
||||
}
|
||||
}
|
||||
if (empty($this->response)) {
|
||||
$this->response = new HTTP_Request2_Response(
|
||||
$string, false, curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)
|
||||
);
|
||||
} else {
|
||||
$this->response->parseHeaderLine($string);
|
||||
if ('' == trim($string)) {
|
||||
// don't bother with 100-Continue responses (bug #15785)
|
||||
if (200 <= $this->response->getStatus()) {
|
||||
$this->request->setLastEvent('receivedHeaders', $this->response);
|
||||
}
|
||||
|
||||
if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) {
|
||||
$redirectUrl = new Net_URL2($this->response->getHeader('location'));
|
||||
|
||||
// for versions lower than 5.2.10, check the redirection URL protocol
|
||||
if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute()
|
||||
&& !in_array($redirectUrl->getScheme(), array('http', 'https'))
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($jar = $this->request->getCookieJar()) {
|
||||
$jar->addCookiesFromResponse($this->response, $this->request->getUrl());
|
||||
if (!$redirectUrl->isAbsolute()) {
|
||||
$redirectUrl = $this->request->getUrl()->resolve($redirectUrl);
|
||||
}
|
||||
if ($cookies = $jar->getMatching($redirectUrl, true)) {
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->eventReceivedHeaders = true;
|
||||
}
|
||||
}
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response body
|
||||
*
|
||||
* @param resource $ch cURL handle (not used)
|
||||
* @param string $string part of the response body
|
||||
*
|
||||
* @return integer number of bytes saved
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @see HTTP_Request2_Response::appendBody()
|
||||
*/
|
||||
protected function callbackWriteBody($ch, $string)
|
||||
{
|
||||
// cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
|
||||
// response doesn't start with proper HTTP status line (see bug #15716)
|
||||
if (empty($this->response)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Malformed response: {$string}",
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
if ($this->request->getConfig('store_body')) {
|
||||
$this->response->appendBody($string);
|
||||
}
|
||||
$this->request->setLastEvent('receivedBodyPart', $string);
|
||||
return strlen($string);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* Can be used to test applications depending on HTTP_Request2 package without
|
||||
* actually performing any HTTP requests. This adapter will return responses
|
||||
* previously added via addResponse()
|
||||
* <code>
|
||||
* $mock = new HTTP_Request2_Adapter_Mock();
|
||||
* $mock->addResponse("HTTP/1.1 ... ");
|
||||
*
|
||||
* $request = new HTTP_Request2();
|
||||
* $request->setAdapter($mock);
|
||||
*
|
||||
* // This will return the response set above
|
||||
* $response = $req->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A queue of responses to be returned by sendRequest()
|
||||
* @var array
|
||||
*/
|
||||
protected $responses = array();
|
||||
|
||||
/**
|
||||
* Returns the next response from the queue built by addResponse()
|
||||
*
|
||||
* Only responses without explicit URLs or with URLs equal to request URL
|
||||
* will be considered. If matching response is not found or the queue is
|
||||
* empty then default empty response with status 400 will be returned,
|
||||
* if an Exception object was added to the queue it will be thrown.
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
$requestUrl = (string)$request->getUrl();
|
||||
$response = null;
|
||||
foreach ($this->responses as $k => $v) {
|
||||
if (!$v[1] || $requestUrl == $v[1]) {
|
||||
$response = $v[0];
|
||||
array_splice($this->responses, $k, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$response) {
|
||||
return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
|
||||
|
||||
} elseif ($response instanceof HTTP_Request2_Response) {
|
||||
return $response;
|
||||
|
||||
} else {
|
||||
// rethrow the exception
|
||||
$class = get_class($response);
|
||||
$message = $response->getMessage();
|
||||
$code = $response->getCode();
|
||||
throw new $class($message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds response to the queue
|
||||
*
|
||||
* @param mixed $response either a string, a pointer to an open file,
|
||||
* an instance of HTTP_Request2_Response or Exception
|
||||
* @param string $url A request URL this response should be valid for
|
||||
* (see {@link http://pear.php.net/bugs/bug.php?id=19276})
|
||||
*
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function addResponse($response, $url = null)
|
||||
{
|
||||
if (is_string($response)) {
|
||||
$response = self::createResponseFromString($response);
|
||||
} elseif (is_resource($response)) {
|
||||
$response = self::createResponseFromFile($response);
|
||||
} elseif (!$response instanceof HTTP_Request2_Response &&
|
||||
!$response instanceof Exception
|
||||
) {
|
||||
throw new HTTP_Request2_Exception('Parameter is not a valid response');
|
||||
}
|
||||
$this->responses[] = array($response, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a string
|
||||
*
|
||||
* @param string $str string containing HTTP response message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromString($str)
|
||||
{
|
||||
$parts = preg_split('!(\r?\n){2}!m', $str, 2);
|
||||
$headerLines = explode("\n", $parts[0]);
|
||||
$response = new HTTP_Request2_Response(array_shift($headerLines));
|
||||
foreach ($headerLines as $headerLine) {
|
||||
$response->parseHeaderLine($headerLine);
|
||||
}
|
||||
$response->parseHeaderLine('');
|
||||
if (isset($parts[1])) {
|
||||
$response->appendBody($parts[1]);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a file
|
||||
*
|
||||
* @param resource $fp file pointer returned by fopen()
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromFile($fp)
|
||||
{
|
||||
$response = new HTTP_Request2_Response(fgets($fp));
|
||||
do {
|
||||
$headerLine = fgets($fp);
|
||||
$response->parseHeaderLine($headerLine);
|
||||
} while ('' != trim($headerLine));
|
||||
|
||||
while (!feof($fp)) {
|
||||
$response->appendBody(fread($fp, 8192));
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,494 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Stores cookies and passes them between HTTP requests
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Class representing a HTTP request message */
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
/**
|
||||
* Stores cookies and passes them between HTTP requests
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_CookieJar implements Serializable
|
||||
{
|
||||
/**
|
||||
* Array of stored cookies
|
||||
*
|
||||
* The array is indexed by domain, path and cookie name
|
||||
* .example.com
|
||||
* /
|
||||
* some_cookie => cookie data
|
||||
* /subdir
|
||||
* other_cookie => cookie data
|
||||
* .example.org
|
||||
* ...
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Whether session cookies should be serialized when serializing the jar
|
||||
* @var bool
|
||||
*/
|
||||
protected $serializeSession = false;
|
||||
|
||||
/**
|
||||
* Whether Public Suffix List should be used for domain matching
|
||||
* @var bool
|
||||
*/
|
||||
protected $useList = true;
|
||||
|
||||
/**
|
||||
* Array with Public Suffix List data
|
||||
* @var array
|
||||
* @link http://publicsuffix.org/
|
||||
*/
|
||||
protected static $psl = array();
|
||||
|
||||
/**
|
||||
* Class constructor, sets various options
|
||||
*
|
||||
* @param bool $serializeSessionCookies Controls serializing session cookies,
|
||||
* see {@link serializeSessionCookies()}
|
||||
* @param bool $usePublicSuffixList Controls using Public Suffix List,
|
||||
* see {@link usePublicSuffixList()}
|
||||
*/
|
||||
public function __construct(
|
||||
$serializeSessionCookies = false, $usePublicSuffixList = true
|
||||
) {
|
||||
$this->serializeSessionCookies($serializeSessionCookies);
|
||||
$this->usePublicSuffixList($usePublicSuffixList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current time formatted in ISO-8601 at UTC timezone
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function now()
|
||||
{
|
||||
$dt = new DateTime();
|
||||
$dt->setTimezone(new DateTimeZone('UTC'));
|
||||
return $dt->format(DateTime::ISO8601);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks cookie array for correctness, possibly updating its 'domain', 'path' and 'expires' fields
|
||||
*
|
||||
* The checks are as follows:
|
||||
* - cookie array should contain 'name' and 'value' fields;
|
||||
* - name and value should not contain disallowed symbols;
|
||||
* - 'expires' should be either empty parseable by DateTime;
|
||||
* - 'domain' and 'path' should be either not empty or an URL where
|
||||
* cookie was set should be provided.
|
||||
* - if $setter is provided, then document at that URL should be allowed
|
||||
* to set a cookie for that 'domain'. If $setter is not provided,
|
||||
* then no domain checks will be made.
|
||||
*
|
||||
* 'expires' field will be converted to ISO8601 format from COOKIE format,
|
||||
* 'domain' and 'path' will be set from setter URL if empty.
|
||||
*
|
||||
* @param array $cookie cookie data, as returned by
|
||||
* {@link HTTP_Request2_Response::getCookies()}
|
||||
* @param Net_URL2 $setter URL of the document that sent Set-Cookie header
|
||||
*
|
||||
* @return array Updated cookie array
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null)
|
||||
{
|
||||
if ($missing = array_diff(array('name', 'value'), array_keys($cookie))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Cookie array should contain 'name' and 'value' fields",
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['name'])) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Invalid cookie name: '{$cookie['name']}'",
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT
|
||||
);
|
||||
}
|
||||
if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['value'])) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Invalid cookie value: '{$cookie['value']}'",
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT
|
||||
);
|
||||
}
|
||||
$cookie += array('domain' => '', 'path' => '', 'expires' => null, 'secure' => false);
|
||||
|
||||
// Need ISO-8601 date @ UTC timezone
|
||||
if (!empty($cookie['expires'])
|
||||
&& !preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+0000$/', $cookie['expires'])
|
||||
) {
|
||||
try {
|
||||
$dt = new DateTime($cookie['expires']);
|
||||
$dt->setTimezone(new DateTimeZone('UTC'));
|
||||
$cookie['expires'] = $dt->format(DateTime::ISO8601);
|
||||
} catch (Exception $e) {
|
||||
throw new HTTP_Request2_LogicException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($cookie['domain']) || empty($cookie['path'])) {
|
||||
if (!$setter) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Cookie misses domain and/or path component, cookie setter URL needed',
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
if (empty($cookie['domain'])) {
|
||||
if ($host = $setter->getHost()) {
|
||||
$cookie['domain'] = $host;
|
||||
} else {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Setter URL does not contain host part, can\'t set cookie domain',
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
}
|
||||
if (empty($cookie['path'])) {
|
||||
$path = $setter->getPath();
|
||||
$cookie['path'] = empty($path)? '/': substr($path, 0, strrpos($path, '/') + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ($setter && !$this->domainMatch($setter->getHost(), $cookie['domain'])) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Domain " . $setter->getHost() . " cannot set cookies for "
|
||||
. $cookie['domain']
|
||||
);
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a cookie in the jar
|
||||
*
|
||||
* @param array $cookie cookie data, as returned by
|
||||
* {@link HTTP_Request2_Response::getCookies()}
|
||||
* @param Net_URL2 $setter URL of the document that sent Set-Cookie header
|
||||
*
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function store(array $cookie, Net_URL2 $setter = null)
|
||||
{
|
||||
$cookie = $this->checkAndUpdateFields($cookie, $setter);
|
||||
|
||||
if (strlen($cookie['value'])
|
||||
&& (is_null($cookie['expires']) || $cookie['expires'] > $this->now())
|
||||
) {
|
||||
if (!isset($this->cookies[$cookie['domain']])) {
|
||||
$this->cookies[$cookie['domain']] = array();
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
|
||||
$this->cookies[$cookie['domain']][$cookie['path']] = array();
|
||||
}
|
||||
$this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
|
||||
|
||||
} elseif (isset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']])) {
|
||||
unset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds cookies set in HTTP response to the jar
|
||||
*
|
||||
* @param HTTP_Request2_Response $response HTTP response message
|
||||
* @param Net_URL2 $setter original request URL, needed for
|
||||
* setting default domain/path
|
||||
*/
|
||||
public function addCookiesFromResponse(HTTP_Request2_Response $response, Net_URL2 $setter)
|
||||
{
|
||||
foreach ($response->getCookies() as $cookie) {
|
||||
$this->store($cookie, $setter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cookies matching a given request URL
|
||||
*
|
||||
* The following checks are made:
|
||||
* - cookie domain should match request host
|
||||
* - cookie path should be a prefix for request path
|
||||
* - 'secure' cookies will only be sent for HTTPS requests
|
||||
*
|
||||
* @param Net_URL2 $url Request url
|
||||
* @param bool $asString Whether to return cookies as string for "Cookie: " header
|
||||
*
|
||||
* @return array|string Matching cookies
|
||||
*/
|
||||
public function getMatching(Net_URL2 $url, $asString = false)
|
||||
{
|
||||
$host = $url->getHost();
|
||||
$path = $url->getPath();
|
||||
$secure = 0 == strcasecmp($url->getScheme(), 'https');
|
||||
|
||||
$matched = $ret = array();
|
||||
foreach (array_keys($this->cookies) as $domain) {
|
||||
if ($this->domainMatch($host, $domain)) {
|
||||
foreach (array_keys($this->cookies[$domain]) as $cPath) {
|
||||
if (0 === strpos($path, $cPath)) {
|
||||
foreach ($this->cookies[$domain][$cPath] as $name => $cookie) {
|
||||
if (!$cookie['secure'] || $secure) {
|
||||
$matched[$name][strlen($cookie['path'])] = $cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($matched as $cookies) {
|
||||
krsort($cookies);
|
||||
$ret = array_merge($ret, $cookies);
|
||||
}
|
||||
if (!$asString) {
|
||||
return $ret;
|
||||
} else {
|
||||
$str = '';
|
||||
foreach ($ret as $c) {
|
||||
$str .= (empty($str)? '': '; ') . $c['name'] . '=' . $c['value'];
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cookies stored in a jar
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
$cookies = array();
|
||||
foreach (array_keys($this->cookies) as $domain) {
|
||||
foreach (array_keys($this->cookies[$domain]) as $path) {
|
||||
foreach ($this->cookies[$domain][$path] as $name => $cookie) {
|
||||
$cookies[] = $cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether session cookies should be serialized when serializing the jar
|
||||
*
|
||||
* @param boolean $serialize serialize?
|
||||
*/
|
||||
public function serializeSessionCookies($serialize)
|
||||
{
|
||||
$this->serializeSession = (bool)$serialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether Public Suffix List should be used for restricting cookie-setting
|
||||
*
|
||||
* Without PSL {@link domainMatch()} will only prevent setting cookies for
|
||||
* top-level domains like '.com' or '.org'. However, it will not prevent
|
||||
* setting a cookie for '.co.uk' even though only third-level registrations
|
||||
* are possible in .uk domain.
|
||||
*
|
||||
* With the List it is possible to find the highest level at which a domain
|
||||
* may be registered for a particular top-level domain and consequently
|
||||
* prevent cookies set for '.co.uk' or '.msk.ru'. The same list is used by
|
||||
* Firefox, Chrome and Opera browsers to restrict cookie setting.
|
||||
*
|
||||
* Note that PSL is licensed differently to HTTP_Request2 package (refer to
|
||||
* the license information in public-suffix-list.php), so you can disable
|
||||
* its use if this is an issue for you.
|
||||
*
|
||||
* @param boolean $useList use the list?
|
||||
*
|
||||
* @link http://publicsuffix.org/learn/
|
||||
*/
|
||||
public function usePublicSuffixList($useList)
|
||||
{
|
||||
$this->useList = (bool)$useList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string representation of object
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see Serializable::serialize()
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
$cookies = $this->getAll();
|
||||
if (!$this->serializeSession) {
|
||||
for ($i = count($cookies) - 1; $i >= 0; $i--) {
|
||||
if (empty($cookies[$i]['expires'])) {
|
||||
unset($cookies[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return serialize(array(
|
||||
'cookies' => $cookies,
|
||||
'serializeSession' => $this->serializeSession,
|
||||
'useList' => $this->useList
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the object from serialized string
|
||||
*
|
||||
* @param string $serialized string representation
|
||||
*
|
||||
* @see Serializable::unserialize()
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
$now = $this->now();
|
||||
$this->serializeSessionCookies($data['serializeSession']);
|
||||
$this->usePublicSuffixList($data['useList']);
|
||||
foreach ($data['cookies'] as $cookie) {
|
||||
if (!empty($cookie['expires']) && $cookie['expires'] <= $now) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']])) {
|
||||
$this->cookies[$cookie['domain']] = array();
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
|
||||
$this->cookies[$cookie['domain']][$cookie['path']] = array();
|
||||
}
|
||||
$this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a cookie domain matches a request host.
|
||||
*
|
||||
* The method is used by {@link store()} to check for whether a document
|
||||
* at given URL can set a cookie with a given domain attribute and by
|
||||
* {@link getMatching()} to find cookies matching the request URL.
|
||||
*
|
||||
* @param string $requestHost request host
|
||||
* @param string $cookieDomain cookie domain
|
||||
*
|
||||
* @return bool match success
|
||||
*/
|
||||
public function domainMatch($requestHost, $cookieDomain)
|
||||
{
|
||||
if ($requestHost == $cookieDomain) {
|
||||
return true;
|
||||
}
|
||||
// IP address, we require exact match
|
||||
if (preg_match('/^(?:\d{1,3}\.){3}\d{1,3}$/', $requestHost)) {
|
||||
return false;
|
||||
}
|
||||
if ('.' != $cookieDomain[0]) {
|
||||
$cookieDomain = '.' . $cookieDomain;
|
||||
}
|
||||
// prevents setting cookies for '.com' and similar domains
|
||||
if (!$this->useList && substr_count($cookieDomain, '.') < 2
|
||||
|| $this->useList && !self::getRegisteredDomain($cookieDomain)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes subdomains to get the registered domain (the first after top-level)
|
||||
*
|
||||
* The method will check Public Suffix List to find out where top-level
|
||||
* domain ends and registered domain starts. It will remove domain parts
|
||||
* to the left of registered one.
|
||||
*
|
||||
* @param string $domain domain name
|
||||
*
|
||||
* @return string|bool registered domain, will return false if $domain is
|
||||
* either invalid or a TLD itself
|
||||
*/
|
||||
public static function getRegisteredDomain($domain)
|
||||
{
|
||||
$domainParts = explode('.', ltrim($domain, '.'));
|
||||
|
||||
// load the list if needed
|
||||
if (empty(self::$psl)) {
|
||||
$path = '@data_dir@' . DIRECTORY_SEPARATOR . 'HTTP_Request2';
|
||||
if (0 === strpos($path, '@' . 'data_dir@')) {
|
||||
$path = realpath(
|
||||
dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'
|
||||
. DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data'
|
||||
);
|
||||
}
|
||||
self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php';
|
||||
}
|
||||
|
||||
if (!($result = self::checkDomainsList($domainParts, self::$psl))) {
|
||||
// known TLD, invalid domain name
|
||||
return false;
|
||||
}
|
||||
|
||||
// unknown TLD
|
||||
if (!strpos($result, '.')) {
|
||||
// fallback to checking that domain "has at least two dots"
|
||||
if (2 > ($count = count($domainParts))) {
|
||||
return false;
|
||||
}
|
||||
return $domainParts[$count - 2] . '.' . $domainParts[$count - 1];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper method for {@link getRegisteredDomain()}
|
||||
*
|
||||
* @param array $domainParts remaining domain parts
|
||||
* @param mixed $listNode node in {@link HTTP_Request2_CookieJar::$psl} to check
|
||||
*
|
||||
* @return string|null concatenated domain parts, null in case of error
|
||||
*/
|
||||
protected static function checkDomainsList(array $domainParts, $listNode)
|
||||
{
|
||||
$sub = array_pop($domainParts);
|
||||
$result = null;
|
||||
|
||||
if (!is_array($listNode) || is_null($sub)
|
||||
|| array_key_exists('!' . $sub, $listNode)
|
||||
) {
|
||||
return $sub;
|
||||
|
||||
} elseif (array_key_exists($sub, $listNode)) {
|
||||
$result = self::checkDomainsList($domainParts, $listNode[$sub]);
|
||||
|
||||
} elseif (array_key_exists('*', $listNode)) {
|
||||
$result = self::checkDomainsList($domainParts, $listNode['*']);
|
||||
|
||||
} else {
|
||||
return $sub;
|
||||
}
|
||||
|
||||
return (strlen($result) > 0) ? ($result . '.' . $sub) : null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception classes for HTTP_Request2 package
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for exceptions in PEAR
|
||||
*/
|
||||
require_once 'PEAR/Exception.php';
|
||||
|
||||
/**
|
||||
* Base exception class for HTTP_Request2 package
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=132
|
||||
*/
|
||||
class HTTP_Request2_Exception extends PEAR_Exception
|
||||
{
|
||||
/** An invalid argument was passed to a method */
|
||||
const INVALID_ARGUMENT = 1;
|
||||
/** Some required value was not available */
|
||||
const MISSING_VALUE = 2;
|
||||
/** Request cannot be processed due to errors in PHP configuration */
|
||||
const MISCONFIGURATION = 3;
|
||||
/** Error reading the local file */
|
||||
const READ_ERROR = 4;
|
||||
|
||||
/** Server returned a response that does not conform to HTTP protocol */
|
||||
const MALFORMED_RESPONSE = 10;
|
||||
/** Failure decoding Content-Encoding or Transfer-Encoding of response */
|
||||
const DECODE_ERROR = 20;
|
||||
/** Operation timed out */
|
||||
const TIMEOUT = 30;
|
||||
/** Number of redirects exceeded 'max_redirects' configuration parameter */
|
||||
const TOO_MANY_REDIRECTS = 40;
|
||||
/** Redirect to a protocol other than http(s):// */
|
||||
const NON_HTTP_REDIRECT = 50;
|
||||
|
||||
/**
|
||||
* Native error code
|
||||
* @var int
|
||||
*/
|
||||
private $_nativeCode;
|
||||
|
||||
/**
|
||||
* Constructor, can set package error code and native error code
|
||||
*
|
||||
* @param string $message exception message
|
||||
* @param int $code package error code, one of class constants
|
||||
* @param int $nativeCode error code from underlying PHP extension
|
||||
*/
|
||||
public function __construct($message = null, $code = null, $nativeCode = null)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
$this->_nativeCode = $nativeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error code produced by underlying PHP extension
|
||||
*
|
||||
* For Socket Adapter this may contain error number returned by
|
||||
* stream_socket_client(), for Curl Adapter this will contain error number
|
||||
* returned by curl_errno()
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getNativeCode()
|
||||
{
|
||||
return $this->_nativeCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown in case of missing features
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception that represents error in the program logic
|
||||
*
|
||||
* This exception usually implies a programmer's error, like passing invalid
|
||||
* data to methods or trying to use PHP extensions that weren't installed or
|
||||
* enabled. Usually exceptions of this kind will be thrown before request even
|
||||
* starts.
|
||||
*
|
||||
* The exception will usually contain a package error code.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_LogicException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when connection to a web or proxy server fails
|
||||
*
|
||||
* The exception will not contain a package error code, but will contain
|
||||
* native error code, as returned by stream_socket_client() or curl_errno().
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when sending or receiving HTTP message fails
|
||||
*
|
||||
* The exception may contain both package error code and native error code.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_MessageException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,268 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper class for building multipart/form-data request body
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Exception class for HTTP_Request2 package */
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class for building multipart/form-data request body
|
||||
*
|
||||
* The class helps to reduce memory consumption by streaming large file uploads
|
||||
* from disk, it also allows monitoring of upload progress (see request #7630)
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://tools.ietf.org/html/rfc1867
|
||||
*/
|
||||
class HTTP_Request2_MultipartBody
|
||||
{
|
||||
/**
|
||||
* MIME boundary
|
||||
* @var string
|
||||
*/
|
||||
private $_boundary;
|
||||
|
||||
/**
|
||||
* Form parameters added via {@link HTTP_Request2::addPostParameter()}
|
||||
* @var array
|
||||
*/
|
||||
private $_params = array();
|
||||
|
||||
/**
|
||||
* File uploads added via {@link HTTP_Request2::addUpload()}
|
||||
* @var array
|
||||
*/
|
||||
private $_uploads = array();
|
||||
|
||||
/**
|
||||
* Header for parts with parameters
|
||||
* @var string
|
||||
*/
|
||||
private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Header for parts with uploads
|
||||
* @var string
|
||||
*/
|
||||
private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Current position in parameter and upload arrays
|
||||
*
|
||||
* First number is index of "current" part, second number is position within
|
||||
* "current" part
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_pos = array(0, 0);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor. Sets the arrays with POST data.
|
||||
*
|
||||
* @param array $params values of form fields set via
|
||||
* {@link HTTP_Request2::addPostParameter()}
|
||||
* @param array $uploads file uploads set via
|
||||
* {@link HTTP_Request2::addUpload()}
|
||||
* @param bool $useBrackets whether to append brackets to array variable names
|
||||
*/
|
||||
public function __construct(array $params, array $uploads, $useBrackets = true)
|
||||
{
|
||||
$this->_params = self::_flattenArray('', $params, $useBrackets);
|
||||
foreach ($uploads as $fieldName => $f) {
|
||||
if (!is_array($f['fp'])) {
|
||||
$this->_uploads[] = $f + array('name' => $fieldName);
|
||||
} else {
|
||||
for ($i = 0; $i < count($f['fp']); $i++) {
|
||||
$upload = array(
|
||||
'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
|
||||
);
|
||||
foreach (array('fp', 'filename', 'size', 'type') as $key) {
|
||||
$upload[$key] = $f[$key][$i];
|
||||
}
|
||||
$this->_uploads[] = $upload;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the body to use in Content-Length header
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLength()
|
||||
{
|
||||
$boundaryLength = strlen($this->getBoundary());
|
||||
$headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
|
||||
$headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
|
||||
$length = $boundaryLength + 6;
|
||||
foreach ($this->_params as $p) {
|
||||
$length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
|
||||
}
|
||||
foreach ($this->_uploads as $u) {
|
||||
$length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
|
||||
strlen($u['filename']) + $u['size'] + 2;
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary to use in Content-Type header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBoundary()
|
||||
{
|
||||
if (empty($this->_boundary)) {
|
||||
$this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
|
||||
}
|
||||
return $this->_boundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next chunk of request body
|
||||
*
|
||||
* @param integer $length Number of bytes to read
|
||||
*
|
||||
* @return string Up to $length bytes of data, empty string if at end
|
||||
* @throws HTTP_Request2_LogicException
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
$ret = '';
|
||||
$boundary = $this->getBoundary();
|
||||
$paramCount = count($this->_params);
|
||||
$uploadCount = count($this->_uploads);
|
||||
while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
|
||||
$oldLength = $length;
|
||||
if ($this->_pos[0] < $paramCount) {
|
||||
$param = sprintf(
|
||||
$this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
|
||||
) . $this->_params[$this->_pos[0]][1] . "\r\n";
|
||||
$ret .= substr($param, $this->_pos[1], $length);
|
||||
$length -= min(strlen($param) - $this->_pos[1], $length);
|
||||
|
||||
} elseif ($this->_pos[0] < $paramCount + $uploadCount) {
|
||||
$pos = $this->_pos[0] - $paramCount;
|
||||
$header = sprintf(
|
||||
$this->_headerUpload, $boundary, $this->_uploads[$pos]['name'],
|
||||
$this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type']
|
||||
);
|
||||
if ($this->_pos[1] < strlen($header)) {
|
||||
$ret .= substr($header, $this->_pos[1], $length);
|
||||
$length -= min(strlen($header) - $this->_pos[1], $length);
|
||||
}
|
||||
$filePos = max(0, $this->_pos[1] - strlen($header));
|
||||
if ($filePos < $this->_uploads[$pos]['size']) {
|
||||
while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) {
|
||||
if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR
|
||||
);
|
||||
}
|
||||
$ret .= $chunk;
|
||||
$length -= strlen($chunk);
|
||||
}
|
||||
}
|
||||
if ($length > 0) {
|
||||
$start = $this->_pos[1] + ($oldLength - $length) -
|
||||
strlen($header) - $this->_uploads[$pos]['size'];
|
||||
$ret .= substr("\r\n", $start, $length);
|
||||
$length -= min(2 - $start, $length);
|
||||
}
|
||||
|
||||
} else {
|
||||
$closing = '--' . $boundary . "--\r\n";
|
||||
$ret .= substr($closing, $this->_pos[1], $length);
|
||||
$length -= min(strlen($closing) - $this->_pos[1], $length);
|
||||
}
|
||||
if ($length > 0) {
|
||||
$this->_pos = array($this->_pos[0] + 1, 0);
|
||||
} else {
|
||||
$this->_pos[1] += $oldLength;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current position to the start of the body
|
||||
*
|
||||
* This allows reusing the same body in another request
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->_pos = array(0, 0);
|
||||
foreach ($this->_uploads as $u) {
|
||||
rewind($u['fp']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body as string
|
||||
*
|
||||
* Note that it reads all file uploads into memory so it is a good idea not
|
||||
* to use this method with large file uploads and rely on read() instead.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$this->rewind();
|
||||
return $this->read($this->getLength());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to change the (probably multidimensional) associative array
|
||||
* into the simple one.
|
||||
*
|
||||
* @param string $name name for item
|
||||
* @param mixed $values item's values
|
||||
* @param bool $useBrackets whether to append [] to array variables' names
|
||||
*
|
||||
* @return array array with the following items: array('item name', 'item value');
|
||||
*/
|
||||
private static function _flattenArray($name, $values, $useBrackets)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
return array(array($name, $values));
|
||||
} else {
|
||||
$ret = array();
|
||||
foreach ($values as $k => $v) {
|
||||
if (empty($name)) {
|
||||
$newName = $k;
|
||||
} elseif ($useBrackets) {
|
||||
$newName = $name . '[' . $k . ']';
|
||||
} else {
|
||||
$newName = $name;
|
||||
}
|
||||
$ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* An observer useful for debugging / testing.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* A debug observer useful for debugging / testing.
|
||||
*
|
||||
* This observer logs to a log target data corresponding to the various request
|
||||
* and response events, it logs by default to php://output but can be configured
|
||||
* to log to a file or via the PEAR Log package.
|
||||
*
|
||||
* A simple example:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* $observer = new HTTP_Request2_Observer_Log();
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* A more complex example with PEAR Log:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
* require_once 'Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* // we want to log with PEAR log
|
||||
* $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
|
||||
*
|
||||
* // we only want to log received headers
|
||||
* $observer->events = array('receivedHeaders');
|
||||
*
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Observer_Log implements SplObserver
|
||||
{
|
||||
// properties {{{
|
||||
|
||||
/**
|
||||
* The log target, it can be a a resource or a PEAR Log instance.
|
||||
*
|
||||
* @var resource|Log $target
|
||||
*/
|
||||
protected $target = null;
|
||||
|
||||
/**
|
||||
* The events to log.
|
||||
*
|
||||
* @var array $events
|
||||
*/
|
||||
public $events = array(
|
||||
'connect',
|
||||
'sentHeaders',
|
||||
'sentBody',
|
||||
'receivedHeaders',
|
||||
'receivedBody',
|
||||
'disconnect',
|
||||
);
|
||||
|
||||
// }}}
|
||||
// __construct() {{{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param mixed $target Can be a file path (default: php://output), a resource,
|
||||
* or an instance of the PEAR Log class.
|
||||
* @param array $events Array of events to listen to (default: all events)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($target = 'php://output', array $events = array())
|
||||
{
|
||||
if (!empty($events)) {
|
||||
$this->events = $events;
|
||||
}
|
||||
if (is_resource($target) || $target instanceof Log) {
|
||||
$this->target = $target;
|
||||
} elseif (false === ($this->target = @fopen($target, 'ab'))) {
|
||||
throw new HTTP_Request2_Exception("Unable to open '{$target}'");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// update() {{{
|
||||
|
||||
/**
|
||||
* Called when the request notifies us of an event.
|
||||
*
|
||||
* @param HTTP_Request2 $subject The HTTP_Request2 instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update(SplSubject $subject)
|
||||
{
|
||||
$event = $subject->getLastEvent();
|
||||
if (!in_array($event['name'], $this->events)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($event['name']) {
|
||||
case 'connect':
|
||||
$this->log('* Connected to ' . $event['data']);
|
||||
break;
|
||||
case 'sentHeaders':
|
||||
$headers = explode("\r\n", $event['data']);
|
||||
array_pop($headers);
|
||||
foreach ($headers as $header) {
|
||||
$this->log('> ' . $header);
|
||||
}
|
||||
break;
|
||||
case 'sentBody':
|
||||
$this->log('> ' . $event['data'] . ' byte(s) sent');
|
||||
break;
|
||||
case 'receivedHeaders':
|
||||
$this->log(sprintf(
|
||||
'< HTTP/%s %s %s', $event['data']->getVersion(),
|
||||
$event['data']->getStatus(), $event['data']->getReasonPhrase()
|
||||
));
|
||||
$headers = $event['data']->getHeader();
|
||||
foreach ($headers as $key => $val) {
|
||||
$this->log('< ' . $key . ': ' . $val);
|
||||
}
|
||||
$this->log('< ');
|
||||
break;
|
||||
case 'receivedBody':
|
||||
$this->log($event['data']->getBody());
|
||||
break;
|
||||
case 'disconnect':
|
||||
$this->log('* Disconnected');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// log() {{{
|
||||
|
||||
/**
|
||||
* Logs the given message to the configured target.
|
||||
*
|
||||
* @param string $message Message to display
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function log($message)
|
||||
{
|
||||
if ($this->target instanceof Log) {
|
||||
$this->target->debug($message);
|
||||
} elseif (is_resource($this->target)) {
|
||||
fwrite($this->target, $message . "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,631 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* The class is designed to be used in "streaming" scenario, building the
|
||||
* response as it is being received:
|
||||
* <code>
|
||||
* $statusLine = read_status_line();
|
||||
* $response = new HTTP_Request2_Response($statusLine);
|
||||
* do {
|
||||
* $headerLine = read_header_line();
|
||||
* $response->parseHeaderLine($headerLine);
|
||||
* } while ($headerLine != '');
|
||||
*
|
||||
* while ($chunk = read_body()) {
|
||||
* $response->appendBody($chunk);
|
||||
* }
|
||||
*
|
||||
* var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6
|
||||
*/
|
||||
class HTTP_Request2_Response
|
||||
{
|
||||
/**
|
||||
* HTTP protocol version (e.g. 1.0, 1.1)
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
* @var integer
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
* @var string
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $reasonPhrase;
|
||||
|
||||
/**
|
||||
* Effective URL (may be different from original request URL in case of redirects)
|
||||
* @var string
|
||||
*/
|
||||
protected $effectiveUrl;
|
||||
|
||||
/**
|
||||
* Associative array of response headers
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Cookies set in the response
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Name of last header processed by parseHederLine()
|
||||
*
|
||||
* Used to handle the headers that span multiple lines
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastHeader = null;
|
||||
|
||||
/**
|
||||
* Response body
|
||||
* @var string
|
||||
*/
|
||||
protected $body = '';
|
||||
|
||||
/**
|
||||
* Whether the body is still encoded by Content-Encoding
|
||||
*
|
||||
* cURL provides the decoded body to the callback; if we are reading from
|
||||
* socket the body is still gzipped / deflated
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $bodyEncoded;
|
||||
|
||||
/**
|
||||
* Associative array of HTTP status code / reason phrase.
|
||||
*
|
||||
* @var array
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-10
|
||||
*/
|
||||
protected static $phrases = array(
|
||||
|
||||
// 1xx: Informational - Request received, continuing process
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
|
||||
// 2xx: Success - The action was successfully received, understood and
|
||||
// accepted
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
// 3xx: Redirection - Further action must be taken in order to complete
|
||||
// the request
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found', // 1.1
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
// 4xx: Client Error - The request contains bad syntax or cannot be
|
||||
// fulfilled
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
// 5xx: Server Error - The server failed to fulfill an apparently
|
||||
// valid request
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
509 => 'Bandwidth Limit Exceeded',
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the default reason phrase for the given code or all reason phrases
|
||||
*
|
||||
* @param int $code Response code
|
||||
*
|
||||
* @return string|array|null Default reason phrase for $code if $code is given
|
||||
* (null if no phrase is available), array of all
|
||||
* reason phrases if $code is null
|
||||
* @link http://pear.php.net/bugs/18716
|
||||
*/
|
||||
public static function getDefaultReasonPhrase($code = null)
|
||||
{
|
||||
if (null === $code) {
|
||||
return self::$phrases;
|
||||
} else {
|
||||
return isset(self::$phrases[$code]) ? self::$phrases[$code] : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, parses the response status line
|
||||
*
|
||||
* @param string $statusLine Response status line (e.g. "HTTP/1.1 200 OK")
|
||||
* @param bool $bodyEncoded Whether body is still encoded by Content-Encoding
|
||||
* @param string $effectiveUrl Effective URL of the response
|
||||
*
|
||||
* @throws HTTP_Request2_MessageException if status line is invalid according to spec
|
||||
*/
|
||||
public function __construct($statusLine, $bodyEncoded = true, $effectiveUrl = null)
|
||||
{
|
||||
if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Malformed response: {$statusLine}",
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
$this->version = $m[1];
|
||||
$this->code = intval($m[2]);
|
||||
$this->reasonPhrase = !empty($m[3]) ? trim($m[3]) : self::getDefaultReasonPhrase($this->code);
|
||||
$this->bodyEncoded = (bool)$bodyEncoded;
|
||||
$this->effectiveUrl = (string)$effectiveUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the line from HTTP response filling $headers array
|
||||
*
|
||||
* The method should be called after reading the line from socket or receiving
|
||||
* it into cURL callback. Passing an empty string here indicates the end of
|
||||
* response headers and triggers additional processing, so be sure to pass an
|
||||
* empty string in the end.
|
||||
*
|
||||
* @param string $headerLine Line from HTTP response
|
||||
*/
|
||||
public function parseHeaderLine($headerLine)
|
||||
{
|
||||
$headerLine = trim($headerLine, "\r\n");
|
||||
|
||||
if ('' == $headerLine) {
|
||||
// empty string signals the end of headers, process the received ones
|
||||
if (!empty($this->headers['set-cookie'])) {
|
||||
$cookies = is_array($this->headers['set-cookie'])?
|
||||
$this->headers['set-cookie']:
|
||||
array($this->headers['set-cookie']);
|
||||
foreach ($cookies as $cookieString) {
|
||||
$this->parseCookie($cookieString);
|
||||
}
|
||||
unset($this->headers['set-cookie']);
|
||||
}
|
||||
foreach (array_keys($this->headers) as $k) {
|
||||
if (is_array($this->headers[$k])) {
|
||||
$this->headers[$k] = implode(', ', $this->headers[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
|
||||
// string of the form header-name: header value
|
||||
$name = strtolower($m[1]);
|
||||
$value = trim($m[2]);
|
||||
if (empty($this->headers[$name])) {
|
||||
$this->headers[$name] = $value;
|
||||
} else {
|
||||
if (!is_array($this->headers[$name])) {
|
||||
$this->headers[$name] = array($this->headers[$name]);
|
||||
}
|
||||
$this->headers[$name][] = $value;
|
||||
}
|
||||
$this->lastHeader = $name;
|
||||
|
||||
} elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
|
||||
// continuation of a previous header
|
||||
if (!is_array($this->headers[$this->lastHeader])) {
|
||||
$this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
|
||||
} else {
|
||||
$key = count($this->headers[$this->lastHeader]) - 1;
|
||||
$this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Set-Cookie header to fill $cookies array
|
||||
*
|
||||
* @param string $cookieString value of Set-Cookie header
|
||||
*
|
||||
* @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
|
||||
*/
|
||||
protected function parseCookie($cookieString)
|
||||
{
|
||||
$cookie = array(
|
||||
'expires' => null,
|
||||
'domain' => null,
|
||||
'path' => null,
|
||||
'secure' => false
|
||||
);
|
||||
|
||||
if (!strpos($cookieString, ';')) {
|
||||
// Only a name=value pair
|
||||
$pos = strpos($cookieString, '=');
|
||||
$cookie['name'] = trim(substr($cookieString, 0, $pos));
|
||||
$cookie['value'] = trim(substr($cookieString, $pos + 1));
|
||||
|
||||
} else {
|
||||
// Some optional parameters are supplied
|
||||
$elements = explode(';', $cookieString);
|
||||
$pos = strpos($elements[0], '=');
|
||||
$cookie['name'] = trim(substr($elements[0], 0, $pos));
|
||||
$cookie['value'] = trim(substr($elements[0], $pos + 1));
|
||||
|
||||
for ($i = 1; $i < count($elements); $i++) {
|
||||
if (false === strpos($elements[$i], '=')) {
|
||||
$elName = trim($elements[$i]);
|
||||
$elValue = null;
|
||||
} else {
|
||||
list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
|
||||
}
|
||||
$elName = strtolower($elName);
|
||||
if ('secure' == $elName) {
|
||||
$cookie['secure'] = true;
|
||||
} elseif ('expires' == $elName) {
|
||||
$cookie['expires'] = str_replace('"', '', $elValue);
|
||||
} elseif ('path' == $elName || 'domain' == $elName) {
|
||||
$cookie[$elName] = urldecode($elValue);
|
||||
} else {
|
||||
$cookie[$elName] = $elValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->cookies[] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string to the response body
|
||||
*
|
||||
* @param string $bodyChunk part of response body
|
||||
*/
|
||||
public function appendBody($bodyChunk)
|
||||
{
|
||||
$this->body .= $bodyChunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective URL of the response
|
||||
*
|
||||
* This may be different from the request URL if redirects were followed.
|
||||
*
|
||||
* @return string
|
||||
* @link http://pear.php.net/bugs/bug.php?id=18412
|
||||
*/
|
||||
public function getEffectiveUrl()
|
||||
{
|
||||
return $this->effectiveUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status code
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason phrase
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase()
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether response is a redirect that can be automatically handled by HTTP_Request2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->code, array(300, 301, 302, 303, 307))
|
||||
&& isset($this->headers['location']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either the named header or all response headers
|
||||
*
|
||||
* @param string $headerName Name of header to return
|
||||
*
|
||||
* @return string|array Value of $headerName header (null if header is
|
||||
* not present), array of all response headers if
|
||||
* $headerName is null
|
||||
*/
|
||||
public function getHeader($headerName = null)
|
||||
{
|
||||
if (null === $headerName) {
|
||||
return $this->headers;
|
||||
} else {
|
||||
$headerName = strtolower($headerName);
|
||||
return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cookies set in response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCookies()
|
||||
{
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body of the response
|
||||
*
|
||||
* @return string
|
||||
* @throws HTTP_Request2_Exception if body cannot be decoded
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
if (0 == strlen($this->body) || !$this->bodyEncoded
|
||||
|| !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
|
||||
) {
|
||||
return $this->body;
|
||||
|
||||
} else {
|
||||
if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
|
||||
$oldEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('8bit');
|
||||
}
|
||||
|
||||
try {
|
||||
switch (strtolower($this->getHeader('content-encoding'))) {
|
||||
case 'gzip':
|
||||
$decoded = self::decodeGzip($this->body);
|
||||
break;
|
||||
case 'deflate':
|
||||
$decoded = self::decodeDeflate($this->body);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
if (!empty($oldEncoding)) {
|
||||
mb_internal_encoding($oldEncoding);
|
||||
}
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP version of the response
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by gzip
|
||||
*
|
||||
* The real decoding work is done by gzinflate() built-in function, this
|
||||
* method only parses the header and checks data for compliance with
|
||||
* RFC 1952
|
||||
*
|
||||
* @param string $data gzip-encoded data
|
||||
*
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @link http://tools.ietf.org/html/rfc1952
|
||||
*/
|
||||
public static function decodeGzip($data)
|
||||
{
|
||||
$length = strlen($data);
|
||||
// If it doesn't look like gzip-encoded data, don't bother
|
||||
if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
|
||||
return $data;
|
||||
}
|
||||
if (!function_exists('gzinflate')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Unable to decode body: gzip extension not available',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
$method = ord(substr($data, 2, 1));
|
||||
if (8 != $method) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: unknown compression method',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$flags = ord(substr($data, 3, 1));
|
||||
if ($flags & 224) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: reserved bits are set',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// header is 10 bytes minimum. may be longer, though.
|
||||
$headerLength = 10;
|
||||
// extra fields, need to skip 'em
|
||||
if ($flags & 4) {
|
||||
if ($length - $headerLength - 2 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$extraLength = unpack('v', substr($data, 10, 2));
|
||||
if ($length - $headerLength - 2 - $extraLength[1] < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $extraLength[1] + 2;
|
||||
}
|
||||
// file name, need to skip that
|
||||
if ($flags & 8) {
|
||||
if ($length - $headerLength - 1 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$filenameLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $filenameLength + 1;
|
||||
}
|
||||
// comment, need to skip that also
|
||||
if ($flags & 16) {
|
||||
if ($length - $headerLength - 1 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$commentLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $commentLength + 1;
|
||||
}
|
||||
// have a CRC for header. let's check
|
||||
if ($flags & 2) {
|
||||
if ($length - $headerLength - 2 < 8) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
|
||||
$crcStored = unpack('v', substr($data, $headerLength, 2));
|
||||
if ($crcReal != $crcStored[1]) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Header CRC check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += 2;
|
||||
}
|
||||
// unpacked data CRC and size at the end of encoded data
|
||||
$tmp = unpack('V2', substr($data, -8));
|
||||
$dataCrc = $tmp[1];
|
||||
$dataSize = $tmp[2];
|
||||
|
||||
// finally, call the gzinflate() function
|
||||
// don't pass $dataSize to gzinflate, see bugs #13135, #14370
|
||||
$unpacked = gzinflate(substr($data, $headerLength, -8));
|
||||
if (false === $unpacked) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'gzinflate() call failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
} elseif ($dataSize != strlen($unpacked)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Data size check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
} elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
|
||||
throw new HTTP_Request2_Exception(
|
||||
'Data CRC check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
return $unpacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by deflate
|
||||
*
|
||||
* @param string $data deflate-encoded data
|
||||
*
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_LogicException
|
||||
*/
|
||||
public static function decodeDeflate($data)
|
||||
{
|
||||
if (!function_exists('gzuncompress')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Unable to decode body: gzip extension not available',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
// RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
|
||||
// while many applications send raw deflate stream from RFC 1951.
|
||||
// We should check for presence of zlib header and use gzuncompress() or
|
||||
// gzinflate() as needed. See bug #15305
|
||||
$header = unpack('n', substr($data, 0, 2));
|
||||
return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* SOCKS5 proxy connection class
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Socket wrapper class used by Socket Adapter */
|
||||
require_once 'HTTP/Request2/SocketWrapper.php';
|
||||
|
||||
/**
|
||||
* SOCKS5 proxy connection class (used by Socket Adapter)
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/bugs/bug.php?id=19332
|
||||
* @link http://tools.ietf.org/html/rfc1928
|
||||
*/
|
||||
class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper
|
||||
{
|
||||
/**
|
||||
* Constructor, tries to connect and authenticate to a SOCKS5 proxy
|
||||
*
|
||||
* @param string $address Proxy address, e.g. 'tcp://localhost:1080'
|
||||
* @param int $timeout Connection timeout (seconds)
|
||||
* @param array $contextOptions Stream context options
|
||||
* @param string $username Proxy user name
|
||||
* @param string $password Proxy password
|
||||
*
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function __construct(
|
||||
$address, $timeout = 10, array $contextOptions = array(),
|
||||
$username = null, $password = null
|
||||
) {
|
||||
parent::__construct($address, $timeout, $contextOptions);
|
||||
|
||||
if (strlen($username)) {
|
||||
$request = pack('C4', 5, 2, 0, 2);
|
||||
} else {
|
||||
$request = pack('C3', 5, 1, 0);
|
||||
}
|
||||
$this->write($request);
|
||||
$response = unpack('Cversion/Cmethod', $this->read(3));
|
||||
if (5 != $response['version']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Invalid version received from SOCKS5 proxy: ' . $response['version'],
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
switch ($response['method']) {
|
||||
case 2:
|
||||
$this->performAuthentication($username, $password);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Connection rejected by proxy due to unsupported auth method"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs username/password authentication for SOCKS5
|
||||
*
|
||||
* @param string $username Proxy user name
|
||||
* @param string $password Proxy password
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @link http://tools.ietf.org/html/rfc1929
|
||||
*/
|
||||
protected function performAuthentication($username, $password)
|
||||
{
|
||||
$request = pack('C2', 1, strlen($username)) . $username
|
||||
. pack('C', strlen($password)) . $password;
|
||||
|
||||
$this->write($request);
|
||||
$response = unpack('Cvn/Cstatus', $this->read(3));
|
||||
if (1 != $response['vn'] || 0 != $response['status']) {
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
'Connection rejected by proxy due to invalid username and/or password'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a remote host via proxy
|
||||
*
|
||||
* @param string $remoteHost Remote host
|
||||
* @param int $remotePort Remote port
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function connect($remoteHost, $remotePort)
|
||||
{
|
||||
$request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost))
|
||||
. $remoteHost . pack('n', $remotePort);
|
||||
|
||||
$this->write($request);
|
||||
$response = unpack('Cversion/Creply/Creserved', $this->read(1024));
|
||||
if (5 != $response['version'] || 0 != $response['reserved']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Invalid response received from SOCKS5 proxy',
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
} elseif (0 != $response['reply']) {
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy",
|
||||
0, $response['reply']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Socket wrapper class used by Socket Adapter
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2014 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Exception classes for HTTP_Request2 package */
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Socket wrapper class used by Socket Adapter
|
||||
*
|
||||
* Needed to properly handle connection errors, global timeout support and
|
||||
* similar things. Loosely based on Net_Socket used by older HTTP_Request.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.2.1
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/bugs/bug.php?id=19332
|
||||
* @link http://tools.ietf.org/html/rfc1928
|
||||
*/
|
||||
class HTTP_Request2_SocketWrapper
|
||||
{
|
||||
/**
|
||||
* PHP warning messages raised during stream_socket_client() call
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionWarnings = array();
|
||||
|
||||
/**
|
||||
* Connected socket
|
||||
* @var resource
|
||||
*/
|
||||
protected $socket;
|
||||
|
||||
/**
|
||||
* Sum of start time and global timeout, exception will be thrown if request continues past this time
|
||||
* @var integer
|
||||
*/
|
||||
protected $deadline;
|
||||
|
||||
/**
|
||||
* Global timeout value, mostly for exception messages
|
||||
* @var integer
|
||||
*/
|
||||
protected $timeout;
|
||||
|
||||
/**
|
||||
* Class constructor, tries to establish connection
|
||||
*
|
||||
* @param string $address Address for stream_socket_client() call,
|
||||
* e.g. 'tcp://localhost:80'
|
||||
* @param int $timeout Connection timeout (seconds)
|
||||
* @param array $contextOptions Context options
|
||||
*
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
*/
|
||||
public function __construct($address, $timeout, array $contextOptions = array())
|
||||
{
|
||||
if (!empty($contextOptions)
|
||||
&& !isset($contextOptions['socket']) && !isset($contextOptions['ssl'])
|
||||
) {
|
||||
// Backwards compatibility with 2.1.0 and 2.1.1 releases
|
||||
$contextOptions = array('ssl' => $contextOptions);
|
||||
}
|
||||
$context = stream_context_create();
|
||||
foreach ($contextOptions as $wrapper => $options) {
|
||||
foreach ($options as $name => $value) {
|
||||
if (!stream_context_set_option($context, $wrapper, $name, $value)) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Error setting '{$wrapper}' wrapper context option '{$name}'"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
set_error_handler(array($this, 'connectionWarningsHandler'));
|
||||
$this->socket = stream_socket_client(
|
||||
$address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context
|
||||
);
|
||||
restore_error_handler();
|
||||
// if we fail to bind to a specified local address (see request #19515),
|
||||
// connection still succeeds, albeit with a warning. Throw an Exception
|
||||
// with the warning text in this case as that connection is unlikely
|
||||
// to be what user wants and as Curl throws an error in similar case.
|
||||
if ($this->connectionWarnings) {
|
||||
if ($this->socket) {
|
||||
fclose($this->socket);
|
||||
}
|
||||
$error = $errstr ? $errstr : implode("\n", $this->connectionWarnings);
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Unable to connect to {$address}. Error: {$error}", 0, $errno
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, disconnects socket
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
fclose($this->socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around fread(), handles global request timeout
|
||||
*
|
||||
* @param int $length Reads up to this number of bytes
|
||||
*
|
||||
* @return string Data read from socket
|
||||
* @throws HTTP_Request2_MessageException In case of timeout
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
if ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
$data = fread($this->socket, $length);
|
||||
$this->checkTimeout();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads until either the end of the socket or a newline, whichever comes first
|
||||
*
|
||||
* Strips the trailing newline from the returned data, handles global
|
||||
* request timeout. Method idea borrowed from Net_Socket PEAR package.
|
||||
*
|
||||
* @param int $bufferSize buffer size to use for reading
|
||||
* @param int $localTimeout timeout value to use just for this call
|
||||
* (used when waiting for "100 Continue" response)
|
||||
*
|
||||
* @return string Available data up to the newline (not including newline)
|
||||
* @throws HTTP_Request2_MessageException In case of timeout
|
||||
*/
|
||||
public function readLine($bufferSize, $localTimeout = null)
|
||||
{
|
||||
$line = '';
|
||||
while (!feof($this->socket)) {
|
||||
if (null !== $localTimeout) {
|
||||
stream_set_timeout($this->socket, $localTimeout);
|
||||
} elseif ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
|
||||
$line .= @fgets($this->socket, $bufferSize);
|
||||
|
||||
if (null === $localTimeout) {
|
||||
$this->checkTimeout();
|
||||
|
||||
} else {
|
||||
$info = stream_get_meta_data($this->socket);
|
||||
// reset socket timeout if we don't have request timeout specified,
|
||||
// prevents further calls failing with a bogus Exception
|
||||
if (!$this->deadline) {
|
||||
$default = (int)@ini_get('default_socket_timeout');
|
||||
stream_set_timeout($this->socket, $default > 0 ? $default : PHP_INT_MAX);
|
||||
}
|
||||
if ($info['timed_out']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"readLine() call timed out", HTTP_Request2_Exception::TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
if (substr($line, -1) == "\n") {
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around fwrite(), handles global request timeout
|
||||
*
|
||||
* @param string $data String to be written
|
||||
*
|
||||
* @return int
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
if ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
$written = fwrite($this->socket, $data);
|
||||
$this->checkTimeout();
|
||||
// http://www.php.net/manual/en/function.fwrite.php#96951
|
||||
if ($written < strlen($data)) {
|
||||
throw new HTTP_Request2_MessageException('Error writing request');
|
||||
}
|
||||
return $written;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for end-of-file on a socket
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function eof()
|
||||
{
|
||||
return feof($this->socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets request deadline
|
||||
*
|
||||
* @param int $deadline Exception will be thrown if request continues
|
||||
* past this time
|
||||
* @param int $timeout Original request timeout value, to use in
|
||||
* Exception message
|
||||
*/
|
||||
public function setDeadline($deadline, $timeout)
|
||||
{
|
||||
$this->deadline = $deadline;
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on encryption on a socket
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
*/
|
||||
public function enableCrypto()
|
||||
{
|
||||
$modes = array(
|
||||
STREAM_CRYPTO_METHOD_TLS_CLIENT,
|
||||
STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
|
||||
STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
|
||||
STREAM_CRYPTO_METHOD_SSLv2_CLIENT
|
||||
);
|
||||
|
||||
foreach ($modes as $mode) {
|
||||
if (stream_socket_enable_crypto($this->socket, true, $mode)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
'Failed to enable secure connection when connecting through proxy'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an Exception if stream timed out
|
||||
*
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
protected function checkTimeout()
|
||||
{
|
||||
$info = stream_get_meta_data($this->socket);
|
||||
if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {
|
||||
$reason = $this->deadline
|
||||
? "after {$this->timeout} second(s)"
|
||||
: 'due to default_socket_timeout php.ini setting';
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler to use during stream_socket_client() call
|
||||
*
|
||||
* One stream_socket_client() call may produce *multiple* PHP warnings
|
||||
* (especially OpenSSL-related), we keep them in an array to later use for
|
||||
* the message of HTTP_Request2_ConnectionException
|
||||
*
|
||||
* @param int $errno error level
|
||||
* @param string $errstr error message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function connectionWarningsHandler($errno, $errstr)
|
||||
{
|
||||
if ($errno & E_WARNING) {
|
||||
array_unshift($this->connectionWarnings, $errstr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,389 +0,0 @@
|
|||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
|
||||
/**
|
||||
* PEAR_Exception
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id$
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 1.3.3
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base PEAR_Exception Class
|
||||
*
|
||||
* 1) Features:
|
||||
*
|
||||
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
|
||||
* - Definable triggers, shot when exceptions occur
|
||||
* - Pretty and informative error messages
|
||||
* - Added more context info available (like class, method or cause)
|
||||
* - cause can be a PEAR_Exception or an array of mixed
|
||||
* PEAR_Exceptions/PEAR_ErrorStack warnings
|
||||
* - callbacks for specific exception classes and their children
|
||||
*
|
||||
* 2) Ideas:
|
||||
*
|
||||
* - Maybe a way to define a 'template' for the output
|
||||
*
|
||||
* 3) Inherited properties from PHP Exception Class:
|
||||
*
|
||||
* protected $message
|
||||
* protected $code
|
||||
* protected $line
|
||||
* protected $file
|
||||
* private $trace
|
||||
*
|
||||
* 4) Inherited methods from PHP Exception Class:
|
||||
*
|
||||
* __clone
|
||||
* __construct
|
||||
* getMessage
|
||||
* getCode
|
||||
* getFile
|
||||
* getLine
|
||||
* getTraceSafe
|
||||
* getTraceSafeAsString
|
||||
* __toString
|
||||
*
|
||||
* 5) Usage example
|
||||
*
|
||||
* <code>
|
||||
* require_once 'PEAR/Exception.php';
|
||||
*
|
||||
* class Test {
|
||||
* function foo() {
|
||||
* throw new PEAR_Exception('Error Message', ERROR_CODE);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* function myLogger($pear_exception) {
|
||||
* echo $pear_exception->getMessage();
|
||||
* }
|
||||
* // each time a exception is thrown the 'myLogger' will be called
|
||||
* // (its use is completely optional)
|
||||
* PEAR_Exception::addObserver('myLogger');
|
||||
* $test = new Test;
|
||||
* try {
|
||||
* $test->foo();
|
||||
* } catch (PEAR_Exception $e) {
|
||||
* print $e;
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.5
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 1.3.3
|
||||
*
|
||||
*/
|
||||
class PEAR_Exception extends Exception
|
||||
{
|
||||
const OBSERVER_PRINT = -2;
|
||||
const OBSERVER_TRIGGER = -4;
|
||||
const OBSERVER_DIE = -8;
|
||||
protected $cause;
|
||||
private static $_observers = array();
|
||||
private static $_uniqueid = 0;
|
||||
private $_trace;
|
||||
|
||||
/**
|
||||
* Supported signatures:
|
||||
* - PEAR_Exception(string $message);
|
||||
* - PEAR_Exception(string $message, int $code);
|
||||
* - PEAR_Exception(string $message, Exception $cause);
|
||||
* - PEAR_Exception(string $message, Exception $cause, int $code);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
|
||||
* - PEAR_Exception(string $message, array $causes);
|
||||
* - PEAR_Exception(string $message, array $causes, int $code);
|
||||
* @param string exception message
|
||||
* @param int|Exception|PEAR_Error|array|null exception cause
|
||||
* @param int|null exception code or null
|
||||
*/
|
||||
public function __construct($message, $p2 = null, $p3 = null)
|
||||
{
|
||||
if (is_int($p2)) {
|
||||
$code = $p2;
|
||||
$this->cause = null;
|
||||
} elseif (is_object($p2) || is_array($p2)) {
|
||||
// using is_object allows both Exception and PEAR_Error
|
||||
if (is_object($p2) && !($p2 instanceof Exception)) {
|
||||
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
|
||||
throw new PEAR_Exception('exception cause must be Exception, ' .
|
||||
'array, or PEAR_Error');
|
||||
}
|
||||
}
|
||||
$code = $p3;
|
||||
if (is_array($p2) && isset($p2['message'])) {
|
||||
// fix potential problem of passing in a single warning
|
||||
$p2 = array($p2);
|
||||
}
|
||||
$this->cause = $p2;
|
||||
} else {
|
||||
$code = null;
|
||||
$this->cause = null;
|
||||
}
|
||||
parent::__construct($message, $code);
|
||||
$this->signal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $callback - A valid php callback, see php func is_callable()
|
||||
* - A PEAR_Exception::OBSERVER_* constant
|
||||
* - An array(const PEAR_Exception::OBSERVER_*,
|
||||
* mixed $options)
|
||||
* @param string $label The name of the observer. Use this if you want
|
||||
* to remove it later with removeObserver()
|
||||
*/
|
||||
public static function addObserver($callback, $label = 'default')
|
||||
{
|
||||
self::$_observers[$label] = $callback;
|
||||
}
|
||||
|
||||
public static function removeObserver($label = 'default')
|
||||
{
|
||||
unset(self::$_observers[$label]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int unique identifier for an observer
|
||||
*/
|
||||
public static function getUniqueId()
|
||||
{
|
||||
return self::$_uniqueid++;
|
||||
}
|
||||
|
||||
private function signal()
|
||||
{
|
||||
foreach (self::$_observers as $func) {
|
||||
if (is_callable($func)) {
|
||||
call_user_func($func, $this);
|
||||
continue;
|
||||
}
|
||||
settype($func, 'array');
|
||||
switch ($func[0]) {
|
||||
case self::OBSERVER_PRINT :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
printf($f, $this->getMessage());
|
||||
break;
|
||||
case self::OBSERVER_TRIGGER :
|
||||
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
|
||||
trigger_error($this->getMessage(), $f);
|
||||
break;
|
||||
case self::OBSERVER_DIE :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
die(printf($f, $this->getMessage()));
|
||||
break;
|
||||
default:
|
||||
trigger_error('invalid observer type', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return specific error information that can be used for more detailed
|
||||
* error messages or translation.
|
||||
*
|
||||
* This method may be overridden in child exception classes in order
|
||||
* to add functionality not present in PEAR_Exception and is a placeholder
|
||||
* to define API
|
||||
*
|
||||
* The returned array must be an associative array of parameter => value like so:
|
||||
* <pre>
|
||||
* array('name' => $name, 'context' => array(...))
|
||||
* </pre>
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorData()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception that caused this exception to be thrown
|
||||
* @access public
|
||||
* @return Exception|array The context of the exception
|
||||
*/
|
||||
public function getCause()
|
||||
{
|
||||
return $this->cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function must be public to call on caused exceptions
|
||||
* @param array
|
||||
*/
|
||||
public function getCauseMessage(&$causes)
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$cause = array('class' => get_class($this),
|
||||
'message' => $this->message,
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
if (isset($trace[0])) {
|
||||
if (isset($trace[0]['file'])) {
|
||||
$cause['file'] = $trace[0]['file'];
|
||||
$cause['line'] = $trace[0]['line'];
|
||||
}
|
||||
}
|
||||
$causes[] = $cause;
|
||||
if ($this->cause instanceof PEAR_Exception) {
|
||||
$this->cause->getCauseMessage($causes);
|
||||
} elseif ($this->cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => $this->cause->getFile(),
|
||||
'line' => $this->cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($this->cause)) {
|
||||
foreach ($this->cause as $cause) {
|
||||
if ($cause instanceof PEAR_Exception) {
|
||||
$cause->getCauseMessage($causes);
|
||||
} elseif ($cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => $cause->getFile(),
|
||||
'line' => $cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($cause) && isset($cause['message'])) {
|
||||
// PEAR_ErrorStack warning
|
||||
$causes[] = array(
|
||||
'class' => $cause['package'],
|
||||
'message' => $cause['message'],
|
||||
'file' => isset($cause['context']['file']) ?
|
||||
$cause['context']['file'] :
|
||||
'unknown',
|
||||
'line' => isset($cause['context']['line']) ?
|
||||
$cause['context']['line'] :
|
||||
'unknown',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTraceSafe()
|
||||
{
|
||||
if (!isset($this->_trace)) {
|
||||
$this->_trace = $this->getTrace();
|
||||
if (empty($this->_trace)) {
|
||||
$backtrace = debug_backtrace();
|
||||
$this->_trace = array($backtrace[count($backtrace)-1]);
|
||||
}
|
||||
}
|
||||
return $this->_trace;
|
||||
}
|
||||
|
||||
public function getErrorClass()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['class'];
|
||||
}
|
||||
|
||||
public function getErrorMethod()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['function'];
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_URI'])) {
|
||||
return $this->toHtml();
|
||||
}
|
||||
return $this->toText();
|
||||
}
|
||||
|
||||
public function toHtml()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
|
||||
foreach ($causes as $i => $cause) {
|
||||
$html .= '<tr><td colspan="3" style="background: #ff9999">'
|
||||
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
|
||||
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
|
||||
. 'on line <b>' . $cause['line'] . '</b>'
|
||||
. "</td></tr>\n";
|
||||
}
|
||||
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
|
||||
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
|
||||
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
|
||||
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
|
||||
|
||||
foreach ($trace as $k => $v) {
|
||||
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
|
||||
. '<td>';
|
||||
if (!empty($v['class'])) {
|
||||
$html .= $v['class'] . $v['type'];
|
||||
}
|
||||
$html .= $v['function'];
|
||||
$args = array();
|
||||
if (!empty($v['args'])) {
|
||||
foreach ($v['args'] as $arg) {
|
||||
if (is_null($arg)) $args[] = 'null';
|
||||
elseif (is_array($arg)) $args[] = 'Array';
|
||||
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
|
||||
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
|
||||
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
|
||||
else {
|
||||
$arg = (string)$arg;
|
||||
$str = htmlspecialchars(substr($arg, 0, 16));
|
||||
if (strlen($arg) > 16) $str .= '…';
|
||||
$args[] = "'" . $str . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
$html .= '(' . implode(', ',$args) . ')'
|
||||
. '</td>'
|
||||
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
|
||||
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
|
||||
. '</td></tr>' . "\n";
|
||||
}
|
||||
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
|
||||
. '<td>{main}</td>'
|
||||
. '<td> </td></tr>' . "\n"
|
||||
. '</table>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function toText()
|
||||
{
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$causeMsg = '';
|
||||
foreach ($causes as $i => $cause) {
|
||||
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
|
||||
. $cause['message'] . ' in ' . $cause['file']
|
||||
. ' on line ' . $cause['line'] . "\n";
|
||||
}
|
||||
return $causeMsg . $this->getTraceAsString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This is only meant for PHP 5 to get rid of certain strict warning
|
||||
* that doesn't get hidden since it's in the shutdown function
|
||||
*/
|
||||
class PEAR5
|
||||
{
|
||||
/**
|
||||
* If you have a class that's mostly/entirely static, and you need static
|
||||
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
|
||||
* You MUST use a reference, or they will not persist!
|
||||
*
|
||||
* @access public
|
||||
* @param string $class The calling classname, to prevent clashes
|
||||
* @param string $var The variable to retrieve.
|
||||
* @return mixed A reference to the variable. If not set it will be
|
||||
* auto initialised to NULL.
|
||||
*/
|
||||
static function &getStaticProperty($class, $var)
|
||||
{
|
||||
static $properties;
|
||||
if (!isset($properties[$class])) {
|
||||
$properties[$class] = array();
|
||||
}
|
||||
|
||||
if (!array_key_exists($var, $properties[$class])) {
|
||||
$properties[$class][$var] = null;
|
||||
}
|
||||
|
||||
return $properties[$class][$var];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
class HTTP_Request extends HTTP_Request2
|
||||
{
|
||||
private $reponse = null;
|
||||
|
||||
public function addHeader($name, $value)
|
||||
{
|
||||
$this->setHeader($name, $value);
|
||||
}
|
||||
|
||||
public function sendRequest($saveBody = true)
|
||||
{
|
||||
$response = $this->send();
|
||||
$this->response = $response;
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getResponseCode() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseHeader() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getHeader();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseBody() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getBody();
|
||||
}
|
||||
}
|
||||
|
||||
public function getResponseCookies() {
|
||||
if($this->response)
|
||||
{
|
||||
return $this->response->getCookies();
|
||||
}
|
||||
}
|
||||
|
||||
public function addPostData($name, $value, $preencoded = false)
|
||||
{
|
||||
$this->addPostParameter($name, $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,861 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Class representing a HTTP request message
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Request2.php 298246 2010-04-21 10:41:16Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class representing an URL as per RFC 3986.
|
||||
*/
|
||||
require_once 'Net/URL2.php';
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class representing a HTTP request message
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-5
|
||||
*/
|
||||
class HTTP_Request2 implements SplSubject
|
||||
{
|
||||
/**#@+
|
||||
* Constants for HTTP request methods
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-5.1.1
|
||||
*/
|
||||
const METHOD_OPTIONS = 'OPTIONS';
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_HEAD = 'HEAD';
|
||||
const METHOD_POST = 'POST';
|
||||
const METHOD_PUT = 'PUT';
|
||||
const METHOD_DELETE = 'DELETE';
|
||||
const METHOD_TRACE = 'TRACE';
|
||||
const METHOD_CONNECT = 'CONNECT';
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* Constants for HTTP authentication schemes
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc2617
|
||||
*/
|
||||
const AUTH_BASIC = 'basic';
|
||||
const AUTH_DIGEST = 'digest';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Regular expression used to check for invalid symbols in RFC 2616 tokens
|
||||
* @link http://pear.php.net/bugs/bug.php?id=15630
|
||||
*/
|
||||
const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';
|
||||
|
||||
/**
|
||||
* Regular expression used to check for invalid symbols in cookie strings
|
||||
* @link http://pear.php.net/bugs/bug.php?id=15630
|
||||
* @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
|
||||
*/
|
||||
const REGEXP_INVALID_COOKIE = '/[\s,;]/';
|
||||
|
||||
/**
|
||||
* Fileinfo magic database resource
|
||||
* @var resource
|
||||
* @see detectMimeType()
|
||||
*/
|
||||
private static $_fileinfoDb;
|
||||
|
||||
/**
|
||||
* Observers attached to the request (instances of SplObserver)
|
||||
* @var array
|
||||
*/
|
||||
protected $observers = array();
|
||||
|
||||
/**
|
||||
* Request URL
|
||||
* @var Net_URL2
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Request method
|
||||
* @var string
|
||||
*/
|
||||
protected $method = self::METHOD_GET;
|
||||
|
||||
/**
|
||||
* Authentication data
|
||||
* @var array
|
||||
* @see getAuth()
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Request headers
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Configuration parameters
|
||||
* @var array
|
||||
* @see setConfig()
|
||||
*/
|
||||
protected $config = array(
|
||||
'adapter' => 'HTTP_Request2_Adapter_Socket',
|
||||
'connect_timeout' => 10,
|
||||
'timeout' => 0,
|
||||
'use_brackets' => true,
|
||||
'protocol_version' => '1.1',
|
||||
'buffer_size' => 16384,
|
||||
'store_body' => true,
|
||||
|
||||
'proxy_host' => '',
|
||||
'proxy_port' => '',
|
||||
'proxy_user' => '',
|
||||
'proxy_password' => '',
|
||||
'proxy_auth_scheme' => self::AUTH_BASIC,
|
||||
|
||||
'ssl_verify_peer' => true,
|
||||
'ssl_verify_host' => true,
|
||||
'ssl_cafile' => null,
|
||||
'ssl_capath' => null,
|
||||
'ssl_local_cert' => null,
|
||||
'ssl_passphrase' => null,
|
||||
|
||||
'digest_compat_ie' => false,
|
||||
|
||||
'follow_redirects' => false,
|
||||
'max_redirects' => 5,
|
||||
'strict_redirects' => false
|
||||
);
|
||||
|
||||
/**
|
||||
* Last event in request / response handling, intended for observers
|
||||
* @var array
|
||||
* @see getLastEvent()
|
||||
*/
|
||||
protected $lastEvent = array(
|
||||
'name' => 'start',
|
||||
'data' => null
|
||||
);
|
||||
|
||||
/**
|
||||
* Request body
|
||||
* @var string|resource
|
||||
* @see setBody()
|
||||
*/
|
||||
protected $body = '';
|
||||
|
||||
/**
|
||||
* Array of POST parameters
|
||||
* @var array
|
||||
*/
|
||||
protected $postParams = array();
|
||||
|
||||
/**
|
||||
* Array of file uploads (for multipart/form-data POST requests)
|
||||
* @var array
|
||||
*/
|
||||
protected $uploads = array();
|
||||
|
||||
/**
|
||||
* Adapter used to perform actual HTTP request
|
||||
* @var HTTP_Request2_Adapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor. Can set request URL, method and configuration array.
|
||||
*
|
||||
* Also sets a default value for User-Agent header.
|
||||
*
|
||||
* @param string|Net_Url2 Request URL
|
||||
* @param string Request method
|
||||
* @param array Configuration for this Request instance
|
||||
*/
|
||||
public function __construct($url = null, $method = self::METHOD_GET, array $config = array())
|
||||
{
|
||||
$this->setConfig($config);
|
||||
if (!empty($url)) {
|
||||
$this->setUrl($url);
|
||||
}
|
||||
if (!empty($method)) {
|
||||
$this->setMethod($method);
|
||||
}
|
||||
$this->setHeader('user-agent', 'HTTP_Request2/0.5.2 ' .
|
||||
'(http://pear.php.net/package/http_request2) ' .
|
||||
'PHP/' . phpversion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL for this request
|
||||
*
|
||||
* If the URL has userinfo part (username & password) these will be removed
|
||||
* and converted to auth data. If the URL does not have a path component,
|
||||
* that will be set to '/'.
|
||||
*
|
||||
* @param string|Net_URL2 Request URL
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
if (is_string($url)) {
|
||||
$url = new Net_URL2(
|
||||
$url, array(Net_URL2::OPTION_USE_BRACKETS => $this->config['use_brackets'])
|
||||
);
|
||||
}
|
||||
if (!$url instanceof Net_URL2) {
|
||||
throw new HTTP_Request2_Exception('Parameter is not a valid HTTP URL');
|
||||
}
|
||||
// URL contains username / password?
|
||||
if ($url->getUserinfo()) {
|
||||
$username = $url->getUser();
|
||||
$password = $url->getPassword();
|
||||
$this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
|
||||
$url->setUserinfo('');
|
||||
}
|
||||
if ('' == $url->getPath()) {
|
||||
$url->setPath('/');
|
||||
}
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request URL
|
||||
*
|
||||
* @return Net_URL2
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request method
|
||||
*
|
||||
* @param string
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception if the method name is invalid
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
// Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
|
||||
if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
|
||||
throw new HTTP_Request2_Exception("Invalid request method '{$method}'");
|
||||
}
|
||||
$this->method = $method;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration parameter(s)
|
||||
*
|
||||
* The following parameters are available:
|
||||
* <ul>
|
||||
* <li> 'adapter' - adapter to use (string)</li>
|
||||
* <li> 'connect_timeout' - Connection timeout in seconds (integer)</li>
|
||||
* <li> 'timeout' - Total number of seconds a request can take.
|
||||
* Use 0 for no limit, should be greater than
|
||||
* 'connect_timeout' if set (integer)</li>
|
||||
* <li> 'use_brackets' - Whether to append [] to array variable names (bool)</li>
|
||||
* <li> 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)</li>
|
||||
* <li> 'buffer_size' - Buffer size to use for reading and writing (int)</li>
|
||||
* <li> 'store_body' - Whether to store response body in response object.
|
||||
* Set to false if receiving a huge response and
|
||||
* using an Observer to save it (boolean)</li>
|
||||
* <li> 'proxy_host' - Proxy server host (string)</li>
|
||||
* <li> 'proxy_port' - Proxy server port (integer)</li>
|
||||
* <li> 'proxy_user' - Proxy auth username (string)</li>
|
||||
* <li> 'proxy_password' - Proxy auth password (string)</li>
|
||||
* <li> 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)</li>
|
||||
* <li> 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)</li>
|
||||
* <li> 'ssl_verify_host' - Whether to check that Common Name in SSL
|
||||
* certificate matches host name (bool)</li>
|
||||
* <li> 'ssl_cafile' - Cerificate Authority file to verify the peer
|
||||
* with (use with 'ssl_verify_peer') (string)</li>
|
||||
* <li> 'ssl_capath' - Directory holding multiple Certificate
|
||||
* Authority files (string)</li>
|
||||
* <li> 'ssl_local_cert' - Name of a file containing local cerificate (string)</li>
|
||||
* <li> 'ssl_passphrase' - Passphrase with which local certificate
|
||||
* was encoded (string)</li>
|
||||
* <li> 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6
|
||||
* in using URL without query string in digest
|
||||
* authentication (boolean)</li>
|
||||
* <li> 'follow_redirects' - Whether to automatically follow HTTP Redirects (boolean)</li>
|
||||
* <li> 'max_redirects' - Maximum number of redirects to follow (integer)</li>
|
||||
* <li> 'strict_redirects' - Whether to keep request method on redirects via status 301 and
|
||||
* 302 (true, needed for compatibility with RFC 2616)
|
||||
* or switch to GET (false, needed for compatibility with most
|
||||
* browsers) (boolean)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param string|array configuration parameter name or array
|
||||
* ('parameter name' => 'parameter value')
|
||||
* @param mixed parameter value if $nameOrConfig is not an array
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception If the parameter is unknown
|
||||
*/
|
||||
public function setConfig($nameOrConfig, $value = null)
|
||||
{
|
||||
if (is_array($nameOrConfig)) {
|
||||
foreach ($nameOrConfig as $name => $value) {
|
||||
$this->setConfig($name, $value);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!array_key_exists($nameOrConfig, $this->config)) {
|
||||
throw new HTTP_Request2_Exception(
|
||||
"Unknown configuration parameter '{$nameOrConfig}'"
|
||||
);
|
||||
}
|
||||
$this->config[$nameOrConfig] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value(s) of the configuration parameter(s)
|
||||
*
|
||||
* @param string parameter name
|
||||
* @return mixed value of $name parameter, array of all configuration
|
||||
* parameters if $name is not given
|
||||
* @throws HTTP_Request2_Exception If the parameter is unknown
|
||||
*/
|
||||
public function getConfig($name = null)
|
||||
{
|
||||
if (null === $name) {
|
||||
return $this->config;
|
||||
} elseif (!array_key_exists($name, $this->config)) {
|
||||
throw new HTTP_Request2_Exception(
|
||||
"Unknown configuration parameter '{$name}'"
|
||||
);
|
||||
}
|
||||
return $this->config[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autentification data
|
||||
*
|
||||
* @param string user name
|
||||
* @param string password
|
||||
* @param string authentication scheme
|
||||
* @return HTTP_Request2
|
||||
*/
|
||||
public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
|
||||
{
|
||||
if (empty($user)) {
|
||||
$this->auth = null;
|
||||
} else {
|
||||
$this->auth = array(
|
||||
'user' => (string)$user,
|
||||
'password' => (string)$password,
|
||||
'scheme' => $scheme
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication data
|
||||
*
|
||||
* The array has the keys 'user', 'password' and 'scheme', where 'scheme'
|
||||
* is one of the HTTP_Request2::AUTH_* constants.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAuth()
|
||||
{
|
||||
return $this->auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets request header(s)
|
||||
*
|
||||
* The first parameter may be either a full header string 'header: value' or
|
||||
* header name. In the former case $value parameter is ignored, in the latter
|
||||
* the header's value will either be set to $value or the header will be
|
||||
* removed if $value is null. The first parameter can also be an array of
|
||||
* headers, in that case method will be called recursively.
|
||||
*
|
||||
* Note that headers are treated case insensitively as per RFC 2616.
|
||||
*
|
||||
* <code>
|
||||
* $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
|
||||
* $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
|
||||
* $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
|
||||
* $req->setHeader('FOO'); // removes 'Foo' header from request
|
||||
* </code>
|
||||
*
|
||||
* @param string|array header name, header string ('Header: value')
|
||||
* or an array of headers
|
||||
* @param string|null header value, header will be removed if null
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function setHeader($name, $value = null)
|
||||
{
|
||||
if (is_array($name)) {
|
||||
foreach ($name as $k => $v) {
|
||||
if (is_string($k)) {
|
||||
$this->setHeader($k, $v);
|
||||
} else {
|
||||
$this->setHeader($v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (null === $value && strpos($name, ':')) {
|
||||
list($name, $value) = array_map('trim', explode(':', $name, 2));
|
||||
}
|
||||
// Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
|
||||
if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
|
||||
throw new HTTP_Request2_Exception("Invalid header name '{$name}'");
|
||||
}
|
||||
// Header names are case insensitive anyway
|
||||
$name = strtolower($name);
|
||||
if (null === $value) {
|
||||
unset($this->headers[$name]);
|
||||
} else {
|
||||
$this->headers[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request headers
|
||||
*
|
||||
* The array is of the form ('header name' => 'header value'), header names
|
||||
* are lowercased
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a cookie to "Cookie:" header
|
||||
*
|
||||
* @param string cookie name
|
||||
* @param string cookie value
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function addCookie($name, $value)
|
||||
{
|
||||
$cookie = $name . '=' . $value;
|
||||
if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
|
||||
throw new HTTP_Request2_Exception("Invalid cookie: '{$cookie}'");
|
||||
}
|
||||
$cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
|
||||
$this->setHeader('cookie', $cookies . $cookie);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request body
|
||||
*
|
||||
* @param string Either a string with the body or filename containing body
|
||||
* @param bool Whether first parameter is a filename
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function setBody($body, $isFilename = false)
|
||||
{
|
||||
if (!$isFilename) {
|
||||
if (!$body instanceof HTTP_Request2_MultipartBody) {
|
||||
$this->body = (string)$body;
|
||||
} else {
|
||||
$this->body = $body;
|
||||
}
|
||||
} else {
|
||||
if (!($fp = @fopen($body, 'rb'))) {
|
||||
throw new HTTP_Request2_Exception("Cannot open file {$body}");
|
||||
}
|
||||
$this->body = $fp;
|
||||
if (empty($this->headers['content-type'])) {
|
||||
$this->setHeader('content-type', self::detectMimeType($body));
|
||||
}
|
||||
}
|
||||
$this->postParams = $this->uploads = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request body
|
||||
*
|
||||
* @return string|resource|HTTP_Request2_MultipartBody
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
if (self::METHOD_POST == $this->method &&
|
||||
(!empty($this->postParams) || !empty($this->uploads))
|
||||
) {
|
||||
if ('application/x-www-form-urlencoded' == $this->headers['content-type']) {
|
||||
$body = http_build_query($this->postParams, '', '&');
|
||||
if (!$this->getConfig('use_brackets')) {
|
||||
$body = preg_replace('/%5B\d+%5D=/', '=', $body);
|
||||
}
|
||||
// support RFC 3986 by not encoding '~' symbol (request #15368)
|
||||
return str_replace('%7E', '~', $body);
|
||||
|
||||
} elseif ('multipart/form-data' == $this->headers['content-type']) {
|
||||
require_once 'HTTP/Request2/MultipartBody.php';
|
||||
return new HTTP_Request2_MultipartBody(
|
||||
$this->postParams, $this->uploads, $this->getConfig('use_brackets')
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to form-based file upload
|
||||
*
|
||||
* Used to emulate file upload via a HTML form. The method also sets
|
||||
* Content-Type of HTTP request to 'multipart/form-data'.
|
||||
*
|
||||
* If you just want to send the contents of a file as the body of HTTP
|
||||
* request you should use setBody() method.
|
||||
*
|
||||
* @param string name of file-upload field
|
||||
* @param mixed full name of local file
|
||||
* @param string filename to send in the request
|
||||
* @param string content-type of file being uploaded
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function addUpload($fieldName, $filename, $sendFilename = null,
|
||||
$contentType = null)
|
||||
{
|
||||
if (!is_array($filename)) {
|
||||
if (!($fp = @fopen($filename, 'rb'))) {
|
||||
throw new HTTP_Request2_Exception("Cannot open file {$filename}");
|
||||
}
|
||||
$this->uploads[$fieldName] = array(
|
||||
'fp' => $fp,
|
||||
'filename' => empty($sendFilename)? basename($filename): $sendFilename,
|
||||
'size' => filesize($filename),
|
||||
'type' => empty($contentType)? self::detectMimeType($filename): $contentType
|
||||
);
|
||||
} else {
|
||||
$fps = $names = $sizes = $types = array();
|
||||
foreach ($filename as $f) {
|
||||
if (!is_array($f)) {
|
||||
$f = array($f);
|
||||
}
|
||||
if (!($fp = @fopen($f[0], 'rb'))) {
|
||||
throw new HTTP_Request2_Exception("Cannot open file {$f[0]}");
|
||||
}
|
||||
$fps[] = $fp;
|
||||
$names[] = empty($f[1])? basename($f[0]): $f[1];
|
||||
$sizes[] = filesize($f[0]);
|
||||
$types[] = empty($f[2])? self::detectMimeType($f[0]): $f[2];
|
||||
}
|
||||
$this->uploads[$fieldName] = array(
|
||||
'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
|
||||
);
|
||||
}
|
||||
if (empty($this->headers['content-type']) ||
|
||||
'application/x-www-form-urlencoded' == $this->headers['content-type']
|
||||
) {
|
||||
$this->setHeader('content-type', 'multipart/form-data');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds POST parameter(s) to the request.
|
||||
*
|
||||
* @param string|array parameter name or array ('name' => 'value')
|
||||
* @param mixed parameter value (can be an array)
|
||||
* @return HTTP_Request2
|
||||
*/
|
||||
public function addPostParameter($name, $value = null)
|
||||
{
|
||||
if (!is_array($name)) {
|
||||
$this->postParams[$name] = $value;
|
||||
} else {
|
||||
foreach ($name as $k => $v) {
|
||||
$this->addPostParameter($k, $v);
|
||||
}
|
||||
}
|
||||
if (empty($this->headers['content-type'])) {
|
||||
$this->setHeader('content-type', 'application/x-www-form-urlencoded');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a new observer
|
||||
*
|
||||
* @param SplObserver
|
||||
*/
|
||||
public function attach(SplObserver $observer)
|
||||
{
|
||||
foreach ($this->observers as $attached) {
|
||||
if ($attached === $observer) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->observers[] = $observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches an existing observer
|
||||
*
|
||||
* @param SplObserver
|
||||
*/
|
||||
public function detach(SplObserver $observer)
|
||||
{
|
||||
foreach ($this->observers as $key => $attached) {
|
||||
if ($attached === $observer) {
|
||||
unset($this->observers[$key]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all observers
|
||||
*/
|
||||
public function notify()
|
||||
{
|
||||
foreach ($this->observers as $observer) {
|
||||
$observer->update($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last event
|
||||
*
|
||||
* Adapters should use this method to set the current state of the request
|
||||
* and notify the observers.
|
||||
*
|
||||
* @param string event name
|
||||
* @param mixed event data
|
||||
*/
|
||||
public function setLastEvent($name, $data = null)
|
||||
{
|
||||
$this->lastEvent = array(
|
||||
'name' => $name,
|
||||
'data' => $data
|
||||
);
|
||||
$this->notify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last event
|
||||
*
|
||||
* Observers should use this method to access the last change in request.
|
||||
* The following event names are possible:
|
||||
* <ul>
|
||||
* <li>'connect' - after connection to remote server,
|
||||
* data is the destination (string)</li>
|
||||
* <li>'disconnect' - after disconnection from server</li>
|
||||
* <li>'sentHeaders' - after sending the request headers,
|
||||
* data is the headers sent (string)</li>
|
||||
* <li>'sentBodyPart' - after sending a part of the request body,
|
||||
* data is the length of that part (int)</li>
|
||||
* <li>'receivedHeaders' - after receiving the response headers,
|
||||
* data is HTTP_Request2_Response object</li>
|
||||
* <li>'receivedBodyPart' - after receiving a part of the response
|
||||
* body, data is that part (string)</li>
|
||||
* <li>'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
|
||||
* encoded by Content-Encoding</li>
|
||||
* <li>'receivedBody' - after receiving the complete response
|
||||
* body, data is HTTP_Request2_Response object</li>
|
||||
* </ul>
|
||||
* Different adapters may not send all the event types. Mock adapter does
|
||||
* not send any events to the observers.
|
||||
*
|
||||
* @return array The array has two keys: 'name' and 'data'
|
||||
*/
|
||||
public function getLastEvent()
|
||||
{
|
||||
return $this->lastEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the adapter used to actually perform the request
|
||||
*
|
||||
* You can pass either an instance of a class implementing HTTP_Request2_Adapter
|
||||
* or a class name. The method will only try to include a file if the class
|
||||
* name starts with HTTP_Request2_Adapter_, it will also try to prepend this
|
||||
* prefix to the class name if it doesn't contain any underscores, so that
|
||||
* <code>
|
||||
* $request->setAdapter('curl');
|
||||
* </code>
|
||||
* will work.
|
||||
*
|
||||
* @param string|HTTP_Request2_Adapter
|
||||
* @return HTTP_Request2
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function setAdapter($adapter)
|
||||
{
|
||||
if (is_string($adapter)) {
|
||||
if (!class_exists($adapter, false)) {
|
||||
if (false === strpos($adapter, '_')) {
|
||||
$adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
|
||||
}
|
||||
if (preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)) {
|
||||
include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
|
||||
}
|
||||
if (!class_exists($adapter, false)) {
|
||||
throw new HTTP_Request2_Exception("Class {$adapter} not found");
|
||||
}
|
||||
}
|
||||
$adapter = new $adapter;
|
||||
}
|
||||
if (!$adapter instanceof HTTP_Request2_Adapter) {
|
||||
throw new HTTP_Request2_Exception('Parameter is not a HTTP request adapter');
|
||||
}
|
||||
$this->adapter = $adapter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the request and returns the response
|
||||
*
|
||||
* @throws HTTP_Request2_Exception
|
||||
* @return HTTP_Request2_Response
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
// Sanity check for URL
|
||||
if (!$this->url instanceof Net_URL2) {
|
||||
throw new HTTP_Request2_Exception('No URL given');
|
||||
} elseif (!$this->url->isAbsolute()) {
|
||||
throw new HTTP_Request2_Exception('Absolute URL required');
|
||||
} elseif (!in_array(strtolower($this->url->getScheme()), array('https', 'http'))) {
|
||||
throw new HTTP_Request2_Exception('Not a HTTP URL');
|
||||
}
|
||||
if (empty($this->adapter)) {
|
||||
$this->setAdapter($this->getConfig('adapter'));
|
||||
}
|
||||
// magic_quotes_runtime may break file uploads and chunked response
|
||||
// processing; see bug #4543. Don't use ini_get() here; see bug #16440.
|
||||
if ($magicQuotes = get_magic_quotes_runtime()) {
|
||||
set_magic_quotes_runtime(false);
|
||||
}
|
||||
// force using single byte encoding if mbstring extension overloads
|
||||
// strlen() and substr(); see bug #1781, bug #10605
|
||||
if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
|
||||
$oldEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('iso-8859-1');
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->adapter->sendRequest($this);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
// cleanup in either case (poor man's "finally" clause)
|
||||
if ($magicQuotes) {
|
||||
set_magic_quotes_runtime(true);
|
||||
}
|
||||
if (!empty($oldEncoding)) {
|
||||
mb_internal_encoding($oldEncoding);
|
||||
}
|
||||
// rethrow the exception
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to detect MIME type of a file
|
||||
*
|
||||
* The method will try to use fileinfo extension if it is available,
|
||||
* deprecated mime_content_type() function in the other case. If neither
|
||||
* works, default 'application/octet-stream' MIME type is returned
|
||||
*
|
||||
* @param string filename
|
||||
* @return string file MIME type
|
||||
*/
|
||||
protected static function detectMimeType($filename)
|
||||
{
|
||||
// finfo extension from PECL available
|
||||
if (function_exists('finfo_open')) {
|
||||
if (!isset(self::$_fileinfoDb)) {
|
||||
self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
|
||||
}
|
||||
if (self::$_fileinfoDb) {
|
||||
$info = finfo_file(self::$_fileinfoDb, $filename);
|
||||
}
|
||||
}
|
||||
// (deprecated) mime_content_type function available
|
||||
if (empty($info) && function_exists('mime_content_type')) {
|
||||
return mime_content_type($filename);
|
||||
}
|
||||
return empty($info)? 'application/octet-stream': $info;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Adapter.php 291118 2009-11-21 17:58:23Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*/
|
||||
require_once 'HTTP/Request2/Response.php';
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* HTTP_Request2 class itself only defines methods for aggregating the request
|
||||
* data, all actual work of sending the request to the remote server and
|
||||
* receiving its response is performed by adapters.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
abstract class HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A list of methods that MUST NOT have a request body, per RFC 2616
|
||||
* @var array
|
||||
*/
|
||||
protected static $bodyDisallowed = array('TRACE');
|
||||
|
||||
/**
|
||||
* Methods having defined semantics for request body
|
||||
*
|
||||
* Content-Length header (indicating that the body follows, section 4.3 of
|
||||
* RFC 2616) will be sent for these methods even if no body was added
|
||||
*
|
||||
* @var array
|
||||
* @link http://pear.php.net/bugs/bug.php?id=12900
|
||||
* @link http://pear.php.net/bugs/bug.php?id=14740
|
||||
*/
|
||||
protected static $bodyRequired = array('POST', 'PUT');
|
||||
|
||||
/**
|
||||
* Request being sent
|
||||
* @var HTTP_Request2
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Request body
|
||||
* @var string|resource|HTTP_Request2_MultipartBody
|
||||
* @see HTTP_Request2::getBody()
|
||||
*/
|
||||
protected $requestBody;
|
||||
|
||||
/**
|
||||
* Length of the request body
|
||||
* @var integer
|
||||
*/
|
||||
protected $contentLength;
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
abstract public function sendRequest(HTTP_Request2 $request);
|
||||
|
||||
/**
|
||||
* Calculates length of the request body, adds proper headers
|
||||
*
|
||||
* @param array associative array of request headers, this method will
|
||||
* add proper 'Content-Length' and 'Content-Type' headers
|
||||
* to this array (or remove them if not needed)
|
||||
*/
|
||||
protected function calculateRequestLength(&$headers)
|
||||
{
|
||||
$this->requestBody = $this->request->getBody();
|
||||
|
||||
if (is_string($this->requestBody)) {
|
||||
$this->contentLength = strlen($this->requestBody);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$stat = fstat($this->requestBody);
|
||||
$this->contentLength = $stat['size'];
|
||||
rewind($this->requestBody);
|
||||
} else {
|
||||
$this->contentLength = $this->requestBody->getLength();
|
||||
$headers['content-type'] = 'multipart/form-data; boundary=' .
|
||||
$this->requestBody->getBoundary();
|
||||
$this->requestBody->rewind();
|
||||
}
|
||||
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
|
||||
0 == $this->contentLength
|
||||
) {
|
||||
// No body: send a Content-Length header nonetheless (request #12900),
|
||||
// but do that only for methods that require a body (bug #14740)
|
||||
if (in_array($this->request->getMethod(), self::$bodyRequired)) {
|
||||
$headers['content-length'] = 0;
|
||||
} else {
|
||||
unset($headers['content-length']);
|
||||
// if the method doesn't require a body and doesn't have a
|
||||
// body, don't send a Content-Type header. (request #16799)
|
||||
unset($headers['content-type']);
|
||||
}
|
||||
} else {
|
||||
if (empty($headers['content-type'])) {
|
||||
$headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
$headers['content-length'] = $this->contentLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,461 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Curl.php 291118 2009-11-21 17:58:23Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* Mapping of header names to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $headerMap = array(
|
||||
'accept-encoding' => CURLOPT_ENCODING,
|
||||
'cookie' => CURLOPT_COOKIE,
|
||||
'referer' => CURLOPT_REFERER,
|
||||
'user-agent' => CURLOPT_USERAGENT
|
||||
);
|
||||
|
||||
/**
|
||||
* Mapping of SSL context options to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $sslContextMap = array(
|
||||
'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
|
||||
'ssl_cafile' => CURLOPT_CAINFO,
|
||||
'ssl_capath' => CURLOPT_CAPATH,
|
||||
'ssl_local_cert' => CURLOPT_SSLCERT,
|
||||
'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
|
||||
);
|
||||
|
||||
/**
|
||||
* Response being received
|
||||
* @var HTTP_Request2_Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Whether 'sentHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventSentHeaders = false;
|
||||
|
||||
/**
|
||||
* Whether 'receivedHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventReceivedHeaders = false;
|
||||
|
||||
/**
|
||||
* Position within request body
|
||||
* @var integer
|
||||
* @see callbackReadBody()
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Information about last transfer, as returned by curl_getinfo()
|
||||
* @var array
|
||||
*/
|
||||
protected $lastInfo;
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new HTTP_Request2_Exception('cURL extension not available');
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->response = null;
|
||||
$this->position = 0;
|
||||
$this->eventSentHeaders = false;
|
||||
$this->eventReceivedHeaders = false;
|
||||
|
||||
try {
|
||||
if (false === curl_exec($ch = $this->createCurlHandle())) {
|
||||
$errorMessage = 'Error sending request: #' . curl_errno($ch) .
|
||||
' ' . curl_error($ch);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
$this->lastInfo = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$response = $this->response;
|
||||
unset($this->request, $this->requestBody, $this->response);
|
||||
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
} elseif (!empty($errorMessage)) {
|
||||
throw new HTTP_Request2_Exception($errorMessage);
|
||||
}
|
||||
|
||||
if (0 < $this->lastInfo['size_download']) {
|
||||
$request->setLastEvent('receivedBody', $response);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about last transfer
|
||||
*
|
||||
* @return array associative array as returned by curl_getinfo()
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->lastInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cURL handle and populates it with data from the request
|
||||
*
|
||||
* @return resource a cURL handle, as created by curl_init()
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
protected function createCurlHandle()
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
// setup write callbacks
|
||||
CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
|
||||
CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
|
||||
// buffer size
|
||||
CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
|
||||
// connection timeout
|
||||
CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
|
||||
// save full outgoing headers, in case someone is interested
|
||||
CURLINFO_HEADER_OUT => true,
|
||||
// request url
|
||||
CURLOPT_URL => $this->request->getUrl()->getUrl()
|
||||
));
|
||||
|
||||
// set up redirects
|
||||
if (!$this->request->getConfig('follow_redirects')) {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects'));
|
||||
// limit redirects to http(s), works in 5.2.10+
|
||||
if (defined('CURLOPT_REDIR_PROTOCOLS')) {
|
||||
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
// works sometime after 5.3.0, http://bugs.php.net/bug.php?id=49571
|
||||
if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR ')) {
|
||||
curl_setopt($ch, CURLOPT_POSTREDIR, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// request timeout
|
||||
if ($timeout = $this->request->getConfig('timeout')) {
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
}
|
||||
|
||||
// set HTTP version
|
||||
switch ($this->request->getConfig('protocol_version')) {
|
||||
case '1.0':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
break;
|
||||
case '1.1':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
}
|
||||
|
||||
// set request method
|
||||
switch ($this->request->getMethod()) {
|
||||
case HTTP_Request2::METHOD_GET:
|
||||
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_POST:
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_HEAD:
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
break;
|
||||
default:
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
|
||||
}
|
||||
|
||||
// set proxy, if needed
|
||||
if ($host = $this->request->getConfig('proxy_host')) {
|
||||
if (!($port = $this->request->getConfig('proxy_port'))) {
|
||||
throw new HTTP_Request2_Exception('Proxy port not provided');
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
|
||||
if ($user = $this->request->getConfig('proxy_user')) {
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $user . ':' .
|
||||
$this->request->getConfig('proxy_password'));
|
||||
switch ($this->request->getConfig('proxy_auth_scheme')) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set authentication data
|
||||
if ($auth = $this->request->getAuth()) {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
|
||||
switch ($auth['scheme']) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
|
||||
// set SSL options
|
||||
if (0 == strcasecmp($this->request->getUrl()->getScheme(), 'https')) {
|
||||
foreach ($this->request->getConfig() as $name => $value) {
|
||||
if ('ssl_verify_host' == $name && null !== $value) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
|
||||
} elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
|
||||
curl_setopt($ch, self::$sslContextMap[$name], $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->request->getHeaders();
|
||||
// make cURL automagically send proper header
|
||||
if (!isset($headers['accept-encoding'])) {
|
||||
$headers['accept-encoding'] = '';
|
||||
}
|
||||
|
||||
// set headers having special cURL keys
|
||||
foreach (self::$headerMap as $name => $option) {
|
||||
if (isset($headers[$name])) {
|
||||
curl_setopt($ch, $option, $headers[$name]);
|
||||
unset($headers[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->calculateRequestLength($headers);
|
||||
if (isset($headers['content-length'])) {
|
||||
$this->workaroundPhpBug47204($ch, $headers);
|
||||
}
|
||||
|
||||
// set headers not having special keys
|
||||
$headersFmt = array();
|
||||
foreach ($headers as $name => $value) {
|
||||
$canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
|
||||
$headersFmt[] = $canonicalName . ': ' . $value;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
|
||||
|
||||
return $ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for PHP bug #47204 that prevents rewinding request body
|
||||
*
|
||||
* The workaround consists of reading the entire request body into memory
|
||||
* and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large
|
||||
* file uploads, use Socket adapter instead.
|
||||
*
|
||||
* @param resource cURL handle
|
||||
* @param array Request headers
|
||||
*/
|
||||
protected function workaroundPhpBug47204($ch, &$headers)
|
||||
{
|
||||
// no redirects, no digest auth -> probably no rewind needed
|
||||
if (!$this->request->getConfig('follow_redirects')
|
||||
&& (!($auth = $this->request->getAuth())
|
||||
|| HTTP_Request2::AUTH_DIGEST != $auth['scheme'])
|
||||
) {
|
||||
curl_setopt($ch, CURLOPT_READFUNCTION, array($this, 'callbackReadBody'));
|
||||
|
||||
// rewind may be needed, read the whole body into memory
|
||||
} else {
|
||||
if ($this->requestBody instanceof HTTP_Request2_MultipartBody) {
|
||||
$this->requestBody = $this->requestBody->__toString();
|
||||
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$fp = $this->requestBody;
|
||||
$this->requestBody = '';
|
||||
while (!feof($fp)) {
|
||||
$this->requestBody .= fread($fp, 16384);
|
||||
}
|
||||
}
|
||||
// curl hangs up if content-length is present
|
||||
unset($headers['content-length']);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for reading the request body
|
||||
*
|
||||
* @param resource cURL handle
|
||||
* @param resource file descriptor (not used)
|
||||
* @param integer maximum length of data to return
|
||||
* @return string part of the request body, up to $length bytes
|
||||
*/
|
||||
protected function callbackReadBody($ch, $fd, $length)
|
||||
{
|
||||
if (!$this->eventSentHeaders) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
$this->eventSentHeaders = true;
|
||||
}
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
|
||||
0 == $this->contentLength || $this->position >= $this->contentLength
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($this->requestBody)) {
|
||||
$string = substr($this->requestBody, $this->position, $length);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$string = fread($this->requestBody, $length);
|
||||
} else {
|
||||
$string = $this->requestBody->read($length);
|
||||
}
|
||||
$this->request->setLastEvent('sentBodyPart', strlen($string));
|
||||
$this->position += strlen($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response headers
|
||||
*
|
||||
* @param resource cURL handle
|
||||
* @param string response header (with trailing CRLF)
|
||||
* @return integer number of bytes saved
|
||||
* @see HTTP_Request2_Response::parseHeaderLine()
|
||||
*/
|
||||
protected function callbackWriteHeader($ch, $string)
|
||||
{
|
||||
// we may receive a second set of headers if doing e.g. digest auth
|
||||
if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
|
||||
// don't bother with 100-Continue responses (bug #15785)
|
||||
if (!$this->eventSentHeaders ||
|
||||
$this->response->getStatus() >= 200
|
||||
) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
}
|
||||
$upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
|
||||
// if body wasn't read by a callback, send event with total body size
|
||||
if ($upload > $this->position) {
|
||||
$this->request->setLastEvent(
|
||||
'sentBodyPart', $upload - $this->position
|
||||
);
|
||||
$this->position = $upload;
|
||||
}
|
||||
$this->eventSentHeaders = true;
|
||||
// we'll need a new response object
|
||||
if ($this->eventReceivedHeaders) {
|
||||
$this->eventReceivedHeaders = false;
|
||||
$this->response = null;
|
||||
}
|
||||
}
|
||||
if (empty($this->response)) {
|
||||
$this->response = new HTTP_Request2_Response($string, false);
|
||||
} else {
|
||||
$this->response->parseHeaderLine($string);
|
||||
if ('' == trim($string)) {
|
||||
// don't bother with 100-Continue responses (bug #15785)
|
||||
if (200 <= $this->response->getStatus()) {
|
||||
$this->request->setLastEvent('receivedHeaders', $this->response);
|
||||
}
|
||||
// for versions lower than 5.2.10, check the redirection URL protocol
|
||||
if ($this->request->getConfig('follow_redirects') && !defined('CURLOPT_REDIR_PROTOCOLS')
|
||||
&& $this->response->isRedirect()
|
||||
) {
|
||||
$redirectUrl = new Net_URL2($this->response->getHeader('location'));
|
||||
if ($redirectUrl->isAbsolute()
|
||||
&& !in_array($redirectUrl->getScheme(), array('http', 'https'))
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
$this->eventReceivedHeaders = true;
|
||||
}
|
||||
}
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response body
|
||||
*
|
||||
* @param resource cURL handle (not used)
|
||||
* @param string part of the response body
|
||||
* @return integer number of bytes saved
|
||||
* @see HTTP_Request2_Response::appendBody()
|
||||
*/
|
||||
protected function callbackWriteBody($ch, $string)
|
||||
{
|
||||
// cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
|
||||
// response doesn't start with proper HTTP status line (see bug #15716)
|
||||
if (empty($this->response)) {
|
||||
throw new HTTP_Request2_Exception("Malformed response: {$string}");
|
||||
}
|
||||
if ($this->request->getConfig('store_body')) {
|
||||
$this->response->appendBody($string);
|
||||
}
|
||||
$this->request->setLastEvent('receivedBodyPart', $string);
|
||||
return strlen($string);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Mock.php 290192 2009-11-03 21:29:32Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* Can be used to test applications depending on HTTP_Request2 package without
|
||||
* actually performing any HTTP requests. This adapter will return responses
|
||||
* previously added via addResponse()
|
||||
* <code>
|
||||
* $mock = new HTTP_Request2_Adapter_Mock();
|
||||
* $mock->addResponse("HTTP/1.1 ... ");
|
||||
*
|
||||
* $request = new HTTP_Request2();
|
||||
* $request->setAdapter($mock);
|
||||
*
|
||||
* // This will return the response set above
|
||||
* $response = $req->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A queue of responses to be returned by sendRequest()
|
||||
* @var array
|
||||
*/
|
||||
protected $responses = array();
|
||||
|
||||
/**
|
||||
* Returns the next response from the queue built by addResponse()
|
||||
*
|
||||
* If the queue is empty it will return default empty response with status 400,
|
||||
* if an Exception object was added to the queue it will be thrown.
|
||||
*
|
||||
* @param HTTP_Request2
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
if (count($this->responses) > 0) {
|
||||
$response = array_shift($this->responses);
|
||||
if ($response instanceof HTTP_Request2_Response) {
|
||||
return $response;
|
||||
} else {
|
||||
// rethrow the exception
|
||||
$class = get_class($response);
|
||||
$message = $response->getMessage();
|
||||
$code = $response->getCode();
|
||||
throw new $class($message, $code);
|
||||
}
|
||||
} else {
|
||||
return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds response to the queue
|
||||
*
|
||||
* @param mixed either a string, a pointer to an open file,
|
||||
* an instance of HTTP_Request2_Response or Exception
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function addResponse($response)
|
||||
{
|
||||
if (is_string($response)) {
|
||||
$response = self::createResponseFromString($response);
|
||||
} elseif (is_resource($response)) {
|
||||
$response = self::createResponseFromFile($response);
|
||||
} elseif (!$response instanceof HTTP_Request2_Response &&
|
||||
!$response instanceof Exception
|
||||
) {
|
||||
throw new HTTP_Request2_Exception('Parameter is not a valid response');
|
||||
}
|
||||
$this->responses[] = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a string
|
||||
*
|
||||
* @param string
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromString($str)
|
||||
{
|
||||
$parts = preg_split('!(\r?\n){2}!m', $str, 2);
|
||||
$headerLines = explode("\n", $parts[0]);
|
||||
$response = new HTTP_Request2_Response(array_shift($headerLines));
|
||||
foreach ($headerLines as $headerLine) {
|
||||
$response->parseHeaderLine($headerLine);
|
||||
}
|
||||
$response->parseHeaderLine('');
|
||||
if (isset($parts[1])) {
|
||||
$response->appendBody($parts[1]);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a file
|
||||
*
|
||||
* @param resource file pointer returned by fopen()
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromFile($fp)
|
||||
{
|
||||
$response = new HTTP_Request2_Response(fgets($fp));
|
||||
do {
|
||||
$headerLine = fgets($fp);
|
||||
$response->parseHeaderLine($headerLine);
|
||||
} while ('' != trim($headerLine));
|
||||
|
||||
while (!feof($fp)) {
|
||||
$response->appendBody(fread($fp, 8192));
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Exception.php 290192 2009-11-03 21:29:32Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for exceptions in PEAR
|
||||
*/
|
||||
require_once 'PEAR/Exception.php';
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*
|
||||
* Such a class is required by the Exception RFC:
|
||||
* http://pear.php.net/pepr/pepr-proposal-show.php?id=132
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @version Release: 0.5.2
|
||||
*/
|
||||
class HTTP_Request2_Exception extends PEAR_Exception
|
||||
{
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper class for building multipart/form-data request body
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: MultipartBody.php 290192 2009-11-03 21:29:32Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for building multipart/form-data request body
|
||||
*
|
||||
* The class helps to reduce memory consumption by streaming large file uploads
|
||||
* from disk, it also allows monitoring of upload progress (see request #7630)
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
* @link http://tools.ietf.org/html/rfc1867
|
||||
*/
|
||||
class HTTP_Request2_MultipartBody
|
||||
{
|
||||
/**
|
||||
* MIME boundary
|
||||
* @var string
|
||||
*/
|
||||
private $_boundary;
|
||||
|
||||
/**
|
||||
* Form parameters added via {@link HTTP_Request2::addPostParameter()}
|
||||
* @var array
|
||||
*/
|
||||
private $_params = array();
|
||||
|
||||
/**
|
||||
* File uploads added via {@link HTTP_Request2::addUpload()}
|
||||
* @var array
|
||||
*/
|
||||
private $_uploads = array();
|
||||
|
||||
/**
|
||||
* Header for parts with parameters
|
||||
* @var string
|
||||
*/
|
||||
private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Header for parts with uploads
|
||||
* @var string
|
||||
*/
|
||||
private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Current position in parameter and upload arrays
|
||||
*
|
||||
* First number is index of "current" part, second number is position within
|
||||
* "current" part
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_pos = array(0, 0);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor. Sets the arrays with POST data.
|
||||
*
|
||||
* @param array values of form fields set via {@link HTTP_Request2::addPostParameter()}
|
||||
* @param array file uploads set via {@link HTTP_Request2::addUpload()}
|
||||
* @param bool whether to append brackets to array variable names
|
||||
*/
|
||||
public function __construct(array $params, array $uploads, $useBrackets = true)
|
||||
{
|
||||
$this->_params = self::_flattenArray('', $params, $useBrackets);
|
||||
foreach ($uploads as $fieldName => $f) {
|
||||
if (!is_array($f['fp'])) {
|
||||
$this->_uploads[] = $f + array('name' => $fieldName);
|
||||
} else {
|
||||
for ($i = 0; $i < count($f['fp']); $i++) {
|
||||
$upload = array(
|
||||
'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
|
||||
);
|
||||
foreach (array('fp', 'filename', 'size', 'type') as $key) {
|
||||
$upload[$key] = $f[$key][$i];
|
||||
}
|
||||
$this->_uploads[] = $upload;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the body to use in Content-Length header
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLength()
|
||||
{
|
||||
$boundaryLength = strlen($this->getBoundary());
|
||||
$headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
|
||||
$headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
|
||||
$length = $boundaryLength + 6;
|
||||
foreach ($this->_params as $p) {
|
||||
$length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
|
||||
}
|
||||
foreach ($this->_uploads as $u) {
|
||||
$length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
|
||||
strlen($u['filename']) + $u['size'] + 2;
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary to use in Content-Type header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBoundary()
|
||||
{
|
||||
if (empty($this->_boundary)) {
|
||||
$this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
|
||||
}
|
||||
return $this->_boundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next chunk of request body
|
||||
*
|
||||
* @param integer Amount of bytes to read
|
||||
* @return string Up to $length bytes of data, empty string if at end
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
$ret = '';
|
||||
$boundary = $this->getBoundary();
|
||||
$paramCount = count($this->_params);
|
||||
$uploadCount = count($this->_uploads);
|
||||
while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
|
||||
$oldLength = $length;
|
||||
if ($this->_pos[0] < $paramCount) {
|
||||
$param = sprintf($this->_headerParam, $boundary,
|
||||
$this->_params[$this->_pos[0]][0]) .
|
||||
$this->_params[$this->_pos[0]][1] . "\r\n";
|
||||
$ret .= substr($param, $this->_pos[1], $length);
|
||||
$length -= min(strlen($param) - $this->_pos[1], $length);
|
||||
|
||||
} elseif ($this->_pos[0] < $paramCount + $uploadCount) {
|
||||
$pos = $this->_pos[0] - $paramCount;
|
||||
$header = sprintf($this->_headerUpload, $boundary,
|
||||
$this->_uploads[$pos]['name'],
|
||||
$this->_uploads[$pos]['filename'],
|
||||
$this->_uploads[$pos]['type']);
|
||||
if ($this->_pos[1] < strlen($header)) {
|
||||
$ret .= substr($header, $this->_pos[1], $length);
|
||||
$length -= min(strlen($header) - $this->_pos[1], $length);
|
||||
}
|
||||
$filePos = max(0, $this->_pos[1] - strlen($header));
|
||||
if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
|
||||
$ret .= fread($this->_uploads[$pos]['fp'], $length);
|
||||
$length -= min($length, $this->_uploads[$pos]['size'] - $filePos);
|
||||
}
|
||||
if ($length > 0) {
|
||||
$start = $this->_pos[1] + ($oldLength - $length) -
|
||||
strlen($header) - $this->_uploads[$pos]['size'];
|
||||
$ret .= substr("\r\n", $start, $length);
|
||||
$length -= min(2 - $start, $length);
|
||||
}
|
||||
|
||||
} else {
|
||||
$closing = '--' . $boundary . "--\r\n";
|
||||
$ret .= substr($closing, $this->_pos[1], $length);
|
||||
$length -= min(strlen($closing) - $this->_pos[1], $length);
|
||||
}
|
||||
if ($length > 0) {
|
||||
$this->_pos = array($this->_pos[0] + 1, 0);
|
||||
} else {
|
||||
$this->_pos[1] += $oldLength;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current position to the start of the body
|
||||
*
|
||||
* This allows reusing the same body in another request
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->_pos = array(0, 0);
|
||||
foreach ($this->_uploads as $u) {
|
||||
rewind($u['fp']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body as string
|
||||
*
|
||||
* Note that it reads all file uploads into memory so it is a good idea not
|
||||
* to use this method with large file uploads and rely on read() instead.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$this->rewind();
|
||||
return $this->read($this->getLength());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to change the (probably multidimensional) associative array
|
||||
* into the simple one.
|
||||
*
|
||||
* @param string name for item
|
||||
* @param mixed item's values
|
||||
* @param bool whether to append [] to array variables' names
|
||||
* @return array array with the following items: array('item name', 'item value');
|
||||
*/
|
||||
private static function _flattenArray($name, $values, $useBrackets)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
return array(array($name, $values));
|
||||
} else {
|
||||
$ret = array();
|
||||
foreach ($values as $k => $v) {
|
||||
if (empty($name)) {
|
||||
$newName = $k;
|
||||
} elseif ($useBrackets) {
|
||||
$newName = $name . '[' . $k . ']';
|
||||
} else {
|
||||
$newName = $name;
|
||||
}
|
||||
$ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* An observer useful for debugging / testing.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Log.php 293416 2010-01-11 18:06:15Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* A debug observer useful for debugging / testing.
|
||||
*
|
||||
* This observer logs to a log target data corresponding to the various request
|
||||
* and response events, it logs by default to php://output but can be configured
|
||||
* to log to a file or via the PEAR Log package.
|
||||
*
|
||||
* A simple example:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* $observer = new HTTP_Request2_Observer_Log();
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* A more complex example with PEAR Log:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
* require_once 'Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* // we want to log with PEAR log
|
||||
* $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
|
||||
*
|
||||
* // we only want to log received headers
|
||||
* $observer->events = array('receivedHeaders');
|
||||
*
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 0.5.2
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Observer_Log implements SplObserver
|
||||
{
|
||||
// properties {{{
|
||||
|
||||
/**
|
||||
* The log target, it can be a a resource or a PEAR Log instance.
|
||||
*
|
||||
* @var resource|Log $target
|
||||
*/
|
||||
protected $target = null;
|
||||
|
||||
/**
|
||||
* The events to log.
|
||||
*
|
||||
* @var array $events
|
||||
*/
|
||||
public $events = array(
|
||||
'connect',
|
||||
'sentHeaders',
|
||||
'sentBodyPart',
|
||||
'receivedHeaders',
|
||||
'receivedBody',
|
||||
'disconnect',
|
||||
);
|
||||
|
||||
// }}}
|
||||
// __construct() {{{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param mixed $target Can be a file path (default: php://output), a resource,
|
||||
* or an instance of the PEAR Log class.
|
||||
* @param array $events Array of events to listen to (default: all events)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($target = 'php://output', array $events = array())
|
||||
{
|
||||
if (!empty($events)) {
|
||||
$this->events = $events;
|
||||
}
|
||||
if (is_resource($target) || $target instanceof Log) {
|
||||
$this->target = $target;
|
||||
} elseif (false === ($this->target = @fopen($target, 'ab'))) {
|
||||
throw new HTTP_Request2_Exception("Unable to open '{$target}'");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// update() {{{
|
||||
|
||||
/**
|
||||
* Called when the request notifies us of an event.
|
||||
*
|
||||
* @param HTTP_Request2 $subject The HTTP_Request2 instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update(SplSubject $subject)
|
||||
{
|
||||
$event = $subject->getLastEvent();
|
||||
if (!in_array($event['name'], $this->events)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($event['name']) {
|
||||
case 'connect':
|
||||
$this->log('* Connected to ' . $event['data']);
|
||||
break;
|
||||
case 'sentHeaders':
|
||||
$headers = explode("\r\n", $event['data']);
|
||||
array_pop($headers);
|
||||
foreach ($headers as $header) {
|
||||
$this->log('> ' . $header);
|
||||
}
|
||||
break;
|
||||
case 'sentBodyPart':
|
||||
$this->log('> ' . $event['data'] . ' byte(s) sent');
|
||||
break;
|
||||
case 'receivedHeaders':
|
||||
$this->log(sprintf('< HTTP/%s %s %s',
|
||||
$event['data']->getVersion(),
|
||||
$event['data']->getStatus(),
|
||||
$event['data']->getReasonPhrase()));
|
||||
$headers = $event['data']->getHeader();
|
||||
foreach ($headers as $key => $val) {
|
||||
$this->log('< ' . $key . ': ' . $val);
|
||||
}
|
||||
$this->log('< ');
|
||||
break;
|
||||
case 'receivedBody':
|
||||
$this->log($event['data']->getBody());
|
||||
break;
|
||||
case 'disconnect':
|
||||
$this->log('* Disconnected');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// log() {{{
|
||||
|
||||
/**
|
||||
* Logs the given message to the configured target.
|
||||
*
|
||||
* @param string $message Message to display
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function log($message)
|
||||
{
|
||||
if ($this->target instanceof Log) {
|
||||
$this->target->debug($message);
|
||||
} elseif (is_resource($this->target)) {
|
||||
fwrite($this->target, $message . "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,559 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The names of the authors may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version SVN: $Id: Response.php 290520 2009-11-11 20:09:42Z avb $
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* The class is designed to be used in "streaming" scenario, building the
|
||||
* response as it is being received:
|
||||
* <code>
|
||||
* $statusLine = read_status_line();
|
||||
* $response = new HTTP_Request2_Response($statusLine);
|
||||
* do {
|
||||
* $headerLine = read_header_line();
|
||||
* $response->parseHeaderLine($headerLine);
|
||||
* } while ($headerLine != '');
|
||||
*
|
||||
* while ($chunk = read_body()) {
|
||||
* $response->appendBody($chunk);
|
||||
* }
|
||||
*
|
||||
* var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
|
||||
* </code>
|
||||
*
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 0.5.2
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6
|
||||
*/
|
||||
class HTTP_Request2_Response
|
||||
{
|
||||
/**
|
||||
* HTTP protocol version (e.g. 1.0, 1.1)
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
* @var integer
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
* @var string
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $reasonPhrase;
|
||||
|
||||
/**
|
||||
* Associative array of response headers
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Cookies set in the response
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Name of last header processed by parseHederLine()
|
||||
*
|
||||
* Used to handle the headers that span multiple lines
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastHeader = null;
|
||||
|
||||
/**
|
||||
* Response body
|
||||
* @var string
|
||||
*/
|
||||
protected $body = '';
|
||||
|
||||
/**
|
||||
* Whether the body is still encoded by Content-Encoding
|
||||
*
|
||||
* cURL provides the decoded body to the callback; if we are reading from
|
||||
* socket the body is still gzipped / deflated
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $bodyEncoded;
|
||||
|
||||
/**
|
||||
* Associative array of HTTP status code / reason phrase.
|
||||
*
|
||||
* @var array
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-10
|
||||
*/
|
||||
protected static $phrases = array(
|
||||
|
||||
// 1xx: Informational - Request received, continuing process
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
|
||||
// 2xx: Success - The action was successfully received, understood and
|
||||
// accepted
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
// 3xx: Redirection - Further action must be taken in order to complete
|
||||
// the request
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found', // 1.1
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
// 4xx: Client Error - The request contains bad syntax or cannot be
|
||||
// fulfilled
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
// 5xx: Server Error - The server failed to fulfill an apparently
|
||||
// valid request
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
509 => 'Bandwidth Limit Exceeded',
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor, parses the response status line
|
||||
*
|
||||
* @param string Response status line (e.g. "HTTP/1.1 200 OK")
|
||||
* @param bool Whether body is still encoded by Content-Encoding
|
||||
* @throws HTTP_Request2_Exception if status line is invalid according to spec
|
||||
*/
|
||||
public function __construct($statusLine, $bodyEncoded = true)
|
||||
{
|
||||
if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
|
||||
throw new HTTP_Request2_Exception("Malformed response: {$statusLine}");
|
||||
}
|
||||
$this->version = $m[1];
|
||||
$this->code = intval($m[2]);
|
||||
if (!empty($m[3])) {
|
||||
$this->reasonPhrase = trim($m[3]);
|
||||
} elseif (!empty(self::$phrases[$this->code])) {
|
||||
$this->reasonPhrase = self::$phrases[$this->code];
|
||||
}
|
||||
$this->bodyEncoded = (bool)$bodyEncoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the line from HTTP response filling $headers array
|
||||
*
|
||||
* The method should be called after reading the line from socket or receiving
|
||||
* it into cURL callback. Passing an empty string here indicates the end of
|
||||
* response headers and triggers additional processing, so be sure to pass an
|
||||
* empty string in the end.
|
||||
*
|
||||
* @param string Line from HTTP response
|
||||
*/
|
||||
public function parseHeaderLine($headerLine)
|
||||
{
|
||||
$headerLine = trim($headerLine, "\r\n");
|
||||
|
||||
// empty string signals the end of headers, process the received ones
|
||||
if ('' == $headerLine) {
|
||||
if (!empty($this->headers['set-cookie'])) {
|
||||
$cookies = is_array($this->headers['set-cookie'])?
|
||||
$this->headers['set-cookie']:
|
||||
array($this->headers['set-cookie']);
|
||||
foreach ($cookies as $cookieString) {
|
||||
$this->parseCookie($cookieString);
|
||||
}
|
||||
unset($this->headers['set-cookie']);
|
||||
}
|
||||
foreach (array_keys($this->headers) as $k) {
|
||||
if (is_array($this->headers[$k])) {
|
||||
$this->headers[$k] = implode(', ', $this->headers[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
// string of the form header-name: header value
|
||||
} elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
|
||||
$name = strtolower($m[1]);
|
||||
$value = trim($m[2]);
|
||||
if (empty($this->headers[$name])) {
|
||||
$this->headers[$name] = $value;
|
||||
} else {
|
||||
if (!is_array($this->headers[$name])) {
|
||||
$this->headers[$name] = array($this->headers[$name]);
|
||||
}
|
||||
$this->headers[$name][] = $value;
|
||||
}
|
||||
$this->lastHeader = $name;
|
||||
|
||||
// continuation of a previous header
|
||||
} elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
|
||||
if (!is_array($this->headers[$this->lastHeader])) {
|
||||
$this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
|
||||
} else {
|
||||
$key = count($this->headers[$this->lastHeader]) - 1;
|
||||
$this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Set-Cookie header to fill $cookies array
|
||||
*
|
||||
* @param string value of Set-Cookie header
|
||||
* @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
|
||||
*/
|
||||
protected function parseCookie($cookieString)
|
||||
{
|
||||
$cookie = array(
|
||||
'expires' => null,
|
||||
'domain' => null,
|
||||
'path' => null,
|
||||
'secure' => false
|
||||
);
|
||||
|
||||
// Only a name=value pair
|
||||
if (!strpos($cookieString, ';')) {
|
||||
$pos = strpos($cookieString, '=');
|
||||
$cookie['name'] = trim(substr($cookieString, 0, $pos));
|
||||
$cookie['value'] = trim(substr($cookieString, $pos + 1));
|
||||
|
||||
// Some optional parameters are supplied
|
||||
} else {
|
||||
$elements = explode(';', $cookieString);
|
||||
$pos = strpos($elements[0], '=');
|
||||
$cookie['name'] = trim(substr($elements[0], 0, $pos));
|
||||
$cookie['value'] = trim(substr($elements[0], $pos + 1));
|
||||
|
||||
for ($i = 1; $i < count($elements); $i++) {
|
||||
if (false === strpos($elements[$i], '=')) {
|
||||
$elName = trim($elements[$i]);
|
||||
$elValue = null;
|
||||
} else {
|
||||
list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
|
||||
}
|
||||
$elName = strtolower($elName);
|
||||
if ('secure' == $elName) {
|
||||
$cookie['secure'] = true;
|
||||
} elseif ('expires' == $elName) {
|
||||
$cookie['expires'] = str_replace('"', '', $elValue);
|
||||
} elseif ('path' == $elName || 'domain' == $elName) {
|
||||
$cookie[$elName] = urldecode($elValue);
|
||||
} else {
|
||||
$cookie[$elName] = $elValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->cookies[] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string to the response body
|
||||
* @param string
|
||||
*/
|
||||
public function appendBody($bodyChunk)
|
||||
{
|
||||
$this->body .= $bodyChunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status code
|
||||
* @return integer
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason phrase
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase()
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether response is a redirect that can be automatically handled by HTTP_Request2
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->code, array(300, 301, 302, 303, 307))
|
||||
&& isset($this->headers['location']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either the named header or all response headers
|
||||
*
|
||||
* @param string Name of header to return
|
||||
* @return string|array Value of $headerName header (null if header is
|
||||
* not present), array of all response headers if
|
||||
* $headerName is null
|
||||
*/
|
||||
public function getHeader($headerName = null)
|
||||
{
|
||||
if (null === $headerName) {
|
||||
return $this->headers;
|
||||
} else {
|
||||
$headerName = strtolower($headerName);
|
||||
return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cookies set in response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCookies()
|
||||
{
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body of the response
|
||||
*
|
||||
* @return string
|
||||
* @throws HTTP_Request2_Exception if body cannot be decoded
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
if (!$this->bodyEncoded ||
|
||||
!in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
|
||||
) {
|
||||
return $this->body;
|
||||
|
||||
} else {
|
||||
if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
|
||||
$oldEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('iso-8859-1');
|
||||
}
|
||||
|
||||
try {
|
||||
switch (strtolower($this->getHeader('content-encoding'))) {
|
||||
case 'gzip':
|
||||
$decoded = self::decodeGzip($this->body);
|
||||
break;
|
||||
case 'deflate':
|
||||
$decoded = self::decodeDeflate($this->body);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
if (!empty($oldEncoding)) {
|
||||
mb_internal_encoding($oldEncoding);
|
||||
}
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP version of the response
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by gzip
|
||||
*
|
||||
* The real decoding work is done by gzinflate() built-in function, this
|
||||
* method only parses the header and checks data for compliance with
|
||||
* RFC 1952
|
||||
*
|
||||
* @param string gzip-encoded data
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_Exception
|
||||
* @link http://tools.ietf.org/html/rfc1952
|
||||
*/
|
||||
public static function decodeGzip($data)
|
||||
{
|
||||
$length = strlen($data);
|
||||
// If it doesn't look like gzip-encoded data, don't bother
|
||||
if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
|
||||
return $data;
|
||||
}
|
||||
if (!function_exists('gzinflate')) {
|
||||
throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
|
||||
}
|
||||
$method = ord(substr($data, 2, 1));
|
||||
if (8 != $method) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: unknown compression method');
|
||||
}
|
||||
$flags = ord(substr($data, 3, 1));
|
||||
if ($flags & 224) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: reserved bits are set');
|
||||
}
|
||||
|
||||
// header is 10 bytes minimum. may be longer, though.
|
||||
$headerLength = 10;
|
||||
// extra fields, need to skip 'em
|
||||
if ($flags & 4) {
|
||||
if ($length - $headerLength - 2 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$extraLength = unpack('v', substr($data, 10, 2));
|
||||
if ($length - $headerLength - 2 - $extraLength[1] < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$headerLength += $extraLength[1] + 2;
|
||||
}
|
||||
// file name, need to skip that
|
||||
if ($flags & 8) {
|
||||
if ($length - $headerLength - 1 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$filenameLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$headerLength += $filenameLength + 1;
|
||||
}
|
||||
// comment, need to skip that also
|
||||
if ($flags & 16) {
|
||||
if ($length - $headerLength - 1 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$commentLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$headerLength += $commentLength + 1;
|
||||
}
|
||||
// have a CRC for header. let's check
|
||||
if ($flags & 2) {
|
||||
if ($length - $headerLength - 2 < 8) {
|
||||
throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
|
||||
}
|
||||
$crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
|
||||
$crcStored = unpack('v', substr($data, $headerLength, 2));
|
||||
if ($crcReal != $crcStored[1]) {
|
||||
throw new HTTP_Request2_Exception('Header CRC check failed');
|
||||
}
|
||||
$headerLength += 2;
|
||||
}
|
||||
// unpacked data CRC and size at the end of encoded data
|
||||
$tmp = unpack('V2', substr($data, -8));
|
||||
$dataCrc = $tmp[1];
|
||||
$dataSize = $tmp[2];
|
||||
|
||||
// finally, call the gzinflate() function
|
||||
// don't pass $dataSize to gzinflate, see bugs #13135, #14370
|
||||
$unpacked = gzinflate(substr($data, $headerLength, -8));
|
||||
if (false === $unpacked) {
|
||||
throw new HTTP_Request2_Exception('gzinflate() call failed');
|
||||
} elseif ($dataSize != strlen($unpacked)) {
|
||||
throw new HTTP_Request2_Exception('Data size check failed');
|
||||
} elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
|
||||
throw new HTTP_Request2_Exception('Data CRC check failed');
|
||||
}
|
||||
return $unpacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by deflate
|
||||
*
|
||||
* @param string deflate-encoded data
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function decodeDeflate($data)
|
||||
{
|
||||
if (!function_exists('gzuncompress')) {
|
||||
throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
|
||||
}
|
||||
// RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
|
||||
// while many applications send raw deflate stream from RFC 1951.
|
||||
// We should check for presence of zlib header and use gzuncompress() or
|
||||
// gzinflate() as needed. See bug #15305
|
||||
$header = unpack('n', substr($data, 0, 2));
|
||||
return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,894 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Net_URL2, a class representing a URL as per RFC 3986.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2007-2009, Peytz & Co. A/S
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the Net_URL2 nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Networking
|
||||
* @package Net_URL2
|
||||
* @author Christian Schmidt <schmidt@php.net>
|
||||
* @copyright 2007-2009 Peytz & Co. A/S
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: URL2.php 290036 2009-10-28 19:52:49Z schmidt $
|
||||
* @link http://www.rfc-editor.org/rfc/rfc3986.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a URL as per RFC 3986.
|
||||
*
|
||||
* @category Networking
|
||||
* @package Net_URL2
|
||||
* @author Christian Schmidt <schmidt@php.net>
|
||||
* @copyright 2007-2009 Peytz & Co. A/S
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/Net_URL2
|
||||
*/
|
||||
class Net_URL2
|
||||
{
|
||||
/**
|
||||
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
|
||||
* is true.
|
||||
*/
|
||||
const OPTION_STRICT = 'strict';
|
||||
|
||||
/**
|
||||
* Represent arrays in query using PHP's [] notation. Default is true.
|
||||
*/
|
||||
const OPTION_USE_BRACKETS = 'use_brackets';
|
||||
|
||||
/**
|
||||
* URL-encode query variable keys. Default is true.
|
||||
*/
|
||||
const OPTION_ENCODE_KEYS = 'encode_keys';
|
||||
|
||||
/**
|
||||
* Query variable separators when parsing the query string. Every character
|
||||
* is considered a separator. Default is "&".
|
||||
*/
|
||||
const OPTION_SEPARATOR_INPUT = 'input_separator';
|
||||
|
||||
/**
|
||||
* Query variable separator used when generating the query string. Default
|
||||
* is "&".
|
||||
*/
|
||||
const OPTION_SEPARATOR_OUTPUT = 'output_separator';
|
||||
|
||||
/**
|
||||
* Default options corresponds to how PHP handles $_GET.
|
||||
*/
|
||||
private $_options = array(
|
||||
self::OPTION_STRICT => true,
|
||||
self::OPTION_USE_BRACKETS => true,
|
||||
self::OPTION_ENCODE_KEYS => true,
|
||||
self::OPTION_SEPARATOR_INPUT => '&',
|
||||
self::OPTION_SEPARATOR_OUTPUT => '&',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_scheme = false;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_userinfo = false;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_host = false;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_port = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_path = '';
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_query = false;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
private $_fragment = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $url an absolute or relative URL
|
||||
* @param array $options an array of OPTION_xxx constants
|
||||
*/
|
||||
public function __construct($url, array $options = array())
|
||||
{
|
||||
foreach ($options as $optionName => $value) {
|
||||
if (array_key_exists($optionName, $this->_options)) {
|
||||
$this->_options[$optionName] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// The regular expression is copied verbatim from RFC 3986, appendix B.
|
||||
// The expression does not validate the URL but matches any string.
|
||||
preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!',
|
||||
$url,
|
||||
$matches);
|
||||
|
||||
// "path" is always present (possibly as an empty string); the rest
|
||||
// are optional.
|
||||
$this->_scheme = !empty($matches[1]) ? $matches[2] : false;
|
||||
$this->setAuthority(!empty($matches[3]) ? $matches[4] : false);
|
||||
$this->_path = $matches[5];
|
||||
$this->_query = !empty($matches[6]) ? $matches[7] : false;
|
||||
$this->_fragment = !empty($matches[8]) ? $matches[9] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Setter.
|
||||
*
|
||||
* This method will magically set the value of a private variable ($var)
|
||||
* with the value passed as the args
|
||||
*
|
||||
* @param string $var The private variable to set.
|
||||
* @param mixed $arg An argument of any type.
|
||||
* @return void
|
||||
*/
|
||||
public function __set($var, $arg)
|
||||
{
|
||||
$method = 'set' . $var;
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Getter.
|
||||
*
|
||||
* This is the magic get method to retrieve the private variable
|
||||
* that was set by either __set() or it's setter...
|
||||
*
|
||||
* @param string $var The property name to retrieve.
|
||||
* @return mixed $this->$var Either a boolean false if the
|
||||
* property is not set or the value
|
||||
* of the private property.
|
||||
*/
|
||||
public function __get($var)
|
||||
{
|
||||
$method = 'get' . $var;
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->$method();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scheme, e.g. "http" or "urn", or false if there is no
|
||||
* scheme specified, i.e. if this is a relative URL.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->_scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scheme, e.g. "http" or "urn". Specify false if there is no
|
||||
* scheme specified, i.e. if this is a relative URL.
|
||||
*
|
||||
* @param string|bool $scheme e.g. "http" or "urn", or false if there is no
|
||||
* scheme specified, i.e. if this is a relative
|
||||
* URL
|
||||
*
|
||||
* @return void
|
||||
* @see getScheme()
|
||||
*/
|
||||
public function setScheme($scheme)
|
||||
{
|
||||
$this->_scheme = $scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user part of the userinfo part (the part preceding the first
|
||||
* ":"), or false if there is no userinfo part.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->_userinfo !== false
|
||||
? preg_replace('@:.*$@', '', $this->_userinfo)
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password part of the userinfo part (the part after the first
|
||||
* ":"), or false if there is no userinfo part (i.e. the URL does not
|
||||
* contain "@" in front of the hostname) or the userinfo part does not
|
||||
* contain ":".
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->_userinfo !== false
|
||||
? substr(strstr($this->_userinfo, ':'), 1)
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the userinfo part, or false if there is none, i.e. if the
|
||||
* authority part does not contain "@".
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getUserinfo()
|
||||
{
|
||||
return $this->_userinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the userinfo part. If two arguments are passed, they are combined
|
||||
* in the userinfo part as username ":" password.
|
||||
*
|
||||
* @param string|bool $userinfo userinfo or username
|
||||
* @param string|bool $password optional password, or false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUserinfo($userinfo, $password = false)
|
||||
{
|
||||
$this->_userinfo = $userinfo;
|
||||
if ($password !== false) {
|
||||
$this->_userinfo .= ':' . $password;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host part, or false if there is no authority part, e.g.
|
||||
* relative URLs.
|
||||
*
|
||||
* @return string|bool a hostname, an IP address, or false
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host part. Specify false if there is no authority part, e.g.
|
||||
* relative URLs.
|
||||
*
|
||||
* @param string|bool $host a hostname, an IP address, or false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->_host = $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port number, or false if there is no port number specified,
|
||||
* i.e. if the default port is to be used.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return $this->_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port number. Specify false if there is no port number specified,
|
||||
* i.e. if the default port is to be used.
|
||||
*
|
||||
* @param string|bool $port a port number, or false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->_port = $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
|
||||
* false if there is no authority.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getAuthority()
|
||||
{
|
||||
if (!$this->_host) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$authority = '';
|
||||
|
||||
if ($this->_userinfo !== false) {
|
||||
$authority .= $this->_userinfo . '@';
|
||||
}
|
||||
|
||||
$authority .= $this->_host;
|
||||
|
||||
if ($this->_port !== false) {
|
||||
$authority .= ':' . $this->_port;
|
||||
}
|
||||
|
||||
return $authority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
|
||||
* false if there is no authority.
|
||||
*
|
||||
* @param string|false $authority a hostname or an IP addresse, possibly
|
||||
* with userinfo prefixed and port number
|
||||
* appended, e.g. "foo:bar@example.org:81".
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAuthority($authority)
|
||||
{
|
||||
$this->_userinfo = false;
|
||||
$this->_host = false;
|
||||
$this->_port = false;
|
||||
if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
|
||||
if ($reg[1]) {
|
||||
$this->_userinfo = $reg[2];
|
||||
}
|
||||
|
||||
$this->_host = $reg[3];
|
||||
if (isset($reg[5])) {
|
||||
$this->_port = $reg[5];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path part (possibly an empty string).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path part (possibly an empty string).
|
||||
*
|
||||
* @param string $path a path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->_path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query string (excluding the leading "?"), or false if "?"
|
||||
* is not present in the URL.
|
||||
*
|
||||
* @return string|bool
|
||||
* @see self::getQueryVariables()
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query string (excluding the leading "?"). Specify false if "?"
|
||||
* is not present in the URL.
|
||||
*
|
||||
* @param string|bool $query a query string, e.g. "foo=1&bar=2"
|
||||
*
|
||||
* @return void
|
||||
* @see self::setQueryVariables()
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->_query = $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fragment name, or false if "#" is not present in the URL.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getFragment()
|
||||
{
|
||||
return $this->_fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fragment name. Specify false if "#" is not present in the URL.
|
||||
*
|
||||
* @param string|bool $fragment a fragment excluding the leading "#", or
|
||||
* false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFragment($fragment)
|
||||
{
|
||||
$this->_fragment = $fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query string like an array as the variables would appear in
|
||||
* $_GET in a PHP script. If the URL does not contain a "?", an empty array
|
||||
* is returned.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryVariables()
|
||||
{
|
||||
$pattern = '/[' .
|
||||
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
|
||||
']/';
|
||||
$parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$return = array();
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '=') !== false) {
|
||||
list($key, $value) = explode('=', $part, 2);
|
||||
} else {
|
||||
$key = $part;
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
|
||||
$key = rawurldecode($key);
|
||||
}
|
||||
$value = rawurldecode($value);
|
||||
|
||||
if ($this->getOption(self::OPTION_USE_BRACKETS) &&
|
||||
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
|
||||
|
||||
$key = $matches[1];
|
||||
$idx = $matches[2];
|
||||
|
||||
// Ensure is an array
|
||||
if (empty($return[$key]) || !is_array($return[$key])) {
|
||||
$return[$key] = array();
|
||||
}
|
||||
|
||||
// Add data
|
||||
if ($idx === '') {
|
||||
$return[$key][] = $value;
|
||||
} else {
|
||||
$return[$key][$idx] = $value;
|
||||
}
|
||||
} elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
|
||||
&& !empty($return[$key])
|
||||
) {
|
||||
$return[$key] = (array) $return[$key];
|
||||
$return[$key][] = $value;
|
||||
} else {
|
||||
$return[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query string to the specified variable in the query string.
|
||||
*
|
||||
* @param array $array (name => value) array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setQueryVariables(array $array)
|
||||
{
|
||||
if (!$array) {
|
||||
$this->_query = false;
|
||||
} else {
|
||||
foreach ($array as $name => $value) {
|
||||
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
|
||||
$name = self::urlencode($name);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $k => $v) {
|
||||
$parts[] = $this->getOption(self::OPTION_USE_BRACKETS)
|
||||
? sprintf('%s[%s]=%s', $name, $k, $v)
|
||||
: ($name . '=' . $v);
|
||||
}
|
||||
} elseif (!is_null($value)) {
|
||||
$parts[] = $name . '=' . self::urlencode($value);
|
||||
} else {
|
||||
$parts[] = $name;
|
||||
}
|
||||
}
|
||||
$this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
|
||||
$parts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified variable in the query string.
|
||||
*
|
||||
* @param string $name variable name
|
||||
* @param mixed $value variable value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function setQueryVariable($name, $value)
|
||||
{
|
||||
$array = $this->getQueryVariables();
|
||||
$array[$name] = $value;
|
||||
$this->setQueryVariables($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specifed variable from the query string.
|
||||
*
|
||||
* @param string $name a query string variable, e.g. "foo" in "?foo=1"
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unsetQueryVariable($name)
|
||||
{
|
||||
$array = $this->getQueryVariables();
|
||||
unset($array[$name]);
|
||||
$this->setQueryVariables($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getURL()
|
||||
{
|
||||
// See RFC 3986, section 5.3
|
||||
$url = "";
|
||||
|
||||
if ($this->_scheme !== false) {
|
||||
$url .= $this->_scheme . ':';
|
||||
}
|
||||
|
||||
$authority = $this->getAuthority();
|
||||
if ($authority !== false) {
|
||||
$url .= '//' . $authority;
|
||||
}
|
||||
$url .= $this->_path;
|
||||
|
||||
if ($this->_query !== false) {
|
||||
$url .= '?' . $this->_query;
|
||||
}
|
||||
|
||||
if ($this->_fragment !== false) {
|
||||
$url .= '#' . $this->_fragment;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this URL.
|
||||
*
|
||||
* @return string
|
||||
* @see toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a normalized string representation of this URL. This is useful
|
||||
* for comparison of URLs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedURL()
|
||||
{
|
||||
$url = clone $this;
|
||||
$url->normalize();
|
||||
return $url->getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a normalized Net_URL2 instance.
|
||||
*
|
||||
* @return Net_URL2
|
||||
*/
|
||||
public function normalize()
|
||||
{
|
||||
// See RFC 3886, section 6
|
||||
|
||||
// Schemes are case-insensitive
|
||||
if ($this->_scheme) {
|
||||
$this->_scheme = strtolower($this->_scheme);
|
||||
}
|
||||
|
||||
// Hostnames are case-insensitive
|
||||
if ($this->_host) {
|
||||
$this->_host = strtolower($this->_host);
|
||||
}
|
||||
|
||||
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
|
||||
if ($this->_port &&
|
||||
$this->_scheme &&
|
||||
$this->_port == getservbyname($this->_scheme, 'tcp')) {
|
||||
|
||||
$this->_port = false;
|
||||
}
|
||||
|
||||
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
|
||||
foreach (array('_userinfo', '_host', '_path') as $part) {
|
||||
if ($this->$part) {
|
||||
$this->$part = preg_replace('/%[0-9a-f]{2}/ie',
|
||||
'strtoupper("\0")',
|
||||
$this->$part);
|
||||
}
|
||||
}
|
||||
|
||||
// Path segment normalization (RFC 3986, section 6.2.2.3)
|
||||
$this->_path = self::removeDotSegments($this->_path);
|
||||
|
||||
// Scheme based normalization (RFC 3986, section 6.2.3)
|
||||
if ($this->_host && !$this->_path) {
|
||||
$this->_path = '/';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this instance represents an absolute URL.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAbsolute()
|
||||
{
|
||||
return (bool) $this->_scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Net_URL2 instance representing an absolute URL relative to
|
||||
* this URL.
|
||||
*
|
||||
* @param Net_URL2|string $reference relative URL
|
||||
*
|
||||
* @return Net_URL2
|
||||
*/
|
||||
public function resolve($reference)
|
||||
{
|
||||
if (!$reference instanceof Net_URL2) {
|
||||
$reference = new self($reference);
|
||||
}
|
||||
if (!$this->isAbsolute()) {
|
||||
throw new Exception('Base-URL must be absolute');
|
||||
}
|
||||
|
||||
// A non-strict parser may ignore a scheme in the reference if it is
|
||||
// identical to the base URI's scheme.
|
||||
if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
|
||||
$reference->_scheme = false;
|
||||
}
|
||||
|
||||
$target = new self('');
|
||||
if ($reference->_scheme !== false) {
|
||||
$target->_scheme = $reference->_scheme;
|
||||
$target->setAuthority($reference->getAuthority());
|
||||
$target->_path = self::removeDotSegments($reference->_path);
|
||||
$target->_query = $reference->_query;
|
||||
} else {
|
||||
$authority = $reference->getAuthority();
|
||||
if ($authority !== false) {
|
||||
$target->setAuthority($authority);
|
||||
$target->_path = self::removeDotSegments($reference->_path);
|
||||
$target->_query = $reference->_query;
|
||||
} else {
|
||||
if ($reference->_path == '') {
|
||||
$target->_path = $this->_path;
|
||||
if ($reference->_query !== false) {
|
||||
$target->_query = $reference->_query;
|
||||
} else {
|
||||
$target->_query = $this->_query;
|
||||
}
|
||||
} else {
|
||||
if (substr($reference->_path, 0, 1) == '/') {
|
||||
$target->_path = self::removeDotSegments($reference->_path);
|
||||
} else {
|
||||
// Merge paths (RFC 3986, section 5.2.3)
|
||||
if ($this->_host !== false && $this->_path == '') {
|
||||
$target->_path = '/' . $this->_path;
|
||||
} else {
|
||||
$i = strrpos($this->_path, '/');
|
||||
if ($i !== false) {
|
||||
$target->_path = substr($this->_path, 0, $i + 1);
|
||||
}
|
||||
$target->_path .= $reference->_path;
|
||||
}
|
||||
$target->_path = self::removeDotSegments($target->_path);
|
||||
}
|
||||
$target->_query = $reference->_query;
|
||||
}
|
||||
$target->setAuthority($this->getAuthority());
|
||||
}
|
||||
$target->_scheme = $this->_scheme;
|
||||
}
|
||||
|
||||
$target->_fragment = $reference->_fragment;
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes dots as described in RFC 3986, section 5.2.4, e.g.
|
||||
* "/foo/../bar/baz" => "/bar/baz"
|
||||
*
|
||||
* @param string $path a path
|
||||
*
|
||||
* @return string a path
|
||||
*/
|
||||
public static function removeDotSegments($path)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
// Make sure not to be trapped in an infinite loop due to a bug in this
|
||||
// method
|
||||
$j = 0;
|
||||
while ($path && $j++ < 100) {
|
||||
if (substr($path, 0, 2) == './') {
|
||||
// Step 2.A
|
||||
$path = substr($path, 2);
|
||||
} elseif (substr($path, 0, 3) == '../') {
|
||||
// Step 2.A
|
||||
$path = substr($path, 3);
|
||||
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
|
||||
// Step 2.B
|
||||
$path = '/' . substr($path, 3);
|
||||
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
|
||||
// Step 2.C
|
||||
$path = '/' . substr($path, 4);
|
||||
$i = strrpos($output, '/');
|
||||
$output = $i === false ? '' : substr($output, 0, $i);
|
||||
} elseif ($path == '.' || $path == '..') {
|
||||
// Step 2.D
|
||||
$path = '';
|
||||
} else {
|
||||
// Step 2.E
|
||||
$i = strpos($path, '/');
|
||||
if ($i === 0) {
|
||||
$i = strpos($path, '/', 1);
|
||||
}
|
||||
if ($i === false) {
|
||||
$i = strlen($path);
|
||||
}
|
||||
$output .= substr($path, 0, $i);
|
||||
$path = substr($path, $i);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Percent-encodes all non-alphanumeric characters except these: _ . - ~
|
||||
* Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
|
||||
* 5.2.x and earlier.
|
||||
*
|
||||
* @param $raw the string to encode
|
||||
* @return string
|
||||
*/
|
||||
public static function urlencode($string)
|
||||
{
|
||||
$encoded = rawurlencode($string);
|
||||
// This is only necessary in PHP < 5.3.
|
||||
$encoded = str_replace('%7E', '~', $encoded);
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Net_URL2 instance representing the canonical URL of the
|
||||
* currently executing PHP script.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCanonical()
|
||||
{
|
||||
if (!isset($_SERVER['REQUEST_METHOD'])) {
|
||||
// ALERT - no current URL
|
||||
throw new Exception('Script was not called through a webserver');
|
||||
}
|
||||
|
||||
// Begin with a relative URL
|
||||
$url = new self($_SERVER['PHP_SELF']);
|
||||
$url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
||||
$url->_host = $_SERVER['SERVER_NAME'];
|
||||
$port = $_SERVER['SERVER_PORT'];
|
||||
if ($url->_scheme == 'http' && $port != 80 ||
|
||||
$url->_scheme == 'https' && $port != 443) {
|
||||
|
||||
$url->_port = $port;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL used to retrieve the current request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getRequestedURL()
|
||||
{
|
||||
return self::getRequested()->getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Net_URL2 instance representing the URL used to retrieve the
|
||||
* current request.
|
||||
*
|
||||
* @return Net_URL2
|
||||
*/
|
||||
public static function getRequested()
|
||||
{
|
||||
if (!isset($_SERVER['REQUEST_METHOD'])) {
|
||||
// ALERT - no current URL
|
||||
throw new Exception('Script was not called through a webserver');
|
||||
}
|
||||
|
||||
// Begin with a relative URL
|
||||
$url = new self($_SERVER['REQUEST_URI']);
|
||||
$url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
||||
// Set host and possibly port
|
||||
$url->setAuthority($_SERVER['HTTP_HOST']);
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified option.
|
||||
*
|
||||
* @param string $optionName The name of the option to retrieve
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function getOption($optionName)
|
||||
{
|
||||
return isset($this->_options[$optionName])
|
||||
? $this->_options[$optionName] : false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,391 +0,0 @@
|
|||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
|
||||
/**
|
||||
* PEAR_Exception
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Exception.php 276383 2009-02-24 23:39:37Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 1.3.3
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base PEAR_Exception Class
|
||||
*
|
||||
* 1) Features:
|
||||
*
|
||||
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
|
||||
* - Definable triggers, shot when exceptions occur
|
||||
* - Pretty and informative error messages
|
||||
* - Added more context info available (like class, method or cause)
|
||||
* - cause can be a PEAR_Exception or an array of mixed
|
||||
* PEAR_Exceptions/PEAR_ErrorStack warnings
|
||||
* - callbacks for specific exception classes and their children
|
||||
*
|
||||
* 2) Ideas:
|
||||
*
|
||||
* - Maybe a way to define a 'template' for the output
|
||||
*
|
||||
* 3) Inherited properties from PHP Exception Class:
|
||||
*
|
||||
* protected $message
|
||||
* protected $code
|
||||
* protected $line
|
||||
* protected $file
|
||||
* private $trace
|
||||
*
|
||||
* 4) Inherited methods from PHP Exception Class:
|
||||
*
|
||||
* __clone
|
||||
* __construct
|
||||
* getMessage
|
||||
* getCode
|
||||
* getFile
|
||||
* getLine
|
||||
* getTraceSafe
|
||||
* getTraceSafeAsString
|
||||
* __toString
|
||||
*
|
||||
* 5) Usage example
|
||||
*
|
||||
* <code>
|
||||
* require_once 'PEAR/Exception.php';
|
||||
*
|
||||
* class Test {
|
||||
* function foo() {
|
||||
* throw new PEAR_Exception('Error Message', ERROR_CODE);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* function myLogger($pear_exception) {
|
||||
* echo $pear_exception->getMessage();
|
||||
* }
|
||||
* // each time a exception is thrown the 'myLogger' will be called
|
||||
* // (its use is completely optional)
|
||||
* PEAR_Exception::addObserver('myLogger');
|
||||
* $test = new Test;
|
||||
* try {
|
||||
* $test->foo();
|
||||
* } catch (PEAR_Exception $e) {
|
||||
* print $e;
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.0
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 1.3.3
|
||||
*
|
||||
*/
|
||||
class PEAR_Exception extends Exception
|
||||
{
|
||||
const OBSERVER_PRINT = -2;
|
||||
const OBSERVER_TRIGGER = -4;
|
||||
const OBSERVER_DIE = -8;
|
||||
protected $cause;
|
||||
private static $_observers = array();
|
||||
private static $_uniqueid = 0;
|
||||
private $_trace;
|
||||
|
||||
/**
|
||||
* Supported signatures:
|
||||
* - PEAR_Exception(string $message);
|
||||
* - PEAR_Exception(string $message, int $code);
|
||||
* - PEAR_Exception(string $message, Exception $cause);
|
||||
* - PEAR_Exception(string $message, Exception $cause, int $code);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
|
||||
* - PEAR_Exception(string $message, array $causes);
|
||||
* - PEAR_Exception(string $message, array $causes, int $code);
|
||||
* @param string exception message
|
||||
* @param int|Exception|PEAR_Error|array|null exception cause
|
||||
* @param int|null exception code or null
|
||||
*/
|
||||
public function __construct($message, $p2 = null, $p3 = null)
|
||||
{
|
||||
if (is_int($p2)) {
|
||||
$code = $p2;
|
||||
$this->cause = null;
|
||||
} elseif (is_object($p2) || is_array($p2)) {
|
||||
// using is_object allows both Exception and PEAR_Error
|
||||
if (is_object($p2) && !($p2 instanceof Exception)) {
|
||||
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
|
||||
throw new PEAR_Exception('exception cause must be Exception, ' .
|
||||
'array, or PEAR_Error');
|
||||
}
|
||||
}
|
||||
$code = $p3;
|
||||
if (is_array($p2) && isset($p2['message'])) {
|
||||
// fix potential problem of passing in a single warning
|
||||
$p2 = array($p2);
|
||||
}
|
||||
$this->cause = $p2;
|
||||
} else {
|
||||
$code = null;
|
||||
$this->cause = null;
|
||||
}
|
||||
parent::__construct($message, $code);
|
||||
$this->signal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $callback - A valid php callback, see php func is_callable()
|
||||
* - A PEAR_Exception::OBSERVER_* constant
|
||||
* - An array(const PEAR_Exception::OBSERVER_*,
|
||||
* mixed $options)
|
||||
* @param string $label The name of the observer. Use this if you want
|
||||
* to remove it later with removeObserver()
|
||||
*/
|
||||
public static function addObserver($callback, $label = 'default')
|
||||
{
|
||||
self::$_observers[$label] = $callback;
|
||||
}
|
||||
|
||||
public static function removeObserver($label = 'default')
|
||||
{
|
||||
unset(self::$_observers[$label]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int unique identifier for an observer
|
||||
*/
|
||||
public static function getUniqueId()
|
||||
{
|
||||
return self::$_uniqueid++;
|
||||
}
|
||||
|
||||
private function signal()
|
||||
{
|
||||
foreach (self::$_observers as $func) {
|
||||
if (is_callable($func)) {
|
||||
call_user_func($func, $this);
|
||||
continue;
|
||||
}
|
||||
settype($func, 'array');
|
||||
switch ($func[0]) {
|
||||
case self::OBSERVER_PRINT :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
printf($f, $this->getMessage());
|
||||
break;
|
||||
case self::OBSERVER_TRIGGER :
|
||||
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
|
||||
trigger_error($this->getMessage(), $f);
|
||||
break;
|
||||
case self::OBSERVER_DIE :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
die(printf($f, $this->getMessage()));
|
||||
break;
|
||||
default:
|
||||
trigger_error('invalid observer type', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return specific error information that can be used for more detailed
|
||||
* error messages or translation.
|
||||
*
|
||||
* This method may be overridden in child exception classes in order
|
||||
* to add functionality not present in PEAR_Exception and is a placeholder
|
||||
* to define API
|
||||
*
|
||||
* The returned array must be an associative array of parameter => value like so:
|
||||
* <pre>
|
||||
* array('name' => $name, 'context' => array(...))
|
||||
* </pre>
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorData()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception that caused this exception to be thrown
|
||||
* @access public
|
||||
* @return Exception|array The context of the exception
|
||||
*/
|
||||
public function getCause()
|
||||
{
|
||||
return $this->cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function must be public to call on caused exceptions
|
||||
* @param array
|
||||
*/
|
||||
public function getCauseMessage(&$causes)
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$cause = array('class' => get_class($this),
|
||||
'message' => $this->message,
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
if (isset($trace[0])) {
|
||||
if (isset($trace[0]['file'])) {
|
||||
$cause['file'] = $trace[0]['file'];
|
||||
$cause['line'] = $trace[0]['line'];
|
||||
}
|
||||
}
|
||||
$causes[] = $cause;
|
||||
if ($this->cause instanceof PEAR_Exception) {
|
||||
$this->cause->getCauseMessage($causes);
|
||||
} elseif ($this->cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => $this->cause->getFile(),
|
||||
'line' => $this->cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($this->cause)) {
|
||||
foreach ($this->cause as $cause) {
|
||||
if ($cause instanceof PEAR_Exception) {
|
||||
$cause->getCauseMessage($causes);
|
||||
} elseif ($cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => $cause->getFile(),
|
||||
'line' => $cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($cause) && isset($cause['message'])) {
|
||||
// PEAR_ErrorStack warning
|
||||
$causes[] = array(
|
||||
'class' => $cause['package'],
|
||||
'message' => $cause['message'],
|
||||
'file' => isset($cause['context']['file']) ?
|
||||
$cause['context']['file'] :
|
||||
'unknown',
|
||||
'line' => isset($cause['context']['line']) ?
|
||||
$cause['context']['line'] :
|
||||
'unknown',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTraceSafe()
|
||||
{
|
||||
if (!isset($this->_trace)) {
|
||||
$this->_trace = $this->getTrace();
|
||||
if (empty($this->_trace)) {
|
||||
$backtrace = debug_backtrace();
|
||||
$this->_trace = array($backtrace[count($backtrace)-1]);
|
||||
}
|
||||
}
|
||||
return $this->_trace;
|
||||
}
|
||||
|
||||
public function getErrorClass()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['class'];
|
||||
}
|
||||
|
||||
public function getErrorMethod()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['function'];
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_URI'])) {
|
||||
return $this->toHtml();
|
||||
}
|
||||
return $this->toText();
|
||||
}
|
||||
|
||||
public function toHtml()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$html = '<table border="1" cellspacing="0">' . "\n";
|
||||
foreach ($causes as $i => $cause) {
|
||||
$html .= '<tr><td colspan="3" bgcolor="#ff9999">'
|
||||
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
|
||||
. htmlspecialchars($cause['message'], ENT_COMPAT | ENT_HTML401, 'UTF-8', false) . ' in <b>' . $cause['file'] . '</b> '
|
||||
. 'on line <b>' . $cause['line'] . '</b>'
|
||||
. "</td></tr>\n";
|
||||
}
|
||||
$html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
|
||||
. '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
|
||||
. '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
|
||||
. '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
|
||||
|
||||
foreach ($trace as $k => $v) {
|
||||
$html .= '<tr><td align="center">' . $k . '</td>'
|
||||
. '<td>';
|
||||
if (!empty($v['class'])) {
|
||||
$html .= $v['class'] . $v['type'];
|
||||
}
|
||||
$html .= $v['function'];
|
||||
$args = array();
|
||||
if (!empty($v['args'])) {
|
||||
foreach ($v['args'] as $arg) {
|
||||
if (is_null($arg)) $args[] = 'null';
|
||||
elseif (is_array($arg)) $args[] = 'Array';
|
||||
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
|
||||
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
|
||||
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
|
||||
else {
|
||||
$arg = (string)$arg;
|
||||
$str = htmlspecialchars(substr($arg, 0, 16), ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
|
||||
if (strlen($arg) > 16) $str .= '…';
|
||||
$args[] = "'" . $str . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
$html .= '(' . implode(', ',$args) . ')'
|
||||
. '</td>'
|
||||
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
|
||||
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
|
||||
. '</td></tr>' . "\n";
|
||||
}
|
||||
$html .= '<tr><td align="center">' . ($k+1) . '</td>'
|
||||
. '<td>{main}</td>'
|
||||
. '<td> </td></tr>' . "\n"
|
||||
. '</table>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function toText()
|
||||
{
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$causeMsg = '';
|
||||
foreach ($causes as $i => $cause) {
|
||||
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
|
||||
. $cause['message'] . ' in ' . $cause['file']
|
||||
. ' on line ' . $cause['line'] . "\n";
|
||||
}
|
||||
return $causeMsg . $this->getTraceAsString();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This is only meant for PHP 5 to get rid of certain strict warning
|
||||
* that doesn't get hidden since it's in the shutdown function
|
||||
*/
|
||||
class PEAR5
|
||||
{
|
||||
/**
|
||||
* If you have a class that's mostly/entirely static, and you need static
|
||||
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
|
||||
* You MUST use a reference, or they will not persist!
|
||||
*
|
||||
* @access public
|
||||
* @param string $class The calling classname, to prevent clashes
|
||||
* @param string $var The variable to retrieve.
|
||||
* @return mixed A reference to the variable. If not set it will be
|
||||
* auto initialised to NULL.
|
||||
*/
|
||||
static function &getStaticProperty($class, $var)
|
||||
{
|
||||
static $properties;
|
||||
if (!isset($properties[$class])) {
|
||||
$properties[$class] = array();
|
||||
}
|
||||
|
||||
if (!array_key_exists($var, $properties[$class])) {
|
||||
$properties[$class][$var] = null;
|
||||
}
|
||||
|
||||
return $properties[$class][$var];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,106 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Listener for HTTP_Request and HTTP_Response objects
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2002-2007, Richard Heyes
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2002-2007 Richard Heyes
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Listener.php,v 1.3 2007/05/18 10:33:31 avb Exp $
|
||||
* @link http://pear.php.net/package/HTTP_Request/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listener for HTTP_Request and HTTP_Response objects
|
||||
*
|
||||
* This class implements the Observer part of a Subject-Observer
|
||||
* design pattern.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @version Release: 1.4.1
|
||||
*/
|
||||
class HTTP_Request_Listener
|
||||
{
|
||||
/**
|
||||
* A listener's identifier
|
||||
* @var string
|
||||
*/
|
||||
var $_id;
|
||||
|
||||
/**
|
||||
* Constructor, sets the object's identifier
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function HTTP_Request_Listener()
|
||||
{
|
||||
$this->_id = md5(uniqid('http_request_', 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the listener's identifier
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getId()
|
||||
{
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called when Listener is notified of an event
|
||||
*
|
||||
* @access public
|
||||
* @param object an object the listener is attached to
|
||||
* @param string Event name
|
||||
* @param mixed Additional data
|
||||
* @abstract
|
||||
*/
|
||||
function update(&$subject, $event, $data = null)
|
||||
{
|
||||
echo "Notified of event: '$event'\n";
|
||||
if (null !== $data) {
|
||||
echo "Additional data: ";
|
||||
var_dump($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,528 +0,0 @@
|
|||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Stig Bakken <ssb@php.net> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Socket.php,v 1.24 2005/02/03 20:40:16 chagenbu Exp $
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
define('NET_SOCKET_READ', 1);
|
||||
define('NET_SOCKET_WRITE', 2);
|
||||
define('NET_SOCKET_ERROR', 3);
|
||||
|
||||
/**
|
||||
* Generalized Socket class.
|
||||
*
|
||||
* @version 1.1
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
*/
|
||||
class Net_Socket extends PEAR {
|
||||
|
||||
/**
|
||||
* Socket file pointer.
|
||||
* @var resource $fp
|
||||
*/
|
||||
var $fp = null;
|
||||
|
||||
/**
|
||||
* Whether the socket is blocking. Defaults to true.
|
||||
* @var boolean $blocking
|
||||
*/
|
||||
var $blocking = true;
|
||||
|
||||
/**
|
||||
* Whether the socket is persistent. Defaults to false.
|
||||
* @var boolean $persistent
|
||||
*/
|
||||
var $persistent = false;
|
||||
|
||||
/**
|
||||
* The IP address to connect to.
|
||||
* @var string $addr
|
||||
*/
|
||||
var $addr = '';
|
||||
|
||||
/**
|
||||
* The port number to connect to.
|
||||
* @var integer $port
|
||||
*/
|
||||
var $port = 0;
|
||||
|
||||
/**
|
||||
* Number of seconds to wait on socket connections before assuming
|
||||
* there's no more data. Defaults to no timeout.
|
||||
* @var integer $timeout
|
||||
*/
|
||||
var $timeout = false;
|
||||
|
||||
/**
|
||||
* Number of bytes to read at a time in readLine() and
|
||||
* readAll(). Defaults to 2048.
|
||||
* @var integer $lineLength
|
||||
*/
|
||||
var $lineLength = 2048;
|
||||
|
||||
/**
|
||||
* Connect to the specified port. If called when the socket is
|
||||
* already connected, it disconnects and connects again.
|
||||
*
|
||||
* @param string $addr IP address or host name.
|
||||
* @param integer $port TCP port number.
|
||||
* @param boolean $persistent (optional) Whether the connection is
|
||||
* persistent (kept open between requests
|
||||
* by the web server).
|
||||
* @param integer $timeout (optional) How long to wait for data.
|
||||
* @param array $options See options for stream_context_create.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure.
|
||||
*/
|
||||
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
}
|
||||
|
||||
if (!$addr) {
|
||||
return $this->raiseError('$addr cannot be empty');
|
||||
} elseif (strspn($addr, '.0123456789') == strlen($addr) ||
|
||||
strstr($addr, '/') !== false) {
|
||||
$this->addr = $addr;
|
||||
} else {
|
||||
$this->addr = @gethostbyname($addr);
|
||||
}
|
||||
|
||||
$this->port = $port % 65536;
|
||||
|
||||
if ($persistent !== null) {
|
||||
$this->persistent = $persistent;
|
||||
}
|
||||
|
||||
if ($timeout !== null) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
if ($options && function_exists('stream_context_create')) {
|
||||
if ($this->timeout) {
|
||||
$timeout = $this->timeout;
|
||||
} else {
|
||||
$timeout = 0;
|
||||
}
|
||||
$context = stream_context_create($options);
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context);
|
||||
} else {
|
||||
if ($this->timeout) {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
|
||||
} else {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
return $this->raiseError($errstr, $errno);
|
||||
}
|
||||
|
||||
$this->fp = $fp;
|
||||
|
||||
return $this->setBlocking($this->blocking);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from the peer, closes the socket.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if the socket is in blocking mode.
|
||||
*
|
||||
* @access public
|
||||
* @return boolean The current blocking mode.
|
||||
*/
|
||||
function isBlocking()
|
||||
{
|
||||
return $this->blocking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the socket connection should be blocking or
|
||||
* not. A read call to a non-blocking socket will return immediately
|
||||
* if there is no data available, whereas it will block until there
|
||||
* is data for blocking sockets.
|
||||
*
|
||||
* @param boolean $mode True for blocking sockets, false for nonblocking.
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setBlocking($mode)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$this->blocking = $mode;
|
||||
socket_set_blocking($this->fp, $this->blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timeout value on socket descriptor,
|
||||
* expressed in the sum of seconds and microseconds
|
||||
*
|
||||
* @param integer $seconds Seconds.
|
||||
* @param integer $microseconds Microseconds.
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setTimeout($seconds, $microseconds)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return socket_set_timeout($this->fp, $seconds, $microseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about an existing socket resource.
|
||||
* Currently returns four entries in the result array:
|
||||
*
|
||||
* <p>
|
||||
* timed_out (bool) - The socket timed out waiting for data<br>
|
||||
* blocked (bool) - The socket was blocked<br>
|
||||
* eof (bool) - Indicates EOF event<br>
|
||||
* unread_bytes (int) - Number of bytes left in the socket buffer<br>
|
||||
* </p>
|
||||
*
|
||||
* @access public
|
||||
* @return mixed Array containing information about existing socket resource or an error object otherwise
|
||||
*/
|
||||
function getStatus()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return socket_get_status($this->fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified line of data
|
||||
*
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function gets($size)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return @fgets($this->fp, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a specified amount of data. This is guaranteed to return,
|
||||
* and has the added benefit of getting everything in one fread()
|
||||
* chunk; if you know the size of the data you're getting
|
||||
* beforehand, this is definitely the way to go.
|
||||
*
|
||||
* @param integer $size The number of bytes to read from the socket.
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function read($size)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return @fread($this->fp, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a specified amount of data.
|
||||
*
|
||||
* @param string $data Data to write.
|
||||
* @param integer $blocksize Amount of data to write at once.
|
||||
* NULL means all at once.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function write($data, $blocksize = null)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
if (is_null($blocksize) && !OS_WINDOWS) {
|
||||
return fwrite($this->fp, $data);
|
||||
} else {
|
||||
if (is_null($blocksize)) {
|
||||
$blocksize = 1024;
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
$size = strlen($data);
|
||||
while ($pos < $size) {
|
||||
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
|
||||
if ($written === false) {
|
||||
return false;
|
||||
}
|
||||
$pos += $written;
|
||||
}
|
||||
|
||||
return $pos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a line of data to the socket, followed by a trailing "\r\n".
|
||||
*
|
||||
* @access public
|
||||
* @return mixed fputs result, or an error
|
||||
*/
|
||||
function writeLine($data)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return fwrite($this->fp, $data . "\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for end-of-file on a socket descriptor.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function eof()
|
||||
{
|
||||
return (is_resource($this->fp) && feof($this->fp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a byte of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 byte of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readByte()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return ord(@fread($this->fp, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a word of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 word of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readWord()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 2);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an int of data
|
||||
*
|
||||
* @access public
|
||||
* @return integer 1 int of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readInt()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 4);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8) +
|
||||
(ord($buf[2]) << 16) + (ord($buf[3]) << 24));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a zero-terminated string of data
|
||||
*
|
||||
* @access public
|
||||
* @return string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readString()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$string = '';
|
||||
while (($char = @fread($this->fp, 1)) != "\x00") {
|
||||
$string .= $char;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an IP Address and returns it in a dot formated string
|
||||
*
|
||||
* @access public
|
||||
* @return Dot formated string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readIPAddress()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 4);
|
||||
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
|
||||
ord($buf[2]), ord($buf[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read until either the end of the socket or a newline, whichever
|
||||
* comes first. Strips the trailing newline from the returned data.
|
||||
*
|
||||
* @access public
|
||||
* @return All available data up to a newline, without that
|
||||
* newline, or until the end of the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readLine()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$line = '';
|
||||
$timeout = time() + $this->timeout;
|
||||
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
|
||||
$line .= @fgets($this->fp, $this->lineLength);
|
||||
if (substr($line, -1) == "\n") {
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read until the socket closes, or until there is no more data in
|
||||
* the inner PHP buffer. If the inner buffer is empty, in blocking
|
||||
* mode we wait for at least 1 byte of data. Therefore, in
|
||||
* blocking mode, if there is no data at all to be read, this
|
||||
* function will never exit (unless the socket is closed on the
|
||||
* remote end).
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string All data until the socket closes, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readAll()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$data = '';
|
||||
while (!feof($this->fp)) {
|
||||
$data .= @fread($this->fp, $this->lineLength);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the equivalent of the select() system call on the socket
|
||||
* with a timeout specified by tv_sec and tv_usec.
|
||||
*
|
||||
* @param integer $state Which of read/write/error to check for.
|
||||
* @param integer $tv_sec Number of seconds for timeout.
|
||||
* @param integer $tv_usec Number of microseconds for timeout.
|
||||
*
|
||||
* @access public
|
||||
* @return False if select fails, integer describing which of read/write/error
|
||||
* are ready, or PEAR_Error if not connected.
|
||||
*/
|
||||
function select($state, $tv_sec, $tv_usec = 0)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$read = null;
|
||||
$write = null;
|
||||
$except = null;
|
||||
if ($state & NET_SOCKET_READ) {
|
||||
$read[] = $this->fp;
|
||||
}
|
||||
if ($state & NET_SOCKET_WRITE) {
|
||||
$write[] = $this->fp;
|
||||
}
|
||||
if ($state & NET_SOCKET_ERROR) {
|
||||
$except[] = $this->fp;
|
||||
}
|
||||
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
if (count($read)) {
|
||||
$result |= NET_SOCKET_READ;
|
||||
}
|
||||
if (count($write)) {
|
||||
$result |= NET_SOCKET_WRITE;
|
||||
}
|
||||
if (count($except)) {
|
||||
$result |= NET_SOCKET_ERROR;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,410 +0,0 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2002-2004, Richard Heyes |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | o Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | o Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution.|
|
||||
// | o The names of the authors may not be used to endorse or promote |
|
||||
// | products derived from this software without specific prior written |
|
||||
// | permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// | |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Author: Richard Heyes <richard at php net> |
|
||||
// +-----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: URL.php,v 1.36 2004/06/19 18:58:50 richard Exp $
|
||||
//
|
||||
// Net_URL Class
|
||||
|
||||
class Net_URL
|
||||
{
|
||||
/**
|
||||
* Full url
|
||||
* @var string
|
||||
*/
|
||||
var $url;
|
||||
|
||||
/**
|
||||
* Protocol
|
||||
* @var string
|
||||
*/
|
||||
var $protocol;
|
||||
|
||||
/**
|
||||
* Username
|
||||
* @var string
|
||||
*/
|
||||
var $username;
|
||||
|
||||
/**
|
||||
* Password
|
||||
* @var string
|
||||
*/
|
||||
var $password;
|
||||
|
||||
/**
|
||||
* Host
|
||||
* @var string
|
||||
*/
|
||||
var $host;
|
||||
|
||||
/**
|
||||
* Port
|
||||
* @var integer
|
||||
*/
|
||||
var $port;
|
||||
|
||||
/**
|
||||
* Path
|
||||
* @var string
|
||||
*/
|
||||
var $path;
|
||||
|
||||
/**
|
||||
* Query string
|
||||
* @var array
|
||||
*/
|
||||
var $querystring;
|
||||
|
||||
/**
|
||||
* Anchor
|
||||
* @var string
|
||||
*/
|
||||
var $anchor;
|
||||
|
||||
/**
|
||||
* Whether to use []
|
||||
* @var bool
|
||||
*/
|
||||
var $useBrackets;
|
||||
|
||||
/**
|
||||
* PHP4 Constructor
|
||||
*
|
||||
* @see __construct()
|
||||
*/
|
||||
function Net_URL($url = null, $useBrackets = true)
|
||||
{
|
||||
$this->__construct($url, $useBrackets);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP5 Constructor
|
||||
*
|
||||
* Parses the given url and stores the various parts
|
||||
* Defaults are used in certain cases
|
||||
*
|
||||
* @param string $url Optional URL
|
||||
* @param bool $useBrackets Whether to use square brackets when
|
||||
* multiple querystrings with the same name
|
||||
* exist
|
||||
*/
|
||||
function __construct($url = null, $useBrackets = true)
|
||||
{
|
||||
$HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
|
||||
|
||||
$this->useBrackets = $useBrackets;
|
||||
$this->url = $url;
|
||||
$this->user = '';
|
||||
$this->pass = '';
|
||||
$this->host = '';
|
||||
$this->port = 80;
|
||||
$this->path = '';
|
||||
$this->querystring = array();
|
||||
$this->anchor = '';
|
||||
|
||||
// Only use defaults if not an absolute URL given
|
||||
if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) {
|
||||
|
||||
$this->protocol = (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 'https' : 'http');
|
||||
|
||||
/**
|
||||
* Figure out host/port
|
||||
*/
|
||||
if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) {
|
||||
$host = $matches[1];
|
||||
if (!empty($matches[3])) {
|
||||
$port = $matches[3];
|
||||
} else {
|
||||
$port = $this->getStandardPort($this->protocol);
|
||||
}
|
||||
}
|
||||
|
||||
$this->user = '';
|
||||
$this->pass = '';
|
||||
$this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost');
|
||||
$this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol));
|
||||
$this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/';
|
||||
$this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null;
|
||||
$this->anchor = '';
|
||||
}
|
||||
|
||||
// Parse the url and store the various parts
|
||||
if (!empty($url)) {
|
||||
$urlinfo = parse_url($url);
|
||||
|
||||
// Default querystring
|
||||
$this->querystring = array();
|
||||
|
||||
foreach ($urlinfo as $key => $value) {
|
||||
switch ($key) {
|
||||
case 'scheme':
|
||||
$this->protocol = $value;
|
||||
$this->port = $this->getStandardPort($value);
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
case 'pass':
|
||||
case 'host':
|
||||
case 'port':
|
||||
$this->$key = $value;
|
||||
break;
|
||||
|
||||
case 'path':
|
||||
if ($value{0} == '/') {
|
||||
$this->path = $value;
|
||||
} else {
|
||||
$path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path);
|
||||
$this->path = sprintf('%s/%s', $path, $value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'query':
|
||||
$this->querystring = $this->_parseRawQueryString($value);
|
||||
break;
|
||||
|
||||
case 'fragment':
|
||||
$this->anchor = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns full url
|
||||
*
|
||||
* @return string Full url
|
||||
* @access public
|
||||
*/
|
||||
function getURL()
|
||||
{
|
||||
$querystring = $this->getQueryString();
|
||||
|
||||
$this->url = $this->protocol . '://'
|
||||
. $this->user . (!empty($this->pass) ? ':' : '')
|
||||
. $this->pass . (!empty($this->user) ? '@' : '')
|
||||
. $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port)
|
||||
. $this->path
|
||||
. (!empty($querystring) ? '?' . $querystring : '')
|
||||
. (!empty($this->anchor) ? '#' . $this->anchor : '');
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a querystring item
|
||||
*
|
||||
* @param string $name Name of item
|
||||
* @param string $value Value of item
|
||||
* @param bool $preencoded Whether value is urlencoded or not, default = not
|
||||
* @access public
|
||||
*/
|
||||
function addQueryString($name, $value, $preencoded = false)
|
||||
{
|
||||
if ($preencoded) {
|
||||
$this->querystring[$name] = $value;
|
||||
} else {
|
||||
$this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a querystring item
|
||||
*
|
||||
* @param string $name Name of item
|
||||
* @access public
|
||||
*/
|
||||
function removeQueryString($name)
|
||||
{
|
||||
if (isset($this->querystring[$name])) {
|
||||
unset($this->querystring[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the querystring to literally what you supply
|
||||
*
|
||||
* @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc
|
||||
* @access public
|
||||
*/
|
||||
function addRawQueryString($querystring)
|
||||
{
|
||||
$this->querystring = $this->_parseRawQueryString($querystring);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns flat querystring
|
||||
*
|
||||
* @return string Querystring
|
||||
* @access public
|
||||
*/
|
||||
function getQueryString()
|
||||
{
|
||||
if (!empty($this->querystring)) {
|
||||
foreach ($this->querystring as $name => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $k => $v) {
|
||||
$querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v);
|
||||
}
|
||||
} elseif (!is_null($value)) {
|
||||
$querystring[] = $name . '=' . $value;
|
||||
} else {
|
||||
$querystring[] = $name;
|
||||
}
|
||||
}
|
||||
$querystring = implode(ini_get('arg_separator.output'), $querystring);
|
||||
} else {
|
||||
$querystring = '';
|
||||
}
|
||||
|
||||
return $querystring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses raw querystring and returns an array of it
|
||||
*
|
||||
* @param string $querystring The querystring to parse
|
||||
* @return array An array of the querystring data
|
||||
* @access private
|
||||
*/
|
||||
function _parseRawQuerystring($querystring)
|
||||
{
|
||||
$parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$return = array();
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '=') !== false) {
|
||||
$value = substr($part, strpos($part, '=') + 1);
|
||||
$key = substr($part, 0, strpos($part, '='));
|
||||
} else {
|
||||
$value = null;
|
||||
$key = $part;
|
||||
}
|
||||
if (substr($key, -2) == '[]') {
|
||||
$key = substr($key, 0, -2);
|
||||
if (@!is_array($return[$key])) {
|
||||
$return[$key] = array();
|
||||
$return[$key][] = $value;
|
||||
} else {
|
||||
$return[$key][] = $value;
|
||||
}
|
||||
} elseif (!$this->useBrackets AND !empty($return[$key])) {
|
||||
$return[$key] = (array)$return[$key];
|
||||
$return[$key][] = $value;
|
||||
} else {
|
||||
$return[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves //, ../ and ./ from a path and returns
|
||||
* the result. Eg:
|
||||
*
|
||||
* /foo/bar/../boo.php => /foo/boo.php
|
||||
* /foo/bar/../../boo.php => /boo.php
|
||||
* /foo/bar/.././/boo.php => /foo/boo.php
|
||||
*
|
||||
* This method can also be called statically.
|
||||
*
|
||||
* @param string $url URL path to resolve
|
||||
* @return string The result
|
||||
*/
|
||||
function resolvePath($path)
|
||||
{
|
||||
$path = explode('/', str_replace('//', '/', $path));
|
||||
|
||||
for ($i=0; $i<count($path); $i++) {
|
||||
if ($path[$i] == '.') {
|
||||
unset($path[$i]);
|
||||
$path = array_values($path);
|
||||
$i--;
|
||||
|
||||
} elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) {
|
||||
unset($path[$i]);
|
||||
unset($path[$i-1]);
|
||||
$path = array_values($path);
|
||||
$i -= 2;
|
||||
|
||||
} elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') {
|
||||
unset($path[$i]);
|
||||
$path = array_values($path);
|
||||
$i--;
|
||||
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return implode('/', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard port number for a protocol
|
||||
*
|
||||
* @param string $scheme The protocol to lookup
|
||||
* @return integer Port number or NULL if no scheme matches
|
||||
*
|
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
|
||||
*/
|
||||
function getStandardPort($scheme)
|
||||
{
|
||||
switch (strtolower($scheme)) {
|
||||
case 'http': return 80;
|
||||
case 'https': return 443;
|
||||
case 'ftp': return 21;
|
||||
case 'imap': return 143;
|
||||
case 'imaps': return 993;
|
||||
case 'pop3': return 110;
|
||||
case 'pop3s': return 995;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the URL to a particular protocol
|
||||
*
|
||||
* @param string $protocol Protocol to force the URL to
|
||||
* @param integer $port Optional port (standard port is used by default)
|
||||
*/
|
||||
function setProtocol($protocol, $port = null)
|
||||
{
|
||||
$this->protocol = $protocol;
|
||||
$this->port = is_null($port) ? $this->getStandardPort() : $port;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
1108
libs/PEAR/PEAR.php
1108
libs/PEAR/PEAR.php
File diff suppressed because it is too large
Load diff
|
|
@ -1,502 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Boston, MA 02110, United States
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
*******************************************************************************
|
||||
* *
|
||||
* IDNA Convert (idna_convert.class.php) *
|
||||
* *
|
||||
* http://idnaconv.phlymail.de mailto:phlymail@phlylabs.de *
|
||||
*******************************************************************************
|
||||
* (c) 2004-2014 phlyLabs, Berlin *
|
||||
* This file is encoded in UTF-8 *
|
||||
*******************************************************************************
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The class idna_convert allows to convert internationalized domain names
|
||||
(see RFC 3490, 3491, 3492 and 3454 for detials) as they can be used with various
|
||||
registries worldwide to be translated between their original (localized) form
|
||||
and their encoded form as it will be used in the DNS (Domain Name System).
|
||||
|
||||
The class provides two public methods, encode() and decode(), which do exactly
|
||||
what you would expect them to do. You are allowed to use complete domain names,
|
||||
simple strings and complete email addresses as well. That means, that you might
|
||||
use any of the following notations:
|
||||
|
||||
- www.nörgler.com
|
||||
- xn--nrgler-wxa
|
||||
- xn--brse-5qa.xn--knrz-1ra.info
|
||||
|
||||
Errors, incorrectly encoded or invalid strings will lead to either a FALSE
|
||||
response (when in strict mode) or to only partially converted strings.
|
||||
You can query the occured error by calling the method get_last_error().
|
||||
|
||||
Unicode strings are expected to be either UTF-8 strings, UCS-4 strings or UCS-4
|
||||
arrays. The default format is UTF-8. For setting different encodings, you can
|
||||
call the method setParams() - please see the inline documentation for details.
|
||||
ACE strings (the Punycode form) are always 7bit ASCII strings.
|
||||
|
||||
ATTENTION: As of version 0.6.0 this class is written in the OOP style of PHP5.
|
||||
Since PHP4 is no longer actively maintained, you should switch to PHP5 as fast as
|
||||
possible.
|
||||
We expect to see no compatibility issues with the upcoming PHP6, too.
|
||||
|
||||
ATTENTION: BC break! As of version 0.6.4 the class per default allows the German
|
||||
ligature ß to be encoded as the DeNIC, the registry for .DE allows domains
|
||||
containing ß.
|
||||
In older builds "ß" was mapped to "ss". Should you still need this behaviour,
|
||||
see example 5 below.
|
||||
|
||||
ATTENTION: As of version 0.8.0 the class fully supports IDNA 2008. Thus the
|
||||
aforementioned parameter is deprecated and replaced by a parameter to switch
|
||||
between the standards. See the updated example 5 below.
|
||||
|
||||
Files
|
||||
-----
|
||||
idna_convert.class.php - The actual class
|
||||
example.php - An example web page for converting
|
||||
transcode_wrapper.php - Convert various encodings, see below
|
||||
uctc.php - phlyLabs' Unicode Transcoder, see below
|
||||
ReadMe.txt - This file
|
||||
LICENCE - The LGPL licence file
|
||||
|
||||
The class is contained in idna_convert.class.php.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
1. Say we wish to encode the domain name nörgler.com:
|
||||
|
||||
// Include the class
|
||||
require_once('idna_convert.class.php');
|
||||
// Instantiate it
|
||||
$IDN = new idna_convert();
|
||||
// The input string, if input is not UTF-8 or UCS-4, it must be converted before
|
||||
$input = utf8_encode('nörgler.com');
|
||||
// Encode it to its punycode presentation
|
||||
$output = $IDN->encode($input);
|
||||
// Output, what we got now
|
||||
echo $output; // This will read: xn--nrgler-wxa.com
|
||||
|
||||
|
||||
2. We received an email from a punycoded domain and are willing to learn, how
|
||||
the domain name reads originally
|
||||
|
||||
// Include the class
|
||||
require_once('idna_convert.class.php');
|
||||
// Instantiate it
|
||||
$IDN = new idna_convert();
|
||||
// The input string
|
||||
$input = 'andre@xn--brse-5qa.xn--knrz-1ra.info';
|
||||
// Encode it to its punycode presentation
|
||||
$output = $IDN->decode($input);
|
||||
// Output, what we got now, if output should be in a format different to UTF-8
|
||||
// or UCS-4, you will have to convert it before outputting it
|
||||
echo utf8_decode($output); // This will read: andre@börse.knörz.info
|
||||
|
||||
|
||||
3. The input is read from a UCS-4 coded file and encoded line by line. By
|
||||
appending the optional second parameter we tell enode() about the input
|
||||
format to be used
|
||||
|
||||
// Include the class
|
||||
require_once('idna_convert.class.php');
|
||||
// Instantiate it
|
||||
$IDN = new dinca_convert();
|
||||
// Iterate through the input file line by line
|
||||
foreach (file('ucs4-domains.txt') as $line) {
|
||||
echo $IDN->encode(trim($line), 'ucs4_string');
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
|
||||
4. We wish to convert a whole URI into the IDNA form, but leave the path or
|
||||
query string component of it alone. Just using encode() would lead to mangled
|
||||
paths or query strings. Here the public method encode_uri() comes into play:
|
||||
|
||||
// Include the class
|
||||
require_once('idna_convert.class.php');
|
||||
// Instantiate it
|
||||
$IDN = new idna_convert();
|
||||
// The input string, a whole URI in UTF-8 (!)
|
||||
$input = 'http://nörgler:secret@nörgler.com/my_päth_is_not_ÄSCII/');
|
||||
// Encode it to its punycode presentation
|
||||
$output = $IDN->encode_uri($input);
|
||||
// Output, what we got now
|
||||
echo $output; // http://nörgler:secret@xn--nrgler-wxa.com/my_päth_is_not_ÄSCII/
|
||||
|
||||
|
||||
5. To support IDNA 2008, the class needs to be invoked with an additional
|
||||
parameter. This can also be achieved on an instance.
|
||||
|
||||
// Include the class
|
||||
require_once('idna_convert.class.php');
|
||||
// Instantiate it
|
||||
$IDN = new idna_convert(array('idn_version' => 2008));
|
||||
// Sth. containing the German letter ß
|
||||
$input = 'meine-straße.de');
|
||||
// Encode it to its punycode presentation
|
||||
$output = $IDN->encode_uri($input);
|
||||
// Output, what we got now
|
||||
echo $output; // xn--meine-strae-46a.de
|
||||
// Switch back to old IDNA 2003, the original standard
|
||||
$IDN->set_parameter('idn_version', 2003);
|
||||
// Sth. containing the German letter ß
|
||||
$input = 'meine-straße.de');
|
||||
// Encode it to its punycode presentation
|
||||
$output = $IDN->encode_uri($input);
|
||||
// Output, what we got now
|
||||
echo $output; // meine-strasse.de
|
||||
|
||||
|
||||
Transcode wrapper
|
||||
-----------------
|
||||
In case you have strings in different encoding than ISO-8859-1 and UTF-8 you might need to
|
||||
translate these strings to UTF-8 before feeding the IDNA converter with it.
|
||||
PHP's built in functions utf8_encode() and utf8_decode() can only deal with ISO-8859-1.
|
||||
Use the file transcode_wrapper.php for the conversion. It requires either iconv, libiconv
|
||||
or mbstring installed together with one of the relevant PHP extensions.
|
||||
The functions you will find useful are
|
||||
encode_utf8() as a replacement for utf8_encode() and
|
||||
decode_utf8() as a replacement for utf8_decode().
|
||||
|
||||
Example usage:
|
||||
<?php
|
||||
require_once('idna_convert.class.php');
|
||||
require_once('transcode_wrapper.php');
|
||||
$mystring = '<something in e.g. ISO-8859-15';
|
||||
$mystring = encode_utf8($mystring, 'ISO-8859-15');
|
||||
echo $IDN->encode($mystring);
|
||||
?>
|
||||
|
||||
|
||||
UCTC - Unicode Transcoder
|
||||
-------------------------
|
||||
Another class you might find useful when dealing with one or more of the Unicode encoding
|
||||
flavours. The class is static, it requires PHP5. It can transcode into each other:
|
||||
- UCS-4 string / array
|
||||
- UTF-8
|
||||
- UTF-7
|
||||
- UTF-7 IMAP (modified UTF-7)
|
||||
All encodings expect / return a string in the given format, with one major exception:
|
||||
UCS-4 array is jsut an array, where each value represents one codepoint in the string, i.e.
|
||||
every value is a 32bit integer value.
|
||||
|
||||
Example usage:
|
||||
<?php
|
||||
require_once('uctc.php');
|
||||
$mystring = 'nörgler.com';
|
||||
echo uctc::convert($mystring, 'utf8', 'utf7imap');
|
||||
?>
|
||||
|
||||
|
||||
Contact us
|
||||
----------
|
||||
In case of errors, bugs, questions, wishes, please don't hesitate to contact us
|
||||
under the email address above.
|
||||
|
||||
The team of phlyLabs
|
||||
http://phlylabs.de
|
||||
mailto:phlymail@phlylabs.de
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
$encoded = $decoded = $add = '';
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
require_once('idna_convert.class.php');
|
||||
|
||||
$idn_version = isset($_REQUEST['idn_version']) && $_REQUEST['idn_version'] == 2003 ? 2003 : 2008;
|
||||
$IDN = new idna_convert(array('idn_version' => $idn_version));
|
||||
|
||||
$version_select = '<select size="1" name="idn_version"><option value="2003">IDNA 2003</option><option value="2008"';
|
||||
if ($idn_version == 2008) {
|
||||
$version_select .= ' selected="selected"';
|
||||
}
|
||||
$version_select .= '>IDNA 2008</option></select>';
|
||||
|
||||
if (isset($_REQUEST['encode'])) {
|
||||
$decoded = isset($_REQUEST['decoded']) ? stripslashes($_REQUEST['decoded']) : '';
|
||||
$encoded = $IDN->encode($decoded);
|
||||
}
|
||||
if (isset($_REQUEST['decode'])) {
|
||||
$encoded = isset($_REQUEST['encoded']) ? stripslashes($_REQUEST['encoded']) : '';
|
||||
$decoded = $IDN->decode($encoded);
|
||||
}
|
||||
$lang = 'en';
|
||||
if (isset($_REQUEST['lang'])) {
|
||||
if ('de' == $_REQUEST['lang'] || 'en' == $_REQUEST['lang']) {
|
||||
$lang = $_REQUEST['lang'];
|
||||
$add .= '<input type="hidden" name="lang" value="'.$lang.'" />'."\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>phlyLabs Punycode Converter</title>
|
||||
<meta name="author" content="phlyLabs" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
body { color:black;background:white;font-size:10pt;font-family:Verdana,Helvetica,Sans-Serif; }
|
||||
body, form { margin:0; }
|
||||
form { display:inline; }
|
||||
input { font-size:8pt;font-family:Verdana,Helvetica,Sans-Serif; }
|
||||
#round { width:730px;padding:10px;background-color:rgb(230,230,240);border:1px solid black;text-align:center;vertical-align:middle;margin:auto;margin-top:50px; }
|
||||
th { font-size:9pt;font-weight:bold; }
|
||||
#copy { font-size:8pt;color:rgb(60,60,80); }
|
||||
#subhead { font-size:8pt; }
|
||||
#bla { font-size:8pt;text-align:left; }
|
||||
h5 {margin:0;font-size:11pt;font-weight:bold;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="round">
|
||||
<h5>phlyLabs' pure PHP IDNA Converter</h5><br />
|
||||
<span id="subhead">
|
||||
See the RFCs <a href="http://faqs.org/rfcs/rfc3490.html" title="IDNA" target="_blank">3490</a>,
|
||||
<a href="http://faqs.org/rfcs/rfc3491.html" title="Nameprep, a Stringprep profile" target="_blank">3491</a>,
|
||||
<a href="http://faqs.org/rfcs/rfc3492.html" title="Punycode" target="_blank">3492</a> and
|
||||
<a href="http://faqs.org/rfcs/rfc3454.html" title="Stringprep" target="_blank">3454</a> as well as
|
||||
<a href="http://faqs.org/rfcs/rfc5890.html" target="_blank">5890</a>,
|
||||
<a href="http://faqs.org/rfcs/rfc5891.html" target="_blank">5891</a>,
|
||||
<a href="http://faqs.org/rfcs/rfc5892.html" target="_blank">5892</a>,
|
||||
<a href="http://faqs.org/rfcs/rfc5893.html" target="_blank">5893</a> and
|
||||
<a href="http://faqs.org/rfcs/rfc5894.html" target="_blank">RFC5894</a>.<br />
|
||||
</span>
|
||||
<br />
|
||||
<div id="bla"><?php if ($lang == 'de') { ?>
|
||||
Dieser Konverter erlaubt die Übersetzung von Domainnamen zwischen der Punycode- und der
|
||||
Unicode-Schreibweise.<br />
|
||||
Geben Sie einfach den Domainnamen im entsprechend bezeichneten Feld ein und klicken Sie dann auf den darunter
|
||||
liegenden Button. Sie können einfache Domainnamen, komplette URLs (wie http://jürgen-müller.de)
|
||||
oder Emailadressen eingeben.<br />
|
||||
<br />
|
||||
Stellen Sie aber sicher, dass Ihr Browser den Zeichensatz <strong>UTF-8</strong> unterstützt.<br />
|
||||
<br />
|
||||
Wenn Sie Interesse an der zugrundeliegenden PHP-Klasse haben, können Sie diese
|
||||
<a href="http://phlymail.com/de/downloads/idna-convert.html">hier herunterladen</a>.<br />
|
||||
<br />
|
||||
Diese Klasse wird ohne Garantie ihrer Funktionstüchtigkeit bereit gestellt. Nutzung auf eigene Gefahr.<br />
|
||||
Um sicher zu stellen, dass eine Zeichenkette korrekt umgewandelt wurde, sollten Sie diese immer zurückwandeln
|
||||
und das Ergebnis mit Ihrer ursprünglichen Eingabe vergleichen.<br />
|
||||
<br />
|
||||
Fehler und Probleme können Sie gern an <a href="mailto:team@phlymail.de">team@phlymail.de</a> senden.<br />
|
||||
<?php } else { ?>
|
||||
This converter allows you to transfer domain names between the encoded (Punycode) notation
|
||||
and the decoded (UTF-8) notation.<br />
|
||||
Just enter the domain name in the respective field and click on the button right below it to have
|
||||
it converted. Please note, that you might even enter complete domain names (like jürgen-müller.de)
|
||||
or a email addresses.<br />
|
||||
<br />
|
||||
Make sure, that your browser is capable of the <strong>UTF-8</strong> character encoding.<br />
|
||||
<br />
|
||||
For those of you interested in the PHP source of the underlying class, you might
|
||||
<a href="http://phlymail.com/en/downloads/idna-convert.html">download it here</a>.<br />
|
||||
<br />
|
||||
Please be aware, that this class is provided as is and without any liability. Use at your own risk.<br />
|
||||
To ensure, that a certain string has been converted correctly, you should convert it both ways and compare the
|
||||
results.<br />
|
||||
<br />
|
||||
Please feel free to report bugs and problems to: <a href="mailto:team@phlymail.com">team@phlymail.com</a>.<br />
|
||||
<?php } ?>
|
||||
<br />
|
||||
</div>
|
||||
<table border="0" cellpadding="2" cellspacing="2" align="center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left">Original (Unicode)</th>
|
||||
<th align="right">Punycode (ACE)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="right">
|
||||
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="get">
|
||||
<input type="text" name="decoded" value="<?php echo htmlspecialchars($decoded, ENT_QUOTES, 'UTF-8'); ?>" size="48" maxlength="255" /><br />
|
||||
<?php echo $version_select; ?>
|
||||
<input type="submit" name="encode" value="Encode >>" /><?php echo $add; ?>
|
||||
</form>
|
||||
</td>
|
||||
<td align="left">
|
||||
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="get">
|
||||
<input type="text" name="encoded" value="<?php echo htmlspecialchars($encoded, ENT_QUOTES, 'UTF-8'); ?>" size="48" maxlength="255" /><br />
|
||||
<input type="submit" name="decode" value="<< Decode" /><?php echo $add; ?>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<span id="copy">Version used: 0.9.0; © 2004-2014 phlyLabs Berlin; part of <a href="http://phlymail.com/">phlyMail</a></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,137 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* transcode wrapper functions
|
||||
* @package IDNA Convert
|
||||
* @subpackage charset transcoding
|
||||
* @author Matthias Sommerfeld, <mso@phlylabs.de>
|
||||
* @version 0.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert a string from any of various encodings to UTF-8
|
||||
*
|
||||
* @param string String to encode
|
||||
*[@param string Encoding; Default: ISO-8859-1]
|
||||
*[@param bool Safe Mode: if set to TRUE, the original string is retunred on errors]
|
||||
* @return string The encoded string or false on failure
|
||||
* @since 0.0.1
|
||||
*/
|
||||
function encode_utf8($string = '', $encoding = 'iso-8859-1', $safe_mode = false)
|
||||
{
|
||||
$safe = ($safe_mode) ? $string : false;
|
||||
if (strtoupper($encoding) == 'UTF-8' || strtoupper($encoding) == 'UTF8') {
|
||||
return $string;
|
||||
} elseif (strtoupper($encoding) == 'ISO-8859-1') {
|
||||
return utf8_encode($string);
|
||||
} elseif (strtoupper($encoding) == 'WINDOWS-1252') {
|
||||
return utf8_encode(map_w1252_iso8859_1($string));
|
||||
} elseif (strtoupper($encoding) == 'UNICODE-1-1-UTF-7') {
|
||||
$encoding = 'utf-7';
|
||||
}
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$conv = @mb_convert_encoding($string, 'UTF-8', strtoupper($encoding));
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
if (function_exists('iconv')) {
|
||||
$conv = @iconv(strtoupper($encoding), 'UTF-8', $string);
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
if (function_exists('libiconv')) {
|
||||
$conv = @libiconv(strtoupper($encoding), 'UTF-8', $string);
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string from UTF-8 to any of various encodings
|
||||
*
|
||||
* @param string String to decode
|
||||
*[@param string Encoding; Default: ISO-8859-1]
|
||||
*[@param bool Safe Mode: if set to TRUE, the original string is retunred on errors]
|
||||
* @return string The decoded string or false on failure
|
||||
* @since 0.0.1
|
||||
*/
|
||||
function decode_utf8($string = '', $encoding = 'iso-8859-1', $safe_mode = false)
|
||||
{
|
||||
$safe = ($safe_mode) ? $string : false;
|
||||
if (!$encoding) $encoding = 'ISO-8859-1';
|
||||
if (strtoupper($encoding) == 'UTF-8' || strtoupper($encoding) == 'UTF8') {
|
||||
return $string;
|
||||
} elseif (strtoupper($encoding) == 'ISO-8859-1') {
|
||||
return utf8_decode($string);
|
||||
} elseif (strtoupper($encoding) == 'WINDOWS-1252') {
|
||||
return map_iso8859_1_w1252(utf8_decode($string));
|
||||
} elseif (strtoupper($encoding) == 'UNICODE-1-1-UTF-7') {
|
||||
$encoding = 'utf-7';
|
||||
}
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$conv = @mb_convert_encoding($string, strtoupper($encoding), 'UTF-8');
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
if (function_exists('iconv')) {
|
||||
$conv = @iconv('UTF-8', strtoupper($encoding), $string);
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
if (function_exists('libiconv')) {
|
||||
$conv = @libiconv('UTF-8', strtoupper($encoding), $string);
|
||||
if ($conv) return $conv;
|
||||
}
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special treatment for our guys in Redmond
|
||||
* Windows-1252 is basically ISO-8859-1 -- with some exceptions, which get accounted for here
|
||||
* @param string Your input in Win1252
|
||||
* @param string The resulting ISO-8859-1 string
|
||||
* @since 3.0.8
|
||||
*/
|
||||
function map_w1252_iso8859_1($string = '')
|
||||
{
|
||||
if ($string == '') return '';
|
||||
$return = '';
|
||||
for ($i = 0; $i < strlen($string); ++$i) {
|
||||
$c = ord($string{$i});
|
||||
switch ($c) {
|
||||
case 129: $return .= chr(252); break;
|
||||
case 132: $return .= chr(228); break;
|
||||
case 142: $return .= chr(196); break;
|
||||
case 148: $return .= chr(246); break;
|
||||
case 153: $return .= chr(214); break;
|
||||
case 154: $return .= chr(220); break;
|
||||
case 225: $return .= chr(223); break;
|
||||
default: $return .= chr($c); break;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special treatment for our guys in Redmond
|
||||
* Windows-1252 is basically ISO-8859-1 -- with some exceptions, which get accounted for here
|
||||
* @param string Your input in ISO-8859-1
|
||||
* @param string The resulting Win1252 string
|
||||
* @since 3.0.8
|
||||
*/
|
||||
function map_iso8859_1_w1252($string = '')
|
||||
{
|
||||
if ($string == '') return '';
|
||||
$return = '';
|
||||
for ($i = 0; $i < strlen($string); ++$i) {
|
||||
$c = ord($string{$i});
|
||||
switch ($c) {
|
||||
case 196: $return .= chr(142); break;
|
||||
case 214: $return .= chr(153); break;
|
||||
case 220: $return .= chr(154); break;
|
||||
case 223: $return .= chr(225); break;
|
||||
case 228: $return .= chr(132); break;
|
||||
case 246: $return .= chr(148); break;
|
||||
case 252: $return .= chr(129); break;
|
||||
default: $return .= chr($c); break;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,300 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* UCTC - The Unicode Transcoder
|
||||
*
|
||||
* Converts between various flavours of Unicode representations like UCS-4 or UTF-8
|
||||
* Supported schemes:
|
||||
* - UCS-4 Little Endian / Big Endian / Array (partially)
|
||||
* - UTF-16 Little Endian / Big Endian (not yet)
|
||||
* - UTF-8
|
||||
* - UTF-7
|
||||
* - UTF-7 IMAP (modified UTF-7)
|
||||
*
|
||||
* @package phlyMail Nahariya 4.0+ Default branch
|
||||
* @author Matthias Sommerfeld <mso@phlyLabs.de>
|
||||
* @copyright 2003-2009 phlyLabs Berlin, http://phlylabs.de
|
||||
* @version 0.0.6 2009-05-10
|
||||
*/
|
||||
class uctc {
|
||||
private static $mechs = array('ucs4', /*'ucs4le', 'ucs4be', */'ucs4array', /*'utf16', 'utf16le', 'utf16be', */'utf8', 'utf7', 'utf7imap');
|
||||
private static $allow_overlong = false;
|
||||
private static $safe_mode;
|
||||
private static $safe_char;
|
||||
|
||||
/**
|
||||
* The actual conversion routine
|
||||
*
|
||||
* @param mixed $data The data to convert, usually a string, array when converting from UCS-4 array
|
||||
* @param string $from Original encoding of the data
|
||||
* @param string $to Target encoding of the data
|
||||
* @param bool $safe_mode SafeMode tries to correct invalid codepoints
|
||||
* @return mixed False on failure, String or array on success, depending on target encoding
|
||||
* @access public
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public static function convert($data, $from, $to, $safe_mode = false, $safe_char = 0xFFFC)
|
||||
{
|
||||
self::$safe_mode = ($safe_mode) ? true : false;
|
||||
self::$safe_char = ($safe_char) ? $safe_char : 0xFFFC;
|
||||
if (self::$safe_mode) self::$allow_overlong = true;
|
||||
if (!in_array($from, self::$mechs)) throw new Exception('Invalid input format specified');
|
||||
if (!in_array($to, self::$mechs)) throw new Exception('Invalid output format specified');
|
||||
if ($from != 'ucs4array') eval('$data = self::'.$from.'_ucs4array($data);');
|
||||
if ($to != 'ucs4array') eval('$data = self::ucs4array_'.$to.'($data);');
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This converts an UTF-8 encoded string to its UCS-4 representation
|
||||
*
|
||||
* @param string $input The UTF-8 string to convert
|
||||
* @return array Array of 32bit values representing each codepoint
|
||||
* @access private
|
||||
*/
|
||||
private static function utf8_ucs4array($input)
|
||||
{
|
||||
$output = array();
|
||||
$out_len = 0;
|
||||
$inp_len = strlen($input);
|
||||
$mode = 'next';
|
||||
$test = 'none';
|
||||
for ($k = 0; $k < $inp_len; ++$k) {
|
||||
$v = ord($input{$k}); // Extract byte from input string
|
||||
|
||||
if ($v < 128) { // We found an ASCII char - put into stirng as is
|
||||
$output[$out_len] = $v;
|
||||
++$out_len;
|
||||
if ('add' == $mode) {
|
||||
if (self::$safe_mode) {
|
||||
$output[$out_len-2] = self::$safe_char;
|
||||
$mode = 'next';
|
||||
} else {
|
||||
throw new Exception('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char
|
||||
$start_byte = $v;
|
||||
$mode = 'add';
|
||||
$test = 'range';
|
||||
if ($v >> 5 == 6) { // &110xxxxx 10xxxxx
|
||||
$next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
|
||||
$v = ($v - 192) << 6;
|
||||
} elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx
|
||||
$next_byte = 1;
|
||||
$v = ($v - 224) << 12;
|
||||
} elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
$next_byte = 2;
|
||||
$v = ($v - 240) << 18;
|
||||
} elseif (self::$safe_mode) {
|
||||
$mode = 'next';
|
||||
$output[$out_len] = self::$safe_char;
|
||||
++$out_len;
|
||||
continue;
|
||||
} else {
|
||||
throw new Exception('This might be UTF-8, but I don\'t understand it at byte '.$k);
|
||||
}
|
||||
if ($inp_len-$k-$next_byte < 2) {
|
||||
$output[$out_len] = self::$safe_char;
|
||||
$mode = 'no';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('add' == $mode) {
|
||||
$output[$out_len] = (int) $v;
|
||||
++$out_len;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('add' == $mode) {
|
||||
if (!self::$allow_overlong && $test == 'range') {
|
||||
$test = 'none';
|
||||
if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) {
|
||||
throw new Exception('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
|
||||
}
|
||||
}
|
||||
if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx
|
||||
$v = ($v-128) << ($next_byte*6);
|
||||
$output[($out_len-1)] += $v;
|
||||
--$next_byte;
|
||||
} else {
|
||||
if (self::$safe_mode) {
|
||||
$output[$out_len-1] = ord(self::$safe_char);
|
||||
$k--;
|
||||
$mode = 'next';
|
||||
continue;
|
||||
} else {
|
||||
throw new Exception('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
|
||||
}
|
||||
}
|
||||
if ($next_byte < 0) {
|
||||
$mode = 'next';
|
||||
}
|
||||
}
|
||||
} // for
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UCS-4 string into UTF-8 string
|
||||
* See utf8_ucs4array() for details
|
||||
* @access private
|
||||
*/
|
||||
private static function ucs4array_utf8($input)
|
||||
{
|
||||
$output = '';
|
||||
foreach ($input as $v) {
|
||||
if ($v < 128) { // 7bit are transferred literally
|
||||
$output .= chr($v);
|
||||
} elseif ($v < (1 << 11)) { // 2 bytes
|
||||
$output .= chr(192+($v >> 6)).chr(128+($v & 63));
|
||||
} elseif ($v < (1 << 16)) { // 3 bytes
|
||||
$output .= chr(224+($v >> 12)).chr(128+(($v >> 6) & 63)).chr(128+($v & 63));
|
||||
} elseif ($v < (1 << 21)) { // 4 bytes
|
||||
$output .= chr(240+($v >> 18)).chr(128+(($v >> 12) & 63)).chr(128+(($v >> 6) & 63)).chr(128+($v & 63));
|
||||
} elseif (self::$safe_mode) {
|
||||
$output .= self::$safe_char;
|
||||
} else {
|
||||
throw new Exception('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k);
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
private static function utf7imap_ucs4array($input)
|
||||
{
|
||||
return self::utf7_ucs4array(str_replace(',', '/', $input), '&');
|
||||
}
|
||||
|
||||
private static function utf7_ucs4array($input, $sc = '+')
|
||||
{
|
||||
$output = array();
|
||||
$out_len = 0;
|
||||
$inp_len = strlen($input);
|
||||
$mode = 'd';
|
||||
$b64 = '';
|
||||
|
||||
for ($k = 0; $k < $inp_len; ++$k) {
|
||||
$c = $input{$k};
|
||||
if (0 == ord($c)) continue; // Ignore zero bytes
|
||||
if ('b' == $mode) {
|
||||
// Sequence got terminated
|
||||
if (!preg_match('![A-Za-z0-9/'.preg_quote($sc, '!').']!', $c)) {
|
||||
if ('-' == $c) {
|
||||
if ($b64 == '') {
|
||||
$output[$out_len] = ord($sc);
|
||||
$out_len++;
|
||||
$mode = 'd';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$tmp = base64_decode($b64);
|
||||
$tmp = substr($tmp, -1 * (strlen($tmp) % 2));
|
||||
for ($i = 0; $i < strlen($tmp); $i++) {
|
||||
if ($i % 2) {
|
||||
$output[$out_len] += ord($tmp{$i});
|
||||
$out_len++;
|
||||
} else {
|
||||
$output[$out_len] = ord($tmp{$i}) << 8;
|
||||
}
|
||||
}
|
||||
$mode = 'd';
|
||||
$b64 = '';
|
||||
continue;
|
||||
} else {
|
||||
$b64 .= $c;
|
||||
}
|
||||
}
|
||||
if ('d' == $mode) {
|
||||
if ($sc == $c) {
|
||||
$mode = 'b';
|
||||
continue;
|
||||
}
|
||||
$output[$out_len] = ord($c);
|
||||
$out_len++;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
private static function ucs4array_utf7imap($input)
|
||||
{
|
||||
return str_replace('/', ',', self::ucs4array_utf7($input, '&'));
|
||||
}
|
||||
|
||||
private static function ucs4array_utf7($input, $sc = '+')
|
||||
{
|
||||
$output = '';
|
||||
$mode = 'd';
|
||||
$b64 = '';
|
||||
while (true) {
|
||||
$v = (!empty($input)) ? array_shift($input) : false;
|
||||
$is_direct = (false !== $v) ? (0x20 <= $v && $v <= 0x7e && $v != ord($sc)) : true;
|
||||
if ($mode == 'b') {
|
||||
if ($is_direct) {
|
||||
if ($b64 == chr(0).$sc) {
|
||||
$output .= $sc.'-';
|
||||
$b64 = '';
|
||||
} elseif ($b64) {
|
||||
$output .= $sc.str_replace('=', '', base64_encode($b64)).'-';
|
||||
$b64 = '';
|
||||
}
|
||||
$mode = 'd';
|
||||
} elseif (false !== $v) {
|
||||
$b64 .= chr(($v >> 8) & 255). chr($v & 255);
|
||||
}
|
||||
}
|
||||
if ($mode == 'd' && false !== $v) {
|
||||
if ($is_direct) {
|
||||
$output .= chr($v);
|
||||
} else {
|
||||
$b64 = chr(($v >> 8) & 255). chr($v & 255);
|
||||
$mode = 'b';
|
||||
}
|
||||
}
|
||||
if (false === $v && $b64 == '') break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UCS-4 array into UCS-4 string (Little Endian at the moment)
|
||||
* @access private
|
||||
*/
|
||||
private static function ucs4array_ucs4($input)
|
||||
{
|
||||
$output = '';
|
||||
foreach ($input as $v) {
|
||||
$output .= chr(($v >> 24) & 255).chr(($v >> 16) & 255).chr(($v >> 8) & 255).chr($v & 255);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UCS-4 string (LE in the moment) into UCS-4 garray
|
||||
* @access private
|
||||
*/
|
||||
private static function ucs4_ucs4array($input)
|
||||
{
|
||||
$output = array();
|
||||
|
||||
$inp_len = strlen($input);
|
||||
// Input length must be dividable by 4
|
||||
if ($inp_len % 4) {
|
||||
throw new Exception('Input UCS4 string is broken');
|
||||
}
|
||||
// Empty input - return empty output
|
||||
if (!$inp_len) return $output;
|
||||
|
||||
for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) {
|
||||
if (!($i % 4)) { // Increment output position every 4 input bytes
|
||||
$out_len++;
|
||||
$output[$out_len] = 0;
|
||||
}
|
||||
$output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,504 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1 +0,0 @@
|
|||
<!DOCTYPE html><title></title>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<!DOCTYPE html><title></title>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPMailer language file.
|
||||
* English Version
|
||||
*/
|
||||
|
||||
$PHPMAILER_LANG = array();
|
||||
|
||||
$PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
|
||||
'recipient email address.';
|
||||
$PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
|
||||
$PHPMAILER_LANG["execute"] = 'Could not execute: ';
|
||||
$PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
|
||||
$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
|
||||
$PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
|
||||
$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
|
||||
'recipients failed: ';
|
||||
$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
|
||||
$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
|
||||
$PHPMAILER_LANG["file_access"] = 'Could not access file: ';
|
||||
$PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
|
||||
$PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
|
||||
$PHPMAILER_LANG["signing"] = 'Signing Error: ';
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,815 +0,0 @@
|
|||
<?php
|
||||
/*~ class.smtp.php
|
||||
.---------------------------------------------------------------------------.
|
||||
| Software: PHPMailer - PHP email class |
|
||||
| Version: 5.1 |
|
||||
| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
|
||||
| Info: http://phpmailer.sourceforge.net |
|
||||
| Support: http://sourceforge.net/projects/phpmailer/ |
|
||||
| ------------------------------------------------------------------------- |
|
||||
| Admin: Andy Prevost (project admininistrator) |
|
||||
| Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
|
||||
| : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
|
||||
| Founder: Brent R. Matzelle (original founder) |
|
||||
| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
|
||||
| Copyright (c) 2001-2003, Brent R. Matzelle |
|
||||
| ------------------------------------------------------------------------- |
|
||||
| License: Distributed under the Lesser General Public License (LGPL) |
|
||||
| http://www.gnu.org/copyleft/lesser.html |
|
||||
| This program is distributed in the hope that it will be useful - WITHOUT |
|
||||
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
||||
| FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| ------------------------------------------------------------------------- |
|
||||
| We offer a number of paid services (www.codeworxtech.com): |
|
||||
| - Web Hosting on highly optimized fast and secure servers |
|
||||
| - Technology Consulting |
|
||||
| - Oursourcing (highly qualified programmers and graphic designers) |
|
||||
'---------------------------------------------------------------------------'
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPMailer - PHP SMTP email transport class
|
||||
* NOTE: Designed for use with PHP version 5 and up
|
||||
* @package PHPMailer
|
||||
* @author Andy Prevost
|
||||
* @author Marcus Bointon
|
||||
* @copyright 2004 - 2008 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
|
||||
* commands except TURN which will always return a not implemented
|
||||
* error. SMTP also provides some utility methods for sending mail
|
||||
* to an SMTP server.
|
||||
* original author: Chris Ryan
|
||||
*/
|
||||
|
||||
class SMTP {
|
||||
/**
|
||||
* SMTP server port
|
||||
* @var int
|
||||
*/
|
||||
public $SMTP_PORT = 25;
|
||||
|
||||
/**
|
||||
* SMTP reply line ending
|
||||
* @var string
|
||||
*/
|
||||
public $CRLF = "\r\n";
|
||||
|
||||
/**
|
||||
* Sets whether debugging is turned on
|
||||
* @var bool
|
||||
*/
|
||||
public $do_debug; // the level of debug to perform
|
||||
|
||||
/**
|
||||
* Sets VERP use on/off (default is off)
|
||||
* @var bool
|
||||
*/
|
||||
public $do_verp = false;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// PROPERTIES, PRIVATE AND PROTECTED
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
private $smtp_conn; // the socket to the server
|
||||
private $error; // error if any on the last call
|
||||
private $helo_rply; // the reply the server sent to us for HELO
|
||||
|
||||
/**
|
||||
* Initialize the class so that the data is in a known state.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->smtp_conn = 0;
|
||||
$this->error = null;
|
||||
$this->helo_rply = null;
|
||||
|
||||
$this->do_debug = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// CONNECTION FUNCTIONS
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Connect to the server specified on the port specified.
|
||||
* If the port is not specified use the default SMTP_PORT.
|
||||
* If tval is specified then a connection will try and be
|
||||
* established with the server for that number of seconds.
|
||||
* If tval is not specified the default is 30 seconds to
|
||||
* try on the connection.
|
||||
*
|
||||
* SMTP CODE SUCCESS: 220
|
||||
* SMTP CODE FAILURE: 421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Connect($host,$port=0,$tval=30) {
|
||||
// set the error val to null so there is no confusion
|
||||
$this->error = null;
|
||||
|
||||
// make sure we are __not__ connected
|
||||
if($this->connected()) {
|
||||
// already connected, generate error
|
||||
$this->error = array("error" => "Already connected to a server");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(empty($port)) {
|
||||
$port = $this->SMTP_PORT;
|
||||
}
|
||||
|
||||
// connect to the smtp server
|
||||
$this->smtp_conn = @fsockopen($host, // the host of the server
|
||||
$port, // the port to use
|
||||
$errno, // error number if any
|
||||
$errstr, // error message if any
|
||||
$tval); // give up after ? secs
|
||||
// verify we connected properly
|
||||
if(empty($this->smtp_conn)) {
|
||||
$this->error = array("error" => "Failed to connect to server",
|
||||
"errno" => $errno,
|
||||
"errstr" => $errstr);
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// SMTP server can take longer to respond, give longer timeout for first read
|
||||
// Windows does not have support for this timeout function
|
||||
if(substr(PHP_OS, 0, 3) != "WIN")
|
||||
socket_set_timeout($this->smtp_conn, $tval, 0);
|
||||
|
||||
// get any announcement
|
||||
$announce = $this->get_lines();
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a TLS communication with the server.
|
||||
*
|
||||
* SMTP CODE 220 Ready to start TLS
|
||||
* SMTP CODE 501 Syntax error (no parameters allowed)
|
||||
* SMTP CODE 454 TLS not available due to temporary reason
|
||||
* @access public
|
||||
* @return bool success
|
||||
*/
|
||||
public function StartTLS() {
|
||||
$this->error = null; # to avoid confusion
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array("error" => "Called StartTLS() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 220) {
|
||||
$this->error =
|
||||
array("error" => "STARTTLS not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Begin encrypted connection
|
||||
if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs SMTP authentication. Must be run after running the
|
||||
* Hello() method. Returns true if successfully authenticated.
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Authenticate($username, $password) {
|
||||
// Start authentication
|
||||
fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($code != 334) {
|
||||
$this->error =
|
||||
array("error" => "AUTH not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send encoded username
|
||||
fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($code != 334) {
|
||||
$this->error =
|
||||
array("error" => "Username not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send encoded password
|
||||
fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($code != 235) {
|
||||
$this->error =
|
||||
array("error" => "Password not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if connected to a server otherwise false
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Connected() {
|
||||
if(!empty($this->smtp_conn)) {
|
||||
$sock_status = socket_get_status($this->smtp_conn);
|
||||
if($sock_status["eof"]) {
|
||||
// the socket is valid but we are not connected
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
|
||||
}
|
||||
$this->Close();
|
||||
return false;
|
||||
}
|
||||
return true; // everything looks good
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket and cleans up the state of the class.
|
||||
* It is not considered good to use this function without
|
||||
* first trying to use QUIT.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function Close() {
|
||||
$this->error = null; // so there is no confusion
|
||||
$this->helo_rply = null;
|
||||
if(!empty($this->smtp_conn)) {
|
||||
// close the connection and cleanup
|
||||
fclose($this->smtp_conn);
|
||||
$this->smtp_conn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// SMTP COMMANDS
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Issues a data command and sends the msg_data to the server
|
||||
* finializing the mail transaction. $msg_data is the message
|
||||
* that is to be send with the headers. Each header needs to be
|
||||
* on a single line followed by a <CRLF> with the message headers
|
||||
* and the message body being seperated by and additional <CRLF>.
|
||||
*
|
||||
* Implements rfc 821: DATA <CRLF>
|
||||
*
|
||||
* SMTP CODE INTERMEDIATE: 354
|
||||
* [data]
|
||||
* <CRLF>.<CRLF>
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE FAILURE: 552,554,451,452
|
||||
* SMTP CODE FAILURE: 451,554
|
||||
* SMTP CODE ERROR : 500,501,503,421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Data($msg_data) {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Data() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"DATA" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 354) {
|
||||
$this->error =
|
||||
array("error" => "DATA command not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* the server is ready to accept data!
|
||||
* according to rfc 821 we should not send more than 1000
|
||||
* including the CRLF
|
||||
* characters on a single line so we will break the data up
|
||||
* into lines by \r and/or \n then if needed we will break
|
||||
* each of those into smaller lines to fit within the limit.
|
||||
* in addition we will be looking for lines that start with
|
||||
* a period '.' and append and additional period '.' to that
|
||||
* line. NOTE: this does not count towards limit.
|
||||
*/
|
||||
|
||||
// normalize the line breaks so we know the explode works
|
||||
$msg_data = str_replace("\r\n","\n",$msg_data);
|
||||
$msg_data = str_replace("\r","\n",$msg_data);
|
||||
$lines = explode("\n",$msg_data);
|
||||
|
||||
/* we need to find a good way to determine is headers are
|
||||
* in the msg_data or if it is a straight msg body
|
||||
* currently I am assuming rfc 822 definitions of msg headers
|
||||
* and if the first field of the first line (':' sperated)
|
||||
* does not contain a space then it _should_ be a header
|
||||
* and we can process all lines before a blank "" line as
|
||||
* headers.
|
||||
*/
|
||||
|
||||
$field = substr($lines[0],0,strpos($lines[0],":"));
|
||||
$in_headers = false;
|
||||
if(!empty($field) && !strstr($field," ")) {
|
||||
$in_headers = true;
|
||||
}
|
||||
|
||||
$max_line_length = 998; // used below; set here for ease in change
|
||||
|
||||
while(list(,$line) = @each($lines)) {
|
||||
$lines_out = null;
|
||||
if($line == "" && $in_headers) {
|
||||
$in_headers = false;
|
||||
}
|
||||
// ok we need to break this line up into several smaller lines
|
||||
while(strlen($line) > $max_line_length) {
|
||||
$pos = strrpos(substr($line,0,$max_line_length)," ");
|
||||
|
||||
// Patch to fix DOS attack
|
||||
if(!$pos) {
|
||||
$pos = $max_line_length - 1;
|
||||
$lines_out[] = substr($line,0,$pos);
|
||||
$line = substr($line,$pos);
|
||||
} else {
|
||||
$lines_out[] = substr($line,0,$pos);
|
||||
$line = substr($line,$pos + 1);
|
||||
}
|
||||
|
||||
/* if we are processing headers we need to
|
||||
* add a LWSP-char to the front of the new line
|
||||
* rfc 822 on long msg headers
|
||||
*/
|
||||
if($in_headers) {
|
||||
$line = "\t" . $line;
|
||||
}
|
||||
}
|
||||
$lines_out[] = $line;
|
||||
|
||||
// send the lines to the server
|
||||
while(list(,$line_out) = @each($lines_out)) {
|
||||
if(strlen($line_out) > 0)
|
||||
{
|
||||
if(substr($line_out, 0, 1) == ".") {
|
||||
$line_out = "." . $line_out;
|
||||
}
|
||||
}
|
||||
fputs($this->smtp_conn,$line_out . $this->CRLF);
|
||||
}
|
||||
}
|
||||
|
||||
// message data has been sent
|
||||
fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250) {
|
||||
$this->error =
|
||||
array("error" => "DATA not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the HELO command to the smtp server.
|
||||
* This makes sure that we and the server are in
|
||||
* the same known state.
|
||||
*
|
||||
* Implements from rfc 821: HELO <SP> <domain> <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE ERROR : 500, 501, 504, 421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Hello($host = '') {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Hello() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if hostname for HELO was not specified send default
|
||||
if(empty($host)) {
|
||||
// determine appropriate default to send to server
|
||||
$host = "localhost";
|
||||
}
|
||||
|
||||
// Send extended hello first (RFC 2821)
|
||||
if(!$this->SendHello("EHLO", $host)) {
|
||||
if(!$this->SendHello("HELO", $host)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a HELO/EHLO command.
|
||||
* @access private
|
||||
* @return bool
|
||||
*/
|
||||
private function SendHello($hello, $host) {
|
||||
fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250) {
|
||||
$this->error =
|
||||
array("error" => $hello . " not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->helo_rply = $rply;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a mail transaction from the email address specified in
|
||||
* $from. Returns true if successful or false otherwise. If True
|
||||
* the mail transaction is started and then one or more Recipient
|
||||
* commands may be called followed by a Data command.
|
||||
*
|
||||
* Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE SUCCESS: 552,451,452
|
||||
* SMTP CODE SUCCESS: 500,501,421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Mail($from) {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Mail() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
$useVerp = ($this->do_verp ? "XVERP" : "");
|
||||
fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250) {
|
||||
$this->error =
|
||||
array("error" => "MAIL not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the quit command to the server and then closes the socket
|
||||
* if there is no error or the $close_on_error argument is true.
|
||||
*
|
||||
* Implements from rfc 821: QUIT <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 221
|
||||
* SMTP CODE ERROR : 500
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Quit($close_on_error=true) {
|
||||
$this->error = null; // so there is no confusion
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Quit() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// send the quit command to the server
|
||||
fputs($this->smtp_conn,"quit" . $this->CRLF);
|
||||
|
||||
// get any good-bye messages
|
||||
$byemsg = $this->get_lines();
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
$rval = true;
|
||||
$e = null;
|
||||
|
||||
$code = substr($byemsg,0,3);
|
||||
if($code != 221) {
|
||||
// use e as a tmp var cause Close will overwrite $this->error
|
||||
$e = array("error" => "SMTP server rejected quit command",
|
||||
"smtp_code" => $code,
|
||||
"smtp_rply" => substr($byemsg,4));
|
||||
$rval = false;
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($e) || $close_on_error) {
|
||||
$this->Close();
|
||||
}
|
||||
|
||||
return $rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the command RCPT to the SMTP server with the TO: argument of $to.
|
||||
* Returns true if the recipient was accepted false if it was rejected.
|
||||
*
|
||||
* Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250,251
|
||||
* SMTP CODE FAILURE: 550,551,552,553,450,451,452
|
||||
* SMTP CODE ERROR : 500,501,503,421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Recipient($to) {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Recipient() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250 && $code != 251) {
|
||||
$this->error =
|
||||
array("error" => "RCPT not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the RSET command to abort and transaction that is
|
||||
* currently in progress. Returns true if successful false
|
||||
* otherwise.
|
||||
*
|
||||
* Implements rfc 821: RSET <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE ERROR : 500,501,504,421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Reset() {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called Reset() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"RSET" . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250) {
|
||||
$this->error =
|
||||
array("error" => "RSET failed",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a mail transaction from the email address specified in
|
||||
* $from. Returns true if successful or false otherwise. If True
|
||||
* the mail transaction is started and then one or more Recipient
|
||||
* commands may be called followed by a Data command. This command
|
||||
* will send the message to the users terminal if they are logged
|
||||
* in and send them an email.
|
||||
*
|
||||
* Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE SUCCESS: 552,451,452
|
||||
* SMTP CODE SUCCESS: 500,501,502,421
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function SendAndMail($from) {
|
||||
$this->error = null; // so no confusion is caused
|
||||
|
||||
if(!$this->connected()) {
|
||||
$this->error = array(
|
||||
"error" => "Called SendAndMail() without being connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
|
||||
|
||||
$rply = $this->get_lines();
|
||||
$code = substr($rply,0,3);
|
||||
|
||||
if($this->do_debug >= 2) {
|
||||
echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
|
||||
if($code != 250) {
|
||||
$this->error =
|
||||
array("error" => "SAML not accepted from server",
|
||||
"smtp_code" => $code,
|
||||
"smtp_msg" => substr($rply,4));
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an optional command for SMTP that this class does not
|
||||
* support. This method is here to make the RFC821 Definition
|
||||
* complete for this class and __may__ be implimented in the future
|
||||
*
|
||||
* Implements from rfc 821: TURN <CRLF>
|
||||
*
|
||||
* SMTP CODE SUCCESS: 250
|
||||
* SMTP CODE FAILURE: 502
|
||||
* SMTP CODE ERROR : 500, 503
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function Turn() {
|
||||
$this->error = array("error" => "This method, TURN, of the SMTP ".
|
||||
"is not implemented");
|
||||
if($this->do_debug >= 1) {
|
||||
echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current error
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getError() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// INTERNAL FUNCTIONS
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Read in as many lines as possible
|
||||
* either before eof or socket timeout occurs on the operation.
|
||||
* With SMTP we can tell if we have more lines to read if the
|
||||
* 4th character is '-' symbol. If it is a space then we don't
|
||||
* need to read anything else.
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function get_lines() {
|
||||
$data = "";
|
||||
while($str = @fgets($this->smtp_conn,515)) {
|
||||
if($this->do_debug >= 4) {
|
||||
echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
|
||||
echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
|
||||
}
|
||||
$data .= $str;
|
||||
if($this->do_debug >= 4) {
|
||||
echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
|
||||
}
|
||||
// if 4th character is a space, we are done reading, break the loop
|
||||
if(substr($str,3,1) == " ") { break; }
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -177,7 +177,6 @@ class adminAdminModel extends admin
|
|||
{
|
||||
Context::loadLang(_XE_PATH_ . 'modules/autoinstall/lang');
|
||||
@set_time_limit(5);
|
||||
require_once(_XE_PATH_ . 'libs/ftp.class.php');
|
||||
|
||||
$ftp_info = Context::getRequestVars();
|
||||
|
||||
|
|
@ -323,8 +322,6 @@ class adminAdminModel extends admin
|
|||
Context::loadLang(_XE_PATH_ . 'modules/autoinstall/lang');
|
||||
@set_time_limit(5);
|
||||
|
||||
require_once(_XE_PATH_ . 'libs/ftp.class.php');
|
||||
|
||||
$ftp_info = Context::getRequestVars();
|
||||
if(!$ftp_info->ftp_user || !$ftp_info->ftp_password)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
require_once(_XE_PATH_ . 'libs/ftp.class.php');
|
||||
|
||||
/**
|
||||
* Module installer
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
|
|
@ -253,8 +251,6 @@ class ModuleInstaller
|
|||
*/
|
||||
function _unPack()
|
||||
{
|
||||
require_once(_XE_PATH_ . 'libs/tar.class.php');
|
||||
|
||||
$oTar = new tar();
|
||||
$oTar->openTAR($this->download_file);
|
||||
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ class installAdminController extends install
|
|||
if($default_url && substr($default_url, -1) !== '/') $default_url = $default_url.'/';
|
||||
|
||||
/* convert NON Alphabet URL to punycode URL - Alphabet URL will not be changed */
|
||||
require_once(_XE_PATH_ . 'libs/idna_convert/idna_convert.class.php');
|
||||
$IDN = new idna_convert(array('idn_version' => 2008));
|
||||
$default_url = $IDN->encode($default_url);
|
||||
$default_url = Context::encodeIdna($default_url);
|
||||
|
||||
$use_ssl = Context::get('use_ssl');
|
||||
if(!$use_ssl) $use_ssl = 'none';
|
||||
|
|
|
|||
|
|
@ -233,7 +233,6 @@ class installController extends install
|
|||
{
|
||||
if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed');
|
||||
|
||||
require_once(_XE_PATH_.'libs/ftp.class.php');
|
||||
$oFtp = new ftp();
|
||||
if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), $ftp_info->ftp_host));
|
||||
|
||||
|
|
@ -292,7 +291,6 @@ class installController extends install
|
|||
}
|
||||
else
|
||||
{
|
||||
require_once(_XE_PATH_.'libs/ftp.class.php');
|
||||
$oFtp = new ftp();
|
||||
if(!$oFtp->ftp_connect('127.0.0.1', $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), 'localhost'));
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ class installModel extends install
|
|||
}
|
||||
else
|
||||
{
|
||||
require_once(_XE_PATH_.'libs/ftp.class.php');
|
||||
$oFtp = new ftp();
|
||||
if($oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -593,7 +593,6 @@ class layoutAdminController extends layout
|
|||
$layout_srl = Context::get('layout_srl');
|
||||
if(!$layout_srl) return new Object('-1','msg_invalid_request');
|
||||
|
||||
require_once(_XE_PATH_.'libs/tar.class.php');
|
||||
$oLayoutModel = getModel('layout');
|
||||
|
||||
// Copy files to temp path
|
||||
|
|
@ -898,7 +897,6 @@ class layoutAdminController extends layout
|
|||
FileHandler::removeFile($user_layout_path . $file);
|
||||
}
|
||||
|
||||
require_once(_XE_PATH_.'libs/tar.class.php');
|
||||
$image_path = $oLayoutModel->getUserLayoutImagePath($layout_srl);
|
||||
FileHandler::makeDir($image_path);
|
||||
$tar = new tar();
|
||||
|
|
|
|||
2
vendor/composer/ClassLoader.php
vendored
2
vendor/composer/ClassLoader.php
vendored
|
|
@ -147,7 +147,7 @@ class ClassLoader
|
|||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
|
|
|
|||
3
vendor/composer/autoload_classmap.php
vendored
3
vendor/composer/autoload_classmap.php
vendored
|
|
@ -6,6 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'FB' => $vendorDir . '/firephp/firephp-core/lib/FirePHPCore/fb.php',
|
||||
'FirePHP' => $vendorDir . '/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php',
|
||||
'HTMLPurifier' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.php',
|
||||
'HTMLPurifier_Arborize' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Arborize.php',
|
||||
'HTMLPurifier_AttrCollections' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php',
|
||||
|
|
@ -297,4 +299,5 @@ return array(
|
|||
'Requests_Utility_CaseInsensitiveDictionary' => $vendorDir . '/rmccue/requests/library/Requests/Utility/CaseInsensitiveDictionary.php',
|
||||
'Requests_Utility_FilteredIterator' => $vendorDir . '/rmccue/requests/library/Requests/Utility/FilteredIterator.php',
|
||||
'Sunra\\PhpSimple\\HtmlDomParser' => $vendorDir . '/sunra/php-simple-html-dom-parser/Src/Sunra/PhpSimple/HtmlDomParser.php',
|
||||
'TrueBV\\Punycode' => $vendorDir . '/true/punycode/src/Punycode.php',
|
||||
);
|
||||
|
|
|
|||
1
vendor/composer/autoload_files.php
vendored
1
vendor/composer/autoload_files.php
vendored
|
|
@ -8,4 +8,5 @@ $baseDir = dirname($vendorDir);
|
|||
return array(
|
||||
'8170285c807a9f24f165f37b15bc9a36' => $vendorDir . '/defuse/php-encryption/Crypto.php',
|
||||
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
|
||||
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||
);
|
||||
|
|
|
|||
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
|
|
@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'TrueBV\\' => array($vendorDir . '/true/punycode/src'),
|
||||
'MatthiasMullie\\PathConverter\\' => array($vendorDir . '/matthiasmullie/path-converter/src'),
|
||||
'MatthiasMullie\\Minify\\' => array($vendorDir . '/matthiasmullie/minify/src'),
|
||||
);
|
||||
|
|
|
|||
363
vendor/composer/installed.json
vendored
363
vendor/composer/installed.json
vendored
|
|
@ -190,117 +190,6 @@
|
|||
"parser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/path-converter",
|
||||
"version": "1.0.6",
|
||||
"version_normalized": "1.0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/path-converter.git",
|
||||
"reference": "9f83d0c398dbe70f45f5840d95ffad73d5efd35f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/9f83d0c398dbe70f45f5840d95ffad73d5efd35f",
|
||||
"reference": "9f83d0c398dbe70f45f5840d95ffad73d5efd35f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pcre": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8",
|
||||
"satooshi/php-coveralls": "~1.0"
|
||||
},
|
||||
"time": "2016-01-05 07:45:30",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MatthiasMullie\\PathConverter\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matthias Mullie",
|
||||
"email": "pathconverter@mullie.eu",
|
||||
"homepage": "http://www.mullie.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Relative path converter",
|
||||
"homepage": "http://github.com/matthiasmullie/path-converter",
|
||||
"keywords": [
|
||||
"converter",
|
||||
"path",
|
||||
"paths",
|
||||
"relative"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
"version": "1.3.30",
|
||||
"version_normalized": "1.3.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/minify.git",
|
||||
"reference": "0cd5108683e7376e795555ced56229c4c16597aa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/0cd5108683e7376e795555ced56229c4c16597aa",
|
||||
"reference": "0cd5108683e7376e795555ced56229c4c16597aa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pcre": "*",
|
||||
"matthiasmullie/path-converter": "~1.0",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"matthiasmullie/scrapbook": "~1.0",
|
||||
"phpunit/phpunit": "~4.8",
|
||||
"satooshi/php-coveralls": "~1.0"
|
||||
},
|
||||
"time": "2016-01-05 07:43:18",
|
||||
"bin": [
|
||||
"bin/minifycss",
|
||||
"bin/minifyjs"
|
||||
],
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MatthiasMullie\\Minify\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matthias Mullie",
|
||||
"email": "minify@mullie.eu",
|
||||
"homepage": "http://www.mullie.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "CSS & JS minifier",
|
||||
"homepage": "http://www.minifier.org",
|
||||
"keywords": [
|
||||
"JS",
|
||||
"css",
|
||||
"javascript",
|
||||
"minifier",
|
||||
"minify"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rmccue/requests",
|
||||
"version": "v1.6.1",
|
||||
|
|
@ -351,5 +240,257 @@
|
|||
"iri",
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/path-converter",
|
||||
"version": "1.0.7",
|
||||
"version_normalized": "1.0.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/path-converter.git",
|
||||
"reference": "83609c1bb251b2540eba912615571a501a0a06a6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/83609c1bb251b2540eba912615571a501a0a06a6",
|
||||
"reference": "83609c1bb251b2540eba912615571a501a0a06a6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pcre": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8",
|
||||
"satooshi/php-coveralls": "~1.0"
|
||||
},
|
||||
"time": "2016-01-07 00:41:13",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MatthiasMullie\\PathConverter\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matthias Mullie",
|
||||
"email": "pathconverter@mullie.eu",
|
||||
"homepage": "http://www.mullie.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Relative path converter",
|
||||
"homepage": "http://github.com/matthiasmullie/path-converter",
|
||||
"keywords": [
|
||||
"converter",
|
||||
"path",
|
||||
"paths",
|
||||
"relative"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
"version": "1.3.32",
|
||||
"version_normalized": "1.3.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/minify.git",
|
||||
"reference": "140c714688908afcecde87338c8309233bdc2519"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/140c714688908afcecde87338c8309233bdc2519",
|
||||
"reference": "140c714688908afcecde87338c8309233bdc2519",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pcre": "*",
|
||||
"matthiasmullie/path-converter": "~1.0",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"matthiasmullie/scrapbook": "~1.0",
|
||||
"phpunit/phpunit": "~4.8",
|
||||
"satooshi/php-coveralls": "~1.0"
|
||||
},
|
||||
"time": "2016-01-11 02:10:11",
|
||||
"bin": [
|
||||
"bin/minifycss",
|
||||
"bin/minifyjs"
|
||||
],
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MatthiasMullie\\Minify\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matthias Mullie",
|
||||
"email": "minify@mullie.eu",
|
||||
"homepage": "http://www.mullie.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "CSS & JS minifier",
|
||||
"homepage": "http://www.minifier.org",
|
||||
"keywords": [
|
||||
"JS",
|
||||
"css",
|
||||
"javascript",
|
||||
"minifier",
|
||||
"minify"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v5.4.1",
|
||||
"version_normalized": "5.4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421",
|
||||
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~0.9.1,<0.9.4"
|
||||
},
|
||||
"time": "2015-06-06 14:19:39",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.4-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/swift_required.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Corbyn"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Swiftmailer, free feature-rich PHP mailer",
|
||||
"homepage": "http://swiftmailer.org",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"mailer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "true/punycode",
|
||||
"version": "v2.0.2",
|
||||
"version_normalized": "2.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/true/php-punycode.git",
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.7",
|
||||
"squizlabs/php_codesniffer": "~2.0"
|
||||
},
|
||||
"time": "2016-01-07 17:12:58",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TrueBV\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Renan Gonçalves",
|
||||
"email": "renan.saddam@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)",
|
||||
"homepage": "https://github.com/true/php-punycode",
|
||||
"keywords": [
|
||||
"idna",
|
||||
"punycode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "firephp/firephp-core",
|
||||
"version": "v0.4.0",
|
||||
"version_normalized": "0.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firephp/firephp-core.git",
|
||||
"reference": "fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firephp/firephp-core/zipball/fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf",
|
||||
"reference": "fabad0f2503f9577fe8dd2cb1d1c7cd73ed2aacf",
|
||||
"shasum": ""
|
||||
},
|
||||
"time": "2013-04-23 15:28:20",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"lib/FirePHPCore/FirePHP.class.php",
|
||||
"lib/FirePHPCore/fb.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christoph Dorn",
|
||||
"email": "christoph@christophdorn.com",
|
||||
"homepage": "http://christophdorn.com"
|
||||
}
|
||||
],
|
||||
"description": "Traditional FirePHPCore library for sending PHP variables to the browser.",
|
||||
"homepage": "https://github.com/firephp/firephp-core"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
1
vendor/firephp/firephp-core/.gitignore
vendored
Normal file
1
vendor/firephp/firephp-core/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
build/
|
||||
171
vendor/firephp/firephp-core/CHANGELOG.md
vendored
Normal file
171
vendor/firephp/firephp-core/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
|
||||
TODO:
|
||||
|
||||
* Fix code indenting in PHP 4 code
|
||||
* Port maxDepth option to PHP 4 code
|
||||
|
||||
2013-04-23 - Release Version: 0.4.0
|
||||
|
||||
* No changes
|
||||
|
||||
2011-06-22 - Release Version: 0.4.0rc3
|
||||
|
||||
* Build fixes
|
||||
|
||||
2011-06-20 - Release Version: 0.4.0rc1
|
||||
|
||||
* (Issue 163) PHP5 class_exists() throws Exception without second parameter
|
||||
* (Issue 166) Non-utf8 array values replaced with null
|
||||
* Cleaned up code formatting [sokolov.innokenty@gmail.com]
|
||||
* Ensure JSON keys are never NULL (due to NULL key in some arrays)
|
||||
* Better UTF-8 encoding detection
|
||||
* Code style cleanup (qbbr)
|
||||
* Changed license to MIT
|
||||
* Refactored project
|
||||
|
||||
2010-10-26 - Release Version: 0.3.2
|
||||
|
||||
2010-10-12 - Release Version: 0.3.2rc6
|
||||
|
||||
* (Issue 154) getRequestHeader uses "getallheaders" even though it doesn't always exist. [25m]
|
||||
|
||||
2010-10-09 - Release Version: 0.3.2rc5
|
||||
|
||||
* (Issue 153) FirePHP incorrectly double-encodes UTF8 when mbstring.func_overload is enabled
|
||||
|
||||
2010-10-08 - Release Version: 0.3.2rc4
|
||||
|
||||
* Trigger upgrade message if part of FirePHP 1.0
|
||||
* Removed FirePHP/Init.php inclusion logic and only load FirePHP.class.php if not already loaded
|
||||
|
||||
2010-07-19 - Release Version: 0.3.2rc3
|
||||
|
||||
* Fixed FirePHP/Init.php inclusion logic
|
||||
|
||||
2010-07-19 - Release Version: 0.3.2rc2
|
||||
|
||||
* (Issue 145) maxDepth option
|
||||
* Changed maxObjectDepth and maxArrayDepth option defaults to 5
|
||||
* Fixed code indentation
|
||||
|
||||
2010-03-05 - Release Version: 0.3.2rc1
|
||||
|
||||
* (Issue 114) Allow options to be passed on to basic logging wrappers
|
||||
* (Issue 122) Filter objectStack property of FirePHP class
|
||||
* (Issue 123) registerErrorHandler(false) by default
|
||||
* Added setOption() and getOption() methods
|
||||
* (Issue 117) dump() method argument validation
|
||||
* Started adding PHPUnit tests
|
||||
* Some refactoring to support unit testing
|
||||
* Deprecated setProcessorUrl() and setRendererUrl()
|
||||
* Check User-Agent and X-FirePHP-Version header to detect FirePHP on client
|
||||
* (Issue 135) FirePHP 0.4.3 with Firebug 1.5 changes user agent on the fly
|
||||
* (Issue 112) Error Predefined Constants Not available for PHP 5.x versions
|
||||
|
||||
2008-06-14 - Release Version: 0.3.1
|
||||
|
||||
* (Issue 108) ignore class name case in object filter
|
||||
|
||||
2009-05-11 - Release Version: 0.3
|
||||
2009-05-01 - Release Version: 0.3.rc.1
|
||||
|
||||
* (Issue 90) PHP4 compatible version of FirePHPCore
|
||||
* (Issue 98) Thrown exceptions don't send an HTTP 500 if the FirePHP exception handler is enabled
|
||||
* (Issue 85) Support associative arrays in encodeTable method in FirePHP.class.php
|
||||
* (Issue 66) Add a new getOptions() public method in API
|
||||
* (Issue 82) Define $this->options outside of __construct
|
||||
* (Issue 72) Message error if group name is null
|
||||
* (Issue 68) registerErrorHandler() and registerExceptionHandler() should returns previous handlers defined
|
||||
* (Issue 69) Add the missing register handler in the triumvirate (error, exception, assert)
|
||||
* (Issue 75) [Error & Exception Handling] Option to not exit script execution
|
||||
* (Issue 83) Exception handler can't throw exceptions
|
||||
* (Issue 80) Auto/Pre collapsing groups AND Custom group row colors
|
||||
|
||||
2008-11-09 - Release Version: 0.2.1
|
||||
|
||||
* (Issue 70) Problem when logging resources
|
||||
|
||||
2008-10-21 - Release Version: 0.2.0
|
||||
|
||||
* Updated version to 0.2.0
|
||||
* Switched to using __sleep instead of __wakeup
|
||||
* Added support to exclude object members when encoding
|
||||
* Add support to enable/disable logging
|
||||
|
||||
2008-10-17 - Release Version: 0.2.b.8
|
||||
|
||||
* New implementation for is_utf8()
|
||||
* (Issue 55) maxObjectDepth Option not working correctly when using TABLE and EXCEPTION Type
|
||||
* Bugfix for max[Object|Array]Depth when encoding nested array/object graphs
|
||||
* Bugfix for FB::setOptions()
|
||||
|
||||
2008-10-16 - Release Version: 0.2.b.7
|
||||
|
||||
* (Issue 45) Truncate dump when string have non utf8 cars
|
||||
* (Issue 52) logging will not work when firephp object gets stored in the session.
|
||||
|
||||
2008-10-16 - Release Version: 0.2.b.6
|
||||
|
||||
* (Issue 37) Display file and line information for each log message
|
||||
* (Issue 51) Limit output of object graphs
|
||||
* Bugfix for encoding object members set to NULL|false|''
|
||||
|
||||
2008-10-14 - Release Version: 0.2.b.5
|
||||
|
||||
* Updated JsonStream wildfire protocol to be more robust
|
||||
* (Issue 33) PHP error notices running demos
|
||||
* (Issue 48) Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given
|
||||
|
||||
2008-10-08 - Release Version: 0.2.b.4
|
||||
|
||||
* Bugfix for logging objects with recursion
|
||||
|
||||
2008-10-08 - Release Version: 0.2.b.3
|
||||
|
||||
* (Issue 43) Notice message in 0.2b2
|
||||
* Added support for PHP's native json_encode() if available
|
||||
* Revised object encoder to detect object recursion
|
||||
|
||||
2008-10-07 - Release Version: 0.2.b.2
|
||||
|
||||
* (Issue 28) Need solution for logging private and protected object variables
|
||||
* Added trace() and table() aliases in FirePHP class
|
||||
* (Issue 41) Use PHP doc in FirePHP
|
||||
* (Issue 39) Static logging method for object oriented API
|
||||
|
||||
2008-10-01 - Release Version: 0.2.b.1
|
||||
|
||||
* Added support for error and exception handling
|
||||
* Updated min PHP version for PEAR package to 5.2
|
||||
* Added version constant for library
|
||||
* Gave server library it's own wildfire plugin namespace
|
||||
* Migrated communication protocol to Wildfire JsonStream
|
||||
* Added support for console groups using "group" and "groupEnd"
|
||||
* Added support for log, info, warn and error logging aliases
|
||||
* (Issue 29) problem with TRACE when using with error_handler
|
||||
* (Issue 33) PHP error notices running demos
|
||||
* (Issue 12) undefined index php notice
|
||||
* Removed closing ?> php tags
|
||||
* (Issue 13) the code in the fb() function has a second return statement that will never be reached
|
||||
|
||||
2008-07-30 - Release Version: 0.1.1.3
|
||||
|
||||
* Include __className property in JSON string if variable was an object
|
||||
* Bugfix - Mis-spelt "Exception" in JSON encoding code
|
||||
|
||||
2008-06-13 - Release Version: 0.1.1.1
|
||||
|
||||
* Bugfix - Standardize windows paths in stack traces
|
||||
* Bugfix - Display correct stack trace info in windows environments
|
||||
* Bugfix - Check $_SERVER['HTTP_USER_AGENT'] before returning
|
||||
|
||||
2008-06-13 - Release Version: 0.1.1
|
||||
|
||||
* Added support for FirePHP::TRACE log style
|
||||
* Changed license to New BSD License
|
||||
|
||||
2008-06-06 - Release Version: 0.0.2
|
||||
|
||||
* Bugfix - Added usleep() to header writing loop to ensure unique index
|
||||
* Bugfix - Ensure chunk_split does not generate trailing "\n" with empty data header
|
||||
* Added support for FirePHP::TABLE log style
|
||||
75
vendor/firephp/firephp-core/README.md
vendored
Normal file
75
vendor/firephp/firephp-core/README.md
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
FirePHPCore
|
||||
===========
|
||||
|
||||
**Status: stable**
|
||||
|
||||
> **FirePHP is an advanced logging system that can display PHP variables in the browser as an application is navigated.**
|
||||
> All communication is out of band to the application meaning that the logging data will not interfere with the normal functioning of the application.
|
||||
|
||||
This project contains the *FirePHPCore* PHP server library and provides a development environment (see `./workspace/`) for working on *FirePHPCore*.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
See [Install/Traditional: FirePHPCore](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/Configuration/Traditional) in the
|
||||
[FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
cd tests
|
||||
phpunit .
|
||||
|
||||
|
||||
Support & Feedback
|
||||
==================
|
||||
|
||||
See [Support](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#support) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
||||
|
||||
|
||||
Contribute
|
||||
==========
|
||||
|
||||
See [Contribute](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#contribute) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
||||
|
||||
|
||||
Author
|
||||
======
|
||||
|
||||
This project is authored and maintained by [Christoph Dorn](http://www.christophdorn.com/).
|
||||
|
||||
|
||||
Documentation License
|
||||
=====================
|
||||
|
||||
[Creative Commons Attribution-NonCommercial-ShareAlike 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/)
|
||||
|
||||
Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
|
||||
|
||||
Code License
|
||||
============
|
||||
|
||||
[MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
|
||||
Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
26
vendor/firephp/firephp-core/composer.json
vendored
Normal file
26
vendor/firephp/firephp-core/composer.json
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "firephp/firephp-core",
|
||||
"description": "Traditional FirePHPCore library for sending PHP variables to the browser.",
|
||||
"type": "library",
|
||||
"homepage": "https://github.com/firephp/firephp-core",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christoph Dorn",
|
||||
"email": "christoph@christophdorn.com",
|
||||
"homepage": "http://christophdorn.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"forum": "http://groups.google.com/group/firephp-dev",
|
||||
"issues": "https://github.com/firephp/firephp-core/issues",
|
||||
"source": "https://github.com/firephp/firephp-core"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"lib/FirePHPCore/FirePHP.class.php",
|
||||
"lib/FirePHPCore/fb.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
82
vendor/firephp/firephp-core/examples/oo.php
vendored
Normal file
82
vendor/firephp/firephp-core/examples/oo.php
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/* *** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/* NOTE: You must have the FirePHPCore library in your include path */
|
||||
|
||||
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
||||
|
||||
|
||||
require('FirePHPCore/FirePHP.class.php');
|
||||
|
||||
/* NOTE: You must have Output Buffering enabled via
|
||||
ob_start() or output_buffering ini directive. */
|
||||
|
||||
|
||||
$firephp = FirePHP::getInstance(true);
|
||||
|
||||
|
||||
$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */
|
||||
|
||||
$firephp->fb('Log message' ,FirePHP::LOG);
|
||||
$firephp->fb('Info message' ,FirePHP::INFO);
|
||||
$firephp->fb('Warn message' ,FirePHP::WARN);
|
||||
$firephp->fb('Error message',FirePHP::ERROR);
|
||||
|
||||
$firephp->fb('Message with label','Label',FirePHP::LOG);
|
||||
|
||||
$firephp->fb(array('key1'=>'val1',
|
||||
'key2'=>array(array('v1','v2'),'v3')),
|
||||
'TestArray',FirePHP::LOG);
|
||||
|
||||
function test($Arg1) {
|
||||
throw new Exception('Test Exception');
|
||||
}
|
||||
try {
|
||||
test(array('Hello'=>'World'));
|
||||
} catch(Exception $e) {
|
||||
/* Log exception including stack trace & variables */
|
||||
$firephp->fb($e);
|
||||
}
|
||||
|
||||
$firephp->fb('Backtrace to here',FirePHP::TRACE);
|
||||
|
||||
$firephp->fb(array('2 SQL queries took 0.06 seconds',array(
|
||||
array('SQL Statement','Time','Result'),
|
||||
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
||||
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
||||
)),FirePHP::TABLE);
|
||||
|
||||
/* Will show only in "Server" tab for the request */
|
||||
$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP);
|
||||
|
||||
|
||||
print 'Hello World';
|
||||
72
vendor/firephp/firephp-core/examples/oo.php4
vendored
Normal file
72
vendor/firephp/firephp-core/examples/oo.php4
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/* *** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/* NOTE: You must have the FirePHPCore library in your include path */
|
||||
|
||||
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
||||
|
||||
|
||||
require('FirePHPCore/FirePHP.class.php4');
|
||||
|
||||
/* NOTE: You must have Output Buffering enabled via
|
||||
ob_start() or output_buffering ini directive. */
|
||||
|
||||
|
||||
$firephp =& FirePHP::getInstance(true);
|
||||
|
||||
|
||||
$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */
|
||||
|
||||
$firephp->fb('Log message' ,FirePHP_LOG);
|
||||
$firephp->fb('Info message' ,FirePHP_INFO);
|
||||
$firephp->fb('Warn message' ,FirePHP_WARN);
|
||||
$firephp->fb('Error message',FirePHP_ERROR);
|
||||
|
||||
$firephp->fb('Message with label','Label',FirePHP_LOG);
|
||||
|
||||
$firephp->fb(array('key1'=>'val1',
|
||||
'key2'=>array(array('v1','v2'),'v3')),
|
||||
'TestArray',FirePHP_LOG);
|
||||
|
||||
$firephp->fb('Backtrace to here',FirePHP_TRACE);
|
||||
|
||||
$firephp->fb(array('2 SQL queries took 0.06 seconds',array(
|
||||
array('SQL Statement','Time','Result'),
|
||||
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
||||
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
||||
)),FirePHP_TABLE);
|
||||
|
||||
/* Will show only in "Server" tab for the request */
|
||||
$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP);
|
||||
|
||||
|
||||
print 'Hello World';
|
||||
79
vendor/firephp/firephp-core/examples/procedural.php
vendored
Normal file
79
vendor/firephp/firephp-core/examples/procedural.php
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/* *** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/* NOTE: You must have the FirePHPCore library in your include path */
|
||||
|
||||
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
||||
|
||||
|
||||
require('FirePHPCore/fb.php');
|
||||
|
||||
/* NOTE: You must have Output Buffering enabled via
|
||||
ob_start() or output_buffering ini directive. */
|
||||
|
||||
fb('Hello World'); /* Defaults to FirePHP::LOG */
|
||||
|
||||
fb('Log message' ,FirePHP::LOG);
|
||||
fb('Info message' ,FirePHP::INFO);
|
||||
fb('Warn message' ,FirePHP::WARN);
|
||||
fb('Error message',FirePHP::ERROR);
|
||||
|
||||
fb('Message with label','Label',FirePHP::LOG);
|
||||
|
||||
fb(array('key1'=>'val1',
|
||||
'key2'=>array(array('v1','v2'),'v3')),
|
||||
'TestArray',FirePHP::LOG);
|
||||
|
||||
function test($Arg1) {
|
||||
throw new Exception('Test Exception');
|
||||
}
|
||||
try {
|
||||
test(array('Hello'=>'World'));
|
||||
} catch(Exception $e) {
|
||||
/* Log exception including stack trace & variables */
|
||||
fb($e);
|
||||
}
|
||||
|
||||
fb('Backtrace to here',FirePHP::TRACE);
|
||||
|
||||
fb(array('2 SQL queries took 0.06 seconds',array(
|
||||
array('SQL Statement','Time','Result'),
|
||||
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
||||
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
||||
)),FirePHP::TABLE);
|
||||
|
||||
/* Will show only in "Server" tab for the request */
|
||||
fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP);
|
||||
|
||||
|
||||
print 'Hello World';
|
||||
|
||||
69
vendor/firephp/firephp-core/examples/procedural.php4
vendored
Normal file
69
vendor/firephp/firephp-core/examples/procedural.php4
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/* *** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/* NOTE: You must have the FirePHPCore library in your include path */
|
||||
|
||||
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
||||
|
||||
|
||||
require('FirePHPCore/fb.php');
|
||||
|
||||
/* NOTE: You must have Output Buffering enabled via
|
||||
ob_start() or output_buffering ini directive. */
|
||||
|
||||
fb('Hello World'); /* Defaults to FirePHP::LOG */
|
||||
|
||||
fb('Log message' ,FirePHP_LOG);
|
||||
fb('Info message' ,FirePHP_INFO);
|
||||
fb('Warn message' ,FirePHP_WARN);
|
||||
fb('Error message',FirePHP_ERROR);
|
||||
|
||||
fb('Message with label','Label',FirePHP_LOG);
|
||||
|
||||
fb(array('key1'=>'val1',
|
||||
'key2'=>array(array('v1','v2'),'v3')),
|
||||
'TestArray',FirePHP_LOG);
|
||||
|
||||
fb('Backtrace to here',FirePHP_TRACE);
|
||||
|
||||
fb(array('2 SQL queries took 0.06 seconds',array(
|
||||
array('SQL Statement','Time','Result'),
|
||||
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
||||
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
||||
)),FirePHP_TABLE);
|
||||
|
||||
/* Will show only in "Server" tab for the request */
|
||||
fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP);
|
||||
|
||||
|
||||
print 'Hello World';
|
||||
|
||||
1828
vendor/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php
vendored
Normal file
1828
vendor/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
275
vendor/firephp/firephp-core/lib/FirePHPCore/fb.php
vendored
Normal file
275
vendor/firephp/firephp-core/lib/FirePHPCore/fb.php
vendored
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - qbbr, Sokolov Innokenty <sokolov.innokenty@gmail.com>, Copyright 2011, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/**
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* @copyright Copyright (C) 2007+ Christoph Dorn
|
||||
* @author Christoph Dorn <christoph@christophdorn.com>
|
||||
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
* @package FirePHPCore
|
||||
*/
|
||||
|
||||
if (!class_exists('FirePHP', false)) {
|
||||
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'FirePHP.class.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given data to the FirePHP Firefox Extension.
|
||||
* The data can be displayed in the Firebug Console or in the
|
||||
* "Server" request tab.
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
function fb()
|
||||
{
|
||||
$instance = FirePHP::getInstance(true);
|
||||
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($instance, 'fb'), $args);
|
||||
}
|
||||
|
||||
|
||||
class FB
|
||||
{
|
||||
/**
|
||||
* Set an Insight console to direct all logging calls to
|
||||
*
|
||||
* @param object $console The console object to log to
|
||||
* @return void
|
||||
*/
|
||||
public static function setLogToInsightConsole($console)
|
||||
{
|
||||
FirePHP::getInstance(true)->setLogToInsightConsole($console);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable and disable logging to Firebug
|
||||
*
|
||||
* @see FirePHP->setEnabled()
|
||||
* @param boolean $enabled TRUE to enable, FALSE to disable
|
||||
* @return void
|
||||
*/
|
||||
public static function setEnabled($enabled)
|
||||
{
|
||||
FirePHP::getInstance(true)->setEnabled($enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logging is enabled
|
||||
*
|
||||
* @see FirePHP->getEnabled()
|
||||
* @return boolean TRUE if enabled
|
||||
*/
|
||||
public static function getEnabled()
|
||||
{
|
||||
return FirePHP::getInstance(true)->getEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a filter to be used when encoding an object
|
||||
*
|
||||
* Filters are used to exclude object members.
|
||||
*
|
||||
* @see FirePHP->setObjectFilter()
|
||||
* @param string $class The class name of the object
|
||||
* @param array $filter An array or members to exclude
|
||||
* @return void
|
||||
*/
|
||||
public static function setObjectFilter($class, $filter)
|
||||
{
|
||||
FirePHP::getInstance(true)->setObjectFilter($class, $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some options for the library
|
||||
*
|
||||
* @see FirePHP->setOptions()
|
||||
* @param array $options The options to be set
|
||||
* @return void
|
||||
*/
|
||||
public static function setOptions($options)
|
||||
{
|
||||
FirePHP::getInstance(true)->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options for the library
|
||||
*
|
||||
* @see FirePHP->getOptions()
|
||||
* @return array The options
|
||||
*/
|
||||
public static function getOptions()
|
||||
{
|
||||
return FirePHP::getInstance(true)->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object to firebug
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function send()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array(FirePHP::getInstance(true), 'fb'), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a group for following messages
|
||||
*
|
||||
* Options:
|
||||
* Collapsed: [true|false]
|
||||
* Color: [#RRGGBB|ColorName]
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $options OPTIONAL Instructions on how to log the group
|
||||
* @return true
|
||||
*/
|
||||
public static function group($name, $options=null)
|
||||
{
|
||||
return FirePHP::getInstance(true)->group($name, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a group you have started before
|
||||
*
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function groupEnd()
|
||||
{
|
||||
return self::send(null, null, FirePHP::GROUP_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::LOG
|
||||
* @param mixes $object
|
||||
* @param string $label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function log($object, $label=null)
|
||||
{
|
||||
return self::send($object, $label, FirePHP::LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::INFO
|
||||
* @param mixes $object
|
||||
* @param string $label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function info($object, $label=null)
|
||||
{
|
||||
return self::send($object, $label, FirePHP::INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::WARN
|
||||
* @param mixes $object
|
||||
* @param string $label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function warn($object, $label=null)
|
||||
{
|
||||
return self::send($object, $label, FirePHP::WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::ERROR
|
||||
* @param mixes $object
|
||||
* @param string $label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function error($object, $label=null)
|
||||
{
|
||||
return self::send($object, $label, FirePHP::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps key and variable to firebug server panel
|
||||
*
|
||||
* @see FirePHP::DUMP
|
||||
* @param string $key
|
||||
* @param mixed $variable
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function dump($key, $variable)
|
||||
{
|
||||
return self::send($variable, $key, FirePHP::DUMP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a trace in the firebug console
|
||||
*
|
||||
* @see FirePHP::TRACE
|
||||
* @param string $label
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function trace($label)
|
||||
{
|
||||
return self::send($label, FirePHP::TRACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a table in the firebug console
|
||||
*
|
||||
* @see FirePHP::TABLE
|
||||
* @param string $label
|
||||
* @param string $table
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function table($label, $table)
|
||||
{
|
||||
return self::send($table, $label, FirePHP::TABLE);
|
||||
}
|
||||
|
||||
}
|
||||
245
vendor/firephp/firephp-core/lib/FirePHPCore/fb.php4
vendored
Normal file
245
vendor/firephp/firephp-core/lib/FirePHPCore/fb.php4
vendored
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
// Authors:
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
||||
// - qbbr, Michael Day <manveru.alma@gmail.com>, Copyright 2008, New BSD License
|
||||
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
*
|
||||
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*
|
||||
* @copyright Copyright (C) 2007+ Christoph Dorn
|
||||
* @author Christoph Dorn <christoph@christophdorn.com>
|
||||
* @author Michael Day <manveru.alma@gmail.com>
|
||||
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
* @package FirePHPCore
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/FirePHP.class.php4';
|
||||
|
||||
/**
|
||||
* Sends the given data to the FirePHP Firefox Extension.
|
||||
* The data can be displayed in the Firebug Console or in the
|
||||
* "Server" request tab.
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
* @throws Exception
|
||||
*/
|
||||
function fb()
|
||||
{
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array(&$instance,'fb'),$args);
|
||||
}
|
||||
|
||||
|
||||
class FB
|
||||
{
|
||||
/**
|
||||
* Enable and disable logging to Firebug
|
||||
*
|
||||
* @see FirePHP->setEnabled()
|
||||
* @param boolean $Enabled TRUE to enable, FALSE to disable
|
||||
* @return void
|
||||
*/
|
||||
function setEnabled($Enabled) {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
$instance->setEnabled($Enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logging is enabled
|
||||
*
|
||||
* @see FirePHP->getEnabled()
|
||||
* @return boolean TRUE if enabled
|
||||
*/
|
||||
function getEnabled() {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
return $instance->getEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a filter to be used when encoding an object
|
||||
*
|
||||
* Filters are used to exclude object members.
|
||||
*
|
||||
* @see FirePHP->setObjectFilter()
|
||||
* @param string $Class The class name of the object
|
||||
* @param array $Filter An array or members to exclude
|
||||
* @return void
|
||||
*/
|
||||
function setObjectFilter($Class, $Filter) {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
$instance->setObjectFilter($Class, $Filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some options for the library
|
||||
*
|
||||
* @see FirePHP->setOptions()
|
||||
* @param array $Options The options to be set
|
||||
* @return void
|
||||
*/
|
||||
function setOptions($Options) {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
$instance->setOptions($Options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options for the library
|
||||
*
|
||||
* @see FirePHP->getOptions()
|
||||
* @return array The options
|
||||
*/
|
||||
function getOptions() {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
return $instance->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object to firebug
|
||||
*
|
||||
* @see http://www.firephp.org/Wiki/Reference/Fb
|
||||
* @param mixed $Object
|
||||
* @return true
|
||||
*/
|
||||
function send()
|
||||
{
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array(&$instance,'fb'),$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a group for following messages
|
||||
*
|
||||
* Options:
|
||||
* Collapsed: [true|false]
|
||||
* Color: [#RRGGBB|ColorName]
|
||||
*
|
||||
* @param string $Name
|
||||
* @param array $Options OPTIONAL Instructions on how to log the group
|
||||
* @return true
|
||||
*/
|
||||
function group($Name, $Options=null) {
|
||||
$instance =& FirePHP::getInstance(true);
|
||||
return $instance->group($Name, $Options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a group you have started before
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
function groupEnd() {
|
||||
return FB::send(null, null, FirePHP_GROUP_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::LOG
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
*/
|
||||
function log($Object, $Label=null) {
|
||||
return FB::send($Object, $Label, FirePHP_LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::INFO
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
*/
|
||||
function info($Object, $Label=null) {
|
||||
return FB::send($Object, $Label, FirePHP_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::WARN
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
*/
|
||||
function warn($Object, $Label=null) {
|
||||
return FB::send($Object, $Label, FirePHP_WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log object with label to firebug console
|
||||
*
|
||||
* @see FirePHP::ERROR
|
||||
* @param mixes $Object
|
||||
* @param string $Label
|
||||
* @return true
|
||||
*/
|
||||
function error($Object, $Label=null) {
|
||||
return FB::send($Object, $Label, FirePHP_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps key and variable to firebug server panel
|
||||
*
|
||||
* @see FirePHP::DUMP
|
||||
* @param string $Key
|
||||
* @param mixed $Variable
|
||||
* @return true
|
||||
*/
|
||||
function dump($Key, $Variable) {
|
||||
return FB::send($Variable, $Key, FirePHP_DUMP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a trace in the firebug console
|
||||
*
|
||||
* @see FirePHP::TRACE
|
||||
* @param string $Label
|
||||
* @return true
|
||||
*/
|
||||
function trace($Label) {
|
||||
return FB::send($Label, FirePHP_TRACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a table in the firebug console
|
||||
*
|
||||
* @see FirePHP::TABLE
|
||||
* @param string $Label
|
||||
* @param string $Table
|
||||
* @return true
|
||||
*/
|
||||
function table($Label, $Table) {
|
||||
return FB::send($Table, $Label, FirePHP_TABLE);
|
||||
}
|
||||
}
|
||||
43
vendor/firephp/firephp-core/package.json
vendored
Normal file
43
vendor/firephp/firephp-core/package.json
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"uid": "https://github.com/firephp/firephp-core/",
|
||||
"name": "firephp-core",
|
||||
"version": "0.4.0",
|
||||
"label": "FirePHP Server Library",
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "git://github.com/firephp/firephp-core.git"
|
||||
}
|
||||
],
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Christoph Dorn",
|
||||
"email": "christoph@christophdorn.com",
|
||||
"web": "http://www.christophdorn.com/",
|
||||
"alias": {
|
||||
"github": "cadorn"
|
||||
}
|
||||
}
|
||||
],
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Christoph Dorn",
|
||||
"email": "christoph@christophdorn.com",
|
||||
"web": "http://www.christophdorn.com/",
|
||||
"alias": {
|
||||
"github": "cadorn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Michael Day",
|
||||
"email": "manveru.alma@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sokolov Innokenty",
|
||||
"email": "sokolov.innokenty@gmail.com",
|
||||
"alias": {
|
||||
"github": "qbbr"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
5
vendor/firephp/firephp-core/program.json
vendored
Normal file
5
vendor/firephp/firephp-core/program.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": {
|
||||
"location": "./workspace/program.json"
|
||||
}
|
||||
}
|
||||
12
vendor/firephp/firephp-core/tests/API/newlines.php
vendored
Normal file
12
vendor/firephp/firephp-core/tests/API/newlines.php
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
set_include_path(dirname(dirname(dirname(__FILE__))).'/lib'.PATH_SEPARATOR.get_include_path());
|
||||
require('FirePHPCore/fb.php');
|
||||
|
||||
|
||||
fb('Hello\nWorld');
|
||||
fb(array('Hello\nWorld'));
|
||||
fb(array('Table cell with newline',array(
|
||||
array('Header'),
|
||||
array('Hello\nWorld'),
|
||||
)),FirePHP::TABLE);
|
||||
181
vendor/firephp/firephp-core/tests/FirePHPCore/FirePHPTest.php
vendored
Normal file
181
vendor/firephp/firephp-core/tests/FirePHPCore/FirePHPTest.php
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
class FirePHPCore_FirePHPTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @issue http://code.google.com/p/firephp/issues/detail?id=117
|
||||
*/
|
||||
public function testDumpArguments()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
$firephp->dump("key", "value");
|
||||
$headers = $firephp->_getHeaders();
|
||||
$this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-1']);
|
||||
$firephp->_clearHeaders();
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->dump(array(), "value");
|
||||
} catch(Exception $e) {
|
||||
// Key passed to dump() is not a string
|
||||
$caught = true;
|
||||
}
|
||||
if(!$caught) $this->fail('No exception thrown');
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->dump("key \n\r value", "value");
|
||||
} catch(Exception $e) {
|
||||
// Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:]
|
||||
$caught = true;
|
||||
}
|
||||
if(!$caught) $this->fail('No exception thrown');
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->dump("keykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeyk1", "value");
|
||||
} catch(Exception $e) {
|
||||
// Key passed to dump() is longer than 100 characters
|
||||
$caught = true;
|
||||
}
|
||||
if(!$caught) $this->fail('No exception thrown');
|
||||
}
|
||||
|
||||
/**
|
||||
* @issue http://code.google.com/p/firephp/issues/detail?id=123
|
||||
*/
|
||||
public function testRegisterErrorHandler()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
$firephp->setOption("maxObjectDepth", 1);
|
||||
$firephp->setOption("maxArrayDepth", 1);
|
||||
|
||||
$firephp->registerErrorHandler();
|
||||
trigger_error("Hello World");
|
||||
$headers = $firephp->_getHeaders();
|
||||
if(!isset($headers["X-Wf-1-1-1-1"])) {
|
||||
$this->fail("Error not in headers");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @issue http://code.google.com/p/firephp/issues/detail?id=122
|
||||
*/
|
||||
public function testFirePHPClassInstanceLogging()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
$firephp->log($firephp);
|
||||
$headers = $firephp->_getHeaders();
|
||||
if(!preg_match_all('/"protected:objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
||||
$this->fail("objectStack member contains value");
|
||||
}
|
||||
if(!preg_match_all('/"protected:static:instance":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
||||
$this->fail("instance member should not be logged");
|
||||
}
|
||||
if(!preg_match_all('/"undeclared:json_objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
||||
$this->fail("json_objectStack member should not be logged");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @issue http://code.google.com/p/firephp/issues/detail?id=114
|
||||
*/
|
||||
public function testCustomFileLineOptions()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
$firephp->log("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$firephp->info("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$firephp->warn("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$firephp->error("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$firephp->dump("key", "value", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$firephp->table("label", array(array("header"),array("cell")), array("File"=>"/file/path", "Line"=>"1"));
|
||||
|
||||
$headers = $firephp->_getHeaders();
|
||||
|
||||
$this->assertEquals('75|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-1']);
|
||||
$this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"INFO","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-2']);
|
||||
$this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"WARN","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-3']);
|
||||
$this->assertEquals('77|[{"File":"\/file\/path","Line":"1","Type":"ERROR","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-4']);
|
||||
$this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-5']);
|
||||
$this->assertEquals('89|[{"File":"\/file\/path","Line":"1","Type":"TABLE","Label":"label"},[["header"],["cell"]]]|', $headers['X-Wf-1-1-1-6']);
|
||||
}
|
||||
|
||||
public function testRecursiveEncode()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
$obj = new FirePHPCore_FirePHPTest__TestObject();
|
||||
$obj->child = $obj;
|
||||
|
||||
$firephp->log($obj, "label", array("File"=>"/file/path", "Line"=>"1"));
|
||||
$headers = $firephp->_getHeaders();
|
||||
$this->assertEquals('215|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},{"__className":"FirePHPCore_FirePHPTest__TestObject","public:var":"value","undeclared:child":"** Recursion (FirePHPCore_FirePHPTest__TestObject) **"}]|', $headers['X-Wf-1-1-1-1']);
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
// defaults
|
||||
$this->assertEquals(5, $firephp->getOption("maxObjectDepth"));
|
||||
$this->assertEquals(5, $firephp->getOption("maxArrayDepth"));
|
||||
$this->assertEquals(true, $firephp->getOption("useNativeJsonEncode"));
|
||||
$this->assertEquals(true, $firephp->getOption("includeLineNumbers"));
|
||||
|
||||
// modify
|
||||
$firephp->setOption("maxObjectDepth", 1);
|
||||
$this->assertEquals(1, $firephp->getOption("maxObjectDepth"));
|
||||
|
||||
// invalid
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->setOption("invalidName", 1);
|
||||
} catch(Exception $e) {
|
||||
$caught = true;
|
||||
}
|
||||
if(!$caught) $this->fail('No exception thrown');
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->getOption("invalidName");
|
||||
} catch(Exception $e) {
|
||||
$caught = true;
|
||||
}
|
||||
if(!$caught) $this->fail('No exception thrown');
|
||||
}
|
||||
|
||||
public function testDeprecatedMethods()
|
||||
{
|
||||
$firephp = new FirePHP_Test_Class();
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->setProcessorUrl('URL');
|
||||
} catch(Exception $e) {
|
||||
$caught = true;
|
||||
$this->assertEquals(E_USER_DEPRECATED, $e->getCode());
|
||||
$this->assertEquals('The FirePHP::setProcessorUrl() method is no longer supported', $e->getMessage());
|
||||
}
|
||||
if(!$caught) $this->fail('No deprecation error thrown');
|
||||
|
||||
$caught = false;
|
||||
try {
|
||||
$firephp->setRendererUrl('URL');
|
||||
} catch(Exception $e) {
|
||||
$caught = true;
|
||||
$this->assertEquals(E_USER_DEPRECATED, $e->getCode());
|
||||
$this->assertEquals('The FirePHP::setRendererUrl() method is no longer supported', $e->getMessage());
|
||||
}
|
||||
if(!$caught) $this->fail('No deprecation error thrown');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FirePHPCore_FirePHPTest__TestObject
|
||||
{
|
||||
public $var = "value";
|
||||
}
|
||||
55
vendor/firephp/firephp-core/tests/TestHelper.php
vendored
Normal file
55
vendor/firephp/firephp-core/tests/TestHelper.php
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
function __autoload__($class)
|
||||
{
|
||||
if (strpos($class, 'FirePHPCore') !== 0 && $class != 'FirePHP') {
|
||||
return;
|
||||
}
|
||||
|
||||
$basePath = dirname(dirname(__FILE__)) . '/lib';
|
||||
if (!file_exists($basePath)) {
|
||||
$basePath = dirname(dirname(dirname(dirname(__FILE__)))) . '/lib';
|
||||
}
|
||||
|
||||
if ($class == 'FirePHP') {
|
||||
$class = 'FirePHPCore/FirePHP.class';
|
||||
}
|
||||
|
||||
// find relative
|
||||
if (file_exists($file = $basePath . '/' . str_replace('_', '/', $class) . '.php')) {
|
||||
require_once($file);
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('__autoload__');
|
||||
|
||||
class FirePHP_Test_Class extends FirePHP {
|
||||
|
||||
private $_headers = array();
|
||||
|
||||
|
||||
public function _getHeaders() {
|
||||
return $this->_headers;
|
||||
}
|
||||
public function _clearHeaders() {
|
||||
$this->_headers = array();
|
||||
}
|
||||
|
||||
|
||||
// ######################
|
||||
// # Subclassed Methods #
|
||||
// ######################
|
||||
|
||||
protected function setHeader($Name, $Value) {
|
||||
$this->_headers[$Name] = $Value;
|
||||
}
|
||||
|
||||
protected function headersSent(&$Filename, &$Linenum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function detectClientExtension() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
2
vendor/firephp/firephp-core/tests/phpunit.xml
vendored
Normal file
2
vendor/firephp/firephp-core/tests/phpunit.xml
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<phpunit bootstrap="TestHelper.php">
|
||||
</phpunit>
|
||||
19
vendor/firephp/firephp-core/workspace/README.md
vendored
Normal file
19
vendor/firephp/firephp-core/workspace/README.md
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
The [PINF JavaScript Loader](https://github.com/pinf/loader-js) is used to provide a development environment and package releases for this project.
|
||||
|
||||
**NOTE:** It is assumed you have the _PINF JavaScript Loader_ mapped to the `commonjs` command and are using the `node` platform by default as explained [here](https://github.com/pinf/loader-js/blob/master/docs/Setup.md).
|
||||
|
||||
|
||||
Publishing
|
||||
==========
|
||||
|
||||
git tag v...
|
||||
|
||||
commonjs -v --script build .
|
||||
|
||||
commonjs -v --script publish .
|
||||
|
||||
|
||||
TODO: Auto-upload to PEAR channel server at http://pear.firephp.org/
|
||||
|
||||
NOTE: For PEAR RC releases: Change release stability to "beta" and capitalize "RC" in release version in package.xml
|
||||
5
vendor/firephp/firephp-core/workspace/lib/project.js
vendored
Normal file
5
vendor/firephp/firephp-core/workspace/lib/project.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
exports.main = function(options)
|
||||
{
|
||||
|
||||
}
|
||||
28
vendor/firephp/firephp-core/workspace/package.json
vendored
Normal file
28
vendor/firephp/firephp-core/workspace/package.json
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "firephp-core",
|
||||
"engine": [
|
||||
"node"
|
||||
],
|
||||
"main": "lib/project.js",
|
||||
"scripts": {
|
||||
"build": {
|
||||
"location": "./",
|
||||
"module": "/scripts/build.js"
|
||||
},
|
||||
"publish": {
|
||||
"location": "./",
|
||||
"module": "/scripts/publish.js"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"nodejs": {
|
||||
"id": "nodejs.org/"
|
||||
},
|
||||
"pinf": {
|
||||
"id": "pinf.org/loader/"
|
||||
},
|
||||
"modules": {
|
||||
"id": "github.com/pinf/modules-js/"
|
||||
}
|
||||
}
|
||||
}
|
||||
78
vendor/firephp/firephp-core/workspace/program.json
vendored
Normal file
78
vendor/firephp/firephp-core/workspace/program.json
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"boot": "workspace",
|
||||
"engine": [
|
||||
"node"
|
||||
],
|
||||
"packages": {
|
||||
"workspace": {
|
||||
"locator": {
|
||||
"location": "./"
|
||||
}
|
||||
},
|
||||
"nodejs.org/": {
|
||||
"provider": "nodejs.org/"
|
||||
},
|
||||
"pinf.org/loader/": {
|
||||
"provider": "pinf.org/loader/"
|
||||
},
|
||||
"github.com/pinf/modules-js/": {
|
||||
"locator": {
|
||||
"archive": "https://github.com/pinf/modules-js/zipball/master"
|
||||
}
|
||||
},
|
||||
"github.com/kriskowal/q/": {
|
||||
"locator": {
|
||||
"archive": "https://github.com/kriskowal/q/zipball/v0.3.0"
|
||||
},
|
||||
"descriptor": {
|
||||
"uid": "https://github.com/kriskowal/q/",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "github.com/pinf/modules-js/"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"private-registry.appspot.com/cadorn.com/github/com.cadorn.baby/projects/sourcemint/packages/client-js/": {
|
||||
"locator": {
|
||||
"archive": "https://github.com/cadorn/com.cadorn.baby/zipball/master",
|
||||
"path": "projects/sourcemint/packages/client-js"
|
||||
}
|
||||
},
|
||||
"github.com/cadorn/aws-lib/": {
|
||||
"locator": {
|
||||
"archive": "https://github.com/cadorn/aws-lib/zipball/master"
|
||||
},
|
||||
"descriptor": {
|
||||
"uid": "https://github.com/cadorn/aws-lib/",
|
||||
"native": true,
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "registry.npmjs.org/sax/"
|
||||
},
|
||||
{
|
||||
"id": "registry.npmjs.org/xml2js/"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"registry.npmjs.org/sax/": {
|
||||
"locator": {
|
||||
"archive": "http://registry.npmjs.org/sax/-/sax-0.1.2.tgz"
|
||||
},
|
||||
"descriptor": {
|
||||
"uid": "http://registry.npmjs.org/sax/",
|
||||
"native": true
|
||||
}
|
||||
},
|
||||
"registry.npmjs.org/xml2js/": {
|
||||
"locator": {
|
||||
"archive": "http://registry.npmjs.org/xml2js/-/xml2js-0.1.6.tgz"
|
||||
},
|
||||
"descriptor": {
|
||||
"uid": "http://registry.npmjs.org/xml2js/",
|
||||
"native": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
164
vendor/firephp/firephp-core/workspace/scripts/build.js
vendored
Normal file
164
vendor/firephp/firephp-core/workspace/scripts/build.js
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
var FILE = require("modules/file"),
|
||||
Q = require("modules/q"),
|
||||
SYSTEM = require("modules/system"),
|
||||
UTIL = require("modules/util"),
|
||||
JSON = require("modules/json");
|
||||
|
||||
|
||||
var pkgPath = FILE.dirname(FILE.dirname(FILE.dirname(module.id))),
|
||||
buildPath = pkgPath + "/build",
|
||||
tplPath = pkgPath + "/workspace/tpl",
|
||||
version = false;
|
||||
|
||||
exports.getBuildPath = function()
|
||||
{
|
||||
return buildPath;
|
||||
}
|
||||
|
||||
exports.main = function()
|
||||
{
|
||||
|
||||
SYSTEM.exec("rm -Rf " + buildPath, function()
|
||||
{
|
||||
FILE.mkdirs(buildPath, 0775);
|
||||
|
||||
SYSTEM.exec("git tag", function(stdout)
|
||||
{
|
||||
version = UTIL.trim(stdout).split("\n").pop().match(/^v(.*)$/)[1];
|
||||
|
||||
// TODO: Compare against version in `../../program.json ~ version` (ensure =)
|
||||
|
||||
module.print("\0cyan(Building version: " + version + "\0)\n");
|
||||
|
||||
buildZipArchive(function()
|
||||
{
|
||||
buildPEARArchive(function()
|
||||
{
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function done()
|
||||
{
|
||||
module.print("\0green(Done\0)\n");
|
||||
}
|
||||
}
|
||||
|
||||
function buildZipArchive(callback)
|
||||
{
|
||||
var targetBasePath = buildPath + "/FirePHPCore-" + version;
|
||||
|
||||
FILE.mkdirs(targetBasePath, 0775);
|
||||
|
||||
SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib " + targetBasePath, function()
|
||||
{
|
||||
replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php");
|
||||
replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php4");
|
||||
|
||||
SYSTEM.exec("cp -Rf " + pkgPath + "/examples " + targetBasePath, function()
|
||||
{
|
||||
next1();
|
||||
});
|
||||
});
|
||||
|
||||
function next1()
|
||||
{
|
||||
var content = FILE.read(tplPath + "/readme.tpl.md");
|
||||
content = content.replace(/%%VERSION%%/g, version);
|
||||
FILE.write(targetBasePath + "/README.md", content);
|
||||
|
||||
var content = FILE.read(tplPath + "/license.tpl.md");
|
||||
FILE.write(targetBasePath + "/LICENSE.md", content);
|
||||
|
||||
FILE.write(buildPath + "/info.json", JSON.encode({
|
||||
version: version
|
||||
}));
|
||||
|
||||
next2();
|
||||
}
|
||||
|
||||
function next2()
|
||||
{
|
||||
SYSTEM.exec("cd " + buildPath + " ; zip -vr FirePHPCore-" + version + ".zip FirePHPCore-" + version, function(stdout)
|
||||
{
|
||||
console.log(stdout);
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buildPEARArchive(callback)
|
||||
{
|
||||
var targetBasePath = buildPath + "/pear";
|
||||
|
||||
FILE.mkdirs(targetBasePath, 0775);
|
||||
|
||||
SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib/FirePHPCore/* " + targetBasePath, function()
|
||||
{
|
||||
replaceVariablesInFile(targetBasePath + "/FirePHP.class.php");
|
||||
replaceVariablesInFile(targetBasePath + "/FirePHP.class.php4");
|
||||
|
||||
next1();
|
||||
});
|
||||
|
||||
function next1()
|
||||
{
|
||||
var content = FILE.read(tplPath + "/pear.package.tpl.xml");
|
||||
|
||||
var date = new Date();
|
||||
content = content.replace(/%%DATE%%/g, date.getFullYear() + "-" + UTIL.padBegin(date.getMonth()+1, 2, "0") + "-" + date.getDate());
|
||||
content = content.replace(/%%VERSION%%/g, version);
|
||||
content = content.replace(/%%STABILITY%%/g, "stable");
|
||||
|
||||
FILE.write(targetBasePath + "/package.xml", content);
|
||||
|
||||
next2();
|
||||
}
|
||||
|
||||
function next2()
|
||||
{
|
||||
SYSTEM.exec("pear channel-discover pear.firephp.org", function(stdout)
|
||||
{
|
||||
console.log(stdout);
|
||||
|
||||
SYSTEM.exec("cd " + targetBasePath + "; pear package package.xml", function(stdout)
|
||||
{
|
||||
console.log(stdout);
|
||||
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function replaceVariablesInFile(path)
|
||||
{
|
||||
var content = FILE.read(path);
|
||||
|
||||
// @pinf replace '0.3' with '%%VERSION%%'
|
||||
var re1 = /\n(.*)\/\/\s*@pinf\s(.*)\n/g;
|
||||
var match1;
|
||||
while (match1 = re1.exec(content)) {
|
||||
var rule = match1[2].match(/^replace (.*?) with (.*)$/);
|
||||
if(rule) {
|
||||
// replace variables in rule
|
||||
var re2 = /%%([^%]*)%%/g;
|
||||
var match2;
|
||||
while (match2 = re2.exec(rule[2])) {
|
||||
var value;
|
||||
if(match2[1]=="VERSION") {
|
||||
value = version;
|
||||
}
|
||||
rule[2] = rule[2].replace(match2[0], value);
|
||||
}
|
||||
match1[1] = match1[1].replace(rule[1], rule[2]);
|
||||
content = content.replace(match1[0], "\n"+match1[1]+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
FILE.write(path, content);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue