Merge pull request #68 from kijin/pr/remove-libs

libs 폴더 내의 오래된 라이브러리들 정리
This commit is contained in:
Kijin Sung 2016-01-15 23:29:23 +09:00
commit 66a6edeffb
458 changed files with 52458 additions and 30848 deletions

1
.gitignore vendored
View file

@ -4,6 +4,7 @@ Thumbs.db
config.user.inc.php
/files/
/build/
/libs/
codeception.yml
/tests/_output/

View file

@ -67,8 +67,7 @@ module.exports = function(grunt) {
"!files/**",
"!tests/**",
"!tools/**",
"!node_modules/**",
"!libs/**",
"!common/libraries/**",
"!vendor/**",
"!tests/_output/**"
],

View file

@ -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;
}
/**

View file

@ -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)
{

View file

@ -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("&lt;", "&gt;", "&amp;"), $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("&lt;", "&gt;", "&amp;"), $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))
{

View file

@ -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
View file

@ -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,

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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/

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;
}
}
}
}
?>

View file

@ -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);
}
}
?>

View file

@ -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

View file

@ -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;
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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");
}
}
// }}}
}
?>

View file

@ -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);
}
}
?>

View file

@ -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']
);
}
}
}
?>

View file

@ -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

View file

@ -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 .= '&hellip;';
$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>&nbsp;</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();
}
}

View file

@ -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];
}
}

View file

@ -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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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);
}
}
?>

View file

@ -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

View file

@ -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
{
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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");
}
}
// }}}
}
?>

View file

@ -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);
}
}
?>

View file

@ -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

View file

@ -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 .= '&hellip;';
$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>&nbsp;</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();
}
}
?>

View file

@ -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

View file

@ -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);
}
}
}
?>

View file

@ -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;
}
}

View file

@ -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;
}
}
?>

File diff suppressed because it is too large Load diff

View file

@ -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!

View file

@ -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

View file

@ -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&#xFC;rgen-m&#xFC;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 &gt;&gt;" /><?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="&lt;&lt; Decode" /><?php echo $add; ?>
</form>
</td>
</tr>
</tbody>
</table>
<br />
<span id="copy">Version used: 0.9.0; &copy; 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

View file

@ -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;
}
?>

View file

@ -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;
}
}
?>

View file

@ -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

View file

@ -1 +0,0 @@
<!DOCTYPE html><title></title>

View file

@ -1 +0,0 @@
<!DOCTYPE html><title></title>

View file

@ -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

View file

@ -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;
}
}
?>

View file

@ -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)
{

View file

@ -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);

View 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';

View file

@ -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'));

View file

@ -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))
{

View file

@ -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();

View file

@ -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

View file

@ -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',
);

View file

@ -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',
);

View file

@ -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'),
);

View file

@ -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"
}
]

View file

@ -0,0 +1 @@
build/

171
vendor/firephp/firephp-core/CHANGELOG.md vendored Normal file
View 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
View 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.

View 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"
]
}
}

View 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';

View 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';

View 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';

View 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';

File diff suppressed because it is too large Load diff

View 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);
}
}

View 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);
}
}

View 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"
}
}
]
}

View file

@ -0,0 +1,5 @@
{
"extends": {
"location": "./workspace/program.json"
}
}

View 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);

View 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";
}

View 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;
}
}

View file

@ -0,0 +1,2 @@
<phpunit bootstrap="TestHelper.php">
</phpunit>

View 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

View file

@ -0,0 +1,5 @@
exports.main = function(options)
{
}

View 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/"
}
}
}

View 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
}
}
}
}

View 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