Import additional composer dependencies

This commit is contained in:
Kijin Sung 2016-01-13 14:03:48 +09:00
parent 01dd26783f
commit c3dc2c68f3
439 changed files with 67918 additions and 138 deletions

View file

@ -23,8 +23,11 @@
"ezyang/htmlpurifier": "4.7.*",
"matthiasmullie/minify": "1.3.*",
"michelf/php-markdown": "1.5.*",
"pear/http_request2": "2.2.*",
"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",

291
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": "97c72bd2862f9d0a77824d769085e926",
"content-hash": "ffd2aaf7dc6705d78c09488d2c7ab024",
"packages": [
{
"name": "defuse/php-encryption",
@ -98,16 +98,16 @@
},
{
"name": "matthiasmullie/minify",
"version": "1.3.30",
"version": "1.3.32",
"source": {
"type": "git",
"url": "https://github.com/matthiasmullie/minify.git",
"reference": "0cd5108683e7376e795555ced56229c4c16597aa"
"reference": "140c714688908afcecde87338c8309233bdc2519"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/0cd5108683e7376e795555ced56229c4c16597aa",
"reference": "0cd5108683e7376e795555ced56229c4c16597aa",
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/140c714688908afcecde87338c8309233bdc2519",
"reference": "140c714688908afcecde87338c8309233bdc2519",
"shasum": ""
},
"require": {
@ -151,20 +151,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 +201,7 @@
"paths",
"relative"
],
"time": "2016-01-05 07:45:30"
"time": "2016-01-07 00:41:13"
},
{
"name": "michelf/php-markdown",
@ -254,6 +254,174 @@
],
"time": "2015-03-01 12:03:08"
},
{
"name": "pear/http_request2",
"version": "v2.2.1",
"source": {
"type": "git",
"url": "https://github.com/pear/HTTP_Request2.git",
"reference": "d6c81670c504045248c1afdf896bb9a3288158de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/HTTP_Request2/zipball/d6c81670c504045248c1afdf896bb9a3288158de",
"reference": "d6c81670c504045248c1afdf896bb9a3288158de",
"shasum": ""
},
"require": {
"pear/net_url2": ">=2.0.0",
"pear/pear_exception": "*",
"php": ">=5.2.0"
},
"suggest": {
"ext-fileinfo": "Adds support for looking up mime-types using finfo.",
"ext-zlib": "Allows handling gzip compressed responses.",
"lib-curl": "Allows using cURL as a request backend.",
"lib-openssl": "Allows handling SSL requests when not using cURL."
},
"type": "library",
"autoload": {
"psr-0": {
"HTTP_Request2": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Alexey Borzov",
"email": "avb@php.net",
"role": "Developer HTML_Common2"
}
],
"description": "Provides an easy way to perform HTTP requests.",
"homepage": "http://pear.php.net/package/HTTP_Request2",
"keywords": [
"PEAR",
"curl",
"http",
"request"
],
"time": "2014-01-16 17:27:21"
},
{
"name": "pear/net_url2",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/pear/Net_URL2.git",
"reference": "fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/Net_URL2/zipball/fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e",
"reference": "fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e",
"shasum": ""
},
"require": {
"php": ">=5.1.4"
},
"require-dev": {
"phpunit/phpunit": ">=3.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2.x-dev"
}
},
"autoload": {
"classmap": [
"Net/URL2.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "David Coallier",
"email": "davidc@php.net"
},
{
"name": "Tom Klingenberg",
"email": "tkli@php.net"
},
{
"name": "Christian Schmidt",
"email": "chmidt@php.net"
}
],
"description": "Class for parsing and handling URL. Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of relative URLs.",
"homepage": "https://github.com/pear/Net_URL2",
"keywords": [
"PEAR",
"net",
"networking",
"rfc3986",
"uri",
"url"
],
"time": "2015-04-18 17:36:57"
},
{
"name": "pear/pear_exception",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/pear/PEAR_Exception.git",
"reference": "8c18719fdae000b690e3912be401c76e406dd13b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b",
"reference": "8c18719fdae000b690e3912be401c76e406dd13b",
"shasum": ""
},
"require": {
"php": ">=4.4.0"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"type": "class",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"PEAR": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"."
],
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Helgi Thormar",
"email": "dufuz@php.net"
},
{
"name": "Greg Beaver",
"email": "cellog@php.net"
}
],
"description": "The PEAR Exception base class.",
"homepage": "https://github.com/pear/PEAR_Exception",
"keywords": [
"exception"
],
"time": "2015-02-10 20:07:52"
},
{
"name": "rmccue/requests",
"version": "v1.6.1",
@ -345,6 +513,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

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

@ -235,6 +235,37 @@ return array(
'HTMLPurifier_VarParser_Flexible' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php',
'HTMLPurifier_VarParser_Native' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php',
'HTMLPurifier_Zipper' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php',
'HTTP_Request2' => $vendorDir . '/pear/http_request2/HTTP/Request2.php',
'HTTP_Request2Test' => $vendorDir . '/pear/http_request2/tests/Request2Test.php',
'HTTP_Request2_Adapter' => $vendorDir . '/pear/http_request2/HTTP/Request2/Adapter.php',
'HTTP_Request2_Adapter_CommonNetworkTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/CommonNetworkTest.php',
'HTTP_Request2_Adapter_Curl' => $vendorDir . '/pear/http_request2/HTTP/Request2/Adapter/Curl.php',
'HTTP_Request2_Adapter_CurlTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/CurlTest.php',
'HTTP_Request2_Adapter_Mock' => $vendorDir . '/pear/http_request2/HTTP/Request2/Adapter/Mock.php',
'HTTP_Request2_Adapter_MockTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/MockTest.php',
'HTTP_Request2_Adapter_Skip_CurlTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/SkippedTests.php',
'HTTP_Request2_Adapter_Skip_SocketProxyTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/SkippedTests.php',
'HTTP_Request2_Adapter_Skip_SocketTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/SkippedTests.php',
'HTTP_Request2_Adapter_Socket' => $vendorDir . '/pear/http_request2/HTTP/Request2/Adapter/Socket.php',
'HTTP_Request2_Adapter_SocketProxyTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/SocketProxyTest.php',
'HTTP_Request2_Adapter_SocketTest' => $vendorDir . '/pear/http_request2/tests/Request2/Adapter/SocketTest.php',
'HTTP_Request2_AllTests' => $vendorDir . '/pear/http_request2/tests/AllTests.php',
'HTTP_Request2_ConnectionException' => $vendorDir . '/pear/http_request2/HTTP/Request2/Exception.php',
'HTTP_Request2_CookieJar' => $vendorDir . '/pear/http_request2/HTTP/Request2/CookieJar.php',
'HTTP_Request2_CookieJarTest' => $vendorDir . '/pear/http_request2/tests/Request2/CookieJarTest.php',
'HTTP_Request2_Exception' => $vendorDir . '/pear/http_request2/HTTP/Request2/Exception.php',
'HTTP_Request2_LogicException' => $vendorDir . '/pear/http_request2/HTTP/Request2/Exception.php',
'HTTP_Request2_MessageException' => $vendorDir . '/pear/http_request2/HTTP/Request2/Exception.php',
'HTTP_Request2_MockObserver' => $vendorDir . '/pear/http_request2/tests/ObserverTest.php',
'HTTP_Request2_MultipartBody' => $vendorDir . '/pear/http_request2/HTTP/Request2/MultipartBody.php',
'HTTP_Request2_MultipartBodyTest' => $vendorDir . '/pear/http_request2/tests/Request2/MultipartBodyTest.php',
'HTTP_Request2_NotImplementedException' => $vendorDir . '/pear/http_request2/HTTP/Request2/Exception.php',
'HTTP_Request2_ObserverTest' => $vendorDir . '/pear/http_request2/tests/ObserverTest.php',
'HTTP_Request2_Observer_Log' => $vendorDir . '/pear/http_request2/HTTP/Request2/Observer/Log.php',
'HTTP_Request2_Response' => $vendorDir . '/pear/http_request2/HTTP/Request2/Response.php',
'HTTP_Request2_ResponseTest' => $vendorDir . '/pear/http_request2/tests/Request2/ResponseTest.php',
'HTTP_Request2_SOCKS5' => $vendorDir . '/pear/http_request2/HTTP/Request2/SOCKS5.php',
'HTTP_Request2_SocketWrapper' => $vendorDir . '/pear/http_request2/HTTP/Request2/SocketWrapper.php',
'MatthiasMullie\\Minify\\CSS' => $vendorDir . '/matthiasmullie/minify/src/CSS.php',
'MatthiasMullie\\Minify\\Exception' => $vendorDir . '/matthiasmullie/minify/src/Exception.php',
'MatthiasMullie\\Minify\\JS' => $vendorDir . '/matthiasmullie/minify/src/JS.php',
@ -243,6 +274,9 @@ return array(
'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php',
'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php',
'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php',
'Net_URL2' => $vendorDir . '/pear/net_url2/Net/URL2.php',
'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
'PEAR_ExceptionTest' => $vendorDir . '/pear/pear_exception/tests/PEAR/ExceptionTest.php',
'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php',
'Requests_Auth' => $vendorDir . '/rmccue/requests/library/Requests/Auth.php',
'Requests_Auth_Basic' => $vendorDir . '/rmccue/requests/library/Requests/Auth/Basic.php',
@ -297,4 +331,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

@ -8,6 +8,8 @@ $baseDir = dirname($vendorDir);
return array(
'Sunra\\PhpSimple\\HtmlDomParser' => array($vendorDir . '/sunra/php-simple-html-dom-parser/Src'),
'Requests' => array($vendorDir . '/rmccue/requests/library'),
'PEAR' => array($vendorDir . '/pear/pear_exception'),
'Michelf' => array($vendorDir . '/michelf/php-markdown'),
'HTTP_Request2' => array($vendorDir . '/pear/http_request2'),
'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
);

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

@ -23,6 +23,10 @@ class ComposerAutoloaderInit1e37ff09eb6590c7436f139ffd9070de
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit1e37ff09eb6590c7436f139ffd9070de', 'loadClassLoader'));
$includePaths = require __DIR__ . '/include_paths.php';
array_push($includePaths, get_include_path());
set_include_path(join(PATH_SEPARATOR, $includePaths));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);

10
vendor/composer/include_paths.php vendored Normal file
View file

@ -0,0 +1,10 @@
<?php
// include_paths.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/pear/pear_exception',
);

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,393 @@
"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": "pear/pear_exception",
"version": "v1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/pear/PEAR_Exception.git",
"reference": "8c18719fdae000b690e3912be401c76e406dd13b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b",
"reference": "8c18719fdae000b690e3912be401c76e406dd13b",
"shasum": ""
},
"require": {
"php": ">=4.4.0"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"time": "2015-02-10 20:07:52",
"type": "class",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"PEAR": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"."
],
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Helgi Thormar",
"email": "dufuz@php.net"
},
{
"name": "Greg Beaver",
"email": "cellog@php.net"
}
],
"description": "The PEAR Exception base class.",
"homepage": "https://github.com/pear/PEAR_Exception",
"keywords": [
"exception"
]
},
{
"name": "pear/net_url2",
"version": "v2.2.0",
"version_normalized": "2.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/pear/Net_URL2.git",
"reference": "fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/Net_URL2/zipball/fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e",
"reference": "fa9b1ecb3c3e640d4a54d58d681a4cb7524f209e",
"shasum": ""
},
"require": {
"php": ">=5.1.4"
},
"require-dev": {
"phpunit/phpunit": ">=3.3.0"
},
"time": "2015-04-18 17:36:57",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"classmap": [
"Net/URL2.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "David Coallier",
"email": "davidc@php.net"
},
{
"name": "Tom Klingenberg",
"email": "tkli@php.net"
},
{
"name": "Christian Schmidt",
"email": "chmidt@php.net"
}
],
"description": "Class for parsing and handling URL. Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of relative URLs.",
"homepage": "https://github.com/pear/Net_URL2",
"keywords": [
"PEAR",
"net",
"networking",
"rfc3986",
"uri",
"url"
]
},
{
"name": "pear/http_request2",
"version": "v2.2.1",
"version_normalized": "2.2.1.0",
"source": {
"type": "git",
"url": "https://github.com/pear/HTTP_Request2.git",
"reference": "d6c81670c504045248c1afdf896bb9a3288158de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/HTTP_Request2/zipball/d6c81670c504045248c1afdf896bb9a3288158de",
"reference": "d6c81670c504045248c1afdf896bb9a3288158de",
"shasum": ""
},
"require": {
"pear/net_url2": ">=2.0.0",
"pear/pear_exception": "*",
"php": ">=5.2.0"
},
"suggest": {
"ext-fileinfo": "Adds support for looking up mime-types using finfo.",
"ext-zlib": "Allows handling gzip compressed responses.",
"lib-curl": "Allows using cURL as a request backend.",
"lib-openssl": "Allows handling SSL requests when not using cURL."
},
"time": "2014-01-16 17:27:21",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"HTTP_Request2": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Alexey Borzov",
"email": "avb@php.net",
"role": "Developer HTML_Common2"
}
],
"description": "Provides an easy way to perform HTTP requests.",
"homepage": "http://pear.php.net/package/HTTP_Request2",
"keywords": [
"PEAR",
"curl",
"http",
"request"
]
},
{
"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"
]
}
]

View file

@ -314,6 +314,10 @@ class CSS extends Minify
// restore the string we've extracted earlier
$css = $this->restoreExtractedData($css);
$source = $source ?: '';
$css = $this->combineImports($source, $css);
$css = $this->importFiles($source, $css);
/*
* If we'll save to a new path, we'll have to fix the relative paths
* to be relative no longer to the source file, but to the new path.
@ -321,15 +325,9 @@ class CSS extends Minify
* conversion happens (because we still want it to go through most
* of the move code...)
*/
$source = $source ?: '';
$converter = new Converter($source, $path ?: $source);
$css = $this->move($converter, $css);
// if no target path is given, relative paths were not converted, so
// they'll still be relative to the source file then
$css = $this->importFiles($path ?: $source, $css);
$css = $this->combineImports($path ?: $source, $css);
// combine css
$content .= $css;
}
@ -522,11 +520,12 @@ class CSS extends Minify
* Strip comments from source code.
*
* @param string $content
*
* @return string
*/
protected function stripEmptyTags($content)
{
return preg_replace('/(^|\})[^\{]+\{\s*\}/', '\\1', $content);
return preg_replace('/(^|\})[^\{\}]+\{\s*\}/', '\\1', $content);
}
/**

View file

@ -1,4 +1,5 @@
<?php
namespace MatthiasMullie\PathConverter;
/**
@ -12,7 +13,6 @@ namespace MatthiasMullie\PathConverter;
* Please report bugs on https://github.com/matthiasmullie/path-converter/issues
*
* @author Matthias Mullie <pathconverter@mullie.eu>
*
* @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved.
* @license MIT License
*/
@ -38,6 +38,11 @@ class Converter
if ($shared === '') {
// when both paths have nothing in common, one of them is probably
// absolute while the other is relative
$cwd = getcwd();
$from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
$to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
// or traveling the tree via `..`
// attempt to resolve path, or assume it's fine if it doesn't exist
$from = realpath($from) ?: $from;
$to = realpath($to) ?: $to;
@ -56,7 +61,8 @@ class Converter
/**
* Normalize path.
*
* @param string $path
* @param string $path
*
* @return string
*/
protected function normalize($path)
@ -87,8 +93,9 @@ class Converter
* share
* /home/forkcms/frontend
*
* @param string $path1
* @param string $path2
* @param string $path1
* @param string $path2
*
* @return string
*/
protected function shared($path1, $path2)
@ -122,7 +129,8 @@ class Converter
* ../../core/layout/images/img.gif relative to
* /home/forkcms/frontend/cache/minified_css
*
* @param string $path The relative path that needs to be converted.
* @param string $path The relative path that needs to be converted.
*
* @return string The new relative path.
*/
public function convert($path)
@ -155,7 +163,8 @@ class Converter
/**
* Attempt to get the directory name from a path.
*
* @param string $path
* @param string $path
*
* @return string
*/
public function dirname($path)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,137 @@
<?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: @package_version@
* @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

@ -0,0 +1,567 @@
<?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: @package_version@
* @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

@ -0,0 +1,166 @@
<?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: @package_version@
* @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

@ -0,0 +1,494 @@
<?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

@ -0,0 +1,160 @@
<?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: @package_version@
* @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: @package_version@
* @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: @package_version@
* @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: @package_version@
* @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: @package_version@
* @link http://pear.php.net/package/HTTP_Request2
*/
class HTTP_Request2_MessageException extends HTTP_Request2_Exception
{
}
?>

View file

@ -0,0 +1,268 @@
<?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: @package_version@
* @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

@ -0,0 +1,192 @@
<?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: @package_version@
* @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

@ -0,0 +1,631 @@
<?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: @package_version@
* @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

@ -0,0 +1,135 @@
<?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: @package_version@
* @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

@ -0,0 +1,297 @@
<?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: @package_version@
* @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;
}
}
?>

80
vendor/pear/http_request2/README.md vendored Normal file
View file

@ -0,0 +1,80 @@
# HTTP_Request2
Provides an easy way to perform HTTP requests, uses pluggable adapters
* Socket: pure PHP implementation of HTTP protocol (does *not* use http stream wrapper), based on older [PEAR HTTP_Request] package
* Curl: wrapper around PHP's cURL extension
* Mock: used for testing packages depending on HTTP_Request2, returns predefined responses without network interaction
Both Socket and Curl adapters support POST requests with data and file uploads, basic and digest
authentication, cookies, managing cookies across requests, HTTP and SOCKS5 proxies, gzip and
deflate encodings, redirects, monitoring the request progress with Observers...
This package is [PEAR HTTP_Request2] and has been migrated from [PEAR SVN]
Please report all issues via the [PEAR bug tracker].
Pull requests are welcome.
[PEAR HTTP_Request]: http://pear.php.net/package/HTTP_Request/
[PEAR HTTP_Request2]: http://pear.php.net/package/HTTP_Request2/
[PEAR SVN]: https://svn.php.net/repository/pear/packages/HTTP_Request2
[PEAR bug tracker]: http://pear.php.net/bugs/search.php?cmd=display&package_name[]=HTTP_Request2
## Basic usage
```PHP
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2('http://pear.php.net/', HTTP_Request2::METHOD_GET);
try {
$response = $request->send();
if (200 == $response->getStatus()) {
echo $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
```
## Documentation
...is available on PEAR website
* Numerous [configuration options](http://pear.php.net/manual/en/package.http.http-request2.config.php)
* How to populate [the request object](http://pear.php.net/manual/en/package.http.http-request2.request.php)
* Description of [available adapters](http://pear.php.net/manual/en/package.http.http-request2.adapters.php)
* Processing of [HTTP response](http://pear.php.net/manual/en/package.http.http-request2.response.php)
* Monitoring the progress of request with [observers](http://pear.php.net/manual/en/package.http.http-request2.observers.php)
* Possible [exceptions](http://pear.php.net/manual/en/package.http.http-request2.exceptions.php)
[Generated API documentation](http://pear.php.net/package/HTTP_Request2/docs/latest/) for the current release is also there.
## Testing, Packaging and Installing (Pear)
To test, run either
$ phpunit tests/
or
$ pear run-tests -r
You may need to set up the NetworkConfig.php file if you want to perform tests that interact with a web server.
Its template is NetworkConfig.php.dist file, consult it for the details.
To build, simply
$ pear package
To install from scratch
$ pear install package.xml
To upgrade
$ pear upgrade -f package.xml

34
vendor/pear/http_request2/composer.json vendored Normal file
View file

@ -0,0 +1,34 @@
{
"name" : "pear/http_request2",
"description" : "Provides an easy way to perform HTTP requests.",
"type" : "library",
"keywords" : [ "http", "request", "pear", "curl" ],
"homepage" : "http://pear.php.net/package/HTTP_Request2",
"license" : "BSD-3-Clause",
"authors" : [
{
"name" : "Alexey Borzov",
"email" : "avb@php.net"
}
],
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=HTTP_Request2",
"source": "https://github.com/pear/HTTP_Request2"
},
"require" : {
"php" : ">=5.2.0",
"pear/net_url2" : ">=2.0.0",
"pear/pear_exception" : "*"
},
"suggest" : {
"ext-fileinfo" : "Adds support for looking up mime-types using finfo.",
"ext-zlib" : "Allows handling gzip compressed responses.",
"lib-curl" : "Allows using cURL as a request backend.",
"lib-openssl" : "Allows handling SSL requests when not using cURL."
},
"autoload": {
"psr-0": {
"HTTP_Request2" : ""
}
}
}

View file

@ -0,0 +1,96 @@
<?php
/**
* Helper file for downloading Public Suffix List and converting it to PHP array
*
* You can run this script to update PSL to the current version instead of
* waiting for a new release of HTTP_Request2.
*/
/** URL to download Public Suffix List from */
define('LIST_URL', 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1');
/** Name of PHP file to write */
define('OUTPUT_FILE', dirname(__FILE__) . '/public-suffix-list.php');
require_once 'HTTP/Request2.php';
function buildSubdomain(&$node, $tldParts)
{
$part = trim(array_pop($tldParts));
if (!array_key_exists($part, $node)) {
$node[$part] = array();
}
if (0 < count($tldParts)) {
buildSubdomain($node[$part], $tldParts);
}
}
function writeNode($fp, $valueTree, $key = null, $indent = 0)
{
if (is_null($key)) {
fwrite($fp, "return ");
} else {
fwrite($fp, str_repeat(' ', $indent) . "'$key' => ");
}
if (0 == ($count = count($valueTree))) {
fwrite($fp, 'true');
} else {
fwrite($fp, "array(\n");
for ($keys = array_keys($valueTree), $i = 0; $i < $count; $i++) {
writeNode($fp, $valueTree[$keys[$i]], $keys[$i], $indent + 1);
if ($i + 1 != $count) {
fwrite($fp, ",\n");
} else {
fwrite($fp, "\n");
}
}
fwrite($fp, str_repeat(' ', $indent) . ")");
}
}
try {
$request = new HTTP_Request2(LIST_URL);
$response = $request->send();
if (200 != $response->getStatus()) {
throw new Exception("List download URL returned status: " .
$response->getStatus() . ' ' . $response->getReasonPhrase());
}
$list = $response->getBody();
if (false === strpos($list, '// ===BEGIN ICANN DOMAINS===')) {
throw new Exception("List download URL does not contain expected phrase");
}
if (!($fp = @fopen(OUTPUT_FILE, 'wt'))) {
throw new Exception("Unable to open " . OUTPUT_FILE);
}
} catch (Exception $e) {
die($e->getMessage());
}
$tldTree = array();
$license = true;
fwrite($fp, "<?php\n");
foreach (array_filter(array_map('trim', explode("\n", $list))) as $line) {
if ('//' != substr($line, 0, 2)) {
buildSubdomain($tldTree, explode('.', $line));
} elseif ($license) {
if (0 === strpos($line, "// ===BEGIN ICANN DOMAINS===")) {
fwrite($fp, "\n");
$license = false;
} else {
fwrite($fp, $line . "\n");
}
}
}
writeNode($fp, $tldTree);
fwrite($fp, ";\n?>");
fclose($fp);
?>

File diff suppressed because it is too large Load diff

31
vendor/pear/http_request2/docs/LICENSE vendored Normal file
View file

@ -0,0 +1,31 @@
HTTP_Request2
Copyright (c) 2008-2014, 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the name of Alexey Borzov nor the names of his 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 HOLDER 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

@ -0,0 +1,58 @@
<?php
/**
* Usage example for HTTP_Request2 package: uploading a file to rapidshare.com
*
* Inspired by Perl usage example: http://images.rapidshare.com/software/rsapi.pl
* Rapidshare API description: http://rapidshare.com/dev.html
*/
require_once 'HTTP/Request2.php';
// You'll probably want to change this
$filename = '/etc/passwd';
try {
// First step: get an available upload server
$request = new HTTP_Request2(
'http://rapidshare.com/cgi-bin/rsapi.cgi?sub=nextuploadserver_v1'
);
$server = $request->send()->getBody();
if (!preg_match('/^(\\d+)$/', $server)) {
throw new Exception("Invalid upload server: {$server}");
}
// Calculate file hash, we'll use it later to check upload
if (false === ($hash = @md5_file($filename))) {
throw new Exception("Cannot calculate MD5 hash of '{$filename}'");
}
// Second step: upload a file to the available server
$uploader = new HTTP_Request2(
"http://rs{$server}l3.rapidshare.com/cgi-bin/upload.cgi",
HTTP_Request2::METHOD_POST
);
// Adding the file
$uploader->addUpload('filecontent', $filename);
// This will tell server to return program-friendly output
$uploader->addPostParameter('rsapi_v1', '1');
$response = $uploader->send()->getBody();
if (!preg_match_all('/^(File[^=]+)=(.+)$/m', $response, $m, PREG_SET_ORDER)) {
throw new Exception("Invalid response: {$response}");
}
$rspAry = array();
foreach ($m as $item) {
$rspAry[$item[1]] = $item[2];
}
// Check that uploaded file has the same hash
if (empty($rspAry['File1.4'])) {
throw new Exception("MD5 hash data not found in response");
} elseif ($hash != strtolower($rspAry['File1.4'])) {
throw new Exception("Upload failed, local MD5 is {$hash}, uploaded MD5 is {$rspAry['File1.4']}");
}
echo "Upload succeeded\nDownload link: {$rspAry['File1.1']}\nDelete link: {$rspAry['File1.2']}\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>

646
vendor/pear/http_request2/package.xml vendored Normal file
View file

@ -0,0 +1,646 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<package version="2.0"
xmlns="http://pear.php.net/dtd/package-2.0"
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>HTTP_Request2</name>
<channel>pear.php.net</channel>
<extends>HTTP_Request</extends>
<summary>Provides an easy way to perform HTTP requests.</summary>
<description>
PHP5 rewrite of HTTP_Request package (with parts of HTTP_Client). Provides
cleaner API and pluggable Adapters:
* Socket adapter, based on old HTTP_Request code,
* Curl adapter, wraps around PHP's cURL extension,
* Mock adapter, to use for testing packages dependent on HTTP_Request2.
Supports POST requests with data and file uploads, basic and digest
authentication, cookies, managing cookies across requests, proxies, gzip and
deflate encodings, redirects, monitoring the request progress with Observers...
</description>
<lead>
<name>Alexey Borzov</name>
<user>avb</user>
<email>avb@php.net</email>
<active>yes</active>
</lead>
<date>2014-01-16</date>
<version>
<release>2.2.1</release>
<api>2.2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/BSD-3-Clause">BSD 3-Clause License</license>
<notes>
* Fixed a bogus timeout Exception in Socket adapter after waiting for
&quot;100 Continue&quot; response: the same one second timeout was used
for further socket operations if explicit 'timeout' parameter was not set.
Thanks to Andrea Brancatelli (abrancatelli as schema31 dot it) for the report.
* Bundled a separate LICENSE file (request #20175). Updated phrasing and links
to mention 3-Clause BSD license the package actually uses.
</notes>
<contents>
<dir name="/">
<dir name="HTTP">
<dir name="Request2">
<dir name="Adapter">
<file role="php" name="Curl.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="Mock.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="Socket.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
</dir>
<file role="php" name="Adapter.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="CookieJar.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
<tasks:replace from="@data_dir@" to="data_dir" type="pear-config" />
</file>
<file role="php" name="Exception.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="MultipartBody.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="SocketWrapper.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file role="php" name="SOCKS5.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<dir name="Observer">
<file role="php" name="Log.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
</dir>
<file role="php" name="Response.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
</dir>
<file role="php" name="Request2.php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
</dir>
<dir name="tests">
<dir name="_files">
<file role="test" name="bug_15305" />
<file role="test" name="bug_18169" />
<file role="test" name="empty.gif" />
<file role="test" name="plaintext.txt" />
<file role="test" name="response_cookies" />
<file role="test" name="response_deflate" />
<file role="test" name="response_gzip" />
<file role="test" name="response_gzip_broken" />
<file role="test" name="response_headers" />
</dir>
<dir name="_network">
<file role="test" name="basicauth.php" />
<file role="test" name="bug19934.php" />
<file role="test" name="cookies.php" />
<file role="test" name="digestauth.php" />
<file role="test" name="getparameters.php" />
<file role="test" name="postparameters.php" />
<file role="test" name="rawpostdata.php" />
<file role="test" name="redirects.php" />
<file role="test" name="setcookie.php" />
<file role="test" name="timeout.php" />
<file role="test" name="uploads.php" />
</dir>
<dir name="Request2">
<dir name="Adapter">
<file role="test" name="AllTests.php" />
<file role="test" name="CommonNetworkTest.php" />
<file role="test" name="CurlTest.php" />
<file role="test" name="MockTest.php" />
<file role="test" name="SkippedTests.php" />
<file role="test" name="SocketProxyTest.php" />
<file role="test" name="SocketTest.php" />
</dir>
<file role="test" name="AllTests.php" />
<file role="test" name="CookieJarTest.php" />
<file role="test" name="MultipartBodyTest.php" />
<file role="test" name="ResponseTest.php" />
</dir>
<file role="test" name="AllTests.php" />
<file role="test" name="NetworkConfig.php.dist" />
<file role="test" name="ObserverTest.php" />
<file role="test" name="Request2Test.php" />
<file role="test" name="TestHelper.php" />
</dir>
<dir name="docs">
<file role="doc" name="LICENSE" />
<file role="doc" name="examples/upload-rapidshare.php" />
</dir>
<dir name="data">
<file role="data" name="generate-list.php" />
<file role="data" name="public-suffix-list.php" />
</dir>
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.2.0</min>
</php>
<pearinstaller>
<min>1.9.2</min>
</pearinstaller>
<package>
<name>Net_URL2</name>
<channel>pear.php.net</channel>
<min>2.0.0</min>
</package>
<package>
<name>PEAR</name>
<channel>pear.php.net</channel>
<min>1.9.2</min>
</package>
</required>
<optional>
<extension>
<name>curl</name>
</extension>
<extension>
<name>fileinfo</name>
</extension>
<extension>
<name>zlib</name>
</extension>
<extension>
<name>openssl</name>
</extension>
</optional>
</dependencies>
<phprelease>
<filelist>
<install as="LICENSE" name="docs/LICENSE" />
<install as="examples/upload-rapidshare.php" name="docs/examples/upload-rapidshare.php" />
<install as="generate-list.php" name="data/generate-list.php" />
<install as="public-suffix-list.php" name="data/public-suffix-list.php" />
<install as="AllTests.php" name="tests/AllTests.php" />
<install as="NetworkConfig.php.dist" name="tests/NetworkConfig.php.dist" />
<install as="ObserverTest.php" name="tests/ObserverTest.php" />
<install as="Request2Test.php" name="tests/Request2Test.php" />
<install as="TestHelper.php" name="tests/TestHelper.php" />
<install as="_files/bug_15305" name="tests/_files/bug_15305" />
<install as="_files/bug_18169" name="tests/_files/bug_18169" />
<install as="_files/empty.gif" name="tests/_files/empty.gif" />
<install as="_files/plaintext.txt" name="tests/_files/plaintext.txt" />
<install as="_files/response_cookies" name="tests/_files/response_cookies" />
<install as="_files/response_deflate" name="tests/_files/response_deflate" />
<install as="_files/response_gzip" name="tests/_files/response_gzip" />
<install as="_files/response_gzip_broken" name="tests/_files/response_gzip_broken" />
<install as="_files/response_headers" name="tests/_files/response_headers" />
<install as="_network/basicauth.php" name="tests/_network/basicauth.php" />
<install as="_network/bug19934.php" name="tests/_network/bug19934.php" />
<install as="_network/cookies.php" name="tests/_network/cookies.php" />
<install as="_network/digestauth.php" name="tests/_network/digestauth.php" />
<install as="_network/getparameters.php" name="tests/_network/getparameters.php" />
<install as="_network/postparameters.php" name="tests/_network/postparameters.php" />
<install as="_network/rawpostdata.php" name="tests/_network/rawpostdata.php" />
<install as="_network/redirects.php" name="tests/_network/redirects.php" />
<install as="_network/setcookie.php" name="tests/_network/setcookie.php" />
<install as="_network/timeout.php" name="tests/_network/timeout.php" />
<install as="_network/uploads.php" name="tests/_network/uploads.php" />
<install as="Request2/AllTests.php" name="tests/Request2/AllTests.php" />
<install as="Request2/CookieJarTest.php" name="tests/Request2/CookieJarTest.php" />
<install as="Request2/MultipartBodyTest.php" name="tests/Request2/MultipartBodyTest.php" />
<install as="Request2/ResponseTest.php" name="tests/Request2/ResponseTest.php" />
<install as="Request2/Adapter/AllTests.php" name="tests/Request2/Adapter/AllTests.php" />
<install as="Request2/Adapter/CommonNetworkTest.php" name="tests/Request2/Adapter/CommonNetworkTest.php" />
<install as="Request2/Adapter/CurlTest.php" name="tests/Request2/Adapter/CurlTest.php" />
<install as="Request2/Adapter/MockTest.php" name="tests/Request2/Adapter/MockTest.php" />
<install as="Request2/Adapter/SkippedTests.php" name="tests/Request2/Adapter/SkippedTests.php" />
<install as="Request2/Adapter/SocketProxyTest.php" name="tests/Request2/Adapter/SocketProxyTest.php" />
<install as="Request2/Adapter/SocketTest.php" name="tests/Request2/Adapter/SocketTest.php" />
</filelist>
</phprelease>
<changelog>
<release>
<date>2014-01-12</date>
<version>
<release>2.2.0</release>
<api>2.2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
New features
* Socket adapter will send &quot;Expect: 100-continue&quot; header and wait for
&quot;100 Continue&quot; response by default before sending large request body
(request #19233). This can be disabled by setting an empty &quot;Expect&quot;
header, the same way as done with Curl adapter (see bug #15937)
* It is possible to specify a local IP address to bind to using 'local_ip'
configuration parameter (request #19515)
Other changes and fixes
* An infinite loop was possible when using a stream wrapper instead of
a regular file with MultipartBody (bug #19934)
* Socket adapter will properly send chunked request body if
&quot;Transfer-Encoding: chunked&quot; header is set for the request (bug #20125)
* Updated Public Suffix List to the latest version and updated its download script
* Unit tests fixes
</notes>
</release>
<release>
<date>2012-04-08</date>
<version>
<release>2.1.1</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
Fixes for SOCKS5 proxies support in Socket adapter
</notes>
</release>
<release>
<date>2012-04-07</date>
<version>
<release>2.1.0</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
New features:
* Mock adapter can return responses based on request URL (request #19276)
* Support for SOCKS5 proxies, added 'proxy_type' configuration parameter
(request #19332)
* Proxy configuration may be given as an URL, e.g.
$request-&gt;setConfig('proxy', 'socks5://localhost:1080');
Other changes and fixes:
* Coding standards fixes (request #14990)
* Unit tests now run from SVN checkout and under PHPUnit 3.6.x
* Explicit dependency on PEAR (until PEAR_Exception is a separate package)
* Get rid of track_errors, use a more robust solution (bug #19337)
* Additional class_exists() check in setAdapter() (request #19344)
* Public suffix list updated to current version
</notes>
</release>
<release>
<date>2011-10-20</date>
<version>
<release>2.0.0</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
2.0.0RC2 repackaged as stable and depending on stable Net_URL2. No code changes.
</notes>
</release>
<release>
<date>2011-10-01</date>
<version>
<release>2.0.0RC2</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Added an accessor method for HTTP_Request2_Response::$phrases (request #18716)
* HTTP_Request2::send() throws an exception if URL is not provided
rather than dies with a fatal error (bug #18755)
* Public Suffix List updated to current version
</notes>
</release>
<release>
<date>2011-05-06</date>
<version>
<release>2.0.0RC1</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
SSL options for Curl Adapter are always set, this prevents errors when
redirecting from HTTP to HTTPS (bug #18443)
</notes>
</release>
<release>
<version>
<release>2.0.0beta3</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2011-04-03</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Added getEffectiveUrl() method to Response object, it returns the URL
response was received from, possibly after redirects (request #18412)
* Curl Adapter didn't send body for PUT requests sometimes (bug #18421)
</notes>
</release>
<release>
<version>
<release>2.0.0beta2</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2011-03-25</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Unit tests can now be run under recent PHPUnit versions (3.5+)
* Public Suffix List updated to current version
* PHP warning produced by stream_socket_client() in Socket adapter is now
added to Exception message (bug #18331)
</notes>
</release>
<release>
<version>
<release>2.0.0beta1</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2011-02-27</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
Additions and changes:
* Implemented cookie jar that allows to store and pass cookies across HTTP
requests (see request #18225)
* Added several specialized subclasses of HTTP_Request2_Exception, they are
now thrown instead of the parent. Also added error codes and possibility
to get native error code (as returned by stream_socket_client() and
curl_errno()) (request #16762)
* An additional 'sentBody' event is now sent to Observers (request #16828)
* setBody() and addUpload() can now accept file pointers (request #16863)
Bugfixes:
* Incorrect check in Socket Adapter prevented Keep-alive from working in
some cases (bug #17031)
</notes>
</release>
<release>
<version>
<release>0.6.0</release>
<api>0.6.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2011-02-14</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
Additions and changes:
* Added test suite that interacts with a webserver. Please refer to
tests/NetworkConfig.php.dist for instructions.
* Packaging changes: docs/ and tests/ contents are installed without
redundant subdirectories.
* Added a $replace parameter to HTTP_Request2::setHeader() that controls
whether new header value will overwrite previous one or be appended
to it (request #17507)
Bugfixes:
* Fixed a typo in Curl Adapter that prevented 'strict_redirects' from working
* Curl Adapter will throw an exception if CURLOPT_FOLLOWLOCATION can not be
enabled due to PHP setup (bug #17450)
* Allow parameters in manually set Content-Type headers (bug #17460)
* Properly reset redirect limit if multiple requests are performed with the
same instance of Socket Adapter (bug #17826)
* Response::getBody() no longer tries to decode empty strings (bug #18169)
</notes>
</release>
<release>
<version>
<release>0.5.2</release>
<api>0.5.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2010-04-21</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* magic_quotes_runtime PHP setting could be incorrectly enabled after
performing the request (bug #16440)
* Unit tests fixes (bugs #17079, #17106, #17326)
* Observer_Log now appends to the log file rather than rewrites it (thanks to
troelskn at gmail dot com for reporting)
</notes>
</release>
<release>
<version>
<release>0.5.1</release>
<api>0.5.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-11-21</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Content-Type request header is no longer removed for POST and PUT requests
with empty request body (request #16799).
* CURLOPT_NOBODY option is now set when doing HEAD requests with Curl adapter.
</notes>
</release>
<release>
<version>
<release>0.5.0</release>
<api>0.5.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-11-18</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Redirect support added, new configuration parameters 'follow_redirects',
'max_redirects' and 'strict_redirects' available
* Implemented workaround for PHP bug #47204, Curl Adapter can now handle
Digest authentication and redirects when doing POST requests, unfortunately
this requires loading the entire request body into memory.
* Config parameter 'use_brackets' is propagated to created instances of Net_URL2
* Prevent memory leaks due to circular references (request #16646)
* Fixed a misleading error message when timing out due to default_socket_timeout
* HTTP_Request2::setBody() can now accept an instance of HTTP_Request2_MultipartBody
without trying to convert it to string
* Calling HTTP_Request2::setBody() now clears post parameters and uploads
</notes>
</release>
<release>
<version>
<release>0.4.1</release>
<api>0.4.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-09-14</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Decoding of gzipped responses failed if mbstring.func_overload was enabled
(bug #16555)
* Changed boundary generation in multipart bodies to work correctly with
rapidshare.com, added first usage example: file uploading to rapidshare.com
* Added forgotten optional dependency on OpenSSL PHP extension
</notes>
</release>
<release>
<version>
<release>0.4.0</release>
<api>0.4.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-05-03</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
* Added 'store_body' config parameter, if set to false it will prevent storing
the response body in Response object (request #15881)
* HTTP_Request2::setHeader() method now works as documented, setHeader('name')
will remove the 'name' header, while setHeader('name', '') will set 'name'
header to empty value (bug #15937)
* Custom 'Host' header will not be overwritten by generated one (bug #16146)
* When trying to reuse the connected socket in Socket adapter, make sure that
it is still connected (bug #16149)
</notes>
</release>
<release>
<version>
<release>0.3.0</release>
<api>0.3.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-01-28</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
API changes:
* Removed HTTP_Request2::getConfigValue() method
Feature additions:
* Added digest authentication (RFC 2617) support to Socket adapter. Thanks
to Tom Snyder (tomsn at inetoffice dot com) who sent me a prototype
implementation for HTTP_Request a couple of years ago.
* Added HTTPS proxy support to Socket adapter, this works through CONNECT
request described in RFC 2817.
* Mock adapter can now throw an Exception instead of returning a response
if Exception object is added via its addResponse() method (request #15629)
Other changes and fixes:
* Support RFC 3986 by not encoding '~' in POST body (request #15368)
* Prevent an error with particular versions of PHP and Curl (bug #15617)
* Regular expressions used in HTTP_Request2 are now class constants
(request #15630)
* Curl adapter now throws an exception in case of malformed (non-HTTP)
response rather than dies with a fatal error (bug #15716)
* Curl handle wasn't closed in Curl adapter in case of error (bug #15721)
* Curl adapter sent an extra 'sentHeaders' event and returned bogus
response status when server returned 100-Continue response (bug #15785)
</notes>
</release>
<release>
<version>
<release>0.2.0</release>
<api>0.2.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2009-01-07</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
API changes:
* HTTP_Request2::getConfigValue() is deprecated and will be removed in next
release. Use HTTP_Request2::getConfig().
* Changed HTTP_Request2::setConfig() to accept a pair of parameter name and
parameter value in addition to array('parameter name' =&gt; 'value')
* Added HTTP_Request2::getConfig() method that can return a single
configuration parameter or the whole configuration array
Other additions and changes:
* Added a debug Observer that can log request progress to a file or an
instance of PEAR::Log (thanks to David Jean Louis, request #15424)
* Added a new 'timeout' parameter that limits total number of seconds
a request can take (see requests #5735 and #8964)
* Added various SSL protocol options: 'ssl_verify_peer', 'ssl_verify_host',
'ssl_cafile', 'ssl_capath', 'ssl_local_cert', 'ssl_passphrase'. Note that
'ssl_verify_host' option behaves differently in Socket and Curl Adapters:
http://bugs.php.net/bug.php?id=47030
Fixes:
* Fixed 'data error' when processing response encoded by 'deflate'
encoding (bug #15305)
* Curl Adapter now passes full request headers in 'sentHeaders' event
</notes>
</release>
<release>
<version>
<release>0.1.0</release>
<api>0.1.0</api>
</version>
<stability>
<release>alpha</release>
<api>alpha</api>
</stability>
<date>2008-11-17</date>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
<notes>
Initial release. The features supported are mostly the same as those of
HTTP_Request, with the following additional feature requests implemented:
* cURL extension support (request #5463)
* It is now possible to monitor the file upload progress with Observers
(request #7630)
* Added 'sentHeaders' notification providing the request headers to the
Observers (request #7633)
* Added support for 'deflate' encoding (request #11246)
</notes>
</release>
</changelog>
</package>

View file

@ -0,0 +1,54 @@
<?php
/**
* Unit tests 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
*/
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'HTTP_Request2_AllTests::main');
}
require_once dirname(__FILE__) . '/Request2Test.php';
require_once dirname(__FILE__) . '/ObserverTest.php';
require_once dirname(__FILE__) . '/Request2/AllTests.php';
class HTTP_Request2_AllTests
{
public static function main()
{
if (!function_exists('phpunit_autoload')) {
require_once 'PHPUnit/TextUI/TestRunner.php';
}
PHPUnit_TextUI_TestRunner::run(self::suite());
}
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package');
$suite->addTest(Request2_AllTests::suite());
$suite->addTestSuite('HTTP_Request2Test');
$suite->addTestSuite('HTTP_Request2_ObserverTest');
return $suite;
}
}
if (PHPUnit_MAIN_METHOD == 'HTTP_Request2_AllTests::main') {
HTTP_Request2_AllTests::main();
}
?>

View file

@ -0,0 +1,58 @@
<?php
/**
* Unit tests 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
*/
/**
* This file contains configuration needed for running HTTP_Request2 tests
* that interact with the network. Do not edit this file, copy it to
* NetworkConfig.php and edit the copy instead.
*/
/**
* Base URL for HTTP_Request2 Adapters tests
*
* To enable the tests that actually perform network interaction, you should
* copy the contents of _network directory to a directory under your web
* server's document root or create a symbolic link to _network directory
* there. Set this constant to point to the URL of that directory.
*/
define('HTTP_REQUEST2_TESTS_BASE_URL', null);
/**
* URL that is protected by server digest authentication
*
* This is needed for testing of 100 Continue handling, we can't implement
* digest in PHP since it will kick in a bit later
*/
define('HTTP_REQUEST2_TESTS_DIGEST_URL', null);
/**#@+
* Proxy setup for Socket Adapter tests
*
* Set these constants to run additional tests for Socket Adapter using a HTTP
* proxy. If proxy host is not set then the tests will not be run.
*/
define('HTTP_REQUEST2_TESTS_PROXY_HOST', null);
define('HTTP_REQUEST2_TESTS_PROXY_PORT', 8080);
define('HTTP_REQUEST2_TESTS_PROXY_USER', '');
define('HTTP_REQUEST2_TESTS_PROXY_PASSWORD', '');
define('HTTP_REQUEST2_TESTS_PROXY_AUTH_SCHEME', 'basic');
define('HTTP_REQUEST2_TESTS_PROXY_TYPE', 'http');
/**#@-*/
?>

View file

@ -0,0 +1,95 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(__FILE__) . '/TestHelper.php';
/**
* Class representing a HTTP request
*/
require_once 'HTTP/Request2.php';
/**
* Mock observer
*/
class HTTP_Request2_MockObserver implements SplObserver
{
public $calls = 0;
public $event;
public function update (SplSubject $subject)
{
$this->calls++;
$this->event = $subject->getLastEvent();
}
}
/**
* Unit test for subject-observer pattern implementation in HTTP_Request2
*/
class HTTP_Request2_ObserverTest extends PHPUnit_Framework_TestCase
{
public function testSetLastEvent()
{
$request = new HTTP_Request2();
$observer = new HTTP_Request2_MockObserver();
$request->attach($observer);
$request->setLastEvent('foo', 'bar');
$this->assertEquals(1, $observer->calls);
$this->assertEquals(array('name' => 'foo', 'data' => 'bar'), $observer->event);
$request->setLastEvent('baz');
$this->assertEquals(2, $observer->calls);
$this->assertEquals(array('name' => 'baz', 'data' => null), $observer->event);
}
public function testAttachOnlyOnce()
{
$request = new HTTP_Request2();
$observer = new HTTP_Request2_MockObserver();
$observer2 = new HTTP_Request2_MockObserver();
$request->attach($observer);
$request->attach($observer2);
$request->attach($observer);
$request->setLastEvent('event', 'data');
$this->assertEquals(1, $observer->calls);
$this->assertEquals(1, $observer2->calls);
}
public function testDetach()
{
$request = new HTTP_Request2();
$observer = new HTTP_Request2_MockObserver();
$observer2 = new HTTP_Request2_MockObserver();
$request->attach($observer);
$request->detach($observer2); // should not be a error
$request->setLastEvent('first');
$request->detach($observer);
$request->setLastEvent('second');
$this->assertEquals(1, $observer->calls);
$this->assertEquals(array('name' => 'first', 'data' => null), $observer->event);
}
}
?>

View file

@ -0,0 +1,70 @@
<?php
/**
* Unit tests 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
*/
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Request2_Adapter_AllTests::main');
}
require_once dirname(__FILE__) . '/MockTest.php';
require_once dirname(__FILE__) . '/SkippedTests.php';
require_once dirname(__FILE__) . '/SocketTest.php';
require_once dirname(__FILE__) . '/SocketProxyTest.php';
require_once dirname(__FILE__) . '/CurlTest.php';
class Request2_Adapter_AllTests
{
public static function main()
{
PHPUnit_TextUI_TestRunner::run(self::suite());
}
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package - Request2 - Adapter');
$suite->addTestSuite('HTTP_Request2_Adapter_MockTest');
if (defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL) {
$suite->addTestSuite('HTTP_Request2_Adapter_SocketTest');
} else {
$suite->addTestSuite('HTTP_Request2_Adapter_Skip_SocketTest');
}
if (defined('HTTP_REQUEST2_TESTS_PROXY_HOST') && HTTP_REQUEST2_TESTS_PROXY_HOST
&& defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL
) {
$suite->addTestSuite('HTTP_Request2_Adapter_SocketProxyTest');
} else {
$suite->addTestSuite('HTTP_Request2_Adapter_Skip_SocketProxyTest');
}
if (defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL
&& extension_loaded('curl')
) {
$suite->addTestSuite('HTTP_Request2_Adapter_CurlTest');
} else {
$suite->addTestSuite('HTTP_Request2_Adapter_Skip_CurlTest');
}
return $suite;
}
}
if (PHPUnit_MAIN_METHOD == 'Request2_Adapter_AllTests::main') {
Request2_Adapter_AllTests::main();
}
?>

View file

@ -0,0 +1,387 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
/** Class representing a HTTP request */
require_once 'HTTP/Request2.php';
/** Class for building multipart/form-data request body */
require_once 'HTTP/Request2/MultipartBody.php';
class SlowpokeBody extends HTTP_Request2_MultipartBody
{
protected $doSleep;
public function rewind()
{
$this->doSleep = true;
parent::rewind();
}
public function read($length)
{
if ($this->doSleep) {
sleep(3);
$this->doSleep = false;
}
return parent::read($length);
}
}
class HeaderObserver implements SplObserver
{
public $headers;
public function update(SplSubject $subject)
{
$event = $subject->getLastEvent();
// force a timeout when writing request body
if ('sentHeaders' == $event['name']) {
$this->headers = $event['data'];
}
}
}
/**
* Tests for HTTP_Request2 package that require a working webserver
*
* The class contains some common tests that should be run for all Adapters,
* it is extended by their unit tests.
*
* You need to properly set up this test suite, refer to NetworkConfig.php.dist
*/
abstract class HTTP_Request2_Adapter_CommonNetworkTest extends PHPUnit_Framework_TestCase
{
/**
* HTTP Request object
* @var HTTP_Request2
*/
protected $request;
/**
* Base URL for remote test files
* @var string
*/
protected $baseUrl;
/**
* Configuration for HTTP Request object
* @var array
*/
protected $config = array();
protected function setUp()
{
if (!defined('HTTP_REQUEST2_TESTS_BASE_URL') || !HTTP_REQUEST2_TESTS_BASE_URL) {
$this->markTestSkipped('Base URL is not configured');
} else {
$this->baseUrl = rtrim(HTTP_REQUEST2_TESTS_BASE_URL, '/') . '/';
$name = strtolower(preg_replace('/^test/i', '', $this->getName())) . '.php';
$this->request = new HTTP_Request2(
$this->baseUrl . $name, HTTP_Request2::METHOD_GET, $this->config
);
}
}
/**
* Tests possibility to send GET parameters
*
* NB: Currently there are problems with Net_URL2::setQueryVariables(), thus
* array structure is simple: http://pear.php.net/bugs/bug.php?id=18267
*/
public function testGetParameters()
{
$data = array(
'bar' => array(
'key' => 'value'
),
'foo' => 'some value',
'numbered' => array('first', 'second')
);
$this->request->getUrl()->setQueryVariables($data);
$response = $this->request->send();
$this->assertEquals(serialize($data), $response->getBody());
}
public function testPostParameters()
{
$data = array(
'bar' => array(
'key' => 'some other value'
),
'baz' => array(
'key1' => array(
'key2' => 'yet another value'
)
),
'foo' => 'some value',
'indexed' => array('first', 'second')
);
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->addPostParameter($data);
$response = $this->request->send();
$this->assertEquals(serialize($data), $response->getBody());
}
public function testUploads()
{
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->addUpload('foo', dirname(dirname(dirname(__FILE__))) . '/_files/empty.gif', 'picture.gif', 'image/gif')
->addUpload('bar', array(
array(dirname(dirname(dirname(__FILE__))) . '/_files/empty.gif', null, 'image/gif'),
array(dirname(dirname(dirname(__FILE__))) . '/_files/plaintext.txt', 'secret.txt', 'text/x-whatever')
));
$response = $this->request->send();
$this->assertContains("foo picture.gif image/gif 43", $response->getBody());
$this->assertContains("bar[0] empty.gif image/gif 43", $response->getBody());
$this->assertContains("bar[1] secret.txt text/x-whatever 15", $response->getBody());
}
public function testRawPostData()
{
$data = 'Nothing to see here, move along';
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setBody($data);
$response = $this->request->send();
$this->assertEquals($data, $response->getBody());
}
public function testCookies()
{
$cookies = array(
'CUSTOMER' => 'WILE_E_COYOTE',
'PART_NUMBER' => 'ROCKET_LAUNCHER_0001'
);
foreach ($cookies as $k => $v) {
$this->request->addCookie($k, $v);
}
$response = $this->request->send();
$this->assertEquals(serialize($cookies), $response->getBody());
}
public function testTimeout()
{
$this->request->setConfig('timeout', 2);
try {
$this->request->send();
$this->fail('Expected HTTP_Request2_Exception was not thrown');
} catch (HTTP_Request2_MessageException $e) {
$this->assertEquals(HTTP_Request2_Exception::TIMEOUT, $e->getCode());
}
}
public function testTimeoutInRequest()
{
$this->request->setConfig('timeout', 2)
->setUrl($this->baseUrl . 'postparameters.php')
->setBody(new SlowpokeBody(array('foo' => 'some value'), array()));
try {
$this->request->send();
$this->fail('Expected HTTP_Request2_MessageException was not thrown');
} catch (HTTP_Request2_MessageException $e) {
$this->assertEquals(HTTP_Request2_Exception::TIMEOUT, $e->getCode());
}
}
public function testBasicAuth()
{
$this->request->getUrl()->setQueryVariables(array(
'user' => 'luser',
'pass' => 'qwerty'
));
$wrong = clone $this->request;
$this->request->setAuth('luser', 'qwerty');
$response = $this->request->send();
$this->assertEquals(200, $response->getStatus());
$wrong->setAuth('luser', 'password');
$response = $wrong->send();
$this->assertEquals(401, $response->getStatus());
}
public function testDigestAuth()
{
$this->request->getUrl()->setQueryVariables(array(
'user' => 'luser',
'pass' => 'qwerty'
));
$wrong = clone $this->request;
$this->request->setAuth('luser', 'qwerty', HTTP_Request2::AUTH_DIGEST);
$response = $this->request->send();
$this->assertEquals(200, $response->getStatus());
$wrong->setAuth('luser', 'password', HTTP_Request2::AUTH_DIGEST);
$response = $wrong->send();
$this->assertEquals(401, $response->getStatus());
}
public function testRedirectsDefault()
{
$this->request->setUrl($this->baseUrl . 'redirects.php')
->setConfig(array('follow_redirects' => true, 'strict_redirects' => false))
->setMethod(HTTP_Request2::METHOD_POST)
->addPostParameter('foo', 'foo value');
$response = $this->request->send();
$this->assertContains('Method=GET', $response->getBody());
$this->assertNotContains('foo', $response->getBody());
$this->assertEquals($this->baseUrl . 'redirects.php?redirects=0', $response->getEffectiveUrl());
}
public function testRedirectsStrict()
{
$this->request->setUrl($this->baseUrl . 'redirects.php')
->setConfig(array('follow_redirects' => true, 'strict_redirects' => true))
->setMethod(HTTP_Request2::METHOD_POST)
->addPostParameter('foo', 'foo value');
$response = $this->request->send();
$this->assertContains('Method=POST', $response->getBody());
$this->assertContains('foo', $response->getBody());
}
public function testRedirectsLimit()
{
$this->request->setUrl($this->baseUrl . 'redirects.php?redirects=4')
->setConfig(array('follow_redirects' => true, 'max_redirects' => 2));
try {
$this->request->send();
$this->fail('Expected HTTP_Request2_Exception was not thrown');
} catch (HTTP_Request2_MessageException $e) {
$this->assertEquals(HTTP_Request2_Exception::TOO_MANY_REDIRECTS, $e->getCode());
}
}
public function testRedirectsRelative()
{
$this->request->setUrl($this->baseUrl . 'redirects.php?special=relative')
->setConfig(array('follow_redirects' => true));
$response = $this->request->send();
$this->assertContains('did relative', $response->getBody());
}
public function testRedirectsNonHTTP()
{
$this->request->setUrl($this->baseUrl . 'redirects.php?special=ftp')
->setConfig(array('follow_redirects' => true));
try {
$this->request->send();
$this->fail('Expected HTTP_Request2_Exception was not thrown');
} catch (HTTP_Request2_MessageException $e) {
$this->assertEquals(HTTP_Request2_Exception::NON_HTTP_REDIRECT, $e->getCode());
}
}
public function testCookieJar()
{
$this->request->setUrl($this->baseUrl . 'setcookie.php?name=cookie_name&value=cookie_value');
$req2 = clone $this->request;
$this->request->setCookieJar()->send();
$jar = $this->request->getCookieJar();
$jar->store(
array('name' => 'foo', 'value' => 'bar'),
$this->request->getUrl()
);
$response = $req2->setUrl($this->baseUrl . 'cookies.php')->setCookieJar($jar)->send();
$this->assertEquals(
serialize(array('cookie_name' => 'cookie_value', 'foo' => 'bar')),
$response->getBody()
);
}
public function testCookieJarAndRedirect()
{
$this->request->setUrl($this->baseUrl . 'redirects.php?special=cookie')
->setConfig('follow_redirects', true)
->setCookieJar();
$response = $this->request->send();
$this->assertEquals(serialize(array('cookie_on_redirect' => 'success')), $response->getBody());
}
/**
* @link http://pear.php.net/bugs/bug.php?id=20125
*/
public function testChunkedRequest()
{
$data = array(
'long' => str_repeat('a', 1000),
'very_long' => str_repeat('b', 2000)
);
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setUrl($this->baseUrl . 'postparameters.php')
->setConfig('buffer_size', 512)
->setHeader('Transfer-Encoding', 'chunked')
->addPostParameter($data);
$response = $this->request->send();
$this->assertEquals(serialize($data), $response->getBody());
}
/**
* @link http://pear.php.net/bugs/bug.php?id=19233
* @link http://pear.php.net/bugs/bug.php?id=15937
*/
public function testPreventExpectHeader()
{
$fp = fopen(dirname(dirname(dirname(__FILE__))) . '/_files/bug_15305', 'rb');
$observer = new HeaderObserver();
$body = new HTTP_Request2_MultipartBody(
array(),
array(
'upload' => array(
'fp' => $fp,
'filename' => 'bug_15305',
'type' => 'application/octet-stream',
'size' => 16338
)
)
);
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setUrl($this->baseUrl . 'uploads.php')
->setHeader('Expect', '')
->setBody($body)
->attach($observer);
$response = $this->request->send();
$this->assertNotContains('Expect:', $observer->headers);
$this->assertContains('upload bug_15305 application/octet-stream 16338', $response->getBody());
}
}
?>

View file

@ -0,0 +1,120 @@
<?php
/**
* Unit tests 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
*/
/** Tests for HTTP_Request2 package that require a working webserver */
require_once dirname(__FILE__) . '/CommonNetworkTest.php';
/** Adapter for HTTP_Request2 wrapping around cURL extension */
/**
* Unit test for Curl Adapter of HTTP_Request2
*/
class HTTP_Request2_Adapter_CurlTest extends HTTP_Request2_Adapter_CommonNetworkTest
{
/**
* Configuration for HTTP Request object
* @var array
*/
protected $config = array(
'adapter' => 'HTTP_Request2_Adapter_Curl'
);
/**
* Checks whether redirect support in cURL is disabled by safe_mode or open_basedir
* @return bool
*/
protected function isRedirectSupportDisabled()
{
return ini_get('safe_mode') || ini_get('open_basedir');
}
public function testRedirectsDefault()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testRedirectsDefault();
}
}
public function testRedirectsStrict()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testRedirectsStrict();
}
}
public function testRedirectsLimit()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testRedirectsLimit();
}
}
public function testRedirectsRelative()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testRedirectsRelative();
}
}
public function testRedirectsNonHTTP()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testRedirectsNonHTTP();
}
}
public function testCookieJarAndRedirect()
{
if ($this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
} else {
parent::testCookieJarAndRedirect();
}
}
public function testBug17450()
{
if (!$this->isRedirectSupportDisabled()) {
$this->markTestSkipped('Neither safe_mode nor open_basedir is enabled');
}
$this->request->setUrl($this->baseUrl . 'redirects.php')
->setConfig(array('follow_redirects' => true));
try {
$this->request->send();
$this->fail('Expected HTTP_Request2_Exception was not thrown');
} catch (HTTP_Request2_LogicException $e) {
$this->assertEquals(HTTP_Request2_Exception::MISCONFIGURATION, $e->getCode());
}
}
}
?>

View file

@ -0,0 +1,157 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
/**
* Class representing a HTTP request
*/
require_once 'HTTP/Request2.php';
/**
* Mock adapter intended for testing
*/
require_once 'HTTP/Request2/Adapter/Mock.php';
/**
* Unit test for HTTP_Request2_Response class
*/
class HTTP_Request2_Adapter_MockTest extends PHPUnit_Framework_TestCase
{
public function testDefaultResponse()
{
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_GET,
array('adapter' => 'mock'));
$response = $req->send();
$this->assertEquals(400, $response->getStatus());
$this->assertEquals(0, count($response->getHeader()));
$this->assertEquals('', $response->getBody());
}
public function testResponseFromString()
{
$mock = new HTTP_Request2_Adapter_Mock();
$mock->addResponse(
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/plain; charset=iso-8859-1\r\n" .
"\r\n" .
"This is a string"
);
$req = new HTTP_Request2('http://www.example.com/');
$req->setAdapter($mock);
$response = $req->send();
$this->assertEquals(200, $response->getStatus());
$this->assertEquals(1, count($response->getHeader()));
$this->assertEquals('This is a string', $response->getBody());
}
public function testResponseFromFile()
{
$mock = new HTTP_Request2_Adapter_Mock();
$mock->addResponse(fopen(dirname(dirname(dirname(__FILE__))) .
'/_files/response_headers', 'rb'));
$req = new HTTP_Request2('http://www.example.com/');
$req->setAdapter($mock);
$response = $req->send();
$this->assertEquals(200, $response->getStatus());
$this->assertEquals(7, count($response->getHeader()));
$this->assertEquals('Nothing to see here, move along.', $response->getBody());
}
public function testResponsesQueue()
{
$mock = new HTTP_Request2_Adapter_Mock();
$mock->addResponse(
"HTTP/1.1 301 Over there\r\n" .
"Location: http://www.example.com/newpage.html\r\n" .
"\r\n" .
"The document is over there"
);
$mock->addResponse(
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/plain; charset=iso-8859-1\r\n" .
"\r\n" .
"This is a string"
);
$req = new HTTP_Request2('http://www.example.com/');
$req->setAdapter($mock);
$this->assertEquals(301, $req->send()->getStatus());
$this->assertEquals(200, $req->send()->getStatus());
$this->assertEquals(400, $req->send()->getStatus());
}
/**
* Returning URL-specific responses
* @link http://pear.php.net/bugs/bug.php?id=19276
*/
public function testRequest19276()
{
$mock = new HTTP_Request2_Adapter_Mock();
$mock->addResponse(
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/plain; charset=iso-8859-1\r\n" .
"\r\n" .
"This is a response from example.org",
'http://example.org/'
);
$mock->addResponse(
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/plain; charset=iso-8859-1\r\n" .
"\r\n" .
"This is a response from example.com",
'http://example.com/'
);
$req1 = new HTTP_Request2('http://localhost/');
$req1->setAdapter($mock);
$this->assertEquals(400, $req1->send()->getStatus());
$req2 = new HTTP_Request2('http://example.com/');
$req2->setAdapter($mock);
$this->assertContains('example.com', $req2->send()->getBody());
$req3 = new HTTP_Request2('http://example.org');
$req3->setAdapter($mock);
$this->assertContains('example.org', $req3->send()->getBody());
}
public function testResponseException()
{
$mock = new HTTP_Request2_Adapter_Mock();
$mock->addResponse(
new HTTP_Request2_Exception('Shit happens')
);
$req = new HTTP_Request2('http://www.example.com/');
$req->setAdapter($mock);
try {
$req->send();
} catch (Exception $e) {
$this->assertEquals('Shit happens', $e->getMessage());
return;
}
$this->fail('Expected HTTP_Request2_Exception was not thrown');
}
}
?>

View file

@ -0,0 +1,56 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
/**
* Shows a skipped test if networked tests are not configured
*/
class HTTP_Request2_Adapter_Skip_SocketTest extends PHPUnit_Framework_TestCase
{
public function testSocketAdapter()
{
$this->markTestSkipped('Socket Adapter tests need base URL configured.');
}
}
/**
* Shows a skipped test if proxy is not configured
*/
class HTTP_Request2_Adapter_Skip_SocketProxyTest extends PHPUnit_Framework_TestCase
{
public function testSocketAdapterWithProxy()
{
$this->markTestSkipped('Socket Adapter proxy tests need base URL and proxy configured');
}
}
/**
* Shows a skipped test if networked tests are not configured or cURL extension is unavailable
*/
class HTTP_Request2_Adapter_Skip_CurlTest extends PHPUnit_Framework_TestCase
{
public function testCurlAdapter()
{
$this->markTestSkipped('Curl Adapter tests need base URL configured and curl extension available');
}
}
?>

View file

@ -0,0 +1,55 @@
<?php
/**
* Unit tests 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
*/
/** Tests for HTTP_Request2 package that require a working webserver */
require_once dirname(__FILE__) . '/CommonNetworkTest.php';
/**
* Unit test for Socket Adapter of HTTP_Request2 working through proxy
*/
class HTTP_Request2_Adapter_SocketProxyTest extends HTTP_Request2_Adapter_CommonNetworkTest
{
/**
* Configuration for HTTP Request object
* @var array
*/
protected $config = array(
'adapter' => 'HTTP_Request2_Adapter_Socket'
);
protected function setUp()
{
if (!defined('HTTP_REQUEST2_TESTS_PROXY_HOST') || !HTTP_REQUEST2_TESTS_PROXY_HOST) {
$this->markTestSkipped('Proxy is not configured');
} else {
$this->config += array(
'proxy_host' => HTTP_REQUEST2_TESTS_PROXY_HOST,
'proxy_port' => HTTP_REQUEST2_TESTS_PROXY_PORT,
'proxy_user' => HTTP_REQUEST2_TESTS_PROXY_USER,
'proxy_password' => HTTP_REQUEST2_TESTS_PROXY_PASSWORD,
'proxy_auth_scheme' => HTTP_REQUEST2_TESTS_PROXY_AUTH_SCHEME,
'proxy_type' => HTTP_REQUEST2_TESTS_PROXY_TYPE
);
parent::setUp();
}
}
}
?>

View file

@ -0,0 +1,159 @@
<?php
/**
* Unit tests 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
*/
/** Tests for HTTP_Request2 package that require a working webserver */
require_once dirname(__FILE__) . '/CommonNetworkTest.php';
/** Socket-based adapter for HTTP_Request2 */
require_once 'HTTP/Request2/Adapter/Socket.php';
/**
* Unit test for Socket Adapter of HTTP_Request2
*/
class HTTP_Request2_Adapter_SocketTest extends HTTP_Request2_Adapter_CommonNetworkTest
{
/**
* Configuration for HTTP Request object
* @var array
*/
protected $config = array(
'adapter' => 'HTTP_Request2_Adapter_Socket'
);
public function testBug17826()
{
$adapter = new HTTP_Request2_Adapter_Socket();
$request1 = new HTTP_Request2($this->baseUrl . 'redirects.php?redirects=2');
$request1->setConfig(array('follow_redirects' => true, 'max_redirects' => 3))
->setAdapter($adapter)
->send();
$request2 = new HTTP_Request2($this->baseUrl . 'redirects.php?redirects=2');
$request2->setConfig(array('follow_redirects' => true, 'max_redirects' => 3))
->setAdapter($adapter)
->send();
}
/**
* Infinite loop with stream wrapper passed as upload
*
* Dunno how the original reporter managed to pass a file pointer
* that doesn't support fstat() to MultipartBody, maybe he didn't use
* addUpload(). So we don't use it, either.
*
* @link http://pear.php.net/bugs/bug.php?id=19934
*/
public function testBug19934()
{
if (!in_array('http', stream_get_wrappers())) {
$this->markTestSkipped("This test requires an HTTP fopen wrapper enabled");
}
$fp = fopen($this->baseUrl . '/bug19934.php', 'rb');
$body = new HTTP_Request2_MultipartBody(
array(),
array(
'upload' => array(
'fp' => $fp,
'filename' => 'foo.txt',
'type' => 'text/plain',
'size' => 20000
)
)
);
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setUrl($this->baseUrl . 'uploads.php')
->setBody($body);
set_error_handler(array($this, 'rewindWarningsHandler'));
$response = $this->request->send();
restore_error_handler();
$this->assertContains("upload foo.txt text/plain 20000", $response->getBody());
}
public function rewindWarningsHandler($errno, $errstr)
{
if (($errno & E_WARNING) && false !== strpos($errstr, 'rewind')) {
return true;
}
return false;
}
/**
* Do not send request body twice to URLs protected by digest auth
*
* @link http://pear.php.net/bugs/bug.php?id=19233
*/
public function test100ContinueHandling()
{
if (!defined('HTTP_REQUEST2_TESTS_DIGEST_URL') || !HTTP_REQUEST2_TESTS_DIGEST_URL) {
$this->markTestSkipped('This test requires an URL protected by server digest auth');
}
$fp = fopen(dirname(dirname(dirname(__FILE__))) . '/_files/bug_15305', 'rb');
$body = $this->getMock(
'HTTP_Request2_MultipartBody', array('read'), array(
array(),
array(
'upload' => array(
'fp' => $fp,
'filename' => 'bug_15305',
'type' => 'application/octet-stream',
'size' => 16338
)
)
)
);
$body->expects($this->never())->method('read');
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setUrl(HTTP_REQUEST2_TESTS_DIGEST_URL)
->setBody($body);
$this->assertEquals(401, $this->request->send()->getStatus());
}
public function test100ContinueTimeoutBug()
{
$fp = fopen(dirname(dirname(dirname(__FILE__))) . '/_files/bug_15305', 'rb');
$body = new HTTP_Request2_MultipartBody(
array(),
array(
'upload' => array(
'fp' => $fp,
'filename' => 'bug_15305',
'type' => 'application/octet-stream',
'size' => 16338
)
)
);
$this->request->setMethod(HTTP_Request2::METHOD_POST)
->setUrl($this->baseUrl . 'uploads.php?slowpoke')
->setBody($body);
$response = $this->request->send();
$this->assertContains('upload bug_15305 application/octet-stream 16338', $response->getBody());
}
}
?>

View file

@ -0,0 +1,56 @@
<?php
/**
* Unit tests 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
*/
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Request2_AllTests::main');
}
require_once dirname(__FILE__) . '/CookieJarTest.php';
require_once dirname(__FILE__) . '/MultipartBodyTest.php';
require_once dirname(__FILE__) . '/ResponseTest.php';
require_once dirname(__FILE__) . '/Adapter/AllTests.php';
class Request2_AllTests
{
public static function main()
{
if (!function_exists('phpunit_autoload')) {
require_once 'PHPUnit/TextUI/TestRunner.php';
}
PHPUnit_TextUI_TestRunner::run(self::suite());
}
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package - Request2');
$suite->addTestSuite('HTTP_Request2_CookieJarTest');
$suite->addTestSuite('HTTP_Request2_MultipartBodyTest');
$suite->addTestSuite('HTTP_Request2_ResponseTest');
$suite->addTest(Request2_Adapter_AllTests::suite());
return $suite;
}
}
if (PHPUnit_MAIN_METHOD == 'Request2_AllTests::main') {
Request2_AllTests::main();
}
?>

View file

@ -0,0 +1,370 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
/** Stores cookies and passes them between HTTP requests */
require_once 'HTTP/Request2/CookieJar.php';
/**
* Unit test for HTTP_Request2_CookieJar class
*/
class HTTP_Request2_CookieJarTest extends PHPUnit_Framework_TestCase
{
/**
* Cookie jar instance being tested
* @var HTTP_Request2_CookieJar
*/
protected $jar;
protected function setUp()
{
$this->jar = new HTTP_Request2_CookieJar();
}
/**
* Test that we can't store junk "cookies" in jar
*
* @dataProvider invalidCookieProvider
* @expectedException HTTP_Request2_LogicException
*/
public function testStoreInvalid($cookie)
{
$this->jar->store($cookie);
}
/**
*
* @dataProvider noPSLDomainsProvider
*/
public function testDomainMatchNoPSL($requestHost, $cookieDomain, $expected)
{
$this->jar->usePublicSuffixList(false);
$this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain));
}
/**
*
* @dataProvider PSLDomainsProvider
*/
public function testDomainMatchPSL($requestHost, $cookieDomain, $expected)
{
$this->jar->usePublicSuffixList(true);
$this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain));
}
public function testConvertExpiresToISO8601()
{
$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('UTC'));
$dt->modify('+1 day');
$this->jar->store(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'expires' => $dt->format(DateTime::COOKIE),
'secure' => false
));
$cookies = $this->jar->getAll();
$this->assertEquals($cookies[0]['expires'], $dt->format(DateTime::ISO8601));
}
public function testProblem2038()
{
$this->jar->store(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'expires' => 'Sun, 01 Jan 2040 03:04:05 GMT',
'secure' => false
));
$cookies = $this->jar->getAll();
$this->assertEquals(array(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'expires' => '2040-01-01T03:04:05+0000',
'secure' => false
)), $cookies);
}
public function testStoreExpired()
{
$base = array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'secure' => false
);
$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('UTC'));
$dt->modify('-1 day');
$yesterday = $dt->format(DateTime::COOKIE);
$dt->modify('+2 days');
$tomorrow = $dt->format(DateTime::COOKIE);
$this->jar->store($base + array('expires' => $yesterday));
$this->assertEquals(0, count($this->jar->getAll()));
$this->jar->store($base + array('expires' => $tomorrow));
$this->assertEquals(1, count($this->jar->getAll()));
$this->jar->store($base + array('expires' => $yesterday));
$this->assertEquals(0, count($this->jar->getAll()));
}
/**
*
* @dataProvider cookieAndSetterProvider
*/
public function testGetDomainAndPathFromSetter($cookie, $setter, $expected)
{
$this->jar->store($cookie, $setter);
$expected = array_merge($cookie, $expected);
$cookies = $this->jar->getAll();
$this->assertEquals($expected, $cookies[0]);
}
/**
*
* @dataProvider cookieMatchProvider
*/
public function testGetMatchingCookies($url, $expectedCount)
{
$cookies = array(
array('domain' => '.example.com', 'path' => '/', 'secure' => false),
array('domain' => '.example.com', 'path' => '/', 'secure' => true),
array('domain' => '.example.com', 'path' => '/path', 'secure' => false),
array('domain' => '.example.com', 'path' => '/other', 'secure' => false),
array('domain' => 'example.com', 'path' => '/', 'secure' => false),
array('domain' => 'www.example.com', 'path' => '/', 'secure' => false),
array('domain' => 'specific.example.com', 'path' => '/path', 'secure' => false),
array('domain' => 'nowww.example.com', 'path' => '/', 'secure' => false),
);
for ($i = 0; $i < count($cookies); $i++) {
$this->jar->store($cookies[$i] + array('expires' => null, 'name' => "cookie{$i}", 'value' => "cookie_{$i}_value"));
}
$this->assertEquals($expectedCount, count($this->jar->getMatching(new Net_URL2($url))));
}
public function testLongestPathFirst()
{
$cookie = array(
'name' => 'foo',
'domain' => '.example.com',
);
foreach (array('/', '/specific/path/', '/specific/') as $path) {
$this->jar->store($cookie + array('path' => $path, 'value' => str_replace('/', '_', $path)));
}
$this->assertEquals(
'foo=_specific_path_; foo=_specific_; foo=_',
$this->jar->getMatching(new Net_URL2('http://example.com/specific/path/file.php'), true)
);
}
public function testSerializable()
{
$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('UTC'));
$dt->modify('+1 day');
$cookie = array('domain' => '.example.com', 'path' => '/', 'secure' => false, 'value' => 'foo');
$this->jar->store($cookie + array('name' => 'session', 'expires' => null));
$this->jar->store($cookie + array('name' => 'long', 'expires' => $dt->format(DateTime::COOKIE)));
$newJar = unserialize(serialize($this->jar));
$cookies = $newJar->getAll();
$this->assertEquals(1, count($cookies));
$this->assertEquals('long', $cookies[0]['name']);
$this->jar->serializeSessionCookies(true);
$newJar = unserialize(serialize($this->jar));
$this->assertEquals($this->jar->getAll(), $newJar->getAll());
}
public function testRemoveExpiredOnUnserialize()
{
$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('UTC'));
$dt->modify('+2 seconds');
$this->jar->store(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'expires' => $dt->format(DateTime::COOKIE),
));
$serialized = serialize($this->jar);
sleep(2);
$newJar = unserialize($serialized);
$this->assertEquals(array(), $newJar->getAll());
}
public static function invalidCookieProvider()
{
return array(
array(array()),
array(array('name' => 'foo')),
array(array(
'name' => 'a name',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
)),
array(array(
'name' => 'foo',
'value' => 'a value',
'domain' => '.example.com',
'path' => '/',
)),
array(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => null,
)),
array(array(
'name' => 'foo',
'value' => 'bar',
'domain' => null,
'path' => '/',
)),
array(array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => '/',
'expires' => 'invalid date',
)),
);
}
public static function noPSLdomainsProvider()
{
return array(
array('localhost', 'localhost', true),
array('www.example.com', 'www.example.com', true),
array('127.0.0.1', '127.0.0.1', true),
array('127.0.0.1', '.0.0.1', false),
array('www.example.com', '.example.com', true),
array('deep.within.example.com', '.example.com', true),
array('example.com', '.com', false),
array('anotherexample.com', 'example.com', false),
array('whatever.msk.ru', '.msk.ru', true),
array('whatever.co.uk', '.co.uk', true),
array('whatever.uk', '.whatever.uk', true),
array('whatever.tokyo.jp', '.whatever.tokyo.jp', true),
array('metro.tokyo.jp', '.metro.tokyo.jp', true),
array('foo.bar', '.foo.bar', true)
);
}
public static function PSLdomainsProvider()
{
return array(
array('localhost', 'localhost', true),
array('www.example.com', 'www.example.com', true),
array('127.0.0.1', '127.0.0.1', true),
array('127.0.0.1', '.0.0.1', false),
array('www.example.com', '.example.com', true),
array('deep.within.example.com', '.example.com', true),
array('example.com', '.com', false),
array('anotherexample.com', 'example.com', false),
array('whatever.msk.ru', '.msk.ru', false),
array('whatever.co.uk', '.co.uk', false),
array('whatever.uk', '.whatever.uk', false),
array('whatever.tr', '.whatever.tr', false),
array('nic.tr', '.nic.tr', true),
array('foo.bar', '.foo.bar', true)
);
}
public static function cookieAndSetterProvider()
{
return array(
array(
array(
'name' => 'foo',
'value' => 'bar',
'domain' => null,
'path' => null,
'expires' => null,
'secure' => false
),
new Net_Url2('http://example.com/directory/file.php'),
array(
'domain' => 'example.com',
'path' => '/directory/'
)
),
array(
array(
'name' => 'foo',
'value' => 'bar',
'domain' => '.example.com',
'path' => null,
'expires' => null,
'secure' => false
),
new Net_Url2('http://example.com/path/to/file.php'),
array(
'path' => '/path/to/'
)
),
array(
array(
'name' => 'foo',
'value' => 'bar',
'domain' => null,
'path' => '/',
'expires' => null,
'secure' => false
),
new Net_Url2('http://example.com/another/file.php'),
array(
'domain' => 'example.com'
)
)
);
}
public static function cookieMatchProvider()
{
return array(
array('http://www.example.com/path/file.php', 4),
array('https://www.example.com/path/file.php', 5),
array('http://example.com/path/file.php', 3),
array('http://specific.example.com/path/file.php', 4),
array('http://specific.example.com/other/file.php', 3),
array('http://another.example.com/another', 2)
);
}
}
?>

View file

@ -0,0 +1,102 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
/**
* Class representing a HTTP request
*/
require_once 'HTTP/Request2.php';
/**
* Unit test for HTTP_Request2_MultipartBody class
*/
class HTTP_Request2_MultipartBodyTest extends PHPUnit_Framework_TestCase
{
public function testUploadSimple()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$body = $req->addPostParameter('foo', 'I am a parameter')
->addUpload('upload', dirname(dirname(__FILE__)) . '/_files/plaintext.txt')
->getBody();
$this->assertTrue($body instanceof HTTP_Request2_MultipartBody);
$asString = $body->__toString();
$boundary = $body->getBoundary();
$this->assertEquals($body->getLength(), strlen($asString));
$this->assertContains('This is a test.', $asString);
$this->assertContains('I am a parameter', $asString);
$this->assertRegexp("!--{$boundary}--\r\n$!", $asString);
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testRequest16863()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$fp = fopen(dirname(dirname(__FILE__)) . '/_files/plaintext.txt', 'rb');
$body = $req->addUpload('upload', $fp)
->getBody();
$asString = $body->__toString();
$this->assertContains('name="upload"; filename="anonymous.blob"', $asString);
$this->assertContains('This is a test.', $asString);
$req->addUpload('bad_upload', fopen('php://input', 'rb'));
}
public function testStreaming()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$body = $req->addPostParameter('foo', 'I am a parameter')
->addUpload('upload', dirname(dirname(__FILE__)) . '/_files/plaintext.txt')
->getBody();
$asString = '';
while ($part = $body->read(10)) {
$asString .= $part;
}
$this->assertEquals($body->getLength(), strlen($asString));
$this->assertContains('This is a test.', $asString);
$this->assertContains('I am a parameter', $asString);
}
public function testUploadArray()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$body = $req->addUpload('upload', array(
array(dirname(dirname(__FILE__)) . '/_files/plaintext.txt', 'bio.txt', 'text/plain'),
array(fopen(dirname(dirname(__FILE__)) . '/_files/empty.gif', 'rb'), 'photo.gif', 'image/gif')
))
->getBody();
$asString = $body->__toString();
$this->assertContains(file_get_contents(dirname(dirname(__FILE__)) . '/_files/empty.gif'), $asString);
$this->assertContains('name="upload[0]"; filename="bio.txt"', $asString);
$this->assertContains('name="upload[1]"; filename="photo.gif"', $asString);
$body2 = $req->setConfig(array('use_brackets' => false))->getBody();
$asString = $body2->__toString();
$this->assertContains('name="upload"; filename="bio.txt"', $asString);
$this->assertContains('name="upload"; filename="photo.gif"', $asString);
}
}
?>

View file

@ -0,0 +1,128 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
/**
* Class representing a HTTP response
*/
require_once 'HTTP/Request2/Response.php';
/**
* Unit test for HTTP_Request2_Response class
*/
class HTTP_Request2_ResponseTest extends PHPUnit_Framework_TestCase
{
/**
*
* @expectedException HTTP_Request2_MessageException
*/
public function testParseStatusLine()
{
$response = new HTTP_Request2_Response('HTTP/1.1 200 OK');
$this->assertEquals('1.1', $response->getVersion());
$this->assertEquals(200, $response->getStatus());
$this->assertEquals('OK', $response->getReasonPhrase());
$response2 = new HTTP_Request2_Response('HTTP/1.2 222 Nishtyak!');
$this->assertEquals('1.2', $response2->getVersion());
$this->assertEquals(222, $response2->getStatus());
$this->assertEquals('Nishtyak!', $response2->getReasonPhrase());
$response3 = new HTTP_Request2_Response('Invalid status line');
}
public function testParseHeaders()
{
$response = $this->readResponseFromFile('response_headers');
$this->assertEquals(7, count($response->getHeader()));
$this->assertEquals('PHP/6.2.2', $response->getHeader('X-POWERED-BY'));
$this->assertEquals('text/html; charset=windows-1251', $response->getHeader('cOnTeNt-TyPe'));
$this->assertEquals('accept-charset, user-agent', $response->getHeader('vary'));
}
public function testParseCookies()
{
$response = $this->readResponseFromFile('response_cookies');
$cookies = $response->getCookies();
$this->assertEquals(4, count($cookies));
$expected = array(
array('name' => 'foo', 'value' => 'bar', 'expires' => null,
'domain' => null, 'path' => null, 'secure' => false),
array('name' => 'PHPSESSID', 'value' => '1234567890abcdef1234567890abcdef',
'expires' => null, 'domain' => null, 'path' => '/', 'secure' => true),
array('name' => 'A', 'value' => 'B=C', 'expires' => null,
'domain' => null, 'path' => null, 'secure' => false),
array('name' => 'baz', 'value' => '%20a%20value', 'expires' => 'Sun, 03 Jan 2010 03:04:05 GMT',
'domain' => 'pear.php.net', 'path' => null, 'secure' => false),
);
foreach ($cookies as $k => $cookie) {
$this->assertEquals($expected[$k], $cookie);
}
}
/**
*
* @expectedException HTTP_Request2_MessageException
*/
public function testGzipEncoding()
{
$response = $this->readResponseFromFile('response_gzip');
$this->assertEquals('0e964e9273c606c46afbd311b5ad4d77', md5($response->getBody()));
$response = $this->readResponseFromFile('response_gzip_broken');
$body = $response->getBody();
}
public function testDeflateEncoding()
{
$response = $this->readResponseFromFile('response_deflate');
$this->assertEquals('0e964e9273c606c46afbd311b5ad4d77', md5($response->getBody()));
}
public function testBug15305()
{
$response = $this->readResponseFromFile('bug_15305');
$this->assertEquals('c8c5088fc8a7652afef380f086c010a6', md5($response->getBody()));
}
public function testBug18169()
{
$response = $this->readResponseFromFile('bug_18169');
$this->assertEquals('', $response->getBody());
}
protected function readResponseFromFile($filename)
{
$fp = fopen(dirname(dirname(__FILE__)) . '/_files/' . $filename, 'rb');
$response = new HTTP_Request2_Response(fgets($fp));
do {
$headerLine = fgets($fp);
$response->parseHeaderLine($headerLine);
} while ('' != trim($headerLine));
while (!feof($fp)) {
$response->appendBody(fread($fp, 1024));
}
return $response;
}
}
?>

View file

@ -0,0 +1,391 @@
<?php
/**
* Unit tests 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
*/
/** Sets up includes */
require_once dirname(__FILE__) . '/TestHelper.php';
/**
* Class representing a HTTP request
*/
require_once 'HTTP/Request2.php';
/**
* Unit test for HTTP_Request2 class
*/
class HTTP_Request2Test extends PHPUnit_Framework_TestCase
{
public function testConstructorSetsDefaults()
{
$url = new Net_URL2('http://www.example.com/foo');
$req = new HTTP_Request2($url, HTTP_Request2::METHOD_POST, array('connect_timeout' => 666));
$this->assertSame($url, $req->getUrl());
$this->assertEquals(HTTP_Request2::METHOD_POST, $req->getMethod());
$this->assertEquals(666, $req->getConfig('connect_timeout'));
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testSetUrl()
{
$urlString = 'http://www.example.com/foo/bar.php';
$url = new Net_URL2($urlString);
$req1 = new HTTP_Request2();
$req1->setUrl($url);
$this->assertSame($url, $req1->getUrl());
$req2 = new HTTP_Request2();
$req2->setUrl($urlString);
$this->assertInstanceOf('Net_URL2', $req2->getUrl());
$this->assertEquals($urlString, $req2->getUrl()->getUrl());
$req3 = new HTTP_Request2();
$req3->setUrl(array('This will cause an error'));
}
public function testConvertUserinfoToAuth()
{
$req = new HTTP_Request2();
$req->setUrl('http://foo:b%40r@www.example.com/');
$this->assertEquals('', (string)$req->getUrl()->getUserinfo());
$this->assertEquals(
array('user' => 'foo', 'password' => 'b@r', 'scheme' => HTTP_Request2::AUTH_BASIC),
$req->getAuth()
);
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testSetMethod()
{
$req = new HTTP_Request2();
$req->setMethod(HTTP_Request2::METHOD_PUT);
$this->assertEquals(HTTP_Request2::METHOD_PUT, $req->getMethod());
$req->setMethod('Invalid method');
}
public function testSetAndGetConfig()
{
$req = new HTTP_Request2();
$this->assertArrayHasKey('connect_timeout', $req->getConfig());
$req->setConfig(array('connect_timeout' => 123));
$this->assertEquals(123, $req->getConfig('connect_timeout'));
try {
$req->setConfig(array('foo' => 'unknown parameter'));
$this->fail('Expected HTTP_Request2_LogicException was not thrown');
} catch (HTTP_Request2_LogicException $e) {}
try {
$req->getConfig('bar');
$this->fail('Expected HTTP_Request2_LogicException was not thrown');
} catch (HTTP_Request2_LogicException $e) {}
}
public function testSetProxyAsUrl()
{
$req = new HTTP_Request2();
$req->setConfig('proxy', 'socks5://foo:bar%25baz@localhost:1080/');
$this->assertEquals('socks5', $req->getConfig('proxy_type'));
$this->assertEquals('localhost', $req->getConfig('proxy_host'));
$this->assertEquals(1080, $req->getConfig('proxy_port'));
$this->assertEquals('foo', $req->getConfig('proxy_user'));
$this->assertEquals('bar%baz', $req->getConfig('proxy_password'));
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testHeaders()
{
$req = new HTTP_Request2();
$autoHeaders = $req->getHeaders();
$req->setHeader('Foo', 'Bar');
$req->setHeader('Foo-Bar: value');
$req->setHeader(array('Another-Header' => 'another value', 'Yet-Another: other_value'));
$this->assertEquals(
array('foo-bar' => 'value', 'another-header' => 'another value',
'yet-another' => 'other_value', 'foo' => 'Bar') + $autoHeaders,
$req->getHeaders()
);
$req->setHeader('FOO-BAR');
$req->setHeader(array('aNOTHER-hEADER'));
$this->assertEquals(
array('yet-another' => 'other_value', 'foo' => 'Bar') + $autoHeaders,
$req->getHeaders()
);
$req->setHeader('Invalid header', 'value');
}
public function testBug15937()
{
$req = new HTTP_Request2();
$autoHeaders = $req->getHeaders();
$req->setHeader('Expect: ');
$req->setHeader('Foo', '');
$this->assertEquals(
array('expect' => '', 'foo' => '') + $autoHeaders,
$req->getHeaders()
);
}
public function testRequest17507()
{
$req = new HTTP_Request2();
$req->setHeader('accept-charset', 'iso-8859-1');
$req->setHeader('accept-charset', array('windows-1251', 'utf-8'), false);
$req->setHeader(array('accept' => 'text/html'));
$req->setHeader(array('accept' => 'image/gif'), null, false);
$headers = $req->getHeaders();
$this->assertEquals('iso-8859-1, windows-1251, utf-8', $headers['accept-charset']);
$this->assertEquals('text/html, image/gif', $headers['accept']);
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testCookies()
{
$req = new HTTP_Request2();
$req->addCookie('name', 'value');
$req->addCookie('foo', 'bar');
$headers = $req->getHeaders();
$this->assertEquals('name=value; foo=bar', $headers['cookie']);
$req->addCookie('invalid cookie', 'value');
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testPlainBody()
{
$req = new HTTP_Request2();
$req->setBody('A string');
$this->assertEquals('A string', $req->getBody());
$req->setBody(dirname(__FILE__) . '/_files/plaintext.txt', true);
$headers = $req->getHeaders();
$this->assertRegexp(
'!^(text/plain|application/octet-stream)!',
$headers['content-type']
);
$this->assertEquals('This is a test.', fread($req->getBody(), 1024));
$req->setBody('missing file', true);
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testRequest16863()
{
$req = new HTTP_Request2();
$req->setBody(fopen(dirname(__FILE__) . '/_files/plaintext.txt', 'rb'));
$headers = $req->getHeaders();
$this->assertEquals('application/octet-stream', $headers['content-type']);
$req->setBody(fopen('php://input', 'rb'));
}
public function testUrlencodedBody()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$req->addPostParameter('foo', 'bar');
$req->addPostParameter(array('baz' => 'quux'));
$req->addPostParameter('foobar', array('one', 'two'));
$this->assertEquals(
'foo=bar&baz=quux&foobar%5B0%5D=one&foobar%5B1%5D=two',
$req->getBody()
);
$req->setConfig(array('use_brackets' => false));
$this->assertEquals(
'foo=bar&baz=quux&foobar=one&foobar=two',
$req->getBody()
);
}
public function testRequest15368()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$req->addPostParameter('foo', 'te~st');
$this->assertContains('~', $req->getBody());
}
/**
*
* @expectedException HTTP_Request2_LogicException
* @expectedExceptionMessage missing file
*/
public function testUpload()
{
$req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
$req->addUpload('upload', dirname(__FILE__) . '/_files/plaintext.txt');
$headers = $req->getHeaders();
$this->assertEquals('multipart/form-data', $headers['content-type']);
$req->addUpload('upload_2', 'missing file');
}
public function testPropagateUseBracketsToNetURL2()
{
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_GET,
array('use_brackets' => false));
$req->getUrl()->setQueryVariable('foo', array('bar', 'baz'));
$this->assertEquals('http://www.example.com/?foo=bar&foo=baz', $req->getUrl()->__toString());
$req->setConfig('use_brackets', true)->setUrl('http://php.example.com/');
$req->getUrl()->setQueryVariable('foo', array('bar', 'baz'));
$this->assertEquals('http://php.example.com/?foo[0]=bar&foo[1]=baz', $req->getUrl()->__toString());
}
public function testSetBodyRemovesPostParameters()
{
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
$req->addPostParameter('foo', 'bar');
$req->setBody('');
$this->assertEquals('', $req->getBody());
}
public function testPostParametersPrecedeSetBodyForPost()
{
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
$req->setBody('Request body');
$req->addPostParameter('foo', 'bar');
$this->assertEquals('foo=bar', $req->getBody());
$req->setMethod(HTTP_Request2::METHOD_PUT);
$this->assertEquals('Request body', $req->getBody());
}
public function testSetMultipartBody()
{
require_once 'HTTP/Request2/MultipartBody.php';
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
$body = new HTTP_Request2_MultipartBody(array('foo' => 'bar'), array());
$req->setBody($body);
$this->assertSame($body, $req->getBody());
}
public function testBug17460()
{
$req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
$req->addPostParameter('foo', 'bar')
->setHeader('content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
$this->assertEquals('foo=bar', $req->getBody());
}
/**
*
* @expectedException HTTP_Request2_LogicException
*/
public function testCookieJar()
{
$req = new HTTP_Request2();
$this->assertNull($req->getCookieJar());
$req->setCookieJar();
$jar = $req->getCookieJar();
$this->assertInstanceOf('HTTP_Request2_CookieJar', $jar);
$req2 = new HTTP_Request2();
$req2->setCookieJar($jar);
$this->assertSame($jar, $req2->getCookieJar());
$req2->setCookieJar(null);
$this->assertNull($req2->getCookieJar());
$req2->setCookieJar('foo');
}
public function testAddCookieToJar()
{
$req = new HTTP_Request2();
$req->setCookieJar();
try {
$req->addCookie('foo', 'bar');
$this->fail('Expected HTTP_Request2_Exception was not thrown');
} catch (HTTP_Request2_LogicException $e) { }
$req->setUrl('http://example.com/path/file.php');
$req->addCookie('foo', 'bar');
$this->assertArrayNotHasKey('cookie', $req->getHeaders());
$cookies = $req->getCookieJar()->getAll();
$this->assertEquals(
array(
'name' => 'foo',
'value' => 'bar',
'domain' => 'example.com',
'path' => '/path/',
'expires' => null,
'secure' => false
),
$cookies[0]
);
}
/**
* @expectedException HTTP_Request2_LogicException
* @expectedExceptionMessage none
*/
public function testDisallowEmptyUrls()
{
$req = new HTTP_Request2();
$req->send();
}
/**
* @expectedException HTTP_Request2_LogicException
* @expectedExceptionMessage '/foo/bar.php'
*/
public function testDisallowRelativeUrls()
{
$req = new HTTP_Request2('/foo/bar.php');
$req->send();
}
}
?>

View file

@ -0,0 +1,51 @@
<?php
/**
* Unit tests 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
*/
/** Include PHPUnit dependencies based on version */
require_once 'PHPUnit/Runner/Version.php';
// If running from SVN checkout, update include_path
if ('@' . 'package_version@' == '@package_version@') {
$classPath = realpath(dirname(dirname(__FILE__)));
$includePath = array_map('realpath', explode(PATH_SEPARATOR, get_include_path()));
if (0 !== ($key = array_search($classPath, $includePath))) {
if (false !== $key) {
unset($includePath[$key]);
}
set_include_path($classPath . PATH_SEPARATOR . implode(PATH_SEPARATOR, $includePath));
}
}
$phpunitVersion = PHPUnit_Runner_Version::id();
if ($phpunitVersion == '@' . 'package_version@' || !version_compare($phpunitVersion, '3.8', '<=')) {
echo "This version of PHPUnit is not supported.";
exit(1);
} elseif (version_compare($phpunitVersion, '3.5.0', '>=')) {
require_once 'PHPUnit/Autoload.php';
} else {
require_once 'PHPUnit/Framework.php';
}
if (!defined('HTTP_REQUEST2_TESTS_BASE_URL')
&& is_readable(dirname(__FILE__) . '/NetworkConfig.php')
) {
require_once dirname(__FILE__) . '/NetworkConfig.php';
}
?>

Binary file not shown.

View file

@ -0,0 +1,9 @@
HTTP/1.1 200 OK
Date: Fri, 01 Jan 2010 02:03:04 GMT
Server: Apache/3.0.1 (Unix)
X-Powered-By: PHP/6.2.2
Content-Type: text/plain; charset=iso-8859-1
Content-Encoding: deflate
Content-Length: 0
Connection: close

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

View file

@ -0,0 +1 @@
This is a test.

View file

@ -0,0 +1,13 @@
HTTP/1.1 200 OK
Date: Fri, 01 Jan 2010 02:03:04 GMT
Server: Apache/3.0.1 (Unix)
X-Powered-By: PHP/6.2.2
Set-Cookie: foo=bar
Set-Cookie: PHPSESSID=1234567890abcdef1234567890abcdef; path=/; secure
Set-Cookie: A=B=C
Set-Cookie: baz=%20a%20value; expires=Sun, 03 Jan 2010 03:04:05 GMT; domain=pear.php.net
Content-Type: text/html; charset=windows-1251
Content-Length: 32
Connection: close
Nothing to see here, move along.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,12 @@
HTTP/1.1 200 OK
Date: Fri, 01 Jan 2010 02:03:04 GMT
Vary: accept-charset
Server: Apache/3.0.1 (Unix)
X-Powered-By: PHP/6.2.2
Vary: user-agent
Content-Type: text/html;
charset=windows-1251
Content-Length: 32
Connection: close
Nothing to see here, move along.

View file

@ -0,0 +1,33 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
$user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
$pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
$wantedUser = isset($_GET['user']) ? $_GET['user'] : null;
$wantedPass = isset($_GET['pass']) ? $_GET['pass'] : null;
if (!$user || !$pass || $user != $wantedUser || $pass != $wantedPass) {
header('WWW-Authenticate: Basic realm="HTTP_Request2 tests"', true, 401);
echo "Login required";
} else {
echo "Username={$user};Password={$pass}";
}
?>

View file

@ -0,0 +1,27 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
for ($i = 0; $i < 20; $i++) {
for ($j = 0; $j < 10; $j++) {
echo str_repeat((string)$j, 98) . "\r\n";
}
flush();
usleep(50000);
}

View file

@ -0,0 +1,24 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
ksort($_COOKIE);
echo serialize($_COOKIE);
?>

View file

@ -0,0 +1,83 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
/**
* Mostly borrowed from PHP manual and Socket Adapter implementation
*
* @link http://php.net/manual/en/features.http-auth.php
*/
/**
* Parses the Digest auth header
*
* @param string $txt
*/
function http_digest_parse($txt)
{
$token = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
$quoted = '"(?:\\\\.|[^\\\\"])*"';
// protect against missing data
$needed_parts = array_flip(array('nonce', 'nc', 'cnonce', 'qop', 'username', 'uri', 'response'));
$data = array();
preg_match_all("!({$token})\\s*=\\s*({$token}|{$quoted})!", $txt, $matches);
for ($i = 0; $i < count($matches[0]); $i++) {
// ignore unneeded parameters
if (isset($needed_parts[$matches[1][$i]])) {
unset($needed_parts[$matches[1][$i]]);
if ('"' == substr($matches[2][$i], 0, 1)) {
$data[$matches[1][$i]] = substr($matches[2][$i], 1, -1);
} else {
$data[$matches[1][$i]] = $matches[2][$i];
}
}
}
return !empty($needed_parts) ? false : $data;
}
$realm = 'HTTP_Request2 tests';
$wantedUser = isset($_GET['user']) ? $_GET['user'] : null;
$wantedPass = isset($_GET['pass']) ? $_GET['pass'] : null;
$validAuth = false;
if (!empty($_SERVER['PHP_AUTH_DIGEST'])
&& ($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']))
&& $wantedUser == $data['username']
) {
// generate the valid response
$a1 = md5($data['username'] . ':' . $realm . ':' . $wantedPass);
$a2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']);
$response = md5($a1. ':' . $data['nonce'] . ':' . $data['nc'] . ':'
. $data['cnonce'] . ':' . $data['qop'] . ':' . $a2);
// check valid response against existing one
$validAuth = ($data['response'] == $response);
}
if (!$validAuth || empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('WWW-Authenticate: Digest realm="' . $realm .
'",qop="auth",nonce="' . uniqid() . '"', true, 401);
echo "Login required";
} else {
echo "Username={$user}";
}
?>

View file

@ -0,0 +1,24 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
ksort($_GET);
echo serialize($_GET);
?>

View file

@ -0,0 +1,24 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
ksort($_POST);
echo serialize($_POST);
?>

View file

@ -0,0 +1,22 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
readfile('php://input');
?>

View file

@ -0,0 +1,47 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
$redirects = isset($_GET['redirects'])? $_GET['redirects']: 1;
$https = !empty($_SERVER['HTTPS']) && ('off' != strtolower($_SERVER['HTTPS']));
$special = isset($_GET['special'])? $_GET['special']: null;
if ('ftp' == $special) {
header('Location: ftp://localhost/pub/exploit.exe', true, 301);
} elseif ('relative' == $special) {
header('Location: ./getparameters.php?msg=did%20relative%20redirect', true, 302);
} elseif ('cookie' == $special) {
setcookie('cookie_on_redirect', 'success');
header('Location: ./cookies.php', true, 302);
} elseif ($redirects > 0) {
$url = ($https? 'https': 'http') . '://' . $_SERVER['SERVER_NAME']
. (($https && 443 == $_SERVER['SERVER_PORT'] || !$https && 80 == $_SERVER['SERVER_PORT'])
? '' : ':' . $_SERVER['SERVER_PORT'])
. $_SERVER['PHP_SELF'] . '?redirects=' . (--$redirects);
header('Location: ' . $url, true, 302);
} else {
echo "Method=" . $_SERVER['REQUEST_METHOD'] . ';';
var_dump($_POST);
var_dump($_GET);
}
?>

View file

@ -0,0 +1,27 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
$name = empty($_GET['name'])? 'foo': $_GET['name'];
$value = empty($_GET['value'])? 'bar': $_GET['value'];
setcookie($name, $value);
echo "Cookie set!";
?>

View file

@ -0,0 +1,23 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
sleep(5);
?>

View file

@ -0,0 +1,36 @@
<?php
/**
* Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
*
* 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
*/
if (isset($_GET['slowpoke'])) {
sleep(3);
}
if (!empty($_FILES)) {
foreach ($_FILES as $name => $file) {
if (is_array($file['name'])) {
foreach($file['name'] as $k => $v) {
echo "{$name}[{$k}] {$v} {$file['type'][$k]} {$file['size'][$k]}\n";
}
} else {
echo "{$name} {$file['name']} {$file['type']} {$file['size']}\n";
}
}
}
?>

7
vendor/pear/net_url2/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
# pear related
/Net_URL2-*.tgz
# composer related
vendor/
/composer.lock
/composer.phar

38
vendor/pear/net_url2/.scrutinizer.yml vendored Normal file
View file

@ -0,0 +1,38 @@
filter:
excluded_paths:
- 'docs/*'
tools:
php_code_coverage:
enabled: true
test_command: phpunit
php_cpd:
excluded_dirs:
- tests
filter:
excluded_paths: []
php_pdepend:
excluded_dirs:
- tests
php_hhvm:
filter:
excluded_paths: []
php_mess_detector:
filter:
excluded_paths: []
php_analyzer:
enabled: true
filter:
excluded_paths: ['docs/*']
php_code_sniffer:
enabled: true
filter:
excluded_paths: ['docs/*']
config:
tab_width: 4
encoding: utf8
ruleset: ~
standard: PEAR
php_loc:
excluded_dirs:
- tests
- docs

17
vendor/pear/net_url2/.travis.yml vendored Normal file
View file

@ -0,0 +1,17 @@
language: php
php:
- 5.2
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
- hhvm-nightly
matrix:
allow_failures:
- php: hhvm-nightly
script: phpunit --coverage-text tests/Net

1219
vendor/pear/net_url2/Net/URL2.php vendored Executable file

File diff suppressed because it is too large Load diff

43
vendor/pear/net_url2/README.md vendored Normal file
View file

@ -0,0 +1,43 @@
[![Net_URL2 on Packagist](https://poser.pugx.org/pear/net_url2/v/stable.png)][pear/net_url2]
[![Build Status](https://travis-ci.org/pear/Net_URL2.png)][Travis CI]
[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/pear/Net_URL2/badges/quality-score.png?s=23b0d3f0ed58ee865317c500ee2cbe94517438ec)](https://scrutinizer-ci.com/g/pear/Net_URL2/)
[![Code Coverage](https://scrutinizer-ci.com/g/pear/Net_URL2/badges/coverage.png?s=44d3682d7cdef471570d80dd8a7290a1e23fdfee)](https://scrutinizer-ci.com/g/pear/Net_URL2/)
# Net_URL2
Class for parsing and handling URL. Provides parsing of URLs into their constituent parts (scheme, host, path etc.),
URL generation, and resolving of relative URLs.
This package is [Pear Net_URL2] and has been migrated from [Pear SVN]
Please report all new issues via the [PEAR bug tracker].
On Packagist as [pear/net_url2].
[Pear Net_URL2]: https://pear.php.net/package/Net_URL2
[Pear SVN]: https://svn.php.net/repository/pear/packages/Net_URL2
[PEAR bug tracker]: https://pear.php.net/bugs/search.php?cmd=display&package_name%5B%5D=Net_URL2
[pear/net_url2]: https://packagist.org/packages/pear/net_url2
[Travis CI]: https://travis-ci.org/pear/Net_URL2
## Testing, Packaging and Installing (Pear)
To test, run either
$ phpunit tests/
or
$ pear run-tests -r
To build, simply
$ pear package
To install from scratch
$ pear install package.xml
To upgrade
$ pear upgrade -f package.xml

47
vendor/pear/net_url2/composer.json vendored Normal file
View file

@ -0,0 +1,47 @@
{
"name": "pear/net_url2",
"description": "Class for parsing and handling URL. Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of relative URLs.",
"type": "library",
"keywords": [
"pear",
"net",
"url",
"uri",
"networking",
"rfc3986"
],
"homepage": "https://github.com/pear/Net_URL2",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Tom Klingenberg",
"email": "tkli@php.net"
},
{
"name": "David Coallier",
"email": "davidc@php.net"
},
{
"name": "Christian Schmidt",
"email": "chmidt@php.net"
}
],
"support": {
"issues": "https://pear.php.net/bugs/search.php?cmd=display&package_name[]=Net_URL2",
"source": "https://github.com/pear/Net_URL2"
},
"require": {
"php": ">=5.1.4"
},
"autoload": {
"classmap": ["Net/URL2.php"]
},
"extra": {
"branch-alias": {
"dev-master": "2.2.x-dev"
}
},
"require-dev": {
"phpunit/phpunit": ">=3.3.0"
}
}

56
vendor/pear/net_url2/docs/6470.php vendored Executable file
View file

@ -0,0 +1,56 @@
<?php
/**
* Net_URL2, a class representing a URL as per RFC 3986.
*
* PHP version 5
*
* This file contains code Copyright (c) 2002-2003, Richard Heyes,
* See BSD-3-CLAUSE-Heyes,
* Author: Richard Heyes <richard at php net>
*
* @category Networking
* @package Net_URL2
* @author Some Pear Developers <pear@php.net>
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
* @link https://tools.ietf.org/html/rfc3986
*/
/**
* This example will decode the url given and display its
* constituent parts.
*/
error_reporting(E_ALL | E_STRICT);
require_once 'Net/URL2.php';
$url = new Net_URL2('https://www.example.com/foo/bar/index.php?foo=bar');
?>
<html>
<body>
<pre>
Protocol...: <?php echo $url->protocol; ?>
Username...: <?php echo $url->user; ?>
Password...: <?php echo $url->pass; ?>
Server.....: <?php echo $url->host; ?>
Port.......: <?php $url->port; ?>
File/path..: <?php $url->path; ?>
Querystring: <?php print_r($url->querystring); ?>
Anchor.....: <?php echo $url->anchor;?>
Full URL...: <?php echo $url->getUrl(); ?>
Resolve path (/.././/foo/bar/joe/./././../jabba): <b><?php
echo $url->resolve('/.././/foo/bar/joe/./././../jabba'); ?></b>
</pre>
</body>
</html>

View file

@ -0,0 +1,27 @@
Copyright (c) 2002-2003, 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:
1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2) 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.
3) Neither the name of the Richard Heyes nor the names of his
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
HOLDER 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.

62
vendor/pear/net_url2/docs/example.php vendored Executable file
View file

@ -0,0 +1,62 @@
<?php
/**
* Net_URL2, a class representing a URL as per RFC 3986.
*
* PHP version 5
*
* This file contains code Copyright (c) 2002-2003, Richard Heyes,
* See BSD-3-CLAUSE-Heyes,
* Author: Richard Heyes <richard at php net>
*
* @category Networking
* @package Net_URL2
* @author Some Pear Developers <pear@php.net>
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
* @link https://tools.ietf.org/html/rfc3986
*/
/**
* This example will decode the url given and display its
* constituent parts.
*/
error_reporting(E_ALL | E_STRICT);
require 'Net/URL2.php';
$url = new Net_URL2(
'https://example.com/pls/portal30/PORTAL30.wwpob_page.changetabs?'
.'p_back_url=http%3A%2F%2Fexample.com%2Fservlet%2Fpage%3F_pageid%3D360'
.'%2C366%2C368%2C382%26_dad%3Dportal30%26_schema%3DPORTAL30&foo=bar'
);
?>
<html>
<body>
<pre>
Protocol...: <?php echo $url->protocol; ?>
Username...: <?php echo $url->user; ?>
Password...: <?php echo $url->pass; ?>
Server.....: <?php echo $url->host; ?>
Port.......: <?php $url->port; ?>
File/path..: <?php $url->path; ?>
Querystring: <?php print_r($url->querystring); ?>
Anchor.....: <?php echo $url->anchor;?>
Full URL...: <?php echo $url->getUrl(); ?>
Resolve path (.././/foo/bar/joe/./././../jabba): <b><?php
echo $url->resolve('.././/foo/bar/joe/./././../jabba'); ?></b>
</pre>
</body>
</html>

469
vendor/pear/net_url2/package.xml vendored Normal file
View file

@ -0,0 +1,469 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.5.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0"
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
<name>Net_URL2</name>
<channel>pear.php.net</channel>
<extends>Net_URL</extends>
<summary>Class for parsing and handling URL.</summary>
<description>
Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of
relative URLs.
</description>
<lead>
<name>Tom Klingenberg</name>
<user>tkli</user>
<email>tkli@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>David Coallier</name>
<user>davidc</user>
<email>davidc@php.net</email>
<active>no</active>
</lead>
<lead>
<name>Christian Schmidt</name>
<user>schmidt</user>
<email>schmidt@php.net</email>
<active>no</active>
</lead>
<date>2015-04-18</date>
<time>19:00:00</time>
<version>
<release>2.2.0</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Changed composer autoloader to classmap, fixes include path pollution
</notes>
<contents>
<dir name="/">
<dir name="docs">
<file baseinstalldir="Net" name="example.php" role="doc" />
<file baseinstalldir="Net" name="6470.php" role="doc" />
<file baseinstalldir="Net" name="BSD-3-CLAUSE-Heyes" role="doc" />
</dir>
<!-- //docs -->
<dir name="tests">
<file name="AllTests.php" role="test" />
<dir name="Net">
<file name="URL2Test.php" role="test">
<tasks:replace type="package-info" to="version" from="@package_version@" />
</file>
</dir>
</dir>
<dir name="Net">
<file name="URL2.php" role="php">
<tasks:replace type="package-info" to="version" from="@package_version@" />
</file>
</dir>
</dir>
<!-- / -->
</contents>
<dependencies>
<required>
<php>
<min>5.1.4</min>
</php>
<pearinstaller>
<min>1.4.0b1</min>
</pearinstaller>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<date>2015-04-18</date>
<time>19:00:00</time>
<version>
<release>2.2.0</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Changed composer autoloader to classmap, fixes include path pollution
</notes>
</release>
<release>
<date>2014-12-27</date>
<time>14:00:00</time>
<version>
<release>2.1.1</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20473: Normalize query and fragment broken
</notes>
</release>
<release>
<date>2014-10-21</date>
<time>18:09:00</time>
<version>
<release>2.1.0</release>
<api>2.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* New: OPTION_DROP_SEQUENCE
</notes>
</release>
<release>
<date>2014-10-21</date>
<time>18:06:00</time>
<version>
<release>2.0.12</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Removed: OPTION_DROP_SEQUENCE
</notes>
</release>
<release>
<date>2014-10-18</date>
<time>08:39:00</time>
<version>
<release>2.0.11</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* New: OPTION_DROP_SEQUENCE
</notes>
</release>
<release>
<date>2014-10-09</date>
<time>22:12:00</time>
<version>
<release>2.0.10</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Imp: composer for pear
* Fix: Documentation problem
</notes>
</release>
<release>
<date>2014-10-08</date>
<time>15:52:00</time>
<version>
<release>2.0.9</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20418: Incorrect normalization of URI with missing authority
* Upd: Test for RFC 3986 Section 1.1.2 Examples
* Upd: Travis CI - PHP 5.6 added
</notes>
</release>
<release>
<date>2014-10-07</date>
<time>23:25:00</time>
<version>
<release>2.0.8</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20420: Inconsistent setAuthority and getAuthority
* Fixed #20423: URI with IPv6 or IPvFuture not parsed
* Imp: Test for RFC 3986 Section 1.1.2 Examples
</notes>
</release>
<release>
<date>2014-09-07</date>
<time>08:34:00</time>
<version>
<release>2.0.7</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20385: Incorrect normalization of userinfo
* Fixed #20399: Setting userinfo to FALSE not transparent
</notes>
</release>
<release>
<date>2014-07-21</date>
<time>00:03:00</time>
<version>
<release>2.0.6</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20304: file:// URI gets crippled
</notes>
</release>
<release>
<date>2014-01-01</date>
<time>21:59:00</time>
<version>
<release>2.0.5</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #17036: Brackets broken for query variables
* Fixed diverse coding style violations and misc. minor issues
* Increased code coverage
</notes>
</release>
<release>
<date>2013-12-31</date>
<time>01:59:00</time>
<version>
<release>2.0.4</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20161: URLs with "0" as host fail to normalize with empty path
* A flaw in NetURL2::removeDotSegments() introduced in 2.0.1 has been fixed
* New: NetURL2::removeDotSegments() emits a warning on loop limit reach
* Url-segment maximum count raised from 100 to 256 (loop limit)
</notes>
</release>
<release>
<date>2013-12-30</date>
<time>01:32:00</time>
<version>
<release>2.0.3</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #20156: setAuthority() flaw with "0" as host
* Fixed #20157: normalize() flaw with "0" as path
* Fixed #20158: Fragment-only references are not resolved to non-absolute base URI
* Fixed #20159: Authority not terminated by slash
* Fixed diverse coding style violations and misc. minor issues
* Increased code coverage
* Added support for Scrutinizer CI
</notes>
</release>
<release>
<date>2013-12-27</date>
<time>19:16:00</time>
<version>
<release>2.0.2</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://spdx.org/licenses/BSD-3-Clause">BSD-3-Clause</license>
<notes>
* Fixed #19684: Redirects containing spaces do not work
* Fixed diverse coding style violations and misc. minor issues
* Improved source package distribution
* Added support for Travis CI
</notes>
</release>
<release>
<date>2013-12-24</date>
<time>18:12:00</time>
<version>
<release>2.0.1</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license>BSD-3-Clause</license>
<notes>
* Fixed Bug #20013: getNormalizedURL() adds leading "@" chars in the Authority
* Fixed Bug #20016: Wrong data in 6d4f4dd "Package.xml preparation."
* Fixed Bug #19176: resolve() does not merge the path if the base path is empty
* Fixed Bug #19315: removeDotSegments("0") not working
</notes>
</release>
<release>
<date>2011-10-20</date>
<time>10:43:00</time>
<version>
<release>2.0.0</release>
<api>2.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license>BSD-3-Clause</license>
<notes>
* Fixed the version of the release. Follow the convention for Package2.
* Fixed Bug #18917: URL2.php moved to ./Net/Net (davidc)
</notes>
</release>
<release>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2011-10-20</date>
<license>BSD-3-Clause</license>
<notes>
* Fixed Bug #17036: Problem with parsed query string
* Fixed Bug #17087: setOption() function is gone
* Fixed #17166: Fluent Interface
* Fixed #17167: Refactor __construct
* Fixed Bug #18267: setQueryVariables() fails to encode array values
* Fixed Bug #14399: Fixed multiple bugs in Net_URL2 (Missing setOption value, unused properties, etc.)
</notes>
</release>
<release>
<version>
<release>0.3.1</release>
<api>0.3.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2011-02-22</date>
<license>BSD-3-Clause</license>
<notes>
* BC break: Removed setOption() to avoid undefined behaviour (bug #16674)
* Fixed Bug #16854: Invalid package.xml making it impossible to install with Pyrus
* Fixed Bug #16651: Port may be an empty string
* Fixed Bug #16653: Don't make OPTION_SEPARATOR_(IN|OUT)PUT default to arg_separator.(in|out)put
</notes>
</release>
<release>
<version>
<release>0.3.0</release>
<api>0.3.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2009-09-05</date>
<license>BSD-3-Clause</license>
<notes>
* Fixed #14399 (Errors in URL parsing (items #1 and #3))
* Fixed #14735 (Encode query string values)
* Fixed #15546 (Add adding __toString())
* Fixed #15367 (Use RFC 3986-compliant version of rawurlencode() in PHP &lt; 5.2)
* Fixed #14289 (Add __get() and __set())
</notes>
</release>
<release>
<version>
<release>0.2.0</release>
<api>0.2.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2008-06-18</date>
<license>BSD-3-Clause</license>
<notes>
* Major rewrite to comply with RFC3986 (bug #11574).
* Much better support for resolving relative URLs.
* WARNING: Method and property names has changed to reflect the terminology used in the RFC - THIS RELEASE IS
NOT BACKWARDS COMPATIBLE WITH VERSION 0.1.0.
</notes>
</release>
<release>
<version>
<release>0.1.0</release>
<api>0.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2007-05-08</date>
<license>BSD-3-Clause</license>
<notes>Convert to PHP5 only. PHP4 users should continue with version 1.0.15</notes>
</release>
</changelog>
</package>

17
vendor/pear/net_url2/phpunit.xml.dist vendored Normal file
View file

@ -0,0 +1,17 @@
<phpunit bootstrap="Net/URL2.php"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="true">
<testsuites>
<testsuite name="Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<file>Net/URL2.php</file>
</whitelist>
</filter>
</phpunit>

59
vendor/pear/net_url2/tests/AllTests.php vendored Normal file
View file

@ -0,0 +1,59 @@
<?php
/**
* Net_URL2, a class representing a URL as per RFC 3986.
*
* PHP version 5
*
* @category Networking
* @package Net_URL2
* @author Some Pear Developers <pear@php.net>
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
* @link https://tools.ietf.org/html/rfc3986
*/
require_once 'PHPUnit/Autoload.php';
chdir(dirname(__FILE__) . '/../');
require_once 'Net/URL2Test.php';
require_once 'Net/URL2.php';
/**
* Test class for Net_URL2.
*
* @category Networking
* @package Net_URL2
* @author Some Pear Developers <pear@php.net>
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
* @version Release: @package_version@
* @link https://pear.php.net/package/Net_URL2
*/
class Net_URL2_AllTests
{
/**
* main()
*
* @return void
*/
public static function main()
{
PHPUnit_TextUI_TestRunner::run(self::suite());
}
/**
* suite()
*
* @return PHPUnit_Framework_TestSuite
*/
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Net_URL2 tests');
/** Add testsuites, if there is. */
$suite->addTestSuite('Net_URL2Test');
return $suite;
}
}
Net_URL2_AllTests::main();

File diff suppressed because it is too large Load diff

6
vendor/pear/pear_exception/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
PEAR_Exception*.tgz
# composer related
composer.lock
composer.phar
vendor

View file

@ -0,0 +1,7 @@
language: php
php:
- 5.6
- 5.5
- 5.4
script:
- cd tests && phpunit --coverage-text .

27
vendor/pear/pear_exception/LICENSE vendored Normal file
View file

@ -0,0 +1,27 @@
Copyright (c) 1997-2009,
Stig Bakken <ssb@php.net>,
Gregory Beaver <cellog@php.net>,
Helgi Þormar Þorbjörnsson <helgi@php.net>,
Tomas V.V.Cox <cox@idecnet.com>,
Martin Jansen <mj@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.
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

@ -0,0 +1,456 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
/**
* PEAR_Exception
*
* PHP version 5
*
* @category PEAR
* @package PEAR_Exception
* @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
* @link http://pear.php.net/package/PEAR_Exception
* @since File available since Release 1.0.0
*/
/**
* 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_Exception
* @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: @package_version@
* @link http://pear.php.net/package/PEAR_Exception
* @since Class available since Release 1.0.0
*/
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 $message exception message
* @param int|Exception|PEAR_Error|array|null $p2 exception cause
* @param int|null $p3 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();
}
/**
* Add an exception observer
*
* @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()
*
* @return void
*/
public static function addObserver($callback, $label = 'default')
{
self::$_observers[$label] = $callback;
}
/**
* Remove an exception observer
*
* @param string $label Name of the observer
*
* @return void
*/
public static function removeObserver($label = 'default')
{
unset(self::$_observers[$label]);
}
/**
* Generate a unique ID for an observer
*
* @return int unique identifier for an observer
*/
public static function getUniqueId()
{
return self::$_uniqueid++;
}
/**
* Send a signal to all observers
*
* @return void
*/
protected 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
*
* @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 $causes Array that gets filled.
*
* @return void
*/
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',
);
}
}
}
}
/**
* Build a backtrace and return it
*
* @return array Backtrace
*/
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;
}
/**
* Gets the first class of the backtrace
*
* @return string Class name
*/
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
/**
* Gets the first method of the backtrace
*
* @return string Method/function name
*/
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
/**
* Converts the exception to a string (HTML or plain text)
*
* @return string String representation
*
* @see toHtml()
* @see toText()
*/
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
/**
* Generates a HTML representation of the exception
*
* @return string HTML code
*/
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';
} else if (is_array($arg)) {
$args[] = 'Array';
} else if (is_object($arg)) {
$args[] = 'Object('.get_class($arg).')';
} else if (is_bool($arg)) {
$args[] = $arg ? 'true' : 'false';
} else if (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;
}
/**
* Generates text representation of the exception and stack trace
*
* @return string
*/
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

@ -0,0 +1,43 @@
{
"name": "pear/pear_exception",
"description": "The PEAR Exception base class.",
"type": "class",
"keywords": [
"exception"
],
"homepage": "https://github.com/pear/PEAR_Exception",
"license": "BSD-2-Clause",
"authors": [
{
"name": "Helgi Thormar",
"email": "dufuz@php.net"
},
{
"name": "Greg Beaver",
"email": "cellog@php.net"
}
],
"require": {
"php": ">=4.4.0"
},
"autoload": {
"psr-0": {
"PEAR": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"include-path": [
"."
],
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR_Exception",
"source": "https://github.com/pear/PEAR_Exception"
},
"require-dev": {
"phpunit/phpunit": "*"
}
}

120
vendor/pear/pear_exception/package.xml vendored Normal file
View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.4" version="2.0"
xmlns="http://pear.php.net/dtd/package-2.0"
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"
>
<name>PEAR_Exception</name>
<channel>pear.php.net</channel>
<summary>The PEAR Exception base class</summary>
<description>PEAR_Exception PHP5 error handling mechanism</description>
<lead>
<name>Christian Weiske</name>
<user>cweiske</user>
<email>cweiske@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Helgi Thormar</name>
<user>dufuz</user>
<email>dufuz@php.net</email>
<active>no</active>
</lead>
<developer>
<name>Greg Beaver</name>
<user>cellog</user>
<email>cellog@php.net</email>
<active>no</active>
</developer>
<date>2015-02-10</date>
<time>21:02:23</time>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
This package was split out from the PEAR package.
If you use PEAR_Exception in your package and use nothing from the PEAR package
then it's better to depend on just PEAR_Exception.
</notes>
<contents>
<dir name="/">
<file name="/PEAR/Exception.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<dir name="tests">
<dir name="PEAR">
<file name="ExceptionTest.php" role="test"/>
</dir>
</dir>
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.4.0</min>
</php>
<pearinstaller>
<min>1.9.5</min>
</pearinstaller>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-02-10</date>
<license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>Release stable version</notes>
</release>
<release>
<version>
<release>1.0.0beta2</release>
<api>1.0.0</api>
</version>
<stability>
<release>beta</release>
<api>stable</api>
</stability>
<date>2014-02-21</date>
<license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>Bump up PEAR dependency.</notes>
</release>
<release>
<version>
<release>1.0.0beta1</release>
<api>1.0.0</api>
</version>
<stability>
<release>beta</release>
<api>stable</api>
</stability>
<date>2012-05-10</date>
<license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
This packge was split out from the PEAR package. If you use PEAR_Exception in your package
and use nothing from the PEAR package then it&apos;s better to depend on just PEAR_Exception.
</notes>
</release>
</changelog>
</package>

View file

@ -0,0 +1,78 @@
<?php
$localFile = __DIR__ . '/../../PEAR/Exception.php';
if (file_exists($localFile)) {
require_once $localFile;
} else {
require_once 'PEAR/Exception.php';
}
class PEAR_ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException PEAR_Exception
* @expectedExceptionMessage foo
*/
public function testThrow()
{
throw new PEAR_Exception('foo');
}
public function testGetCauseNone()
{
$e = new PEAR_Exception('foo bar');
$this->assertNull($e->getCause());
}
public function testGetCauseException()
{
$cause = new Exception('foo bar');
$e = new PEAR_Exception('I caught an exception', $cause);
$this->assertNotNull($e->getCause());
$this->assertInstanceOf('Exception', $e->getCause());
$this->assertEquals($cause, $e->getCause());
}
public function testGetCauseMessage()
{
$cause = new Exception('foo bar');
$e = new PEAR_Exception('I caught an exception', $cause);
$e->getCauseMessage($causes);
$this->assertEquals('I caught an exception', $causes[0]['message']);
$this->assertEquals('foo bar', $causes[1]['message']);
}
public function testGetTraceSafe()
{
$e = new PEAR_Exception('oops');
$this->assertInternalType('array', $e->getTraceSafe());
}
public function testGetErrorClass()
{
$e = new PEAR_Exception('oops');
$this->assertEquals('PEAR_ExceptionTest', $e->getErrorClass());
}
public function testGetErrorMethod()
{
$e = new PEAR_Exception('oops');
$this->assertEquals('testGetErrorMethod', $e->getErrorMethod());
}
public function test__toString()
{
$e = new PEAR_Exception('oops');
$this->assertInternalType('string', (string) $e);
$this->assertContains('oops', (string) $e);
}
public function testToHtml()
{
$e = new PEAR_Exception('oops');
$html = $e->toHtml();
$this->assertInternalType('string', $html);
$this->assertContains('oops', $html);
}
}
?>

View file

@ -0,0 +1,9 @@
*.crt -crlf
*.key -crlf
*.srl -crlf
*.pub -crlf
*.priv -crlf
*.txt -crlf
# ignore /notes in the git-generated distributed .zip archive
/notes export-ignore

View file

@ -0,0 +1,4 @@
/tests/acceptance.conf.php
/tests/smoke.conf.php
/build/*
/vendor/

View file

@ -0,0 +1,25 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm-nightly
before_script:
- cp tests/acceptance.conf.php.default tests/acceptance.conf.php
- cp tests/smoke.conf.php.default tests/smoke.conf.php
- composer self-update
- composer update --no-interaction --prefer-source
- gem install mailcatcher
- mailcatcher --smtp-port 4456
script:
- phpunit --verbose
matrix:
allow_failures:
- php: 5.6
- php: hhvm-nightly
fast_finish: true

206
vendor/swiftmailer/swiftmailer/CHANGES vendored Normal file
View file

@ -0,0 +1,206 @@
Changelog
=========
5.4.1 (2015-06-06)
------------------
* made Swiftmailer exceptions confirm to PHP base exception constructor signature
* fixed MAIL FROM & RCPT TO headers to be RFC compliant
5.4.0 (2015-03-14)
------------------
* added the possibility to add extra certs to PKCS#7 signature
* fix base64 encoding with streams
* added a new RESULT_SPOOLED status for SpoolTransport
* fixed getBody() on attachments when called more than once
* removed dots from generated filenames in filespool
5.3.1 (2014-12-05)
------------------
* fixed cloning of messages with attachments
5.3.0 (2014-10-04)
------------------
* fixed cloning when using signers
* reverted removal of Swift_Encoding
* drop support for PHP 5.2.x
5.2.2 (2014-09-20)
------------------
* fixed Japanese support
* fixed the memory spool when the message changes when in the pool
* added support for cloning messages
* fixed PHP warning in the redirect plugin
* changed the way to and cc-ed email are sent to only use one transaction
5.2.1 (2014-06-13)
------------------
* SECURITY FIX: fixed CLI escaping when using sendmail as a transport
Prior to 5.2.1, the sendmail transport (Swift_Transport_SendmailTransport)
was vulnerable to an arbitrary shell execution if the "From" header came
from a non-trusted source and no "Return-Path" is configured.
* fixed parameter in DKIMSigner
* fixed compatibility with PHP < 5.4
5.2.0 (2014-05-08)
------------------
* fixed Swift_ByteStream_FileByteStream::read() to match to the specification
* fixed from-charset and to-charset arguments in mbstring_convert_encoding() usages
* fixed infinite loop in StreamBuffer
* fixed NullTransport to return the number of ignored emails instead of 0
* Use phpunit and mockery for unit testing (realityking)
5.1.0 (2014-03-18)
------------------
* fixed data writing to stream when sending large messages
* added support for libopendkim (https://github.com/xdecock/php-opendkim)
* merged SignedMessage and Message
* added Gmail XOAuth2 authentication
* updated the list of known mime types
* added NTLM authentication
5.0.3 (2013-12-03)
------------------
* fixed double-dot bug
* fixed DKIM signer
5.0.2 (2013-08-30)
------------------
* handled correct exception type while reading IoBuffer output
5.0.1 (2013-06-17)
------------------
* changed the spool to only start the transport when a mail has to be sent
* fixed compatibility with PHP 5.2
* fixed LICENSE file
5.0.0 (2013-04-30)
------------------
* changed the license from LGPL to MIT
4.3.1 (2013-04-11)
------------------
* removed usage of the native QP encoder when the charset is not UTF-8
* fixed usage of uniqid to avoid collisions
* made a performance improvement when tokenizing large headers
* fixed usage of the PHP native QP encoder on PHP 5.4.7+
4.3.0 (2013-01-08)
------------------
* made the temporary directory configurable via the TMPDIR env variable
* added S/MIME signer and encryption support
4.2.2 (2012-10-25)
------------------
* added the possibility to throttle messages per second in ThrottlerPlugin (mostly for Amazon SES)
* switched mime.qpcontentencoder to automatically use the PHP native encoder on PHP 5.4.7+
* allowed specifying a whitelist with regular expressions in RedirectingPlugin
4.2.1 (2012-07-13)
------------------
* changed the coding standards to PSR-1/2
* fixed issue with autoloading
* added NativeQpContentEncoder to enhance performance (for PHP 5.3+)
4.2.0 (2012-06-29)
------------------
* added documentation about how to use the Japanese support introduced in 4.1.8
* added a way to override the default configuration in a lazy way
* changed the PEAR init script to lazy-load the initialization
* fixed a bug when calling Swift_Preferences before anything else (regression introduced in 4.1.8)
4.1.8 (2012-06-17)
------------------
* added Japanese iso-2022-jp support
* changed the init script to lazy-load the initialization
* fixed docblocks (@id) which caused some problems with libraries parsing the dobclocks
* fixed Swift_Mime_Headers_IdentificationHeader::setId() when passed an array of ids
* fixed encoding of email addresses in headers
* added replacements setter to the Decorator plugin
4.1.7 (2012-04-26)
------------------
* fixed QpEncoder safeMapShareId property
4.1.6 (2012-03-23)
------------------
* reduced the size of serialized Messages
4.1.5 (2012-01-04)
------------------
* enforced Swift_Spool::queueMessage() to return a Boolean
* made an optimization to the memory spool: start the transport only when required
* prevented stream_socket_client() from generating an error and throw a Swift_TransportException instead
* fixed a PHP warning when calling to mail() when safe_mode is off
* many doc tweaks
4.1.4 (2011-12-16)
------------------
* added a memory spool (Swift_MemorySpool)
* fixed too many opened files when sending emails with attachments
4.1.3 (2011-10-27)
------------------
* added STARTTLS support
* added missing @return tags on fluent methods
* added a MessageLogger plugin that logs all sent messages
* added composer.json
4.1.2 (2011-09-13)
------------------
* fixed wrong detection of magic_quotes_runtime
* fixed fatal errors when no To or Subject header has been set
* fixed charset on parameter header continuations
* added documentation about how to install Swiftmailer from the PEAR channel
* fixed various typos and markup problem in the documentation
* fixed warning when cache directory does not exist
* fixed "slashes are escaped" bug
* changed require_once() to require() in autoload
4.1.1 (2011-07-04)
------------------
* added missing file in PEAR package
4.1.0 (2011-06-30)
------------------
* documentation has been converted to ReST
4.1.0 RC1 (2011-06-17)
----------------------
New features:
* changed the Decorator Plugin to allow replacements in all headers
* added Swift_Mime_Grammar and Swift_Validate to validate an email address
* modified the autoloader to lazy-initialize Swiftmailer
* removed Swift_Mailer::batchSend()
* added NullTransport
* added new plugins: RedirectingPlugin and ImpersonatePlugin
* added a way to send messages asynchronously (Spool)

19
vendor/swiftmailer/swiftmailer/LICENSE vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2013 Fabien Potencier
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.

16
vendor/swiftmailer/swiftmailer/README vendored Normal file
View file

@ -0,0 +1,16 @@
Swift Mailer
------------
Swift Mailer is a component based mailing solution for PHP 5.
It is released under the MIT license.
Homepage: http://swiftmailer.org
Documentation: http://swiftmailer.org/docs
Mailing List: http://groups.google.com/group/swiftmailer
Bugs: https://github.com/swiftmailer/swiftmailer/issues
Repository: https://github.com/swiftmailer/swiftmailer
Swift Mailer is highly object-oriented by design and lends itself
to use in complex web application with a great deal of flexibility.
For full details on usage, see the documentation.

View file

@ -0,0 +1 @@
Swift-5.4.1

View file

@ -0,0 +1,31 @@
{
"name": "swiftmailer/swiftmailer",
"type": "library",
"description": "Swiftmailer, free feature-rich PHP mailer",
"keywords": ["mail","mailer","email"],
"homepage": "http://swiftmailer.org",
"license": "MIT",
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"mockery/mockery": "~0.9.1,<0.9.4"
},
"autoload": {
"files": ["lib/swift_required.php"]
},
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
}
}

View file

@ -0,0 +1,742 @@
Message Headers
===============
Sometimes you'll want to add your own headers to a message or modify/remove
headers that are already present. You work with the message's HeaderSet to do
this.
Header Basics
-------------
All MIME entities in Swift Mailer -- including the message itself --
store their headers in a single object called a HeaderSet. This HeaderSet is
retrieved with the ``getHeaders()`` method.
As mentioned in the previous chapter, everything that forms a part of a message
in Swift Mailer is a MIME entity that is represented by an instance of
``Swift_Mime_MimeEntity``. This includes -- most notably -- the message object
itself, attachments, MIME parts and embedded images. Each of these MIME entities
consists of a body and a set of headers that describe the body.
For all of the "standard" headers in these MIME entities, such as the
``Content-Type``, there are named methods for working with them, such as
``setContentType()`` and ``getContentType()``. This is because headers are a
moderately complex area of the library. Each header has a slightly different
required structure that it must meet in order to comply with the standards that
govern email (and that are checked by spam blockers etc).
You fetch the HeaderSet from a MIME entity like so:
.. code-block:: php
$message = Swift_Message::newInstance();
// Fetch the HeaderSet from a Message object
$headers = $message->getHeaders();
$attachment = Swift_Attachment::fromPath('document.pdf');
// Fetch the HeaderSet from an attachment object
$headers = $attachment->getHeaders();
The job of the HeaderSet is to contain and manage instances of Header objects.
Depending upon the MIME entity the HeaderSet came from, the contents of the
HeaderSet will be different, since an attachment for example has a different
set of headers to those in a message.
You can find out what the HeaderSet contains with a quick loop, dumping out
the names of the headers:
.. code-block:: php
foreach ($headers->getAll() as $header) {
printf("%s<br />\n", $header->getFieldName());
}
/*
Content-Transfer-Encoding
Content-Type
MIME-Version
Date
Message-ID
From
Subject
To
*/
You can also dump out the rendered HeaderSet by calling its ``toString()``
method:
.. code-block:: php
echo $headers->toString();
/*
Message-ID: <1234869991.499a9ee7f1d5e@swift.generated>
Date: Tue, 17 Feb 2009 22:26:31 +1100
Subject: Awesome subject!
From: sender@example.org
To: recipient@example.org
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
*/
Where the complexity comes in is when you want to modify an existing header.
This complexity comes from the fact that each header can be of a slightly
different type (such as a Date header, or a header that contains email
addresses, or a header that has key-value parameters on it!). Each header in the
HeaderSet is an instance of ``Swift_Mime_Header``. They all have common
functionality, but knowing exactly what type of header you're working with will
allow you a little more control.
You can determine the type of header by comparing the return value of its
``getFieldType()`` method with the constants ``TYPE_TEXT``,
``TYPE_PARAMETERIZED``, ``TYPE_DATE``, ``TYPE_MAILBOX``, ``TYPE_ID`` and
``TYPE_PATH`` which are defined in ``Swift_Mime_Header``.
.. code-block:: php
foreach ($headers->getAll() as $header) {
switch ($header->getFieldType()) {
case Swift_Mime_Header::TYPE_TEXT: $type = 'text';
break;
case Swift_Mime_Header::TYPE_PARAMETERIZED: $type = 'parameterized';
break;
case Swift_Mime_Header::TYPE_MAILBOX: $type = 'mailbox';
break;
case Swift_Mime_Header::TYPE_DATE: $type = 'date';
break;
case Swift_Mime_Header::TYPE_ID: $type = 'ID';
break;
case Swift_Mime_Header::TYPE_PATH: $type = 'path';
break;
}
printf("%s: is a %s header<br />\n", $header->getFieldName(), $type);
}
/*
Content-Transfer-Encoding: is a text header
Content-Type: is a parameterized header
MIME-Version: is a text header
Date: is a date header
Message-ID: is a ID header
From: is a mailbox header
Subject: is a text header
To: is a mailbox header
*/
Headers can be removed from the set, modified within the set, or added to the
set.
The following sections show you how to work with the HeaderSet and explain the
details of each implementation of ``Swift_Mime_Header`` that may
exist within the HeaderSet.
Header Types
------------
Because all headers are modeled on different data (dates, addresses, text!)
there are different types of Header in Swift Mailer. Swift Mailer attempts to
categorize all possible MIME headers into more general groups, defined by a
small number of classes.
Text Headers
~~~~~~~~~~~~
Text headers are the simplest type of Header. They contain textual information
with no special information included within it -- for example the Subject
header in a message.
There's nothing particularly interesting about a text header, though it is
probably the one you'd opt to use if you need to add a custom header to a
message. It represents text just like you'd think it does. If the text
contains characters that are not permitted in a message header (such as new
lines, or non-ascii characters) then the header takes care of encoding the
text so that it can be used.
No header -- including text headers -- in Swift Mailer is vulnerable to
header-injection attacks. Swift Mailer breaks any attempt at header injection by
encoding the dangerous data into a non-dangerous form.
It's easy to add a new text header to a HeaderSet. You do this by calling the
HeaderSet's ``addTextHeader()`` method.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addTextHeader('Your-Header-Name', 'the header value');
Changing the value of an existing text header is done by calling it's
``setValue()`` method.
.. code-block:: php
$subject = $message->getHeaders()->get('Subject');
$subject->setValue('new subject');
When output via ``toString()``, a text header produces something like the
following:
.. code-block:: php
$subject = $message->getHeaders()->get('Subject');
$subject->setValue('amazing subject line');
echo $subject->toString();
/*
Subject: amazing subject line
*/
If the header contains any characters that are outside of the US-ASCII range
however, they will be encoded. This is nothing to be concerned about since
mail clients will decode them back.
.. code-block:: php
$subject = $message->getHeaders()->get('Subject');
$subject->setValue('contains dash');
echo $subject->toString();
/*
Subject: contains =?utf-8?Q?=E2=80=93?= dash
*/
Parameterized Headers
~~~~~~~~~~~~~~~~~~~~~
Parameterized headers are text headers that contain key-value parameters
following the textual content. The Content-Type header of a message is a
parameterized header since it contains charset information after the content
type.
The parameterized header type is a special type of text header. It extends the
text header by allowing additional information to follow it. All of the methods
from text headers are available in addition to the methods described here.
Adding a parameterized header to a HeaderSet is done by using the
``addParameterizedHeader()`` method which takes a text value like
``addTextHeader()`` but it also accepts an associative array of
key-value parameters.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addParameterizedHeader(
'Header-Name', 'header value',
array('foo' => 'bar')
);
To change the text value of the header, call it's ``setValue()`` method just as
you do with text headers.
To change the parameters in the header, call the header's ``setParameters()``
method or the ``setParameter()`` method (note the pluralization).
.. code-block:: php
$type = $message->getHeaders()->get('Content-Type');
// setParameters() takes an associative array
$type->setParameters(array(
'name' => 'file.txt',
'charset' => 'iso-8859-1'
));
// setParameter() takes two args for $key and $value
$type->setParameter('charset', 'iso-8859-1');
When output via ``toString()``, a parameterized header produces something like
the following:
.. code-block:: php
$type = $message->getHeaders()->get('Content-Type');
$type->setValue('text/html');
$type->setParameter('charset', 'utf-8');
echo $type->toString();
/*
Content-Type: text/html; charset=utf-8
*/
If the header contains any characters that are outside of the US-ASCII range
however, they will be encoded, just like they are for text headers. This is
nothing to be concerned about since mail clients will decode them back.
Likewise, if the parameters contain any non-ascii characters they will be
encoded so that they can be transmitted safely.
.. code-block:: php
$attachment = Swift_Attachment::newInstance();
$disp = $attachment->getHeaders()->get('Content-Disposition');
$disp->setValue('attachment');
$disp->setParameter('filename', 'reportmay.pdf');
echo $disp->toString();
/*
Content-Disposition: attachment; filename*=utf-8''report%E2%80%93may.pdf
*/
Date Headers
~~~~~~~~~~~~
Date headers contains an RFC 2822 formatted date (i.e. what PHP's ``date('r')``
returns). They are used anywhere a date or time is needed to be presented as a
message header.
The data on which a date header is modeled is simply a UNIX timestamp such as
that returned by ``time()`` or ``strtotime()``. The timestamp is used to create
a correctly structured RFC 2822 formatted date such as
``Tue, 17 Feb 2009 22:26:31 +1100``.
The obvious place this header type is used is in the ``Date:`` header of the
message itself.
It's easy to add a new date header to a HeaderSet. You do this by calling
the HeaderSet's ``addDateHeader()`` method.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addDateHeader('Your-Header-Name', strtotime('3 days ago'));
Changing the value of an existing date header is done by calling it's
``setTimestamp()`` method.
.. code-block:: php
$date = $message->getHeaders()->get('Date');
$date->setTimestamp(time());
When output via ``toString()``, a date header produces something like the
following:
.. code-block:: php
$date = $message->getHeaders()->get('Date');
echo $date->toString();
/*
Date: Wed, 18 Feb 2009 13:35:02 +1100
*/
Mailbox (e-mail address) Headers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mailbox headers contain one or more email addresses, possibly with
personalized names attached to them. The data on which they are modeled is
represented by an associative array of email addresses and names.
Mailbox headers are probably the most complex header type to understand in
Swift Mailer because they accept their input as an array which can take various
forms, as described in the previous chapter.
All of the headers that contain e-mail addresses in a message -- with the
exception of ``Return-Path:`` which has a stricter syntax -- use this header
type. That is, ``To:``, ``From:`` etc.
You add a new mailbox header to a HeaderSet by calling the HeaderSet's
``addMailboxHeader()`` method.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addMailboxHeader('Your-Header-Name', array(
'person1@example.org' => 'Person Name One',
'person2@example.org',
'person3@example.org',
'person4@example.org' => 'Another named person'
));
Changing the value of an existing mailbox header is done by calling it's
``setNameAddresses()`` method.
.. code-block:: php
$to = $message->getHeaders()->get('To');
$to->setNameAddresses(array(
'joe@example.org' => 'Joe Bloggs',
'john@example.org' => 'John Doe',
'no-name@example.org'
));
If you don't wish to concern yourself with the complicated accepted input
formats accepted by ``setNameAddresses()`` as described in the previous chapter
and you only want to set one or more addresses (not names) then you can just
use the ``setAddresses()`` method instead.
.. code-block:: php
$to = $message->getHeaders()->get('To');
$to->setAddresses(array(
'joe@example.org',
'john@example.org',
'no-name@example.org'
));
.. note::
Both methods will accept the above input format in practice.
If all you want to do is set a single address in the header, you can use a
string as the input parameter to ``setAddresses()`` and/or
``setNameAddresses()``.
.. code-block:: php
$to = $message->getHeaders()->get('To');
$to->setAddresses('joe-bloggs@example.org');
When output via ``toString()``, a mailbox header produces something like the
following:
.. code-block:: php
$to = $message->getHeaders()->get('To');
$to->setNameAddresses(array(
'person1@example.org' => 'Name of Person',
'person2@example.org',
'person3@example.org' => 'Another Person'
));
echo $to->toString();
/*
To: Name of Person <person1@example.org>, person2@example.org, Another Person
<person3@example.org>
*/
ID Headers
~~~~~~~~~~
ID headers contain identifiers for the entity (or the message). The most
notable ID header is the Message-ID header on the message itself.
An ID that exists inside an ID header looks more-or-less less like an email
address. For example, ``<1234955437.499becad62ec2@example.org>``.
The part to the left of the @ sign is usually unique, based on the current time
and some random factor. The part on the right is usually a domain name.
Any ID passed to the header's ``setId()`` method absolutely MUST conform to
this structure, otherwise you'll get an Exception thrown at you by Swift Mailer
(a ``Swift_RfcComplianceException``). This is to ensure that the generated
email complies with relevant RFC documents and therefore is less likely to be
blocked as spam.
It's easy to add a new ID header to a HeaderSet. You do this by calling
the HeaderSet's ``addIdHeader()`` method.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addIdHeader('Your-Header-Name', '123456.unqiue@example.org');
Changing the value of an existing date header is done by calling its
``setId()`` method.
.. code-block:: php
$msgId = $message->getHeaders()->get('Message-ID');
$msgId->setId(time() . '.' . uniqid('thing') . '@example.org');
When output via ``toString()``, an ID header produces something like the
following:
.. code-block:: php
$msgId = $message->getHeaders()->get('Message-ID');
echo $msgId->toString();
/*
Message-ID: <1234955437.499becad62ec2@example.org>
*/
Path Headers
~~~~~~~~~~~~
Path headers are like very-restricted mailbox headers. They contain a single
email address with no associated name. The Return-Path header of a message is
a path header.
You add a new path header to a HeaderSet by calling the HeaderSet's
``addPathHeader()`` method.
.. code-block:: php
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addPathHeader('Your-Header-Name', 'person@example.org');
Changing the value of an existing path header is done by calling its
``setAddress()`` method.
.. code-block:: php
$return = $message->getHeaders()->get('Return-Path');
$return->setAddress('my-address@example.org');
When output via ``toString()``, a path header produces something like the
following:
.. code-block:: php
$return = $message->getHeaders()->get('Return-Path');
$return->setAddress('person@example.org');
echo $return->toString();
/*
Return-Path: <person@example.org>
*/
Header Operations
-----------------
Working with the headers in a message involves knowing how to use the methods
on the HeaderSet and on the individual Headers within the HeaderSet.
Adding new Headers
~~~~~~~~~~~~~~~~~~
New headers can be added to the HeaderSet by using one of the provided
``add..Header()`` methods.
To add a header to a MIME entity (such as the message):
Get the HeaderSet from the entity by via its ``getHeaders()`` method.
* Add the header to the HeaderSet by calling one of the ``add..Header()``
methods.
The added header will appear in the message when it is sent.
.. code-block:: php
// Adding a custom header to a message
$message = Swift_Message::newInstance();
$headers = $message->getHeaders();
$headers->addTextHeader('X-Mine', 'something here');
// Adding a custom header to an attachment
$attachment = Swift_Attachment::fromPath('/path/to/doc.pdf');
$attachment->getHeaders()->addDateHeader('X-Created-Time', time());
Retrieving Headers
~~~~~~~~~~~~~~~~~~
Headers are retrieved through the HeaderSet's ``get()`` and ``getAll()``
methods.
To get a header, or several headers from a MIME entity:
* Get the HeaderSet from the entity by via its ``getHeaders()`` method.
* Get the header(s) from the HeaderSet by calling either ``get()`` or
``getAll()``.
When using ``get()`` a single header is returned that matches the name (case
insensitive) that is passed to it. When using ``getAll()`` with a header name,
an array of headers with that name are returned. Calling ``getAll()`` with no
arguments returns an array of all headers present in the entity.
.. note::
It's valid for some headers to appear more than once in a message (e.g.
the Received header). For this reason ``getAll()`` exists to fetch all
headers with a specified name. In addition, ``get()`` accepts an optional
numerical index, starting from zero to specify which header you want more
specifically.
.. note::
If you want to modify the contents of the header and you don't know for
sure what type of header it is then you may need to check the type by
calling its ``getFieldType()`` method.
.. code-block:: php
$headers = $message->getHeaders();
// Get the To: header
$toHeader = $headers->get('To');
// Get all headers named "X-Foo"
$fooHeaders = $headers->getAll('X-Foo');
// Get the second header named "X-Foo"
$foo = $headers->get('X-Foo', 1);
// Get all headers that are present
$all = $headers->getAll();
Check if a Header Exists
~~~~~~~~~~~~~~~~~~~~~~~~
You can check if a named header is present in a HeaderSet by calling its
``has()`` method.
To check if a header exists:
* Get the HeaderSet from the entity by via its ``getHeaders()`` method.
* Call the HeaderSet's ``has()`` method specifying the header you're looking
for.
If the header exists, ``true`` will be returned or ``false`` if not.
.. note::
It's valid for some headers to appear more than once in a message (e.g.
the Received header). For this reason ``has()`` accepts an optional
numerical index, starting from zero to specify which header you want to
check more specifically.
.. code-block:: php
$headers = $message->getHeaders();
// Check if the To: header exists
if ($headers->has('To')) {
echo 'To: exists';
}
// Check if an X-Foo header exists twice (i.e. check for the 2nd one)
if ($headers->has('X-Foo', 1)) {
echo 'Second X-Foo header exists';
}
Removing Headers
~~~~~~~~~~~~~~~~
Removing a Header from the HeaderSet is done by calling the HeaderSet's
``remove()`` or ``removeAll()`` methods.
To remove an existing header:
* Get the HeaderSet from the entity by via its ``getHeaders()`` method.
* Call the HeaderSet's ``remove()`` or ``removeAll()`` methods specifying the
header you want to remove.
When calling ``remove()`` a single header will be removed. When calling
``removeAll()`` all headers with the given name will be removed. If no headers
exist with the given name, no errors will occur.
.. note::
It's valid for some headers to appear more than once in a message (e.g.
the Received header). For this reason ``remove()`` accepts an optional
numerical index, starting from zero to specify which header you want to
check more specifically. For the same reason, ``removeAll()`` exists to
remove all headers that have the given name.
.. code-block:: php
$headers = $message->getHeaders();
// Remove the Subject: header
$headers->remove('Subject');
// Remove all X-Foo headers
$headers->removeAll('X-Foo');
// Remove only the second X-Foo header
$headers->remove('X-Foo', 1);
Modifying a Header's Content
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To change a Header's content you should know what type of header it is and then
call it's appropriate setter method. All headers also have a
``setFieldBodyModel()`` method that accepts a mixed parameter and delegates to
the correct setter.
To modify an existing header:
* Get the HeaderSet from the entity by via its ``getHeaders()`` method.
* Get the Header by using the HeaderSet's ``get()``.
* Call the Header's appropriate setter method or call the header's
``setFieldBodyModel()`` method.
The header will be updated inside the HeaderSet and the changes will be seen
when the message is sent.
.. code-block:: php
$headers = $message->getHeaders();
// Change the Subject: header
$subj = $headers->get('Subject');
$subj->setValue('new subject here');
// Change the To: header
$to = $headers->get('To');
$to->setNameAddresses(array(
'person@example.org' => 'Person',
'thing@example.org'
));
// Using the setFieldBodyModel() just delegates to the correct method
// So here to calls setNameAddresses()
$to->setFieldBodyModel(array(
'person@example.org' => 'Person',
'thing@example.org'
));

View file

@ -0,0 +1,44 @@
Getting Help
============
There are a number of ways you can get help when using Swift Mailer, depending
upon the nature of your problem. For bug reports and feature requests create a
new ticket in GitHub. For general advice ask on the Google Group
(swiftmailer).
Submitting Bugs & Feature Requests
----------------------------------
Bugs and feature requests should be posted on GitHub.
If you post a bug or request a feature in the forum, or on the Google Group
you will most likely be asked to create a ticket in `GitHub`_ since it is
simply not feasible to manage such requests from a number of a different
sources.
When you go to GitHub you will be asked to create a username and password
before you can create a ticket. This is free and takes very little time.
When you create your ticket, do not assign it to any milestones. A developer
will assess your ticket and re-assign it as needed.
If your ticket is reporting a bug present in the current version, which was
not present in the previous version please include the tag "regression" in
your ticket.
GitHub will update you when work is performed on your ticket.
Ask on the Google Group
-----------------------
You can seek advice at Google Groups, within the "swiftmailer" `group`_.
You can post messages to this group if you want help, or there's something you
wish to discuss with the developers and with other users.
This is probably the fastest way to get help since it is primarily email-based
for most users, though bug reports should not be posted here since they may
not be resolved.
.. _`GitHub`: https://github.com/swiftmailer/swiftmailer/issues
.. _`group`: http://groups.google.com/group/swiftmailer

View file

@ -0,0 +1,46 @@
Including Swift Mailer (Autoloading)
====================================
If you are using Composer, Swift Mailer will be automatically autoloaded.
If not, you can use the built-in autoloader by requiring the
``swift_required.php`` file::
require_once '/path/to/swift-mailer/lib/swift_required.php';
/* rest of code goes here */
If you want to override the default Swift Mailer configuration, call the
``init()`` method on the ``Swift`` class and pass it a valid PHP callable (a
PHP function name, a PHP 5.3 anonymous function, ...)::
require_once '/path/to/swift-mailer/lib/swift_required.php';
function swiftmailer_configurator() {
// configure Swift Mailer
Swift_DependencyContainer::getInstance()->...
Swift_Preferences::getInstance()->...
}
Swift::init('swiftmailer_configurator');
/* rest of code goes here */
The advantage of using the ``init()`` method is that your code will be
executed only if you use Swift Mailer in your script.
.. note::
While Swift Mailer's autoloader is designed to play nicely with other
autoloaders, sometimes you may have a need to avoid using Swift Mailer's
autoloader and use your own instead. Include the ``swift_init.php``
instead of the ``swift_required.php`` if you need to do this. The very
minimum include is the ``swift_init.php`` file since Swift Mailer will not
work without the dependency injection this file sets up:
.. code-block:: php
require_once '/path/to/swift-mailer/lib/swift_init.php';
/* rest of code goes here */

View file

@ -0,0 +1,16 @@
Swiftmailer
===========
.. toctree::
:maxdepth: 2
introduction
overview
installing
help-resources
including-the-files
messages
headers
sending
plugins
japanese

View file

@ -0,0 +1,89 @@
Installing the Library
======================
Installing with Composer
------------------------
The recommended way to install Swiftmailer is via Composer:
.. code-block:: bash
$ php composer.phar require swiftmailer/swiftmailer @stable
Installing from Git
-------------------
It's possible to download and install Swift Mailer directly from github.com if
you want to keep up-to-date with ease.
Swift Mailer's source code is kept in a git repository at github.com so you
can get the source directly from the repository.
.. note::
You do not need to have git installed to use Swift Mailer from GitHub. If
you don't have git installed, go to `GitHub`_ and click the "Download"
button.
Cloning the Repository
~~~~~~~~~~~~~~~~~~~~~~
The repository can be cloned from git://github.com/swiftmailer/swiftmailer.git
using the ``git clone`` command.
You will need to have ``git`` installed before you can use the
``git clone`` command.
To clone the repository:
* Open your favorite terminal environment (command line).
* Move to the directory you want to clone to.
* Run the command ``git clone git://github.com/swiftmailer/swiftmailer.git
swiftmailer``.
The source code will be downloaded into a directory called "swiftmailer".
The example shows the process on a UNIX-like system such as Linux, BSD or Mac
OS X.
.. code-block:: bash
$ cd source_code/
$ git clone git://github.com/swiftmailer/swiftmailer.git swiftmailer
Initialized empty Git repository in /Users/chris/source_code/swiftmailer/.git/
remote: Counting objects: 6815, done.
remote: Compressing objects: 100% (2761/2761), done.
remote: Total 6815 (delta 3641), reused 6326 (delta 3286)
Receiving objects: 100% (6815/6815), 4.35 MiB | 162 KiB/s, done.
Resolving deltas: 100% (3641/3641), done.
Checking out files: 100% (1847/1847), done.
$ cd swiftmailer/
$ ls
CHANGES LICENSE ...
$
Troubleshooting
---------------
Swift Mailer does not work when used with function overloading as implemented
by ``mbstring`` (``mbstring.func_overload`` set to ``2``). A workaround is to
temporarily change the internal encoding to ``ASCII`` when sending an email:
.. code-block:: php
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
{
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}
// Create your message and send it with Swift Mailer
if (isset($mbEncoding))
{
mb_internal_encoding($mbEncoding);
}
.. _`GitHub`: http://github.com/swiftmailer/swiftmailer

Some files were not shown because too many files have changed in this diff Show more