<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[52328] trunk: HTTP API: Revert changeset [52244].</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/52328">52328</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/52328","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-12-06 21:29:00 +0000 (Mon, 06 Dec 2021)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>HTTP API: Revert changeset <a href="https://core.trac.wordpress.org/changeset/52244">[52244]</a>.
Reverting Requests 2.0.0 changes and moving to WordPress 6.0 cycle. Why? The namespace and file case renaming revealed 2 issues in Core's upgrader process.
See https://core.trac.wordpress.org/ticket/54504#comment:22 for more information.
Follow-up to <a href="https://core.trac.wordpress.org/changeset/52327">[52327]</a>.
See <a href="https://core.trac.wordpress.org/ticket/54562">#54562</a>, <a href="https://core.trac.wordpress.org/ticket/54504">#54504</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesRequestsAuthBasicphp">trunk/src/wp-includes/Requests/Auth/Basic.php</a></li>
<li><a href="#trunksrcwpincludesRequestsAuthphp">trunk/src/wp-includes/Requests/Auth.php</a></li>
<li><a href="#trunksrcwpincludesRequestsCookieJarphp">trunk/src/wp-includes/Requests/Cookie/Jar.php</a></li>
<li><a href="#trunksrcwpincludesRequestsCookiephp">trunk/src/wp-includes/Requests/Cookie.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionTransportphp">trunk/src/wp-includes/Requests/Exception/Transport.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionphp">trunk/src/wp-includes/Requests/Exception.php</a></li>
<li><a href="#trunksrcwpincludesRequestsHooksphp">trunk/src/wp-includes/Requests/Hooks.php</a></li>
<li><a href="#trunksrcwpincludesRequestsProxyphp">trunk/src/wp-includes/Requests/Proxy.php</a></li>
<li><a href="#trunksrcwpincludesRequestsResponseHeadersphp">trunk/src/wp-includes/Requests/Response/Headers.php</a></li>
<li><a href="#trunksrcwpincludesRequestsResponsephp">trunk/src/wp-includes/Requests/Response.php</a></li>
<li><a href="#trunksrcwpincludesRequestsSessionphp">trunk/src/wp-includes/Requests/Session.php</a></li>
<li><a href="#trunksrcwpincludesRequestsTransportphp">trunk/src/wp-includes/Requests/Transport.php</a></li>
<li><a href="#trunksrcwpincludesRequestsUtilityCaseInsensitiveDictionaryphp">trunk/src/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php</a></li>
<li><a href="#trunksrcwpincludesRequestsUtilityFilteredIteratorphp">trunk/src/wp-includes/Requests/Utility/FilteredIterator.php</a></li>
<li><a href="#trunksrcwpincludesclassrequestsphp">trunk/src/wp-includes/class-requests.php</a></li>
<li><a href="#trunksrcwpincludesclasswphttprequestshooksphp">trunk/src/wp-includes/class-wp-http-requests-hooks.php</a></li>
<li><a href="#trunksrcwpincludesclasswphttprequestsresponsephp">trunk/src/wp-includes/class-wp-http-requests-response.php</a></li>
<li><a href="#trunksrcwpincludesclasswphttpphp">trunk/src/wp-includes/class-wp-http.php</a></li>
<li><a href="#trunksrcwpincludeshttpphp">trunk/src/wp-includes/http.php</a></li>
<li><a href="#trunksrcwpincludesrestapiphp">trunk/src/wp-includes/rest-api.php</a></li>
<li><a href="#trunktestsphpunittestsfeedwpSimplePieFilephp">trunk/tests/phpunit/tests/feed/wpSimplePieFile.php</a></li>
<li><a href="#trunktestsphpunittestsfunctionsphp">trunk/tests/phpunit/tests/functions.php</a></li>
<li><a href="#trunktestsphpunittestshttpfunctionsphp">trunk/tests/phpunit/tests/http/functions.php</a></li>
<li><a href="#trunktestsphpunittestshttphttpphp">trunk/tests/phpunit/tests/http/http.php</a></li>
<li><a href="#trunktestsphpunittestsrestapirestwidgetscontrollerphp">trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetRssphp">trunk/tests/phpunit/tests/widgets/wpWidgetRss.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>trunk/src/wp-includes/Requests/Exception/HTTP/</li>
<li><a href="#trunksrcwpincludesRequestsExceptionHTTPphp">trunk/src/wp-includes/Requests/Exception/HTTP.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionTransportcURLphp">trunk/src/wp-includes/Requests/Exception/Transport/cURL.php</a></li>
<li><a href="#trunksrcwpincludesRequestsHookerphp">trunk/src/wp-includes/Requests/Hooker.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIDNAEncoderphp">trunk/src/wp-includes/Requests/IDNAEncoder.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIPv6php">trunk/src/wp-includes/Requests/IPv6.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIRIphp">trunk/src/wp-includes/Requests/IRI.php</a></li>
<li><a href="#trunksrcwpincludesRequestsProxyHTTPphp">trunk/src/wp-includes/Requests/Proxy/HTTP.php</a></li>
<li><a href="#trunksrcwpincludesRequestsSSLphp">trunk/src/wp-includes/Requests/SSL.php</a></li>
<li><a href="#trunksrcwpincludesRequestsTransportcURLphp">trunk/src/wp-includes/Requests/Transport/cURL.php</a></li>
<li><a href="#trunksrcwpincludesRequestsTransportfsockopenphp">trunk/src/wp-includes/Requests/Transport/fsockopen.php</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesRequestsAutoloadphp">trunk/src/wp-includes/Requests/Autoload.php</a></li>
<li><a href="#trunksrcwpincludesRequestsCapabilityphp">trunk/src/wp-includes/Requests/Capability.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionArgumentCountphp">trunk/src/wp-includes/Requests/Exception/ArgumentCount.php</a></li>
<li>trunk/src/wp-includes/Requests/Exception/Http/</li>
<li><a href="#trunksrcwpincludesRequestsExceptionHttpphp">trunk/src/wp-includes/Requests/Exception/Http.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionInvalidArgumentphp">trunk/src/wp-includes/Requests/Exception/InvalidArgument.php</a></li>
<li><a href="#trunksrcwpincludesRequestsExceptionTransportCurlphp">trunk/src/wp-includes/Requests/Exception/Transport/Curl.php</a></li>
<li><a href="#trunksrcwpincludesRequestsHookManagerphp">trunk/src/wp-includes/Requests/HookManager.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIdnaEncoderphp">trunk/src/wp-includes/Requests/IdnaEncoder.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIpv6php">trunk/src/wp-includes/Requests/Ipv6.php</a></li>
<li><a href="#trunksrcwpincludesRequestsIriphp">trunk/src/wp-includes/Requests/Iri.php</a></li>
<li><a href="#trunksrcwpincludesRequestsPortphp">trunk/src/wp-includes/Requests/Port.php</a></li>
<li><a href="#trunksrcwpincludesRequestsProxyHttpphp">trunk/src/wp-includes/Requests/Proxy/Http.php</a></li>
<li><a href="#trunksrcwpincludesRequestsRequestsphp">trunk/src/wp-includes/Requests/Requests.php</a></li>
<li><a href="#trunksrcwpincludesRequestsSslphp">trunk/src/wp-includes/Requests/Ssl.php</a></li>
<li><a href="#trunksrcwpincludesRequestsTransportCurlphp">trunk/src/wp-includes/Requests/Transport/Curl.php</a></li>
<li><a href="#trunksrcwpincludesRequestsTransportFsockopenphp">trunk/src/wp-includes/Requests/Transport/Fsockopen.php</a></li>
<li><a href="#trunksrcwpincludesRequestsUtilityInputValidatorphp">trunk/src/wp-includes/Requests/Utility/InputValidator.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesRequestsAuthBasicphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Auth/Basic.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Auth/Basic.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Auth/Basic.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,16 +2,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Basic Authentication provider
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Auth;
-
-use WpOrg\Requests\Auth;
-use WpOrg\Requests\Exception\ArgumentCount;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Hooks;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Basic Authentication provider
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -18,9 +12,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Provides a handler for Basic HTTP authentication via the Authorization
</span><span class="cx" style="display: block; padding: 0 10px"> * header.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Basic implements Auth {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Auth_Basic implements Requests_Auth {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Username
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -38,45 +33,35 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Constructor
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @since 2.0 Throws an `InvalidArgument` exception.
- * @since 2.0 Throws an `ArgumentCount` exception instead of the Requests base `Exception.
- *
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param array|null $args Array of user and password. Must have exactly two elements
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array or null.
- * @throws \WpOrg\Requests\Exception\ArgumentCount On incorrect number of array elements (`authbasicbadargs`).
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function __construct($args = null) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_array($args)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($args) !== 2) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw ArgumentCount::create('an array with exactly two elements', count($args), 'authbasicbadargs');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Requests_Exception('Invalid number of arguments', 'authbasicbadargs');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> list($this->user, $this->pass) = $args;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return;
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- if ($args !== null) {
- throw InvalidArgument::create(1, '$args', 'array|null', gettype($args));
- }
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Register the necessary callbacks
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Auth\Basic::curl_before_send()
- * @see \WpOrg\Requests\Auth\Basic::fsockopen_header()
- * @param \WpOrg\Requests\Hooks $hooks Hook system
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see curl_before_send
+ * @see fsockopen_header
+ * @param Requests_Hooks $hooks Hook system
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function register(Hooks $hooks) {
- $hooks->register('curl.before_send', [$this, 'curl_before_send']);
- $hooks->register('fsockopen.after_headers', [$this, 'fsockopen_header']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function register(Requests_Hooks $hooks) {
+ $hooks->register('curl.before_send', array($this, 'curl_before_send'));
+ $hooks->register('fsockopen.after_headers', array($this, 'fsockopen_header'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Set cURL parameters before the data is sent
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param resource|\CurlHandle $handle cURL handle
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param resource $handle cURL resource
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function curl_before_send(&$handle) {
</span><span class="cx" style="display: block; padding: 0 10px"> curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsAuthphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Auth.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Auth.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Auth.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,13 +2,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Authentication provider interface
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Hooks;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Authentication provider interface
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -17,20 +14,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Parameters should be passed via the constructor where possible, as this
</span><span class="cx" style="display: block; padding: 0 10px"> * makes it much easier for users to use your provider.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Hooks
- *
- * @package Requests\Authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests_Hooks
+ * @package Requests
+ * @subpackage Authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-interface Auth {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+interface Requests_Auth {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Register hooks as needed
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * This method is called in {@see \WpOrg\Requests\Requests::request()} when the user
- * has set an instance as the 'auth' option. Use this callback to register all the
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * This method is called in {@see Requests::request} when the user has set
+ * an instance as the 'auth' option. Use this callback to register all the
</ins><span class="cx" style="display: block; padding: 0 10px"> * hooks you'll need.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Hooks::register()
- * @param \WpOrg\Requests\Hooks $hooks Hook system
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests_Hooks::register
+ * @param Requests_Hooks $hooks Hook system
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function register(Hooks $hooks);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function register(Requests_Hooks $hooks);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsAutoloadphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Autoload.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Autoload.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Autoload.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,187 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Autoloader for Requests for PHP.
- *
- * Include this file if you'd like to avoid having to create your own autoloader.
- *
- * @package Requests
- * @since 2.0.0
- *
- * @codeCoverageIgnore
- */
-
-namespace WpOrg\Requests;
-
-/*
- * Ensure the autoloader is only declared once.
- * This safeguard is in place as this is the typical entry point for this library
- * and this file being required unconditionally could easily cause
- * fatal "Class already declared" errors.
- */
-if (class_exists('WpOrg\Requests\Autoload') === false) {
-
- /**
- * Autoloader for Requests for PHP.
- *
- * This autoloader supports the PSR-4 based Requests 2.0.0 classes in a case-sensitive manner
- * as the most common server OS-es are case-sensitive and the file names are in mixed case.
- *
- * For the PSR-0 Requests 1.x BC-layer, requested classes will be treated case-insensitively.
- *
- * @package Requests
- */
- final class Autoload {
-
- /**
- * List of the old PSR-0 class names in lowercase as keys with their PSR-4 case-sensitive name as a value.
- *
- * @var array
- */
- private static $deprecated_classes = [
- // Interfaces.
- 'requests_auth' => '\WpOrg\Requests\Auth',
- 'requests_hooker' => '\WpOrg\Requests\HookManager',
- 'requests_proxy' => '\WpOrg\Requests\Proxy',
- 'requests_transport' => '\WpOrg\Requests\Transport',
-
- // Classes.
- 'requests_cookie' => '\WpOrg\Requests\Cookie',
- 'requests_exception' => '\WpOrg\Requests\Exception',
- 'requests_hooks' => '\WpOrg\Requests\Hooks',
- 'requests_idnaencoder' => '\WpOrg\Requests\IdnaEncoder',
- 'requests_ipv6' => '\WpOrg\Requests\Ipv6',
- 'requests_iri' => '\WpOrg\Requests\Iri',
- 'requests_response' => '\WpOrg\Requests\Response',
- 'requests_session' => '\WpOrg\Requests\Session',
- 'requests_ssl' => '\WpOrg\Requests\Ssl',
- 'requests_auth_basic' => '\WpOrg\Requests\Auth\Basic',
- 'requests_cookie_jar' => '\WpOrg\Requests\Cookie\Jar',
- 'requests_proxy_http' => '\WpOrg\Requests\Proxy\Http',
- 'requests_response_headers' => '\WpOrg\Requests\Response\Headers',
- 'requests_transport_curl' => '\WpOrg\Requests\Transport\Curl',
- 'requests_transport_fsockopen' => '\WpOrg\Requests\Transport\Fsockopen',
- 'requests_utility_caseinsensitivedictionary' => '\WpOrg\Requests\Utility\CaseInsensitiveDictionary',
- 'requests_utility_filterediterator' => '\WpOrg\Requests\Utility\FilteredIterator',
- 'requests_exception_http' => '\WpOrg\Requests\Exception\Http',
- 'requests_exception_transport' => '\WpOrg\Requests\Exception\Transport',
- 'requests_exception_transport_curl' => '\WpOrg\Requests\Exception\Transport\Curl',
- 'requests_exception_http_304' => '\WpOrg\Requests\Exception\Http\Status304',
- 'requests_exception_http_305' => '\WpOrg\Requests\Exception\Http\Status305',
- 'requests_exception_http_306' => '\WpOrg\Requests\Exception\Http\Status306',
- 'requests_exception_http_400' => '\WpOrg\Requests\Exception\Http\Status400',
- 'requests_exception_http_401' => '\WpOrg\Requests\Exception\Http\Status401',
- 'requests_exception_http_402' => '\WpOrg\Requests\Exception\Http\Status402',
- 'requests_exception_http_403' => '\WpOrg\Requests\Exception\Http\Status403',
- 'requests_exception_http_404' => '\WpOrg\Requests\Exception\Http\Status404',
- 'requests_exception_http_405' => '\WpOrg\Requests\Exception\Http\Status405',
- 'requests_exception_http_406' => '\WpOrg\Requests\Exception\Http\Status406',
- 'requests_exception_http_407' => '\WpOrg\Requests\Exception\Http\Status407',
- 'requests_exception_http_408' => '\WpOrg\Requests\Exception\Http\Status408',
- 'requests_exception_http_409' => '\WpOrg\Requests\Exception\Http\Status409',
- 'requests_exception_http_410' => '\WpOrg\Requests\Exception\Http\Status410',
- 'requests_exception_http_411' => '\WpOrg\Requests\Exception\Http\Status411',
- 'requests_exception_http_412' => '\WpOrg\Requests\Exception\Http\Status412',
- 'requests_exception_http_413' => '\WpOrg\Requests\Exception\Http\Status413',
- 'requests_exception_http_414' => '\WpOrg\Requests\Exception\Http\Status414',
- 'requests_exception_http_415' => '\WpOrg\Requests\Exception\Http\Status415',
- 'requests_exception_http_416' => '\WpOrg\Requests\Exception\Http\Status416',
- 'requests_exception_http_417' => '\WpOrg\Requests\Exception\Http\Status417',
- 'requests_exception_http_418' => '\WpOrg\Requests\Exception\Http\Status418',
- 'requests_exception_http_428' => '\WpOrg\Requests\Exception\Http\Status428',
- 'requests_exception_http_429' => '\WpOrg\Requests\Exception\Http\Status429',
- 'requests_exception_http_431' => '\WpOrg\Requests\Exception\Http\Status431',
- 'requests_exception_http_500' => '\WpOrg\Requests\Exception\Http\Status500',
- 'requests_exception_http_501' => '\WpOrg\Requests\Exception\Http\Status501',
- 'requests_exception_http_502' => '\WpOrg\Requests\Exception\Http\Status502',
- 'requests_exception_http_503' => '\WpOrg\Requests\Exception\Http\Status503',
- 'requests_exception_http_504' => '\WpOrg\Requests\Exception\Http\Status504',
- 'requests_exception_http_505' => '\WpOrg\Requests\Exception\Http\Status505',
- 'requests_exception_http_511' => '\WpOrg\Requests\Exception\Http\Status511',
- 'requests_exception_http_unknown' => '\WpOrg\Requests\Exception\Http\StatusUnknown',
- ];
-
- /**
- * Register the autoloader.
- *
- * Note: the autoloader is *prepended* in the autoload queue.
- * This is done to ensure that the Requests 2.0 autoloader takes precedence
- * over a potentially (dependency-registered) Requests 1.x autoloader.
- *
- * @internal This method contains a safeguard against the autoloader being
- * registered multiple times. This safeguard uses a global constant to
- * (hopefully/in most cases) still function correctly, even if the
- * class would be renamed.
- *
- * @return void
- */
- public static function register() {
- if (defined('REQUESTS_AUTOLOAD_REGISTERED') === false) {
- spl_autoload_register([self::class, 'load'], true);
- define('REQUESTS_AUTOLOAD_REGISTERED', true);
- }
- }
-
- /**
- * Autoloader.
- *
- * @param string $class_name Name of the class name to load.
- *
- * @return bool Whether a class was loaded or not.
- */
- public static function load($class_name) {
- // Check that the class starts with "Requests" (PSR-0) or "WpOrg\Requests" (PSR-4).
- $psr_4_prefix_pos = strpos($class_name, 'WpOrg\\Requests\\');
-
- if (stripos($class_name, 'Requests') !== 0 && $psr_4_prefix_pos !== 0) {
- return false;
- }
-
- $class_lower = strtolower($class_name);
-
- if ($class_lower === 'requests') {
- // Reference to the original PSR-0 Requests class.
- $file = dirname(__DIR__) . '/library/Requests.php';
- } elseif ($psr_4_prefix_pos === 0) {
- // PSR-4 classname.
- $file = __DIR__ . '/' . strtr(substr($class_name, 15), '\\', '/') . '.php';
- }
-
- if (isset($file) && file_exists($file)) {
- include $file;
- return true;
- }
-
- /*
- * Okay, so the class starts with "Requests", but we couldn't find the file.
- * If this is one of the deprecated/renamed PSR-0 classes being requested,
- * let's alias it to the new name and throw a deprecation notice.
- */
- if (isset(self::$deprecated_classes[$class_lower])) {
- /*
- * Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
- * by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
- * The constant needs to be defined before the first deprecated class is requested
- * via this autoloader.
- */
- if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- trigger_error(
- 'The PSR-0 `Requests_...` class names in the Request library are deprecated.'
- . ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.',
- E_USER_DEPRECATED
- );
-
- // Prevent the deprecation notice from being thrown twice.
- if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
- define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
- }
- }
-
- // Create an alias and let the autoloader recursively kick in to load the PSR-4 class.
- return class_alias(self::$deprecated_classes[$class_lower], $class_name, true);
- }
-
- return false;
- }
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsCapabilityphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Capability.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Capability.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Capability.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,36 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Capability interface declaring the known capabilities.
- *
- * @package Requests\Utilities
- */
-
-namespace WpOrg\Requests;
-
-/**
- * Capability interface declaring the known capabilities.
- *
- * This is used as the authoritative source for which capabilities can be queried.
- *
- * @package Requests\Utilities
- */
-interface Capability {
-
- /**
- * Support for SSL.
- *
- * @var string
- */
- const SSL = 'ssl';
-
- /**
- * Collection of all capabilities supported in Requests.
- *
- * Note: this does not automatically mean that the capability will be supported for your chosen transport!
- *
- * @var array<string>
- */
- const ALL = [
- self::SSL,
- ];
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsCookieJarphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Cookie/Jar.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Cookie/Jar.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Cookie/Jar.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,123 +2,112 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie holder object
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Cookies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Cookies
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Cookie;
-
-use ArrayAccess;
-use ArrayIterator;
-use IteratorAggregate;
-use ReturnTypeWillChange;
-use WpOrg\Requests\Cookie;
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\HookManager;
-use WpOrg\Requests\Iri;
-use WpOrg\Requests\Response;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie holder object
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Cookies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Cookies
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Jar implements ArrayAccess, IteratorAggregate {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Actual item data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- protected $cookies = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected $cookies = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Create a new jar
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $cookies Existing cookie values
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct($cookies = []) {
- if (is_array($cookies) === false) {
- throw InvalidArgument::create(1, '$cookies', 'array', gettype($cookies));
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct($cookies = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->cookies = $cookies;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Normalise cookie data into a \WpOrg\Requests\Cookie
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Normalise cookie data into a Requests_Cookie
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string|\WpOrg\Requests\Cookie $cookie
- * @return \WpOrg\Requests\Cookie
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string|Requests_Cookie $cookie
+ * @return Requests_Cookie
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function normalize_cookie($cookie, $key = '') {
- if ($cookie instanceof Cookie) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function normalize_cookie($cookie, $key = null) {
+ if ($cookie instanceof Requests_Cookie) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $cookie;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return Cookie::parse($cookie, $key);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return Requests_Cookie::parse($cookie, $key);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Normalise cookie data into a Requests_Cookie
+ *
+ * @codeCoverageIgnore
+ * @deprecated Use {@see Requests_Cookie_Jar::normalize_cookie}
+ * @return Requests_Cookie
+ */
+ public function normalizeCookie($cookie, $key = null) {
+ return $this->normalize_cookie($cookie, $key);
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Check if the given item exists
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item key
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Item key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return boolean Does the item exist?
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetExists($offset) {
- return isset($this->cookies[$offset]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetExists($key) {
+ return isset($this->cookies[$key]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get the value for the item
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item key
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Item key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return string|null Item value (null if offsetExists is false)
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetGet($offset) {
- if (!isset($this->cookies[$offset])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetGet($key) {
+ if (!isset($this->cookies[$key])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->cookies[$offset];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $this->cookies[$key];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Set the given item
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
+ *
+ * @param string $key Item name
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $value Item value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetSet($offset, $value) {
- if ($offset === null) {
- throw new Exception('Object is a dictionary, not a list', 'invalidset');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetSet($key, $value) {
+ if ($key === null) {
+ throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->cookies[$offset] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->cookies[$key] = $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Unset the given header
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetUnset($offset) {
- unset($this->cookies[$offset]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetUnset($key) {
+ unset($this->cookies[$key]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get an iterator for the data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return \ArrayIterator
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return ArrayIterator
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
</del><span class="cx" style="display: block; padding: 0 10px"> public function getIterator() {
</span><span class="cx" style="display: block; padding: 0 10px"> return new ArrayIterator($this->cookies);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -126,11 +115,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Register the cookie handler with the request's hooking system
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param \WpOrg\Requests\HookManager $hooks Hooking system
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param Requests_Hooker $hooks Hooking system
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function register(HookManager $hooks) {
- $hooks->register('requests.before_request', [$this, 'before_request']);
- $hooks->register('requests.before_redirect_check', [$this, 'before_redirect_check']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function register(Requests_Hooker $hooks) {
+ $hooks->register('requests.before_request', array($this, 'before_request'));
+ $hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -145,12 +134,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $options
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function before_request($url, &$headers, &$data, &$type, &$options) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!$url instanceof Iri) {
- $url = new Iri($url);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!$url instanceof Requests_IRI) {
+ $url = new Requests_IRI($url);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($this->cookies)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookies = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookies = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->cookies as $key => $cookie) {
</span><span class="cx" style="display: block; padding: 0 10px"> $cookie = $this->normalize_cookie($cookie, $key);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -171,16 +160,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Parse all cookies from a response and attach them to the response
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param \WpOrg\Requests\Response $response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var Requests_Response $response
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function before_redirect_check(Response $response) {
- $url = $response->url;
- if (!$url instanceof Iri) {
- $url = new Iri($url);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function before_redirect_check(Requests_Response $return) {
+ $url = $return->url;
+ if (!$url instanceof Requests_IRI) {
+ $url = new Requests_IRI($url);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookies = Cookie::parse_from_headers($response->headers, $url);
- $this->cookies = array_merge($this->cookies, $cookies);
- $response->cookies = $this;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookies = Requests_Cookie::parse_from_headers($return->headers, $url);
+ $this->cookies = array_merge($this->cookies, $cookies);
+ $return->cookies = $this;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsCookiephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Cookie.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Cookie.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Cookie.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,23 +2,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie storage object
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Cookies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Cookies
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Iri;
-use WpOrg\Requests\Response\Headers;
-use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
-use WpOrg\Requests\Utility\InputValidator;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie storage object
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Cookies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Cookies
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Cookie {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Cookie {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie name.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -39,9 +33,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Valid keys are (currently) path, domain, expires, max-age, secure and
</span><span class="cx" style="display: block; padding: 0 10px"> * httponly.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var \WpOrg\Requests\Utility\CaseInsensitiveDictionary|array Array-like object
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var Requests_Utility_CaseInsensitiveDictionary|array Array-like object
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $attributes = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $attributes = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookie flags
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -51,7 +45,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $flags = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $flags = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Reference time for relative calculations
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -68,46 +62,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $name
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param array|\WpOrg\Requests\Utility\CaseInsensitiveDictionary $attributes Associative array of attribute data
- * @param array $flags
- * @param int|null $reference_time
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $name argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $value argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $attributes argument is not an array or iterable object with array access.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $flags argument is not an array.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $reference_time argument is not an integer or null.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array|Requests_Utility_CaseInsensitiveDictionary $attributes Associative array of attribute data
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct($name, $value, $attributes = [], $flags = [], $reference_time = null) {
- if (is_string($name) === false) {
- throw InvalidArgument::create(1, '$name', 'string', gettype($name));
- }
-
- if (is_string($value) === false) {
- throw InvalidArgument::create(2, '$value', 'string', gettype($value));
- }
-
- if (InputValidator::has_array_access($attributes) === false || InputValidator::is_iterable($attributes) === false) {
- throw InvalidArgument::create(3, '$attributes', 'array|ArrayAccess&Traversable', gettype($attributes));
- }
-
- if (is_array($flags) === false) {
- throw InvalidArgument::create(4, '$flags', 'array', gettype($flags));
- }
-
- if ($reference_time !== null && is_int($reference_time) === false) {
- throw InvalidArgument::create(5, '$reference_time', 'integer|null', gettype($reference_time));
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct($name, $value, $attributes = array(), $flags = array(), $reference_time = null) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->name = $name;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->value = $value;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->attributes = $attributes;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $default_flags = [
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $default_flags = array(
</ins><span class="cx" style="display: block; padding: 0 10px"> 'creation' => time(),
</span><span class="cx" style="display: block; padding: 0 10px"> 'last-access' => time(),
</span><span class="cx" style="display: block; padding: 0 10px"> 'persistent' => false,
</span><span class="cx" style="display: block; padding: 0 10px"> 'host-only' => true,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- ];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ );
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->flags = array_merge($default_flags, $flags);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->reference_time = time();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -119,15 +85,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Get the cookie value
- *
- * Attributes and other data can be accessed via methods.
- */
- public function __toString() {
- return $this->value;
- }
-
- /**
</del><span class="cx" style="display: block; padding: 0 10px"> * Check if a cookie is expired.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Checks the age against $this->reference_time to determine if the cookie
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -156,10 +113,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Check if a cookie is valid for a given URI
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param \WpOrg\Requests\Iri $uri URI to check
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param Requests_IRI $uri URI to check
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return boolean Whether the cookie is valid for the given URI
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function uri_matches(Iri $uri) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function uri_matches(Requests_IRI $uri) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->domain_matches($uri->host)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -174,14 +131,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Check if a cookie is valid for a given domain
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $domain Domain to check
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $string Domain to check
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return boolean Whether the cookie is valid for the given domain
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function domain_matches($domain) {
- if (is_string($domain) === false) {
- return false;
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function domain_matches($string) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!isset($this->attributes['domain'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> // Cookies created manually; cookies created by Requests will set
</span><span class="cx" style="display: block; padding: 0 10px"> // the domain to the requested domain
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -188,9 +141,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookie_domain = $this->attributes['domain'];
- if ($cookie_domain === $domain) {
- // The cookie domain and the passed domain are identical.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $domain_string = $this->attributes['domain'];
+ if ($domain_string === $string) {
+ // The domain string and the string are identical.
</ins><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -200,26 +153,26 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (strlen($domain) <= strlen($cookie_domain)) {
- // For obvious reasons, the cookie domain cannot be a suffix if the passed domain
- // is shorter than the cookie domain
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (strlen($string) <= strlen($domain_string)) {
+ // For obvious reasons, the string cannot be a suffix if the domain
+ // is shorter than the domain string
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (substr($domain, -1 * strlen($cookie_domain)) !== $cookie_domain) {
- // The cookie domain should be a suffix of the passed domain.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (substr($string, -1 * strlen($domain_string)) !== $domain_string) {
+ // The domain string should be a suffix of the string.
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $prefix = substr($domain, 0, strlen($domain) - strlen($cookie_domain));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $prefix = substr($string, 0, strlen($string) - strlen($domain_string));
</ins><span class="cx" style="display: block; padding: 0 10px"> if (substr($prefix, -1) !== '.') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The last character of the passed domain that is not included in the
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // The last character of the string that is not included in the
</ins><span class="cx" style="display: block; padding: 0 10px"> // domain string should be a %x2E (".") character.
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The passed domain should be a host name (i.e., not an IP address).
- return !preg_match('#^(.+\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $domain);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // The string should be a host name (i.e., not an IP address).
+ return !preg_match('#^(.+\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $string);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -242,10 +195,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_scalar($request_path) === false) {
- return false;
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> $cookie_path = $this->attributes['path'];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($cookie_path === $request_path) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -368,6 +317,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Format a cookie for a Cookie header
+ *
+ * @codeCoverageIgnore
+ * @deprecated Use {@see Requests_Cookie::format_for_header}
+ * @return string
+ */
+ public function formatForHeader() {
+ return $this->format_for_header();
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Format a cookie for a Set-Cookie header
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * This is used when sending cookies to clients. This isn't really
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -378,7 +338,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function format_for_set_cookie() {
</span><span class="cx" style="display: block; padding: 0 10px"> $header_value = $this->format_for_header();
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($this->attributes)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $parts = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $parts = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->attributes as $key => $value) {
</span><span class="cx" style="display: block; padding: 0 10px"> // Ignore non-associative attributes
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_numeric($key)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -395,6 +355,26 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Format a cookie for a Set-Cookie header
+ *
+ * @codeCoverageIgnore
+ * @deprecated Use {@see Requests_Cookie::format_for_set_cookie}
+ * @return string
+ */
+ public function formatForSetCookie() {
+ return $this->format_for_set_cookie();
+ }
+
+ /**
+ * Get the cookie value
+ *
+ * Attributes and other data can be accessed via methods.
+ */
+ public function __toString() {
+ return $this->value;
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Parse a cookie string into a cookie object
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Based on Mozilla's parsing code in Firefox and related projects, which
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -401,28 +381,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265
</span><span class="cx" style="display: block; padding: 0 10px"> * specifies some of this handling, but not in a thorough manner.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $cookie_header Cookie header value (from a Set-Cookie header)
- * @param string $name
- * @param int|null $reference_time
- * @return \WpOrg\Requests\Cookie Parsed cookie object
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cookie_header argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $name argument is not a string.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string Cookie header value (from a Set-Cookie header)
+ * @return Requests_Cookie Parsed cookie object
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public static function parse($cookie_header, $name = '', $reference_time = null) {
- if (is_string($cookie_header) === false) {
- throw InvalidArgument::create(1, '$cookie_header', 'string', gettype($cookie_header));
- }
-
- if (is_string($name) === false) {
- throw InvalidArgument::create(2, '$name', 'string', gettype($name));
- }
-
- $parts = explode(';', $cookie_header);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function parse($string, $name = '', $reference_time = null) {
+ $parts = explode(';', $string);
</ins><span class="cx" style="display: block; padding: 0 10px"> $kvparts = array_shift($parts);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($name)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $value = $cookie_header;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $value = $string;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> elseif (strpos($kvparts, '=') === false) {
</span><span class="cx" style="display: block; padding: 0 10px"> // Some sites might only have a value without the equals separator.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -439,8 +406,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $name = trim($name);
</span><span class="cx" style="display: block; padding: 0 10px"> $value = trim($value);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Attribute keys are handled case-insensitively
- $attributes = new CaseInsensitiveDictionary();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Attribute key are handled case-insensitively
+ $attributes = new Requests_Utility_CaseInsensitiveDictionary();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($parts)) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($parts as $part) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -458,24 +425,24 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return new static($name, $value, $attributes, [], $reference_time);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return new Requests_Cookie($name, $value, $attributes, array(), $reference_time);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Parse all Set-Cookie headers from request headers
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param \WpOrg\Requests\Response\Headers $headers Headers to parse from
- * @param \WpOrg\Requests\Iri|null $origin URI for comparing cookie origins
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param Requests_Response_Headers $headers Headers to parse from
+ * @param Requests_IRI|null $origin URI for comparing cookie origins
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param int|null $time Reference time for expiration calculation
</span><span class="cx" style="display: block; padding: 0 10px"> * @return array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public static function parse_from_headers(Headers $headers, Iri $origin = null, $time = null) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function parse_from_headers(Requests_Response_Headers $headers, Requests_IRI $origin = null, $time = null) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $cookie_headers = $headers->getValues('Set-Cookie');
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($cookie_headers)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookies = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookies = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($cookie_headers as $header) {
</span><span class="cx" style="display: block; padding: 0 10px"> $parsed = self::parse($header, '', $time);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -524,4 +491,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return $cookies;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /**
+ * Parse all Set-Cookie headers from request headers
+ *
+ * @codeCoverageIgnore
+ * @deprecated Use {@see Requests_Cookie::parse_from_headers}
+ * @return array
+ */
+ public static function parseFromHeaders(Requests_Response_Headers $headers) {
+ return self::parse_from_headers($headers);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionArgumentCountphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Exception/ArgumentCount.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/ArgumentCount.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception/ArgumentCount.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,47 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-namespace WpOrg\Requests\Exception;
-
-use WpOrg\Requests\Exception;
-
-/**
- * Exception for when an incorrect number of arguments are passed to a method.
- *
- * Typically, this exception is used when all arguments for a method are optional,
- * but certain arguments need to be passed together, i.e. a method which can be called
- * with no arguments or with two arguments, but not with one argument.
- *
- * Along the same lines, this exception is also used if a method expects an array
- * with a certain number of elements and the provided number of elements does not comply.
- *
- * @package Requests\Exceptions
- * @since 2.0.0
- */
-final class ArgumentCount extends Exception {
-
- /**
- * Create a new argument count exception with a standardized text.
- *
- * @param string $expected The argument count expected as a phrase.
- * For example: `at least 2 arguments` or `exactly 1 argument`.
- * @param int $received The actual argument count received.
- * @param string $type Exception type.
- *
- * @return \WpOrg\Requests\Exception\ArgumentCount
- */
- public static function create($expected, $received, $type) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
- $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
-
- return new self(
- sprintf(
- '%s::%s() expects %s, %d given',
- $stack[1]['class'],
- $stack[1]['function'],
- $expected,
- $received
- ),
- $type
- );
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionHTTPphpfromrev52243trunksrcwpincludesRequestsExceptionHTTPphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Exception/HTTP.php (from rev 52243, trunk/src/wp-includes/Requests/Exception/HTTP.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/HTTP.php (rev 0)
+++ trunk/src/wp-includes/Requests/Exception/HTTP.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,71 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Exception based on HTTP response
+ *
+ * @package Requests
+ */
+
+/**
+ * Exception based on HTTP response
+ *
+ * @package Requests
+ */
+class Requests_Exception_HTTP extends Requests_Exception {
+ /**
+ * HTTP status code
+ *
+ * @var integer
+ */
+ protected $code = 0;
+
+ /**
+ * Reason phrase
+ *
+ * @var string
+ */
+ protected $reason = 'Unknown';
+
+ /**
+ * Create a new exception
+ *
+ * There is no mechanism to pass in the status code, as this is set by the
+ * subclass used. Reason phrases can vary, however.
+ *
+ * @param string|null $reason Reason phrase
+ * @param mixed $data Associated data
+ */
+ public function __construct($reason = null, $data = null) {
+ if ($reason !== null) {
+ $this->reason = $reason;
+ }
+
+ $message = sprintf('%d %s', $this->code, $this->reason);
+ parent::__construct($message, 'httpresponse', $data, $this->code);
+ }
+
+ /**
+ * Get the status message
+ */
+ public function getReason() {
+ return $this->reason;
+ }
+
+ /**
+ * Get the correct exception class for a given error code
+ *
+ * @param int|bool $code HTTP status code, or false if unavailable
+ * @return string Exception class name to use
+ */
+ public static function get_class($code) {
+ if (!$code) {
+ return 'Requests_Exception_HTTP_Unknown';
+ }
+
+ $class = sprintf('Requests_Exception_HTTP_%d', $code);
+ if (class_exists($class)) {
+ return $class;
+ }
+
+ return 'Requests_Exception_HTTP_Unknown';
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionHttpphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Exception/Http.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/Http.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception/Http.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,78 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Exception based on HTTP response
- *
- * @package Requests\Exceptions
- */
-
-namespace WpOrg\Requests\Exception;
-
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\Http\StatusUnknown;
-
-/**
- * Exception based on HTTP response
- *
- * @package Requests\Exceptions
- */
-class Http extends Exception {
- /**
- * HTTP status code
- *
- * @var integer
- */
- protected $code = 0;
-
- /**
- * Reason phrase
- *
- * @var string
- */
- protected $reason = 'Unknown';
-
- /**
- * Create a new exception
- *
- * There is no mechanism to pass in the status code, as this is set by the
- * subclass used. Reason phrases can vary, however.
- *
- * @param string|null $reason Reason phrase
- * @param mixed $data Associated data
- */
- public function __construct($reason = null, $data = null) {
- if ($reason !== null) {
- $this->reason = $reason;
- }
-
- $message = sprintf('%d %s', $this->code, $this->reason);
- parent::__construct($message, 'httpresponse', $data, $this->code);
- }
-
- /**
- * Get the status message.
- *
- * @return string
- */
- public function getReason() {
- return $this->reason;
- }
-
- /**
- * Get the correct exception class for a given error code
- *
- * @param int|bool $code HTTP status code, or false if unavailable
- * @return string Exception class name to use
- */
- public static function get_class($code) {
- if (!$code) {
- return StatusUnknown::class;
- }
-
- $class = sprintf('\WpOrg\Requests\Exception\Http\Status%d', $code);
- if (class_exists($class)) {
- return $class;
- }
-
- return StatusUnknown::class;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionInvalidArgumentphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Exception/InvalidArgument.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/InvalidArgument.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception/InvalidArgument.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,41 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-namespace WpOrg\Requests\Exception;
-
-use InvalidArgumentException;
-
-/**
- * Exception for an invalid argument passed.
- *
- * @package Requests\Exceptions
- * @since 2.0.0
- */
-final class InvalidArgument extends InvalidArgumentException {
-
- /**
- * Create a new invalid argument exception with a standardized text.
- *
- * @param int $position The argument position in the function signature. 1-based.
- * @param string $name The argument name in the function signature.
- * @param string $expected The argument type expected as a string.
- * @param string $received The actual argument type received.
- *
- * @return \WpOrg\Requests\Exception\InvalidArgument
- */
- public static function create($position, $name, $expected, $received) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
- $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
-
- return new self(
- sprintf(
- '%s::%s(): Argument #%d (%s) must be of type %s, %s given',
- $stack[1]['class'],
- $stack[1]['function'],
- $position,
- $name,
- $expected,
- $received
- )
- );
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionTransportCurlphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Exception/Transport/Curl.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/Transport/Curl.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception/Transport/Curl.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,80 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * CURL Transport Exception.
- *
- * @package Requests\Exceptions
- */
-
-namespace WpOrg\Requests\Exception\Transport;
-
-use WpOrg\Requests\Exception\Transport;
-
-/**
- * CURL Transport Exception.
- *
- * @package Requests\Exceptions
- */
-final class Curl extends Transport {
-
- const EASY = 'cURLEasy';
- const MULTI = 'cURLMulti';
- const SHARE = 'cURLShare';
-
- /**
- * cURL error code
- *
- * @var integer
- */
- protected $code = -1;
-
- /**
- * Which type of cURL error
- *
- * EASY|MULTI|SHARE
- *
- * @var string
- */
- protected $type = 'Unknown';
-
- /**
- * Clear text error message
- *
- * @var string
- */
- protected $reason = 'Unknown';
-
- /**
- * Create a new exception.
- *
- * @param string $message Exception message.
- * @param string $type Exception type.
- * @param mixed $data Associated data, if applicable.
- * @param int $code Exception numerical code, if applicable.
- */
- public function __construct($message, $type, $data = null, $code = 0) {
- if ($type !== null) {
- $this->type = $type;
- }
-
- if ($code !== null) {
- $this->code = (int) $code;
- }
-
- if ($message !== null) {
- $this->reason = $message;
- }
-
- $message = sprintf('%d %s', $this->code, $this->reason);
- parent::__construct($message, $this->type, $data, $this->code);
- }
-
- /**
- * Get the error message.
- *
- * @return string
- */
- public function getReason() {
- return $this->reason;
- }
-
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionTransportcURLphpfromrev52243trunksrcwpincludesRequestsExceptionTransportcURLphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Exception/Transport/cURL.php (from rev 52243, trunk/src/wp-includes/Requests/Exception/Transport/cURL.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/Transport/cURL.php (rev 0)
+++ trunk/src/wp-includes/Requests/Exception/Transport/cURL.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,56 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+class Requests_Exception_Transport_cURL extends Requests_Exception_Transport {
+
+ const EASY = 'cURLEasy';
+ const MULTI = 'cURLMulti';
+ const SHARE = 'cURLShare';
+
+ /**
+ * cURL error code
+ *
+ * @var integer
+ */
+ protected $code = -1;
+
+ /**
+ * Which type of cURL error
+ *
+ * EASY|MULTI|SHARE
+ *
+ * @var string
+ */
+ protected $type = 'Unknown';
+
+ /**
+ * Clear text error message
+ *
+ * @var string
+ */
+ protected $reason = 'Unknown';
+
+ public function __construct($message, $type, $data = null, $code = 0) {
+ if ($type !== null) {
+ $this->type = $type;
+ }
+
+ if ($code !== null) {
+ $this->code = $code;
+ }
+
+ if ($message !== null) {
+ $this->reason = $message;
+ }
+
+ $message = sprintf('%d %s', $this->code, $this->reason);
+ parent::__construct($message, $this->type, $data, $this->code);
+ }
+
+ /**
+ * Get the error message
+ */
+ public function getReason() {
+ return $this->reason;
+ }
+
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionTransportphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Exception/Transport.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception/Transport.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception/Transport.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,17 +1,5 @@
</span><span class="cx" style="display: block; padding: 0 10px"> <?php
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Transport Exception
- *
- * @package Requests\Exceptions
- */
</del><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Exception;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Exception_Transport extends Requests_Exception {
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-use WpOrg\Requests\Exception;
-
-/**
- * Transport Exception
- *
- * @package Requests\Exceptions
- */
-class Transport extends Exception {}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsExceptionphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Exception.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Exception.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Exception.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,19 +2,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Exception for HTTP requests
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Exceptions
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use Exception as PHPException;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Exception for HTTP requests
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Exceptions
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Exception extends PHPException {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Exception extends Exception {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Type of exception
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -45,7 +41,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Like {@see \Exception::getCode()}, but a string code.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Like {@see getCode()}, but a string code.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @codeCoverageIgnore
</span><span class="cx" style="display: block; padding: 0 10px"> * @return string
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsHookManagerphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/HookManager.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/HookManager.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/HookManager.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,33 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Event dispatcher
- *
- * @package Requests\EventDispatcher
- */
-
-namespace WpOrg\Requests;
-
-/**
- * Event dispatcher
- *
- * @package Requests\EventDispatcher
- */
-interface HookManager {
- /**
- * Register a callback for a hook
- *
- * @param string $hook Hook name
- * @param callable $callback Function/method to call on event
- * @param int $priority Priority number. <0 is executed earlier, >0 is executed later
- */
- public function register($hook, $callback, $priority = 0);
-
- /**
- * Dispatch a message
- *
- * @param string $hook Hook name
- * @param array $parameters Parameters to pass to callbacks
- * @return boolean Successfulness
- */
- public function dispatch($hook, $parameters = []);
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsHookerphpfromrev52243trunksrcwpincludesRequestsHookerphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Hooker.php (from rev 52243, trunk/src/wp-includes/Requests/Hooker.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Hooker.php (rev 0)
+++ trunk/src/wp-includes/Requests/Hooker.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,33 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Event dispatcher
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+
+/**
+ * Event dispatcher
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+interface Requests_Hooker {
+ /**
+ * Register a callback for a hook
+ *
+ * @param string $hook Hook name
+ * @param callback $callback Function/method to call on event
+ * @param int $priority Priority number. <0 is executed earlier, >0 is executed later
+ */
+ public function register($hook, $callback, $priority = 0);
+
+ /**
+ * Dispatch a message
+ *
+ * @param string $hook Hook name
+ * @param array $parameters Parameters to pass to callbacks
+ * @return boolean Successfulness
+ */
+ public function dispatch($hook, $parameters = array());
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsHooksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Hooks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Hooks.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Hooks.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,59 +2,46 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Handles adding and dispatching events
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\EventDispatcher
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\HookManager;
-use WpOrg\Requests\Utility\InputValidator;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Handles adding and dispatching events
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\EventDispatcher
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Hooks implements HookManager {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Hooks implements Requests_Hooker {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Registered callbacks for each hook
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- protected $hooks = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected $hooks = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Constructor
+ */
+ public function __construct() {
+ // pass
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Register a callback for a hook
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $hook Hook name
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param callable $callback Function/method to call on event
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param callback $callback Function/method to call on event
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param int $priority Priority number. <0 is executed earlier, >0 is executed later
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $hook argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $callback argument is not callable.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $priority argument is not an integer.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function register($hook, $callback, $priority = 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_string($hook) === false) {
- throw InvalidArgument::create(1, '$hook', 'string', gettype($hook));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!isset($this->hooks[$hook])) {
+ $this->hooks[$hook] = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- if (is_callable($callback) === false) {
- throw InvalidArgument::create(2, '$callback', 'callable', gettype($callback));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!isset($this->hooks[$hook][$priority])) {
+ $this->hooks[$hook][$priority] = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (InputValidator::is_numeric_array_key($priority) === false) {
- throw InvalidArgument::create(3, '$priority', 'integer', gettype($priority));
- }
-
- if (!isset($this->hooks[$hook])) {
- $this->hooks[$hook] = [
- $priority => [],
- ];
- } elseif (!isset($this->hooks[$hook][$priority])) {
- $this->hooks[$hook][$priority] = [];
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> $this->hooks[$hook][$priority][] = $callback;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -64,31 +51,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $hook Hook name
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $parameters Parameters to pass to callbacks
</span><span class="cx" style="display: block; padding: 0 10px"> * @return boolean Successfulness
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $hook argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $parameters argument is not an array.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function dispatch($hook, $parameters = []) {
- if (is_string($hook) === false) {
- throw InvalidArgument::create(1, '$hook', 'string', gettype($hook));
- }
-
- // Check strictly against array, as Array* objects don't work in combination with `call_user_func_array()`.
- if (is_array($parameters) === false) {
- throw InvalidArgument::create(2, '$parameters', 'array', gettype($parameters));
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function dispatch($hook, $parameters = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if (empty($this->hooks[$hook])) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!empty($parameters)) {
- // Strip potential keys from the array to prevent them being interpreted as parameter names in PHP 8.0.
- $parameters = array_values($parameters);
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->hooks[$hook] as $priority => $hooked) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($hooked as $callback) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $callback(...$parameters);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ call_user_func_array($callback, $parameters);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsIDNAEncoderphpfromrev52243trunksrcwpincludesRequestsIDNAEncoderphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/IDNAEncoder.php (from rev 52243, trunk/src/wp-includes/Requests/IDNAEncoder.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/IDNAEncoder.php (rev 0)
+++ trunk/src/wp-includes/Requests/IDNAEncoder.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,387 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * IDNA URL encoder
+ *
+ * Note: Not fully compliant, as nameprep does nothing yet.
+ *
+ * @package Requests
+ * @subpackage Utilities
+ * @see https://tools.ietf.org/html/rfc3490 IDNA specification
+ * @see https://tools.ietf.org/html/rfc3492 Punycode/Bootstrap specification
+ */
+class Requests_IDNAEncoder {
+ /**
+ * ACE prefix used for IDNA
+ *
+ * @see https://tools.ietf.org/html/rfc3490#section-5
+ * @var string
+ */
+ const ACE_PREFIX = 'xn--';
+
+ /**#@+
+ * Bootstrap constant for Punycode
+ *
+ * @see https://tools.ietf.org/html/rfc3492#section-5
+ * @var int
+ */
+ const BOOTSTRAP_BASE = 36;
+ const BOOTSTRAP_TMIN = 1;
+ const BOOTSTRAP_TMAX = 26;
+ const BOOTSTRAP_SKEW = 38;
+ const BOOTSTRAP_DAMP = 700;
+ const BOOTSTRAP_INITIAL_BIAS = 72;
+ const BOOTSTRAP_INITIAL_N = 128;
+ /**#@-*/
+
+ /**
+ * Encode a hostname using Punycode
+ *
+ * @param string $string Hostname
+ * @return string Punycode-encoded hostname
+ */
+ public static function encode($string) {
+ $parts = explode('.', $string);
+ foreach ($parts as &$part) {
+ $part = self::to_ascii($part);
+ }
+ return implode('.', $parts);
+ }
+
+ /**
+ * Convert a UTF-8 string to an ASCII string using Punycode
+ *
+ * @throws Requests_Exception Provided string longer than 64 ASCII characters (`idna.provided_too_long`)
+ * @throws Requests_Exception Prepared string longer than 64 ASCII characters (`idna.prepared_too_long`)
+ * @throws Requests_Exception Provided string already begins with xn-- (`idna.provided_is_prefixed`)
+ * @throws Requests_Exception Encoded string longer than 64 ASCII characters (`idna.encoded_too_long`)
+ *
+ * @param string $string ASCII or UTF-8 string (max length 64 characters)
+ * @return string ASCII string
+ */
+ public static function to_ascii($string) {
+ // Step 1: Check if the string is already ASCII
+ if (self::is_ascii($string)) {
+ // Skip to step 7
+ if (strlen($string) < 64) {
+ return $string;
+ }
+
+ throw new Requests_Exception('Provided string is too long', 'idna.provided_too_long', $string);
+ }
+
+ // Step 2: nameprep
+ $string = self::nameprep($string);
+
+ // Step 3: UseSTD3ASCIIRules is false, continue
+ // Step 4: Check if it's ASCII now
+ if (self::is_ascii($string)) {
+ // Skip to step 7
+ if (strlen($string) < 64) {
+ return $string;
+ }
+
+ throw new Requests_Exception('Prepared string is too long', 'idna.prepared_too_long', $string);
+ }
+
+ // Step 5: Check ACE prefix
+ if (strpos($string, self::ACE_PREFIX) === 0) {
+ throw new Requests_Exception('Provided string begins with ACE prefix', 'idna.provided_is_prefixed', $string);
+ }
+
+ // Step 6: Encode with Punycode
+ $string = self::punycode_encode($string);
+
+ // Step 7: Prepend ACE prefix
+ $string = self::ACE_PREFIX . $string;
+
+ // Step 8: Check size
+ if (strlen($string) < 64) {
+ return $string;
+ }
+
+ throw new Requests_Exception('Encoded string is too long', 'idna.encoded_too_long', $string);
+ }
+
+ /**
+ * Check whether a given string contains only ASCII characters
+ *
+ * @internal (Testing found regex was the fastest implementation)
+ *
+ * @param string $string
+ * @return bool Is the string ASCII-only?
+ */
+ protected static function is_ascii($string) {
+ return (preg_match('/(?:[^\x00-\x7F])/', $string) !== 1);
+ }
+
+ /**
+ * Prepare a string for use as an IDNA name
+ *
+ * @todo Implement this based on RFC 3491 and the newer 5891
+ * @param string $string
+ * @return string Prepared string
+ */
+ protected static function nameprep($string) {
+ return $string;
+ }
+
+ /**
+ * Convert a UTF-8 string to a UCS-4 codepoint array
+ *
+ * Based on Requests_IRI::replace_invalid_with_pct_encoding()
+ *
+ * @throws Requests_Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`)
+ * @param string $input
+ * @return array Unicode code points
+ */
+ protected static function utf8_to_codepoints($input) {
+ $codepoints = array();
+
+ // Get number of bytes
+ $strlen = strlen($input);
+
+ // phpcs:ignore Generic.CodeAnalysis.JumbledIncrementer -- This is a deliberate choice.
+ for ($position = 0; $position < $strlen; $position++) {
+ $value = ord($input[$position]);
+
+ // One byte sequence:
+ if ((~$value & 0x80) === 0x80) {
+ $character = $value;
+ $length = 1;
+ $remaining = 0;
+ }
+ // Two byte sequence:
+ elseif (($value & 0xE0) === 0xC0) {
+ $character = ($value & 0x1F) << 6;
+ $length = 2;
+ $remaining = 1;
+ }
+ // Three byte sequence:
+ elseif (($value & 0xF0) === 0xE0) {
+ $character = ($value & 0x0F) << 12;
+ $length = 3;
+ $remaining = 2;
+ }
+ // Four byte sequence:
+ elseif (($value & 0xF8) === 0xF0) {
+ $character = ($value & 0x07) << 18;
+ $length = 4;
+ $remaining = 3;
+ }
+ // Invalid byte:
+ else {
+ throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $value);
+ }
+
+ if ($remaining > 0) {
+ if ($position + $length > $strlen) {
+ throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
+ }
+ for ($position++; $remaining > 0; $position++) {
+ $value = ord($input[$position]);
+
+ // If it is invalid, count the sequence as invalid and reprocess the current byte:
+ if (($value & 0xC0) !== 0x80) {
+ throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
+ }
+
+ --$remaining;
+ $character |= ($value & 0x3F) << ($remaining * 6);
+ }
+ $position--;
+ }
+
+ if (// Non-shortest form sequences are invalid
+ $length > 1 && $character <= 0x7F
+ || $length > 2 && $character <= 0x7FF
+ || $length > 3 && $character <= 0xFFFF
+ // Outside of range of ucschar codepoints
+ // Noncharacters
+ || ($character & 0xFFFE) === 0xFFFE
+ || $character >= 0xFDD0 && $character <= 0xFDEF
+ || (
+ // Everything else not in ucschar
+ $character > 0xD7FF && $character < 0xF900
+ || $character < 0x20
+ || $character > 0x7E && $character < 0xA0
+ || $character > 0xEFFFD
+ )
+ ) {
+ throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
+ }
+
+ $codepoints[] = $character;
+ }
+
+ return $codepoints;
+ }
+
+ /**
+ * RFC3492-compliant encoder
+ *
+ * @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
+ * @throws Requests_Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)
+ *
+ * @param string $input UTF-8 encoded string to encode
+ * @return string Punycode-encoded string
+ */
+ public static function punycode_encode($input) {
+ $output = '';
+ // let n = initial_n
+ $n = self::BOOTSTRAP_INITIAL_N;
+ // let delta = 0
+ $delta = 0;
+ // let bias = initial_bias
+ $bias = self::BOOTSTRAP_INITIAL_BIAS;
+ // let h = b = the number of basic code points in the input
+ $h = 0;
+ $b = 0; // see loop
+ // copy them to the output in order
+ $codepoints = self::utf8_to_codepoints($input);
+ $extended = array();
+
+ foreach ($codepoints as $char) {
+ if ($char < 128) {
+ // Character is valid ASCII
+ // TODO: this should also check if it's valid for a URL
+ $output .= chr($char);
+ $h++;
+ }
+ // Check if the character is non-ASCII, but below initial n
+ // This never occurs for Punycode, so ignore in coverage
+ // @codeCoverageIgnoreStart
+ elseif ($char < $n) {
+ throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char);
+ }
+ // @codeCoverageIgnoreEnd
+ else {
+ $extended[$char] = true;
+ }
+ }
+ $extended = array_keys($extended);
+ sort($extended);
+ $b = $h;
+ // [copy them] followed by a delimiter if b > 0
+ if (strlen($output) > 0) {
+ $output .= '-';
+ }
+ // {if the input contains a non-basic code point < n then fail}
+ // while h < length(input) do begin
+ $codepointcount = count($codepoints);
+ while ($h < $codepointcount) {
+ // let m = the minimum code point >= n in the input
+ $m = array_shift($extended);
+ //printf('next code point to insert is %s' . PHP_EOL, dechex($m));
+ // let delta = delta + (m - n) * (h + 1), fail on overflow
+ $delta += ($m - $n) * ($h + 1);
+ // let n = m
+ $n = $m;
+ // for each code point c in the input (in order) do begin
+ for ($num = 0; $num < $codepointcount; $num++) {
+ $c = $codepoints[$num];
+ // if c < n then increment delta, fail on overflow
+ if ($c < $n) {
+ $delta++;
+ }
+ // if c == n then begin
+ elseif ($c === $n) {
+ // let q = delta
+ $q = $delta;
+ // for k = base to infinity in steps of base do begin
+ for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
+ // let t = tmin if k <= bias {+ tmin}, or
+ // tmax if k >= bias + tmax, or k - bias otherwise
+ if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
+ $t = self::BOOTSTRAP_TMIN;
+ }
+ elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
+ $t = self::BOOTSTRAP_TMAX;
+ }
+ else {
+ $t = $k - $bias;
+ }
+ // if q < t then break
+ if ($q < $t) {
+ break;
+ }
+ // output the code point for digit t + ((q - t) mod (base - t))
+ $digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
+ $output .= self::digit_to_char($digit);
+ // let q = (q - t) div (base - t)
+ $q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
+ } // end
+ // output the code point for digit q
+ $output .= self::digit_to_char($q);
+ // let bias = adapt(delta, h + 1, test h equals b?)
+ $bias = self::adapt($delta, $h + 1, $h === $b);
+ // let delta = 0
+ $delta = 0;
+ // increment h
+ $h++;
+ } // end
+ } // end
+ // increment delta and n
+ $delta++;
+ $n++;
+ } // end
+
+ return $output;
+ }
+
+ /**
+ * Convert a digit to its respective character
+ *
+ * @see https://tools.ietf.org/html/rfc3492#section-5
+ * @throws Requests_Exception On invalid digit (`idna.invalid_digit`)
+ *
+ * @param int $digit Digit in the range 0-35
+ * @return string Single character corresponding to digit
+ */
+ protected static function digit_to_char($digit) {
+ // @codeCoverageIgnoreStart
+ // As far as I know, this never happens, but still good to be sure.
+ if ($digit < 0 || $digit > 35) {
+ throw new Requests_Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit);
+ }
+ // @codeCoverageIgnoreEnd
+ $digits = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ return substr($digits, $digit, 1);
+ }
+
+ /**
+ * Adapt the bias
+ *
+ * @see https://tools.ietf.org/html/rfc3492#section-6.1
+ * @param int $delta
+ * @param int $numpoints
+ * @param bool $firsttime
+ * @return int New bias
+ *
+ * function adapt(delta,numpoints,firsttime):
+ */
+ protected static function adapt($delta, $numpoints, $firsttime) {
+ // if firsttime then let delta = delta div damp
+ if ($firsttime) {
+ $delta = floor($delta / self::BOOTSTRAP_DAMP);
+ }
+ // else let delta = delta div 2
+ else {
+ $delta = floor($delta / 2);
+ }
+ // let delta = delta + (delta div numpoints)
+ $delta += floor($delta / $numpoints);
+ // let k = 0
+ $k = 0;
+ // while delta > ((base - tmin) * tmax) div 2 do begin
+ $max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
+ while ($delta > $max) {
+ // let delta = delta div (base - tmin)
+ $delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
+ // let k = k + base
+ $k += self::BOOTSTRAP_BASE;
+ } // end
+ // return k + (((base - tmin + 1) * delta) div (delta + skew))
+ return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsIPv6phpfromrev52243trunksrcwpincludesRequestsIPv6php"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/IPv6.php (from rev 52243, trunk/src/wp-includes/Requests/IPv6.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/IPv6.php (rev 0)
+++ trunk/src/wp-includes/Requests/IPv6.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,190 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Class to validate and to work with IPv6 addresses
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+
+/**
+ * Class to validate and to work with IPv6 addresses
+ *
+ * This was originally based on the PEAR class of the same name, but has been
+ * entirely rewritten.
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+class Requests_IPv6 {
+ /**
+ * Uncompresses an IPv6 address
+ *
+ * RFC 4291 allows you to compress consecutive zero pieces in an address to
+ * '::'. This method expects a valid IPv6 address and expands the '::' to
+ * the required number of zero pieces.
+ *
+ * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
+ * ::1 -> 0:0:0:0:0:0:0:1
+ *
+ * @author Alexander Merz <alexander.merz@web.de>
+ * @author elfrink at introweb dot nl
+ * @author Josh Peck <jmp at joshpeck dot org>
+ * @copyright 2003-2005 The PHP Group
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @param string $ip An IPv6 address
+ * @return string The uncompressed IPv6 address
+ */
+ public static function uncompress($ip) {
+ if (substr_count($ip, '::') !== 1) {
+ return $ip;
+ }
+
+ list($ip1, $ip2) = explode('::', $ip);
+ $c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
+ $c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
+
+ if (strpos($ip2, '.') !== false) {
+ $c2++;
+ }
+ // ::
+ if ($c1 === -1 && $c2 === -1) {
+ $ip = '0:0:0:0:0:0:0:0';
+ }
+ // ::xxx
+ elseif ($c1 === -1) {
+ $fill = str_repeat('0:', 7 - $c2);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ // xxx::
+ elseif ($c2 === -1) {
+ $fill = str_repeat(':0', 7 - $c1);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ // xxx::xxx
+ else {
+ $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ return $ip;
+ }
+
+ /**
+ * Compresses an IPv6 address
+ *
+ * RFC 4291 allows you to compress consecutive zero pieces in an address to
+ * '::'. This method expects a valid IPv6 address and compresses consecutive
+ * zero pieces to '::'.
+ *
+ * Example: FF01:0:0:0:0:0:0:101 -> FF01::101
+ * 0:0:0:0:0:0:0:1 -> ::1
+ *
+ * @see uncompress()
+ * @param string $ip An IPv6 address
+ * @return string The compressed IPv6 address
+ */
+ public static function compress($ip) {
+ // Prepare the IP to be compressed
+ $ip = self::uncompress($ip);
+ $ip_parts = self::split_v6_v4($ip);
+
+ // Replace all leading zeros
+ $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
+
+ // Find bunches of zeros
+ if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
+ $max = 0;
+ $pos = null;
+ foreach ($matches[0] as $match) {
+ if (strlen($match[0]) > $max) {
+ $max = strlen($match[0]);
+ $pos = $match[1];
+ }
+ }
+
+ $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
+ }
+
+ if ($ip_parts[1] !== '') {
+ return implode(':', $ip_parts);
+ }
+ else {
+ return $ip_parts[0];
+ }
+ }
+
+ /**
+ * Splits an IPv6 address into the IPv6 and IPv4 representation parts
+ *
+ * RFC 4291 allows you to represent the last two parts of an IPv6 address
+ * using the standard IPv4 representation
+ *
+ * Example: 0:0:0:0:0:0:13.1.68.3
+ * 0:0:0:0:0:FFFF:129.144.52.38
+ *
+ * @param string $ip An IPv6 address
+ * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
+ */
+ protected static function split_v6_v4($ip) {
+ if (strpos($ip, '.') !== false) {
+ $pos = strrpos($ip, ':');
+ $ipv6_part = substr($ip, 0, $pos);
+ $ipv4_part = substr($ip, $pos + 1);
+ return array($ipv6_part, $ipv4_part);
+ }
+ else {
+ return array($ip, '');
+ }
+ }
+
+ /**
+ * Checks an IPv6 address
+ *
+ * Checks if the given IP is a valid IPv6 address
+ *
+ * @param string $ip An IPv6 address
+ * @return bool true if $ip is a valid IPv6 address
+ */
+ public static function check_ipv6($ip) {
+ $ip = self::uncompress($ip);
+ list($ipv6, $ipv4) = self::split_v6_v4($ip);
+ $ipv6 = explode(':', $ipv6);
+ $ipv4 = explode('.', $ipv4);
+ if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
+ foreach ($ipv6 as $ipv6_part) {
+ // The section can't be empty
+ if ($ipv6_part === '') {
+ return false;
+ }
+
+ // Nor can it be over four characters
+ if (strlen($ipv6_part) > 4) {
+ return false;
+ }
+
+ // Remove leading zeros (this is safe because of the above)
+ $ipv6_part = ltrim($ipv6_part, '0');
+ if ($ipv6_part === '') {
+ $ipv6_part = '0';
+ }
+
+ // Check the value is valid
+ $value = hexdec($ipv6_part);
+ if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
+ return false;
+ }
+ }
+ if (count($ipv4) === 4) {
+ foreach ($ipv4 as $ipv4_part) {
+ $value = (int) $ipv4_part;
+ if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsIRIphpfromrev52243trunksrcwpincludesRequestsIRIphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/IRI.php (from rev 52243, trunk/src/wp-includes/Requests/IRI.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/IRI.php (rev 0)
+++ trunk/src/wp-includes/Requests/IRI.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,1086 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * IRI parser/serialiser/normaliser
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+
+/**
+ * IRI parser/serialiser/normaliser
+ *
+ * Copyright (c) 2007-2010, Geoffrey Sneddon and Steve Minutillo.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND 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.
+ *
+ * @package Requests
+ * @subpackage Utilities
+ * @author Geoffrey Sneddon
+ * @author Steve Minutillo
+ * @copyright 2007-2009 Geoffrey Sneddon and Steve Minutillo
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @link http://hg.gsnedders.com/iri/
+ *
+ * @property string $iri IRI we're working with
+ * @property-read string $uri IRI in URI form, {@see to_uri}
+ * @property string $scheme Scheme part of the IRI
+ * @property string $authority Authority part, formatted for a URI (userinfo + host + port)
+ * @property string $iauthority Authority part of the IRI (userinfo + host + port)
+ * @property string $userinfo Userinfo part, formatted for a URI (after '://' and before '@')
+ * @property string $iuserinfo Userinfo part of the IRI (after '://' and before '@')
+ * @property string $host Host part, formatted for a URI
+ * @property string $ihost Host part of the IRI
+ * @property string $port Port part of the IRI (after ':')
+ * @property string $path Path part, formatted for a URI (after first '/')
+ * @property string $ipath Path part of the IRI (after first '/')
+ * @property string $query Query part, formatted for a URI (after '?')
+ * @property string $iquery Query part of the IRI (after '?')
+ * @property string $fragment Fragment, formatted for a URI (after '#')
+ * @property string $ifragment Fragment part of the IRI (after '#')
+ */
+class Requests_IRI {
+ /**
+ * Scheme
+ *
+ * @var string|null
+ */
+ protected $scheme = null;
+
+ /**
+ * User Information
+ *
+ * @var string|null
+ */
+ protected $iuserinfo = null;
+
+ /**
+ * ihost
+ *
+ * @var string|null
+ */
+ protected $ihost = null;
+
+ /**
+ * Port
+ *
+ * @var string|null
+ */
+ protected $port = null;
+
+ /**
+ * ipath
+ *
+ * @var string
+ */
+ protected $ipath = '';
+
+ /**
+ * iquery
+ *
+ * @var string|null
+ */
+ protected $iquery = null;
+
+ /**
+ * ifragment|null
+ *
+ * @var string
+ */
+ protected $ifragment = null;
+
+ /**
+ * Normalization database
+ *
+ * Each key is the scheme, each value is an array with each key as the IRI
+ * part and value as the default value for that part.
+ *
+ * @var array
+ */
+ protected $normalization = array(
+ 'acap' => array(
+ 'port' => 674
+ ),
+ 'dict' => array(
+ 'port' => 2628
+ ),
+ 'file' => array(
+ 'ihost' => 'localhost'
+ ),
+ 'http' => array(
+ 'port' => 80,
+ ),
+ 'https' => array(
+ 'port' => 443,
+ ),
+ );
+
+ /**
+ * Return the entire IRI when you try and read the object as a string
+ *
+ * @return string
+ */
+ public function __toString() {
+ return $this->get_iri();
+ }
+
+ /**
+ * Overload __set() to provide access via properties
+ *
+ * @param string $name Property name
+ * @param mixed $value Property value
+ */
+ public function __set($name, $value) {
+ if (method_exists($this, 'set_' . $name)) {
+ call_user_func(array($this, 'set_' . $name), $value);
+ }
+ elseif (
+ $name === 'iauthority'
+ || $name === 'iuserinfo'
+ || $name === 'ihost'
+ || $name === 'ipath'
+ || $name === 'iquery'
+ || $name === 'ifragment'
+ ) {
+ call_user_func(array($this, 'set_' . substr($name, 1)), $value);
+ }
+ }
+
+ /**
+ * Overload __get() to provide access via properties
+ *
+ * @param string $name Property name
+ * @return mixed
+ */
+ public function __get($name) {
+ // isset() returns false for null, we don't want to do that
+ // Also why we use array_key_exists below instead of isset()
+ $props = get_object_vars($this);
+
+ if (
+ $name === 'iri' ||
+ $name === 'uri' ||
+ $name === 'iauthority' ||
+ $name === 'authority'
+ ) {
+ $method = 'get_' . $name;
+ $return = $this->$method();
+ }
+ elseif (array_key_exists($name, $props)) {
+ $return = $this->$name;
+ }
+ // host -> ihost
+ elseif (($prop = 'i' . $name) && array_key_exists($prop, $props)) {
+ $name = $prop;
+ $return = $this->$prop;
+ }
+ // ischeme -> scheme
+ elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props)) {
+ $name = $prop;
+ $return = $this->$prop;
+ }
+ else {
+ trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
+ $return = null;
+ }
+
+ if ($return === null && isset($this->normalization[$this->scheme][$name])) {
+ return $this->normalization[$this->scheme][$name];
+ }
+ else {
+ return $return;
+ }
+ }
+
+ /**
+ * Overload __isset() to provide access via properties
+ *
+ * @param string $name Property name
+ * @return bool
+ */
+ public function __isset($name) {
+ return (method_exists($this, 'get_' . $name) || isset($this->$name));
+ }
+
+ /**
+ * Overload __unset() to provide access via properties
+ *
+ * @param string $name Property name
+ */
+ public function __unset($name) {
+ if (method_exists($this, 'set_' . $name)) {
+ call_user_func(array($this, 'set_' . $name), '');
+ }
+ }
+
+ /**
+ * Create a new IRI object, from a specified string
+ *
+ * @param string|null $iri
+ */
+ public function __construct($iri = null) {
+ $this->set_iri($iri);
+ }
+
+ /**
+ * Create a new IRI object by resolving a relative IRI
+ *
+ * Returns false if $base is not absolute, otherwise an IRI.
+ *
+ * @param Requests_IRI|string $base (Absolute) Base IRI
+ * @param Requests_IRI|string $relative Relative IRI
+ * @return Requests_IRI|false
+ */
+ public static function absolutize($base, $relative) {
+ if (!($relative instanceof Requests_IRI)) {
+ $relative = new Requests_IRI($relative);
+ }
+ if (!$relative->is_valid()) {
+ return false;
+ }
+ elseif ($relative->scheme !== null) {
+ return clone $relative;
+ }
+
+ if (!($base instanceof Requests_IRI)) {
+ $base = new Requests_IRI($base);
+ }
+ if ($base->scheme === null || !$base->is_valid()) {
+ return false;
+ }
+
+ if ($relative->get_iri() !== '') {
+ if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null) {
+ $target = clone $relative;
+ $target->scheme = $base->scheme;
+ }
+ else {
+ $target = new Requests_IRI;
+ $target->scheme = $base->scheme;
+ $target->iuserinfo = $base->iuserinfo;
+ $target->ihost = $base->ihost;
+ $target->port = $base->port;
+ if ($relative->ipath !== '') {
+ if ($relative->ipath[0] === '/') {
+ $target->ipath = $relative->ipath;
+ }
+ elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '') {
+ $target->ipath = '/' . $relative->ipath;
+ }
+ elseif (($last_segment = strrpos($base->ipath, '/')) !== false) {
+ $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
+ }
+ else {
+ $target->ipath = $relative->ipath;
+ }
+ $target->ipath = $target->remove_dot_segments($target->ipath);
+ $target->iquery = $relative->iquery;
+ }
+ else {
+ $target->ipath = $base->ipath;
+ if ($relative->iquery !== null) {
+ $target->iquery = $relative->iquery;
+ }
+ elseif ($base->iquery !== null) {
+ $target->iquery = $base->iquery;
+ }
+ }
+ $target->ifragment = $relative->ifragment;
+ }
+ }
+ else {
+ $target = clone $base;
+ $target->ifragment = null;
+ }
+ $target->scheme_normalization();
+ return $target;
+ }
+
+ /**
+ * Parse an IRI into scheme/authority/path/query/fragment segments
+ *
+ * @param string $iri
+ * @return array
+ */
+ protected function parse_iri($iri) {
+ $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
+ $has_match = preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match);
+ if (!$has_match) {
+ throw new Requests_Exception('Cannot parse supplied IRI', 'iri.cannot_parse', $iri);
+ }
+
+ if ($match[1] === '') {
+ $match['scheme'] = null;
+ }
+ if (!isset($match[3]) || $match[3] === '') {
+ $match['authority'] = null;
+ }
+ if (!isset($match[5])) {
+ $match['path'] = '';
+ }
+ if (!isset($match[6]) || $match[6] === '') {
+ $match['query'] = null;
+ }
+ if (!isset($match[8]) || $match[8] === '') {
+ $match['fragment'] = null;
+ }
+ return $match;
+ }
+
+ /**
+ * Remove dot segments from a path
+ *
+ * @param string $input
+ * @return string
+ */
+ protected function remove_dot_segments($input) {
+ $output = '';
+ while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') {
+ // A: If the input buffer begins with a prefix of "../" or "./",
+ // then remove that prefix from the input buffer; otherwise,
+ if (strpos($input, '../') === 0) {
+ $input = substr($input, 3);
+ }
+ elseif (strpos($input, './') === 0) {
+ $input = substr($input, 2);
+ }
+ // B: if the input buffer begins with a prefix of "/./" or "/.",
+ // where "." is a complete path segment, then replace that prefix
+ // with "/" in the input buffer; otherwise,
+ elseif (strpos($input, '/./') === 0) {
+ $input = substr($input, 2);
+ }
+ elseif ($input === '/.') {
+ $input = '/';
+ }
+ // C: if the input buffer begins with a prefix of "/../" or "/..",
+ // where ".." is a complete path segment, then replace that prefix
+ // with "/" in the input buffer and remove the last segment and its
+ // preceding "/" (if any) from the output buffer; otherwise,
+ elseif (strpos($input, '/../') === 0) {
+ $input = substr($input, 3);
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ elseif ($input === '/..') {
+ $input = '/';
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ // D: if the input buffer consists only of "." or "..", then remove
+ // that from the input buffer; otherwise,
+ elseif ($input === '.' || $input === '..') {
+ $input = '';
+ }
+ // E: move the first path segment in the input buffer to the end of
+ // the output buffer, including the initial "/" character (if any)
+ // and any subsequent characters up to, but not including, the next
+ // "/" character or the end of the input buffer
+ elseif (($pos = strpos($input, '/', 1)) !== false) {
+ $output .= substr($input, 0, $pos);
+ $input = substr_replace($input, '', 0, $pos);
+ }
+ else {
+ $output .= $input;
+ $input = '';
+ }
+ }
+ return $output . $input;
+ }
+
+ /**
+ * Replace invalid character with percent encoding
+ *
+ * @param string $string Input string
+ * @param string $extra_chars Valid characters not in iunreserved or
+ * iprivate (this is ASCII-only)
+ * @param bool $iprivate Allow iprivate
+ * @return string
+ */
+ protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false) {
+ // Normalize as many pct-encoded sections as possible
+ $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $string);
+
+ // Replace invalid percent characters
+ $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
+
+ // Add unreserved and % to $extra_chars (the latter is safe because all
+ // pct-encoded sections are now valid).
+ $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
+
+ // Now replace any bytes that aren't allowed with their pct-encoded versions
+ $position = 0;
+ $strlen = strlen($string);
+ while (($position += strspn($string, $extra_chars, $position)) < $strlen) {
+ $value = ord($string[$position]);
+
+ // Start position
+ $start = $position;
+
+ // By default we are valid
+ $valid = true;
+
+ // No one byte sequences are valid due to the while.
+ // Two byte sequence:
+ if (($value & 0xE0) === 0xC0) {
+ $character = ($value & 0x1F) << 6;
+ $length = 2;
+ $remaining = 1;
+ }
+ // Three byte sequence:
+ elseif (($value & 0xF0) === 0xE0) {
+ $character = ($value & 0x0F) << 12;
+ $length = 3;
+ $remaining = 2;
+ }
+ // Four byte sequence:
+ elseif (($value & 0xF8) === 0xF0) {
+ $character = ($value & 0x07) << 18;
+ $length = 4;
+ $remaining = 3;
+ }
+ // Invalid byte:
+ else {
+ $valid = false;
+ $length = 1;
+ $remaining = 0;
+ }
+
+ if ($remaining) {
+ if ($position + $length <= $strlen) {
+ for ($position++; $remaining; $position++) {
+ $value = ord($string[$position]);
+
+ // Check that the byte is valid, then add it to the character:
+ if (($value & 0xC0) === 0x80) {
+ $character |= ($value & 0x3F) << (--$remaining * 6);
+ }
+ // If it is invalid, count the sequence as invalid and reprocess the current byte:
+ else {
+ $valid = false;
+ $position--;
+ break;
+ }
+ }
+ }
+ else {
+ $position = $strlen - 1;
+ $valid = false;
+ }
+ }
+
+ // Percent encode anything invalid or not in ucschar
+ if (
+ // Invalid sequences
+ !$valid
+ // Non-shortest form sequences are invalid
+ || $length > 1 && $character <= 0x7F
+ || $length > 2 && $character <= 0x7FF
+ || $length > 3 && $character <= 0xFFFF
+ // Outside of range of ucschar codepoints
+ // Noncharacters
+ || ($character & 0xFFFE) === 0xFFFE
+ || $character >= 0xFDD0 && $character <= 0xFDEF
+ || (
+ // Everything else not in ucschar
+ $character > 0xD7FF && $character < 0xF900
+ || $character < 0xA0
+ || $character > 0xEFFFD
+ )
+ && (
+ // Everything not in iprivate, if it applies
+ !$iprivate
+ || $character < 0xE000
+ || $character > 0x10FFFD
+ )
+ ) {
+ // If we were a character, pretend we weren't, but rather an error.
+ if ($valid) {
+ $position--;
+ }
+
+ for ($j = $start; $j <= $position; $j++) {
+ $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
+ $j += 2;
+ $position += 2;
+ $strlen += 2;
+ }
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * Callback function for preg_replace_callback.
+ *
+ * Removes sequences of percent encoded bytes that represent UTF-8
+ * encoded characters in iunreserved
+ *
+ * @param array $match PCRE match
+ * @return string Replacement
+ */
+ protected function remove_iunreserved_percent_encoded($match) {
+ // As we just have valid percent encoded sequences we can just explode
+ // and ignore the first member of the returned array (an empty string).
+ $bytes = explode('%', $match[0]);
+
+ // Initialize the new string (this is what will be returned) and that
+ // there are no bytes remaining in the current sequence (unsurprising
+ // at the first byte!).
+ $string = '';
+ $remaining = 0;
+
+ // Loop over each and every byte, and set $value to its value
+ for ($i = 1, $len = count($bytes); $i < $len; $i++) {
+ $value = hexdec($bytes[$i]);
+
+ // If we're the first byte of sequence:
+ if (!$remaining) {
+ // Start position
+ $start = $i;
+
+ // By default we are valid
+ $valid = true;
+
+ // One byte sequence:
+ if ($value <= 0x7F) {
+ $character = $value;
+ $length = 1;
+ }
+ // Two byte sequence:
+ elseif (($value & 0xE0) === 0xC0) {
+ $character = ($value & 0x1F) << 6;
+ $length = 2;
+ $remaining = 1;
+ }
+ // Three byte sequence:
+ elseif (($value & 0xF0) === 0xE0) {
+ $character = ($value & 0x0F) << 12;
+ $length = 3;
+ $remaining = 2;
+ }
+ // Four byte sequence:
+ elseif (($value & 0xF8) === 0xF0) {
+ $character = ($value & 0x07) << 18;
+ $length = 4;
+ $remaining = 3;
+ }
+ // Invalid byte:
+ else {
+ $valid = false;
+ $remaining = 0;
+ }
+ }
+ // Continuation byte:
+ else {
+ // Check that the byte is valid, then add it to the character:
+ if (($value & 0xC0) === 0x80) {
+ $remaining--;
+ $character |= ($value & 0x3F) << ($remaining * 6);
+ }
+ // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
+ else {
+ $valid = false;
+ $remaining = 0;
+ $i--;
+ }
+ }
+
+ // If we've reached the end of the current byte sequence, append it to Unicode::$data
+ if (!$remaining) {
+ // Percent encode anything invalid or not in iunreserved
+ if (
+ // Invalid sequences
+ !$valid
+ // Non-shortest form sequences are invalid
+ || $length > 1 && $character <= 0x7F
+ || $length > 2 && $character <= 0x7FF
+ || $length > 3 && $character <= 0xFFFF
+ // Outside of range of iunreserved codepoints
+ || $character < 0x2D
+ || $character > 0xEFFFD
+ // Noncharacters
+ || ($character & 0xFFFE) === 0xFFFE
+ || $character >= 0xFDD0 && $character <= 0xFDEF
+ // Everything else not in iunreserved (this is all BMP)
+ || $character === 0x2F
+ || $character > 0x39 && $character < 0x41
+ || $character > 0x5A && $character < 0x61
+ || $character > 0x7A && $character < 0x7E
+ || $character > 0x7E && $character < 0xA0
+ || $character > 0xD7FF && $character < 0xF900
+ ) {
+ for ($j = $start; $j <= $i; $j++) {
+ $string .= '%' . strtoupper($bytes[$j]);
+ }
+ }
+ else {
+ for ($j = $start; $j <= $i; $j++) {
+ $string .= chr(hexdec($bytes[$j]));
+ }
+ }
+ }
+ }
+
+ // If we have any bytes left over they are invalid (i.e., we are
+ // mid-way through a multi-byte sequence)
+ if ($remaining) {
+ for ($j = $start; $j < $len; $j++) {
+ $string .= '%' . strtoupper($bytes[$j]);
+ }
+ }
+
+ return $string;
+ }
+
+ protected function scheme_normalization() {
+ if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo']) {
+ $this->iuserinfo = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost']) {
+ $this->ihost = null;
+ }
+ if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port']) {
+ $this->port = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath']) {
+ $this->ipath = '';
+ }
+ if (isset($this->ihost) && empty($this->ipath)) {
+ $this->ipath = '/';
+ }
+ if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery']) {
+ $this->iquery = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment']) {
+ $this->ifragment = null;
+ }
+ }
+
+ /**
+ * Check if the object represents a valid IRI. This needs to be done on each
+ * call as some things change depending on another part of the IRI.
+ *
+ * @return bool
+ */
+ public function is_valid() {
+ $isauthority = $this->iuserinfo !== null || $this->ihost !== null || $this->port !== null;
+ if ($this->ipath !== '' &&
+ (
+ $isauthority && $this->ipath[0] !== '/' ||
+ (
+ $this->scheme === null &&
+ !$isauthority &&
+ strpos($this->ipath, ':') !== false &&
+ (strpos($this->ipath, '/') === false ? true : strpos($this->ipath, ':') < strpos($this->ipath, '/'))
+ )
+ )
+ ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Set the entire IRI. Returns true on success, false on failure (if there
+ * are any invalid characters).
+ *
+ * @param string $iri
+ * @return bool
+ */
+ protected function set_iri($iri) {
+ static $cache;
+ if (!$cache) {
+ $cache = array();
+ }
+
+ if ($iri === null) {
+ return true;
+ }
+ if (isset($cache[$iri])) {
+ list($this->scheme,
+ $this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $this->ipath,
+ $this->iquery,
+ $this->ifragment,
+ $return) = $cache[$iri];
+ return $return;
+ }
+
+ $parsed = $this->parse_iri((string) $iri);
+
+ $return = $this->set_scheme($parsed['scheme'])
+ && $this->set_authority($parsed['authority'])
+ && $this->set_path($parsed['path'])
+ && $this->set_query($parsed['query'])
+ && $this->set_fragment($parsed['fragment']);
+
+ $cache[$iri] = array($this->scheme,
+ $this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $this->ipath,
+ $this->iquery,
+ $this->ifragment,
+ $return);
+ return $return;
+ }
+
+ /**
+ * Set the scheme. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $scheme
+ * @return bool
+ */
+ protected function set_scheme($scheme) {
+ if ($scheme === null) {
+ $this->scheme = null;
+ }
+ elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme)) {
+ $this->scheme = null;
+ return false;
+ }
+ else {
+ $this->scheme = strtolower($scheme);
+ }
+ return true;
+ }
+
+ /**
+ * Set the authority. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $authority
+ * @return bool
+ */
+ protected function set_authority($authority) {
+ static $cache;
+ if (!$cache) {
+ $cache = array();
+ }
+
+ if ($authority === null) {
+ $this->iuserinfo = null;
+ $this->ihost = null;
+ $this->port = null;
+ return true;
+ }
+ if (isset($cache[$authority])) {
+ list($this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $return) = $cache[$authority];
+
+ return $return;
+ }
+
+ $remaining = $authority;
+ if (($iuserinfo_end = strrpos($remaining, '@')) !== false) {
+ $iuserinfo = substr($remaining, 0, $iuserinfo_end);
+ $remaining = substr($remaining, $iuserinfo_end + 1);
+ }
+ else {
+ $iuserinfo = null;
+ }
+ if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false) {
+ $port = substr($remaining, $port_start + 1);
+ if ($port === false || $port === '') {
+ $port = null;
+ }
+ $remaining = substr($remaining, 0, $port_start);
+ }
+ else {
+ $port = null;
+ }
+
+ $return = $this->set_userinfo($iuserinfo) &&
+ $this->set_host($remaining) &&
+ $this->set_port($port);
+
+ $cache[$authority] = array($this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $return);
+
+ return $return;
+ }
+
+ /**
+ * Set the iuserinfo.
+ *
+ * @param string $iuserinfo
+ * @return bool
+ */
+ protected function set_userinfo($iuserinfo) {
+ if ($iuserinfo === null) {
+ $this->iuserinfo = null;
+ }
+ else {
+ $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
+ $this->scheme_normalization();
+ }
+
+ return true;
+ }
+
+ /**
+ * Set the ihost. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $ihost
+ * @return bool
+ */
+ protected function set_host($ihost) {
+ if ($ihost === null) {
+ $this->ihost = null;
+ return true;
+ }
+ if (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']') {
+ if (Requests_IPv6::check_ipv6(substr($ihost, 1, -1))) {
+ $this->ihost = '[' . Requests_IPv6::compress(substr($ihost, 1, -1)) . ']';
+ }
+ else {
+ $this->ihost = null;
+ return false;
+ }
+ }
+ else {
+ $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
+
+ // Lowercase, but ignore pct-encoded sections (as they should
+ // remain uppercase). This must be done after the previous step
+ // as that can add unescaped characters.
+ $position = 0;
+ $strlen = strlen($ihost);
+ while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen) {
+ if ($ihost[$position] === '%') {
+ $position += 3;
+ }
+ else {
+ $ihost[$position] = strtolower($ihost[$position]);
+ $position++;
+ }
+ }
+
+ $this->ihost = $ihost;
+ }
+
+ $this->scheme_normalization();
+
+ return true;
+ }
+
+ /**
+ * Set the port. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $port
+ * @return bool
+ */
+ protected function set_port($port) {
+ if ($port === null) {
+ $this->port = null;
+ return true;
+ }
+
+ if (strspn($port, '0123456789') === strlen($port)) {
+ $this->port = (int) $port;
+ $this->scheme_normalization();
+ return true;
+ }
+
+ $this->port = null;
+ return false;
+ }
+
+ /**
+ * Set the ipath.
+ *
+ * @param string $ipath
+ * @return bool
+ */
+ protected function set_path($ipath) {
+ static $cache;
+ if (!$cache) {
+ $cache = array();
+ }
+
+ $ipath = (string) $ipath;
+
+ if (isset($cache[$ipath])) {
+ $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
+ }
+ else {
+ $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
+ $removed = $this->remove_dot_segments($valid);
+
+ $cache[$ipath] = array($valid, $removed);
+ $this->ipath = ($this->scheme !== null) ? $removed : $valid;
+ }
+ $this->scheme_normalization();
+ return true;
+ }
+
+ /**
+ * Set the iquery.
+ *
+ * @param string $iquery
+ * @return bool
+ */
+ protected function set_query($iquery) {
+ if ($iquery === null) {
+ $this->iquery = null;
+ }
+ else {
+ $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
+ $this->scheme_normalization();
+ }
+ return true;
+ }
+
+ /**
+ * Set the ifragment.
+ *
+ * @param string $ifragment
+ * @return bool
+ */
+ protected function set_fragment($ifragment) {
+ if ($ifragment === null) {
+ $this->ifragment = null;
+ }
+ else {
+ $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
+ $this->scheme_normalization();
+ }
+ return true;
+ }
+
+ /**
+ * Convert an IRI to a URI (or parts thereof)
+ *
+ * @param string|bool IRI to convert (or false from {@see get_iri})
+ * @return string|false URI if IRI is valid, false otherwise.
+ */
+ protected function to_uri($string) {
+ if (!is_string($string)) {
+ return false;
+ }
+
+ static $non_ascii;
+ if (!$non_ascii) {
+ $non_ascii = implode('', range("\x80", "\xFF"));
+ }
+
+ $position = 0;
+ $strlen = strlen($string);
+ while (($position += strcspn($string, $non_ascii, $position)) < $strlen) {
+ $string = substr_replace($string, sprintf('%%%02X', ord($string[$position])), $position, 1);
+ $position += 3;
+ $strlen += 2;
+ }
+
+ return $string;
+ }
+
+ /**
+ * Get the complete IRI
+ *
+ * @return string|false
+ */
+ protected function get_iri() {
+ if (!$this->is_valid()) {
+ return false;
+ }
+
+ $iri = '';
+ if ($this->scheme !== null) {
+ $iri .= $this->scheme . ':';
+ }
+ if (($iauthority = $this->get_iauthority()) !== null) {
+ $iri .= '//' . $iauthority;
+ }
+ $iri .= $this->ipath;
+ if ($this->iquery !== null) {
+ $iri .= '?' . $this->iquery;
+ }
+ if ($this->ifragment !== null) {
+ $iri .= '#' . $this->ifragment;
+ }
+
+ return $iri;
+ }
+
+ /**
+ * Get the complete URI
+ *
+ * @return string
+ */
+ protected function get_uri() {
+ return $this->to_uri($this->get_iri());
+ }
+
+ /**
+ * Get the complete iauthority
+ *
+ * @return string|null
+ */
+ protected function get_iauthority() {
+ if ($this->iuserinfo === null && $this->ihost === null && $this->port === null) {
+ return null;
+ }
+
+ $iauthority = '';
+ if ($this->iuserinfo !== null) {
+ $iauthority .= $this->iuserinfo . '@';
+ }
+ if ($this->ihost !== null) {
+ $iauthority .= $this->ihost;
+ }
+ if ($this->port !== null) {
+ $iauthority .= ':' . $this->port;
+ }
+ return $iauthority;
+ }
+
+ /**
+ * Get the complete authority
+ *
+ * @return string
+ */
+ protected function get_authority() {
+ $iauthority = $this->get_iauthority();
+ if (is_string($iauthority)) {
+ return $this->to_uri($iauthority);
+ }
+ else {
+ return $iauthority;
+ }
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsIdnaEncoderphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/IdnaEncoder.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/IdnaEncoder.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/IdnaEncoder.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,418 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * IDNA URL encoder
- *
- * Note: Not fully compliant, as nameprep does nothing yet.
- *
- * @package Requests\Utilities
- *
- * @link https://tools.ietf.org/html/rfc3490 IDNA specification
- * @link https://tools.ietf.org/html/rfc3492 Punycode/Bootstrap specification
- */
-class IdnaEncoder {
- /**
- * ACE prefix used for IDNA
- *
- * @link https://tools.ietf.org/html/rfc3490#section-5
- * @var string
- */
- const ACE_PREFIX = 'xn--';
-
- /**
- * Maximum length of a IDNA URL in ASCII.
- *
- * @see \WpOrg\Requests\IdnaEncoder::to_ascii()
- *
- * @since 2.0.0
- *
- * @var int
- */
- const MAX_LENGTH = 64;
-
- /**#@+
- * Bootstrap constant for Punycode
- *
- * @link https://tools.ietf.org/html/rfc3492#section-5
- * @var int
- */
- const BOOTSTRAP_BASE = 36;
- const BOOTSTRAP_TMIN = 1;
- const BOOTSTRAP_TMAX = 26;
- const BOOTSTRAP_SKEW = 38;
- const BOOTSTRAP_DAMP = 700;
- const BOOTSTRAP_INITIAL_BIAS = 72;
- const BOOTSTRAP_INITIAL_N = 128;
- /**#@-*/
-
- /**
- * Encode a hostname using Punycode
- *
- * @param string|Stringable $hostname Hostname
- * @return string Punycode-encoded hostname
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
- */
- public static function encode($hostname) {
- if (InputValidator::is_string_or_stringable($hostname) === false) {
- throw InvalidArgument::create(1, '$hostname', 'string|Stringable', gettype($hostname));
- }
-
- $parts = explode('.', $hostname);
- foreach ($parts as &$part) {
- $part = self::to_ascii($part);
- }
- return implode('.', $parts);
- }
-
- /**
- * Convert a UTF-8 text string to an ASCII string using Punycode
- *
- * @param string $text ASCII or UTF-8 string (max length 64 characters)
- * @return string ASCII string
- *
- * @throws \WpOrg\Requests\Exception Provided string longer than 64 ASCII characters (`idna.provided_too_long`)
- * @throws \WpOrg\Requests\Exception Prepared string longer than 64 ASCII characters (`idna.prepared_too_long`)
- * @throws \WpOrg\Requests\Exception Provided string already begins with xn-- (`idna.provided_is_prefixed`)
- * @throws \WpOrg\Requests\Exception Encoded string longer than 64 ASCII characters (`idna.encoded_too_long`)
- */
- public static function to_ascii($text) {
- // Step 1: Check if the text is already ASCII
- if (self::is_ascii($text)) {
- // Skip to step 7
- if (strlen($text) < self::MAX_LENGTH) {
- return $text;
- }
-
- throw new Exception('Provided string is too long', 'idna.provided_too_long', $text);
- }
-
- // Step 2: nameprep
- $text = self::nameprep($text);
-
- // Step 3: UseSTD3ASCIIRules is false, continue
- // Step 4: Check if it's ASCII now
- if (self::is_ascii($text)) {
- // Skip to step 7
- /*
- * As the `nameprep()` method returns the original string, this code will never be reached until
- * that method is properly implemented.
- */
- // @codeCoverageIgnoreStart
- if (strlen($text) < self::MAX_LENGTH) {
- return $text;
- }
-
- throw new Exception('Prepared string is too long', 'idna.prepared_too_long', $text);
- // @codeCoverageIgnoreEnd
- }
-
- // Step 5: Check ACE prefix
- if (strpos($text, self::ACE_PREFIX) === 0) {
- throw new Exception('Provided string begins with ACE prefix', 'idna.provided_is_prefixed', $text);
- }
-
- // Step 6: Encode with Punycode
- $text = self::punycode_encode($text);
-
- // Step 7: Prepend ACE prefix
- $text = self::ACE_PREFIX . $text;
-
- // Step 8: Check size
- if (strlen($text) < self::MAX_LENGTH) {
- return $text;
- }
-
- throw new Exception('Encoded string is too long', 'idna.encoded_too_long', $text);
- }
-
- /**
- * Check whether a given text string contains only ASCII characters
- *
- * @internal (Testing found regex was the fastest implementation)
- *
- * @param string $text
- * @return bool Is the text string ASCII-only?
- */
- protected static function is_ascii($text) {
- return (preg_match('/(?:[^\x00-\x7F])/', $text) !== 1);
- }
-
- /**
- * Prepare a text string for use as an IDNA name
- *
- * @todo Implement this based on RFC 3491 and the newer 5891
- * @param string $text
- * @return string Prepared string
- */
- protected static function nameprep($text) {
- return $text;
- }
-
- /**
- * Convert a UTF-8 string to a UCS-4 codepoint array
- *
- * Based on \WpOrg\Requests\Iri::replace_invalid_with_pct_encoding()
- *
- * @param string $input
- * @return array Unicode code points
- *
- * @throws \WpOrg\Requests\Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`)
- */
- protected static function utf8_to_codepoints($input) {
- $codepoints = [];
-
- // Get number of bytes
- $strlen = strlen($input);
-
- // phpcs:ignore Generic.CodeAnalysis.JumbledIncrementer -- This is a deliberate choice.
- for ($position = 0; $position < $strlen; $position++) {
- $value = ord($input[$position]);
-
- // One byte sequence:
- if ((~$value & 0x80) === 0x80) {
- $character = $value;
- $length = 1;
- $remaining = 0;
- }
- // Two byte sequence:
- elseif (($value & 0xE0) === 0xC0) {
- $character = ($value & 0x1F) << 6;
- $length = 2;
- $remaining = 1;
- }
- // Three byte sequence:
- elseif (($value & 0xF0) === 0xE0) {
- $character = ($value & 0x0F) << 12;
- $length = 3;
- $remaining = 2;
- }
- // Four byte sequence:
- elseif (($value & 0xF8) === 0xF0) {
- $character = ($value & 0x07) << 18;
- $length = 4;
- $remaining = 3;
- }
- // Invalid byte:
- else {
- throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $value);
- }
-
- if ($remaining > 0) {
- if ($position + $length > $strlen) {
- throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
- }
- for ($position++; $remaining > 0; $position++) {
- $value = ord($input[$position]);
-
- // If it is invalid, count the sequence as invalid and reprocess the current byte:
- if (($value & 0xC0) !== 0x80) {
- throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
- }
-
- --$remaining;
- $character |= ($value & 0x3F) << ($remaining * 6);
- }
- $position--;
- }
-
- if (// Non-shortest form sequences are invalid
- $length > 1 && $character <= 0x7F
- || $length > 2 && $character <= 0x7FF
- || $length > 3 && $character <= 0xFFFF
- // Outside of range of ucschar codepoints
- // Noncharacters
- || ($character & 0xFFFE) === 0xFFFE
- || $character >= 0xFDD0 && $character <= 0xFDEF
- || (
- // Everything else not in ucschar
- $character > 0xD7FF && $character < 0xF900
- || $character < 0x20
- || $character > 0x7E && $character < 0xA0
- || $character > 0xEFFFD
- )
- ) {
- throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
- }
-
- $codepoints[] = $character;
- }
-
- return $codepoints;
- }
-
- /**
- * RFC3492-compliant encoder
- *
- * @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
- *
- * @param string $input UTF-8 encoded string to encode
- * @return string Punycode-encoded string
- *
- * @throws \WpOrg\Requests\Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)
- */
- public static function punycode_encode($input) {
- $output = '';
- // let n = initial_n
- $n = self::BOOTSTRAP_INITIAL_N;
- // let delta = 0
- $delta = 0;
- // let bias = initial_bias
- $bias = self::BOOTSTRAP_INITIAL_BIAS;
- // let h = b = the number of basic code points in the input
- $h = 0;
- $b = 0; // see loop
- // copy them to the output in order
- $codepoints = self::utf8_to_codepoints($input);
- $extended = [];
-
- foreach ($codepoints as $char) {
- if ($char < 128) {
- // Character is valid ASCII
- // TODO: this should also check if it's valid for a URL
- $output .= chr($char);
- $h++;
- }
- // Check if the character is non-ASCII, but below initial n
- // This never occurs for Punycode, so ignore in coverage
- // @codeCoverageIgnoreStart
- elseif ($char < $n) {
- throw new Exception('Invalid character', 'idna.character_outside_domain', $char);
- }
- // @codeCoverageIgnoreEnd
- else {
- $extended[$char] = true;
- }
- }
- $extended = array_keys($extended);
- sort($extended);
- $b = $h;
- // [copy them] followed by a delimiter if b > 0
- if (strlen($output) > 0) {
- $output .= '-';
- }
- // {if the input contains a non-basic code point < n then fail}
- // while h < length(input) do begin
- $codepointcount = count($codepoints);
- while ($h < $codepointcount) {
- // let m = the minimum code point >= n in the input
- $m = array_shift($extended);
- //printf('next code point to insert is %s' . PHP_EOL, dechex($m));
- // let delta = delta + (m - n) * (h + 1), fail on overflow
- $delta += ($m - $n) * ($h + 1);
- // let n = m
- $n = $m;
- // for each code point c in the input (in order) do begin
- for ($num = 0; $num < $codepointcount; $num++) {
- $c = $codepoints[$num];
- // if c < n then increment delta, fail on overflow
- if ($c < $n) {
- $delta++;
- }
- // if c == n then begin
- elseif ($c === $n) {
- // let q = delta
- $q = $delta;
- // for k = base to infinity in steps of base do begin
- for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
- // let t = tmin if k <= bias {+ tmin}, or
- // tmax if k >= bias + tmax, or k - bias otherwise
- if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
- $t = self::BOOTSTRAP_TMIN;
- }
- elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
- $t = self::BOOTSTRAP_TMAX;
- }
- else {
- $t = $k - $bias;
- }
- // if q < t then break
- if ($q < $t) {
- break;
- }
- // output the code point for digit t + ((q - t) mod (base - t))
- $digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
- $output .= self::digit_to_char($digit);
- // let q = (q - t) div (base - t)
- $q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
- } // end
- // output the code point for digit q
- $output .= self::digit_to_char($q);
- // let bias = adapt(delta, h + 1, test h equals b?)
- $bias = self::adapt($delta, $h + 1, $h === $b);
- // let delta = 0
- $delta = 0;
- // increment h
- $h++;
- } // end
- } // end
- // increment delta and n
- $delta++;
- $n++;
- } // end
-
- return $output;
- }
-
- /**
- * Convert a digit to its respective character
- *
- * @link https://tools.ietf.org/html/rfc3492#section-5
- *
- * @param int $digit Digit in the range 0-35
- * @return string Single character corresponding to digit
- *
- * @throws \WpOrg\Requests\Exception On invalid digit (`idna.invalid_digit`)
- */
- protected static function digit_to_char($digit) {
- // @codeCoverageIgnoreStart
- // As far as I know, this never happens, but still good to be sure.
- if ($digit < 0 || $digit > 35) {
- throw new Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit);
- }
- // @codeCoverageIgnoreEnd
- $digits = 'abcdefghijklmnopqrstuvwxyz0123456789';
- return substr($digits, $digit, 1);
- }
-
- /**
- * Adapt the bias
- *
- * @link https://tools.ietf.org/html/rfc3492#section-6.1
- * @param int $delta
- * @param int $numpoints
- * @param bool $firsttime
- * @return int New bias
- *
- * function adapt(delta,numpoints,firsttime):
- */
- protected static function adapt($delta, $numpoints, $firsttime) {
- // if firsttime then let delta = delta div damp
- if ($firsttime) {
- $delta = floor($delta / self::BOOTSTRAP_DAMP);
- }
- // else let delta = delta div 2
- else {
- $delta = floor($delta / 2);
- }
- // let delta = delta + (delta div numpoints)
- $delta += floor($delta / $numpoints);
- // let k = 0
- $k = 0;
- // while delta > ((base - tmin) * tmax) div 2 do begin
- $max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
- while ($delta > $max) {
- // let delta = delta div (base - tmin)
- $delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
- // let k = k + base
- $k += self::BOOTSTRAP_BASE;
- } // end
- // return k + (((base - tmin + 1) * delta) div (delta + skew))
- return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsIpv6php"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Ipv6.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Ipv6.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Ipv6.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,205 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Class to validate and to work with IPv6 addresses
- *
- * @package Requests\Utilities
- */
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * Class to validate and to work with IPv6 addresses
- *
- * This was originally based on the PEAR class of the same name, but has been
- * entirely rewritten.
- *
- * @package Requests\Utilities
- */
-final class Ipv6 {
- /**
- * Uncompresses an IPv6 address
- *
- * RFC 4291 allows you to compress consecutive zero pieces in an address to
- * '::'. This method expects a valid IPv6 address and expands the '::' to
- * the required number of zero pieces.
- *
- * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
- * ::1 -> 0:0:0:0:0:0:0:1
- *
- * @author Alexander Merz <alexander.merz@web.de>
- * @author elfrink at introweb dot nl
- * @author Josh Peck <jmp at joshpeck dot org>
- * @copyright 2003-2005 The PHP Group
- * @license https://opensource.org/licenses/bsd-license.php
- *
- * @param string|Stringable $ip An IPv6 address
- * @return string The uncompressed IPv6 address
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
- */
- public static function uncompress($ip) {
- if (InputValidator::is_string_or_stringable($ip) === false) {
- throw InvalidArgument::create(1, '$ip', 'string|Stringable', gettype($ip));
- }
-
- $ip = (string) $ip;
-
- if (substr_count($ip, '::') !== 1) {
- return $ip;
- }
-
- list($ip1, $ip2) = explode('::', $ip);
- $c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
- $c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
-
- if (strpos($ip2, '.') !== false) {
- $c2++;
- }
- // ::
- if ($c1 === -1 && $c2 === -1) {
- $ip = '0:0:0:0:0:0:0:0';
- }
- // ::xxx
- elseif ($c1 === -1) {
- $fill = str_repeat('0:', 7 - $c2);
- $ip = str_replace('::', $fill, $ip);
- }
- // xxx::
- elseif ($c2 === -1) {
- $fill = str_repeat(':0', 7 - $c1);
- $ip = str_replace('::', $fill, $ip);
- }
- // xxx::xxx
- else {
- $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
- $ip = str_replace('::', $fill, $ip);
- }
- return $ip;
- }
-
- /**
- * Compresses an IPv6 address
- *
- * RFC 4291 allows you to compress consecutive zero pieces in an address to
- * '::'. This method expects a valid IPv6 address and compresses consecutive
- * zero pieces to '::'.
- *
- * Example: FF01:0:0:0:0:0:0:101 -> FF01::101
- * 0:0:0:0:0:0:0:1 -> ::1
- *
- * @see \WpOrg\Requests\IPv6::uncompress()
- *
- * @param string $ip An IPv6 address
- * @return string The compressed IPv6 address
- */
- public static function compress($ip) {
- // Prepare the IP to be compressed.
- // Note: Input validation is handled in the `uncompress()` method, which is the first call made in this method.
- $ip = self::uncompress($ip);
- $ip_parts = self::split_v6_v4($ip);
-
- // Replace all leading zeros
- $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
-
- // Find bunches of zeros
- if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
- $max = 0;
- $pos = null;
- foreach ($matches[0] as $match) {
- if (strlen($match[0]) > $max) {
- $max = strlen($match[0]);
- $pos = $match[1];
- }
- }
-
- $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
- }
-
- if ($ip_parts[1] !== '') {
- return implode(':', $ip_parts);
- }
- else {
- return $ip_parts[0];
- }
- }
-
- /**
- * Splits an IPv6 address into the IPv6 and IPv4 representation parts
- *
- * RFC 4291 allows you to represent the last two parts of an IPv6 address
- * using the standard IPv4 representation
- *
- * Example: 0:0:0:0:0:0:13.1.68.3
- * 0:0:0:0:0:FFFF:129.144.52.38
- *
- * @param string $ip An IPv6 address
- * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
- */
- private static function split_v6_v4($ip) {
- if (strpos($ip, '.') !== false) {
- $pos = strrpos($ip, ':');
- $ipv6_part = substr($ip, 0, $pos);
- $ipv4_part = substr($ip, $pos + 1);
- return [$ipv6_part, $ipv4_part];
- }
- else {
- return [$ip, ''];
- }
- }
-
- /**
- * Checks an IPv6 address
- *
- * Checks if the given IP is a valid IPv6 address
- *
- * @param string $ip An IPv6 address
- * @return bool true if $ip is a valid IPv6 address
- */
- public static function check_ipv6($ip) {
- // Note: Input validation is handled in the `uncompress()` method, which is the first call made in this method.
- $ip = self::uncompress($ip);
- list($ipv6, $ipv4) = self::split_v6_v4($ip);
- $ipv6 = explode(':', $ipv6);
- $ipv4 = explode('.', $ipv4);
- if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
- foreach ($ipv6 as $ipv6_part) {
- // The section can't be empty
- if ($ipv6_part === '') {
- return false;
- }
-
- // Nor can it be over four characters
- if (strlen($ipv6_part) > 4) {
- return false;
- }
-
- // Remove leading zeros (this is safe because of the above)
- $ipv6_part = ltrim($ipv6_part, '0');
- if ($ipv6_part === '') {
- $ipv6_part = '0';
- }
-
- // Check the value is valid
- $value = hexdec($ipv6_part);
- if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
- return false;
- }
- }
- if (count($ipv4) === 4) {
- foreach ($ipv4 as $ipv4_part) {
- $value = (int) $ipv4_part;
- if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
- return false;
- }
- }
- }
- return true;
- }
- else {
- return false;
- }
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsIriphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Iri.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Iri.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Iri.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,1101 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * IRI parser/serialiser/normaliser
- *
- * @package Requests\Utilities
- */
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Ipv6;
-use WpOrg\Requests\Port;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * IRI parser/serialiser/normaliser
- *
- * Copyright (c) 2007-2010, Geoffrey Sneddon and Steve Minutillo.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of the SimplePie Team nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND 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.
- *
- * @package Requests\Utilities
- * @author Geoffrey Sneddon
- * @author Steve Minutillo
- * @copyright 2007-2009 Geoffrey Sneddon and Steve Minutillo
- * @license https://opensource.org/licenses/bsd-license.php
- * @link http://hg.gsnedders.com/iri/
- *
- * @property string $iri IRI we're working with
- * @property-read string $uri IRI in URI form, {@see \WpOrg\Requests\IRI::to_uri()}
- * @property string $scheme Scheme part of the IRI
- * @property string $authority Authority part, formatted for a URI (userinfo + host + port)
- * @property string $iauthority Authority part of the IRI (userinfo + host + port)
- * @property string $userinfo Userinfo part, formatted for a URI (after '://' and before '@')
- * @property string $iuserinfo Userinfo part of the IRI (after '://' and before '@')
- * @property string $host Host part, formatted for a URI
- * @property string $ihost Host part of the IRI
- * @property string $port Port part of the IRI (after ':')
- * @property string $path Path part, formatted for a URI (after first '/')
- * @property string $ipath Path part of the IRI (after first '/')
- * @property string $query Query part, formatted for a URI (after '?')
- * @property string $iquery Query part of the IRI (after '?')
- * @property string $fragment Fragment, formatted for a URI (after '#')
- * @property string $ifragment Fragment part of the IRI (after '#')
- */
-class Iri {
- /**
- * Scheme
- *
- * @var string|null
- */
- protected $scheme = null;
-
- /**
- * User Information
- *
- * @var string|null
- */
- protected $iuserinfo = null;
-
- /**
- * ihost
- *
- * @var string|null
- */
- protected $ihost = null;
-
- /**
- * Port
- *
- * @var string|null
- */
- protected $port = null;
-
- /**
- * ipath
- *
- * @var string
- */
- protected $ipath = '';
-
- /**
- * iquery
- *
- * @var string|null
- */
- protected $iquery = null;
-
- /**
- * ifragment|null
- *
- * @var string
- */
- protected $ifragment = null;
-
- /**
- * Normalization database
- *
- * Each key is the scheme, each value is an array with each key as the IRI
- * part and value as the default value for that part.
- *
- * @var array
- */
- protected $normalization = array(
- 'acap' => array(
- 'port' => Port::ACAP,
- ),
- 'dict' => array(
- 'port' => Port::DICT,
- ),
- 'file' => array(
- 'ihost' => 'localhost',
- ),
- 'http' => array(
- 'port' => Port::HTTP,
- ),
- 'https' => array(
- 'port' => Port::HTTPS,
- ),
- );
-
- /**
- * Return the entire IRI when you try and read the object as a string
- *
- * @return string
- */
- public function __toString() {
- return $this->get_iri();
- }
-
- /**
- * Overload __set() to provide access via properties
- *
- * @param string $name Property name
- * @param mixed $value Property value
- */
- public function __set($name, $value) {
- if (method_exists($this, 'set_' . $name)) {
- call_user_func(array($this, 'set_' . $name), $value);
- }
- elseif (
- $name === 'iauthority'
- || $name === 'iuserinfo'
- || $name === 'ihost'
- || $name === 'ipath'
- || $name === 'iquery'
- || $name === 'ifragment'
- ) {
- call_user_func(array($this, 'set_' . substr($name, 1)), $value);
- }
- }
-
- /**
- * Overload __get() to provide access via properties
- *
- * @param string $name Property name
- * @return mixed
- */
- public function __get($name) {
- // isset() returns false for null, we don't want to do that
- // Also why we use array_key_exists below instead of isset()
- $props = get_object_vars($this);
-
- if (
- $name === 'iri' ||
- $name === 'uri' ||
- $name === 'iauthority' ||
- $name === 'authority'
- ) {
- $method = 'get_' . $name;
- $return = $this->$method();
- }
- elseif (array_key_exists($name, $props)) {
- $return = $this->$name;
- }
- // host -> ihost
- elseif (($prop = 'i' . $name) && array_key_exists($prop, $props)) {
- $name = $prop;
- $return = $this->$prop;
- }
- // ischeme -> scheme
- elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props)) {
- $name = $prop;
- $return = $this->$prop;
- }
- else {
- trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
- $return = null;
- }
-
- if ($return === null && isset($this->normalization[$this->scheme][$name])) {
- return $this->normalization[$this->scheme][$name];
- }
- else {
- return $return;
- }
- }
-
- /**
- * Overload __isset() to provide access via properties
- *
- * @param string $name Property name
- * @return bool
- */
- public function __isset($name) {
- return (method_exists($this, 'get_' . $name) || isset($this->$name));
- }
-
- /**
- * Overload __unset() to provide access via properties
- *
- * @param string $name Property name
- */
- public function __unset($name) {
- if (method_exists($this, 'set_' . $name)) {
- call_user_func(array($this, 'set_' . $name), '');
- }
- }
-
- /**
- * Create a new IRI object, from a specified string
- *
- * @param string|Stringable|null $iri
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $iri argument is not a string, Stringable or null.
- */
- public function __construct($iri = null) {
- if ($iri !== null && InputValidator::is_string_or_stringable($iri) === false) {
- throw InvalidArgument::create(1, '$iri', 'string|Stringable|null', gettype($iri));
- }
-
- $this->set_iri($iri);
- }
-
- /**
- * Create a new IRI object by resolving a relative IRI
- *
- * Returns false if $base is not absolute, otherwise an IRI.
- *
- * @param \WpOrg\Requests\Iri|string $base (Absolute) Base IRI
- * @param \WpOrg\Requests\Iri|string $relative Relative IRI
- * @return \WpOrg\Requests\Iri|false
- */
- public static function absolutize($base, $relative) {
- if (!($relative instanceof self)) {
- $relative = new self($relative);
- }
- if (!$relative->is_valid()) {
- return false;
- }
- elseif ($relative->scheme !== null) {
- return clone $relative;
- }
-
- if (!($base instanceof self)) {
- $base = new self($base);
- }
- if ($base->scheme === null || !$base->is_valid()) {
- return false;
- }
-
- if ($relative->get_iri() !== '') {
- if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null) {
- $target = clone $relative;
- $target->scheme = $base->scheme;
- }
- else {
- $target = new self;
- $target->scheme = $base->scheme;
- $target->iuserinfo = $base->iuserinfo;
- $target->ihost = $base->ihost;
- $target->port = $base->port;
- if ($relative->ipath !== '') {
- if ($relative->ipath[0] === '/') {
- $target->ipath = $relative->ipath;
- }
- elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '') {
- $target->ipath = '/' . $relative->ipath;
- }
- elseif (($last_segment = strrpos($base->ipath, '/')) !== false) {
- $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
- }
- else {
- $target->ipath = $relative->ipath;
- }
- $target->ipath = $target->remove_dot_segments($target->ipath);
- $target->iquery = $relative->iquery;
- }
- else {
- $target->ipath = $base->ipath;
- if ($relative->iquery !== null) {
- $target->iquery = $relative->iquery;
- }
- elseif ($base->iquery !== null) {
- $target->iquery = $base->iquery;
- }
- }
- $target->ifragment = $relative->ifragment;
- }
- }
- else {
- $target = clone $base;
- $target->ifragment = null;
- }
- $target->scheme_normalization();
- return $target;
- }
-
- /**
- * Parse an IRI into scheme/authority/path/query/fragment segments
- *
- * @param string $iri
- * @return array
- */
- protected function parse_iri($iri) {
- $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
- $has_match = preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match);
- if (!$has_match) {
- throw new Exception('Cannot parse supplied IRI', 'iri.cannot_parse', $iri);
- }
-
- if ($match[1] === '') {
- $match['scheme'] = null;
- }
- if (!isset($match[3]) || $match[3] === '') {
- $match['authority'] = null;
- }
- if (!isset($match[5])) {
- $match['path'] = '';
- }
- if (!isset($match[6]) || $match[6] === '') {
- $match['query'] = null;
- }
- if (!isset($match[8]) || $match[8] === '') {
- $match['fragment'] = null;
- }
- return $match;
- }
-
- /**
- * Remove dot segments from a path
- *
- * @param string $input
- * @return string
- */
- protected function remove_dot_segments($input) {
- $output = '';
- while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') {
- // A: If the input buffer begins with a prefix of "../" or "./",
- // then remove that prefix from the input buffer; otherwise,
- if (strpos($input, '../') === 0) {
- $input = substr($input, 3);
- }
- elseif (strpos($input, './') === 0) {
- $input = substr($input, 2);
- }
- // B: if the input buffer begins with a prefix of "/./" or "/.",
- // where "." is a complete path segment, then replace that prefix
- // with "/" in the input buffer; otherwise,
- elseif (strpos($input, '/./') === 0) {
- $input = substr($input, 2);
- }
- elseif ($input === '/.') {
- $input = '/';
- }
- // C: if the input buffer begins with a prefix of "/../" or "/..",
- // where ".." is a complete path segment, then replace that prefix
- // with "/" in the input buffer and remove the last segment and its
- // preceding "/" (if any) from the output buffer; otherwise,
- elseif (strpos($input, '/../') === 0) {
- $input = substr($input, 3);
- $output = substr_replace($output, '', strrpos($output, '/'));
- }
- elseif ($input === '/..') {
- $input = '/';
- $output = substr_replace($output, '', strrpos($output, '/'));
- }
- // D: if the input buffer consists only of "." or "..", then remove
- // that from the input buffer; otherwise,
- elseif ($input === '.' || $input === '..') {
- $input = '';
- }
- // E: move the first path segment in the input buffer to the end of
- // the output buffer, including the initial "/" character (if any)
- // and any subsequent characters up to, but not including, the next
- // "/" character or the end of the input buffer
- elseif (($pos = strpos($input, '/', 1)) !== false) {
- $output .= substr($input, 0, $pos);
- $input = substr_replace($input, '', 0, $pos);
- }
- else {
- $output .= $input;
- $input = '';
- }
- }
- return $output . $input;
- }
-
- /**
- * Replace invalid character with percent encoding
- *
- * @param string $text Input string
- * @param string $extra_chars Valid characters not in iunreserved or
- * iprivate (this is ASCII-only)
- * @param bool $iprivate Allow iprivate
- * @return string
- */
- protected function replace_invalid_with_pct_encoding($text, $extra_chars, $iprivate = false) {
- // Normalize as many pct-encoded sections as possible
- $text = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $text);
-
- // Replace invalid percent characters
- $text = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $text);
-
- // Add unreserved and % to $extra_chars (the latter is safe because all
- // pct-encoded sections are now valid).
- $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
-
- // Now replace any bytes that aren't allowed with their pct-encoded versions
- $position = 0;
- $strlen = strlen($text);
- while (($position += strspn($text, $extra_chars, $position)) < $strlen) {
- $value = ord($text[$position]);
-
- // Start position
- $start = $position;
-
- // By default we are valid
- $valid = true;
-
- // No one byte sequences are valid due to the while.
- // Two byte sequence:
- if (($value & 0xE0) === 0xC0) {
- $character = ($value & 0x1F) << 6;
- $length = 2;
- $remaining = 1;
- }
- // Three byte sequence:
- elseif (($value & 0xF0) === 0xE0) {
- $character = ($value & 0x0F) << 12;
- $length = 3;
- $remaining = 2;
- }
- // Four byte sequence:
- elseif (($value & 0xF8) === 0xF0) {
- $character = ($value & 0x07) << 18;
- $length = 4;
- $remaining = 3;
- }
- // Invalid byte:
- else {
- $valid = false;
- $length = 1;
- $remaining = 0;
- }
-
- if ($remaining) {
- if ($position + $length <= $strlen) {
- for ($position++; $remaining; $position++) {
- $value = ord($text[$position]);
-
- // Check that the byte is valid, then add it to the character:
- if (($value & 0xC0) === 0x80) {
- $character |= ($value & 0x3F) << (--$remaining * 6);
- }
- // If it is invalid, count the sequence as invalid and reprocess the current byte:
- else {
- $valid = false;
- $position--;
- break;
- }
- }
- }
- else {
- $position = $strlen - 1;
- $valid = false;
- }
- }
-
- // Percent encode anything invalid or not in ucschar
- if (
- // Invalid sequences
- !$valid
- // Non-shortest form sequences are invalid
- || $length > 1 && $character <= 0x7F
- || $length > 2 && $character <= 0x7FF
- || $length > 3 && $character <= 0xFFFF
- // Outside of range of ucschar codepoints
- // Noncharacters
- || ($character & 0xFFFE) === 0xFFFE
- || $character >= 0xFDD0 && $character <= 0xFDEF
- || (
- // Everything else not in ucschar
- $character > 0xD7FF && $character < 0xF900
- || $character < 0xA0
- || $character > 0xEFFFD
- )
- && (
- // Everything not in iprivate, if it applies
- !$iprivate
- || $character < 0xE000
- || $character > 0x10FFFD
- )
- ) {
- // If we were a character, pretend we weren't, but rather an error.
- if ($valid) {
- $position--;
- }
-
- for ($j = $start; $j <= $position; $j++) {
- $text = substr_replace($text, sprintf('%%%02X', ord($text[$j])), $j, 1);
- $j += 2;
- $position += 2;
- $strlen += 2;
- }
- }
- }
-
- return $text;
- }
-
- /**
- * Callback function for preg_replace_callback.
- *
- * Removes sequences of percent encoded bytes that represent UTF-8
- * encoded characters in iunreserved
- *
- * @param array $regex_match PCRE match
- * @return string Replacement
- */
- protected function remove_iunreserved_percent_encoded($regex_match) {
- // As we just have valid percent encoded sequences we can just explode
- // and ignore the first member of the returned array (an empty string).
- $bytes = explode('%', $regex_match[0]);
-
- // Initialize the new string (this is what will be returned) and that
- // there are no bytes remaining in the current sequence (unsurprising
- // at the first byte!).
- $string = '';
- $remaining = 0;
-
- // Loop over each and every byte, and set $value to its value
- for ($i = 1, $len = count($bytes); $i < $len; $i++) {
- $value = hexdec($bytes[$i]);
-
- // If we're the first byte of sequence:
- if (!$remaining) {
- // Start position
- $start = $i;
-
- // By default we are valid
- $valid = true;
-
- // One byte sequence:
- if ($value <= 0x7F) {
- $character = $value;
- $length = 1;
- }
- // Two byte sequence:
- elseif (($value & 0xE0) === 0xC0) {
- $character = ($value & 0x1F) << 6;
- $length = 2;
- $remaining = 1;
- }
- // Three byte sequence:
- elseif (($value & 0xF0) === 0xE0) {
- $character = ($value & 0x0F) << 12;
- $length = 3;
- $remaining = 2;
- }
- // Four byte sequence:
- elseif (($value & 0xF8) === 0xF0) {
- $character = ($value & 0x07) << 18;
- $length = 4;
- $remaining = 3;
- }
- // Invalid byte:
- else {
- $valid = false;
- $remaining = 0;
- }
- }
- // Continuation byte:
- else {
- // Check that the byte is valid, then add it to the character:
- if (($value & 0xC0) === 0x80) {
- $remaining--;
- $character |= ($value & 0x3F) << ($remaining * 6);
- }
- // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
- else {
- $valid = false;
- $remaining = 0;
- $i--;
- }
- }
-
- // If we've reached the end of the current byte sequence, append it to Unicode::$data
- if (!$remaining) {
- // Percent encode anything invalid or not in iunreserved
- if (
- // Invalid sequences
- !$valid
- // Non-shortest form sequences are invalid
- || $length > 1 && $character <= 0x7F
- || $length > 2 && $character <= 0x7FF
- || $length > 3 && $character <= 0xFFFF
- // Outside of range of iunreserved codepoints
- || $character < 0x2D
- || $character > 0xEFFFD
- // Noncharacters
- || ($character & 0xFFFE) === 0xFFFE
- || $character >= 0xFDD0 && $character <= 0xFDEF
- // Everything else not in iunreserved (this is all BMP)
- || $character === 0x2F
- || $character > 0x39 && $character < 0x41
- || $character > 0x5A && $character < 0x61
- || $character > 0x7A && $character < 0x7E
- || $character > 0x7E && $character < 0xA0
- || $character > 0xD7FF && $character < 0xF900
- ) {
- for ($j = $start; $j <= $i; $j++) {
- $string .= '%' . strtoupper($bytes[$j]);
- }
- }
- else {
- for ($j = $start; $j <= $i; $j++) {
- $string .= chr(hexdec($bytes[$j]));
- }
- }
- }
- }
-
- // If we have any bytes left over they are invalid (i.e., we are
- // mid-way through a multi-byte sequence)
- if ($remaining) {
- for ($j = $start; $j < $len; $j++) {
- $string .= '%' . strtoupper($bytes[$j]);
- }
- }
-
- return $string;
- }
-
- protected function scheme_normalization() {
- if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo']) {
- $this->iuserinfo = null;
- }
- if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost']) {
- $this->ihost = null;
- }
- if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port']) {
- $this->port = null;
- }
- if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath']) {
- $this->ipath = '';
- }
- if (isset($this->ihost) && empty($this->ipath)) {
- $this->ipath = '/';
- }
- if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery']) {
- $this->iquery = null;
- }
- if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment']) {
- $this->ifragment = null;
- }
- }
-
- /**
- * Check if the object represents a valid IRI. This needs to be done on each
- * call as some things change depending on another part of the IRI.
- *
- * @return bool
- */
- public function is_valid() {
- $isauthority = $this->iuserinfo !== null || $this->ihost !== null || $this->port !== null;
- if ($this->ipath !== '' &&
- (
- $isauthority && $this->ipath[0] !== '/' ||
- (
- $this->scheme === null &&
- !$isauthority &&
- strpos($this->ipath, ':') !== false &&
- (strpos($this->ipath, '/') === false ? true : strpos($this->ipath, ':') < strpos($this->ipath, '/'))
- )
- )
- ) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Set the entire IRI. Returns true on success, false on failure (if there
- * are any invalid characters).
- *
- * @param string $iri
- * @return bool
- */
- protected function set_iri($iri) {
- static $cache;
- if (!$cache) {
- $cache = array();
- }
-
- if ($iri === null) {
- return true;
- }
-
- $iri = (string) $iri;
-
- if (isset($cache[$iri])) {
- list($this->scheme,
- $this->iuserinfo,
- $this->ihost,
- $this->port,
- $this->ipath,
- $this->iquery,
- $this->ifragment,
- $return) = $cache[$iri];
- return $return;
- }
-
- $parsed = $this->parse_iri($iri);
-
- $return = $this->set_scheme($parsed['scheme'])
- && $this->set_authority($parsed['authority'])
- && $this->set_path($parsed['path'])
- && $this->set_query($parsed['query'])
- && $this->set_fragment($parsed['fragment']);
-
- $cache[$iri] = array($this->scheme,
- $this->iuserinfo,
- $this->ihost,
- $this->port,
- $this->ipath,
- $this->iquery,
- $this->ifragment,
- $return);
- return $return;
- }
-
- /**
- * Set the scheme. Returns true on success, false on failure (if there are
- * any invalid characters).
- *
- * @param string $scheme
- * @return bool
- */
- protected function set_scheme($scheme) {
- if ($scheme === null) {
- $this->scheme = null;
- }
- elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme)) {
- $this->scheme = null;
- return false;
- }
- else {
- $this->scheme = strtolower($scheme);
- }
- return true;
- }
-
- /**
- * Set the authority. Returns true on success, false on failure (if there are
- * any invalid characters).
- *
- * @param string $authority
- * @return bool
- */
- protected function set_authority($authority) {
- static $cache;
- if (!$cache) {
- $cache = array();
- }
-
- if ($authority === null) {
- $this->iuserinfo = null;
- $this->ihost = null;
- $this->port = null;
- return true;
- }
- if (isset($cache[$authority])) {
- list($this->iuserinfo,
- $this->ihost,
- $this->port,
- $return) = $cache[$authority];
-
- return $return;
- }
-
- $remaining = $authority;
- if (($iuserinfo_end = strrpos($remaining, '@')) !== false) {
- $iuserinfo = substr($remaining, 0, $iuserinfo_end);
- $remaining = substr($remaining, $iuserinfo_end + 1);
- }
- else {
- $iuserinfo = null;
- }
- if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false) {
- $port = substr($remaining, $port_start + 1);
- if ($port === false || $port === '') {
- $port = null;
- }
- $remaining = substr($remaining, 0, $port_start);
- }
- else {
- $port = null;
- }
-
- $return = $this->set_userinfo($iuserinfo) &&
- $this->set_host($remaining) &&
- $this->set_port($port);
-
- $cache[$authority] = array($this->iuserinfo,
- $this->ihost,
- $this->port,
- $return);
-
- return $return;
- }
-
- /**
- * Set the iuserinfo.
- *
- * @param string $iuserinfo
- * @return bool
- */
- protected function set_userinfo($iuserinfo) {
- if ($iuserinfo === null) {
- $this->iuserinfo = null;
- }
- else {
- $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
- $this->scheme_normalization();
- }
-
- return true;
- }
-
- /**
- * Set the ihost. Returns true on success, false on failure (if there are
- * any invalid characters).
- *
- * @param string $ihost
- * @return bool
- */
- protected function set_host($ihost) {
- if ($ihost === null) {
- $this->ihost = null;
- return true;
- }
- if (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']') {
- if (Ipv6::check_ipv6(substr($ihost, 1, -1))) {
- $this->ihost = '[' . Ipv6::compress(substr($ihost, 1, -1)) . ']';
- }
- else {
- $this->ihost = null;
- return false;
- }
- }
- else {
- $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
-
- // Lowercase, but ignore pct-encoded sections (as they should
- // remain uppercase). This must be done after the previous step
- // as that can add unescaped characters.
- $position = 0;
- $strlen = strlen($ihost);
- while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen) {
- if ($ihost[$position] === '%') {
- $position += 3;
- }
- else {
- $ihost[$position] = strtolower($ihost[$position]);
- $position++;
- }
- }
-
- $this->ihost = $ihost;
- }
-
- $this->scheme_normalization();
-
- return true;
- }
-
- /**
- * Set the port. Returns true on success, false on failure (if there are
- * any invalid characters).
- *
- * @param string $port
- * @return bool
- */
- protected function set_port($port) {
- if ($port === null) {
- $this->port = null;
- return true;
- }
-
- if (strspn($port, '0123456789') === strlen($port)) {
- $this->port = (int) $port;
- $this->scheme_normalization();
- return true;
- }
-
- $this->port = null;
- return false;
- }
-
- /**
- * Set the ipath.
- *
- * @param string $ipath
- * @return bool
- */
- protected function set_path($ipath) {
- static $cache;
- if (!$cache) {
- $cache = array();
- }
-
- $ipath = (string) $ipath;
-
- if (isset($cache[$ipath])) {
- $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
- }
- else {
- $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
- $removed = $this->remove_dot_segments($valid);
-
- $cache[$ipath] = array($valid, $removed);
- $this->ipath = ($this->scheme !== null) ? $removed : $valid;
- }
- $this->scheme_normalization();
- return true;
- }
-
- /**
- * Set the iquery.
- *
- * @param string $iquery
- * @return bool
- */
- protected function set_query($iquery) {
- if ($iquery === null) {
- $this->iquery = null;
- }
- else {
- $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
- $this->scheme_normalization();
- }
- return true;
- }
-
- /**
- * Set the ifragment.
- *
- * @param string $ifragment
- * @return bool
- */
- protected function set_fragment($ifragment) {
- if ($ifragment === null) {
- $this->ifragment = null;
- }
- else {
- $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
- $this->scheme_normalization();
- }
- return true;
- }
-
- /**
- * Convert an IRI to a URI (or parts thereof)
- *
- * @param string|bool $iri IRI to convert (or false from {@see \WpOrg\Requests\IRI::get_iri()})
- * @return string|false URI if IRI is valid, false otherwise.
- */
- protected function to_uri($iri) {
- if (!is_string($iri)) {
- return false;
- }
-
- static $non_ascii;
- if (!$non_ascii) {
- $non_ascii = implode('', range("\x80", "\xFF"));
- }
-
- $position = 0;
- $strlen = strlen($iri);
- while (($position += strcspn($iri, $non_ascii, $position)) < $strlen) {
- $iri = substr_replace($iri, sprintf('%%%02X', ord($iri[$position])), $position, 1);
- $position += 3;
- $strlen += 2;
- }
-
- return $iri;
- }
-
- /**
- * Get the complete IRI
- *
- * @return string|false
- */
- protected function get_iri() {
- if (!$this->is_valid()) {
- return false;
- }
-
- $iri = '';
- if ($this->scheme !== null) {
- $iri .= $this->scheme . ':';
- }
- if (($iauthority = $this->get_iauthority()) !== null) {
- $iri .= '//' . $iauthority;
- }
- $iri .= $this->ipath;
- if ($this->iquery !== null) {
- $iri .= '?' . $this->iquery;
- }
- if ($this->ifragment !== null) {
- $iri .= '#' . $this->ifragment;
- }
-
- return $iri;
- }
-
- /**
- * Get the complete URI
- *
- * @return string
- */
- protected function get_uri() {
- return $this->to_uri($this->get_iri());
- }
-
- /**
- * Get the complete iauthority
- *
- * @return string|null
- */
- protected function get_iauthority() {
- if ($this->iuserinfo === null && $this->ihost === null && $this->port === null) {
- return null;
- }
-
- $iauthority = '';
- if ($this->iuserinfo !== null) {
- $iauthority .= $this->iuserinfo . '@';
- }
- if ($this->ihost !== null) {
- $iauthority .= $this->ihost;
- }
- if ($this->port !== null) {
- $iauthority .= ':' . $this->port;
- }
- return $iauthority;
- }
-
- /**
- * Get the complete authority
- *
- * @return string
- */
- protected function get_authority() {
- $iauthority = $this->get_iauthority();
- if (is_string($iauthority)) {
- return $this->to_uri($iauthority);
- }
- else {
- return $iauthority;
- }
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsPortphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Port.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Port.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Port.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,75 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Port utilities for Requests
- *
- * @package Requests\Utilities
- * @since 2.0.0
- */
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-
-/**
- * Find the correct port depending on the Request type.
- *
- * @package Requests\Utilities
- * @since 2.0.0
- */
-final class Port {
-
- /**
- * Port to use with Acap requests.
- *
- * @var int
- */
- const ACAP = 674;
-
- /**
- * Port to use with Dictionary requests.
- *
- * @var int
- */
- const DICT = 2628;
-
- /**
- * Port to use with HTTP requests.
- *
- * @var int
- */
- const HTTP = 80;
-
- /**
- * Port to use with HTTP over SSL requests.
- *
- * @var int
- */
- const HTTPS = 443;
-
- /**
- * Retrieve the port number to use.
- *
- * @param string $type Request type.
- * The following requests types are supported:
- * 'acap', 'dict', 'http' and 'https'.
- *
- * @return int
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When a non-string input has been passed.
- * @throws \WpOrg\Requests\Exception When a non-supported port is requested ('portnotsupported').
- */
- public static function get($type) {
- if (!is_string($type)) {
- throw InvalidArgument::create(1, '$type', 'string', gettype($type));
- }
-
- $type = strtoupper($type);
- if (!defined("self::{$type}")) {
- $message = sprintf('Invalid port type (%s) passed', $type);
- throw new Exception($message, 'portnotsupported');
- }
-
- return constant("self::{$type}");
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsProxyHTTPphpfromrev52243trunksrcwpincludesRequestsProxyHTTPphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Proxy/HTTP.php (from rev 52243, trunk/src/wp-includes/Requests/Proxy/HTTP.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Proxy/HTTP.php (rev 0)
+++ trunk/src/wp-includes/Requests/Proxy/HTTP.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,151 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * HTTP Proxy connection interface
+ *
+ * @package Requests
+ * @subpackage Proxy
+ * @since 1.6
+ */
+
+/**
+ * HTTP Proxy connection interface
+ *
+ * Provides a handler for connection via an HTTP proxy
+ *
+ * @package Requests
+ * @subpackage Proxy
+ * @since 1.6
+ */
+class Requests_Proxy_HTTP implements Requests_Proxy {
+ /**
+ * Proxy host and port
+ *
+ * Notation: "host:port" (eg 127.0.0.1:8080 or someproxy.com:3128)
+ *
+ * @var string
+ */
+ public $proxy;
+
+ /**
+ * Username
+ *
+ * @var string
+ */
+ public $user;
+
+ /**
+ * Password
+ *
+ * @var string
+ */
+ public $pass;
+
+ /**
+ * Do we need to authenticate? (ie username & password have been provided)
+ *
+ * @var boolean
+ */
+ public $use_authentication;
+
+ /**
+ * Constructor
+ *
+ * @since 1.6
+ * @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
+ * @param array|null $args Array of user and password. Must have exactly two elements
+ */
+ public function __construct($args = null) {
+ if (is_string($args)) {
+ $this->proxy = $args;
+ }
+ elseif (is_array($args)) {
+ if (count($args) === 1) {
+ list($this->proxy) = $args;
+ }
+ elseif (count($args) === 3) {
+ list($this->proxy, $this->user, $this->pass) = $args;
+ $this->use_authentication = true;
+ }
+ else {
+ throw new Requests_Exception('Invalid number of arguments', 'proxyhttpbadargs');
+ }
+ }
+ }
+
+ /**
+ * Register the necessary callbacks
+ *
+ * @since 1.6
+ * @see curl_before_send
+ * @see fsockopen_remote_socket
+ * @see fsockopen_remote_host_path
+ * @see fsockopen_header
+ * @param Requests_Hooks $hooks Hook system
+ */
+ public function register(Requests_Hooks $hooks) {
+ $hooks->register('curl.before_send', array($this, 'curl_before_send'));
+
+ $hooks->register('fsockopen.remote_socket', array($this, 'fsockopen_remote_socket'));
+ $hooks->register('fsockopen.remote_host_path', array($this, 'fsockopen_remote_host_path'));
+ if ($this->use_authentication) {
+ $hooks->register('fsockopen.after_headers', array($this, 'fsockopen_header'));
+ }
+ }
+
+ /**
+ * Set cURL parameters before the data is sent
+ *
+ * @since 1.6
+ * @param resource $handle cURL resource
+ */
+ public function curl_before_send(&$handle) {
+ curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ curl_setopt($handle, CURLOPT_PROXY, $this->proxy);
+
+ if ($this->use_authentication) {
+ curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+ curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string());
+ }
+ }
+
+ /**
+ * Alter remote socket information before opening socket connection
+ *
+ * @since 1.6
+ * @param string $remote_socket Socket connection string
+ */
+ public function fsockopen_remote_socket(&$remote_socket) {
+ $remote_socket = $this->proxy;
+ }
+
+ /**
+ * Alter remote path before getting stream data
+ *
+ * @since 1.6
+ * @param string $path Path to send in HTTP request string ("GET ...")
+ * @param string $url Full URL we're requesting
+ */
+ public function fsockopen_remote_host_path(&$path, $url) {
+ $path = $url;
+ }
+
+ /**
+ * Add extra headers to the request before sending
+ *
+ * @since 1.6
+ * @param string $out HTTP header string
+ */
+ public function fsockopen_header(&$out) {
+ $out .= sprintf("Proxy-Authorization: Basic %s\r\n", base64_encode($this->get_auth_string()));
+ }
+
+ /**
+ * Get the authentication string (user:pass)
+ *
+ * @since 1.6
+ * @return string
+ */
+ public function get_auth_string() {
+ return $this->user . ':' . $this->pass;
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsProxyHttpphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Proxy/Http.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Proxy/Http.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Proxy/Http.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,167 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * HTTP Proxy connection interface
- *
- * @package Requests\Proxy
- * @since 1.6
- */
-
-namespace WpOrg\Requests\Proxy;
-
-use WpOrg\Requests\Exception\ArgumentCount;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Hooks;
-use WpOrg\Requests\Proxy;
-
-/**
- * HTTP Proxy connection interface
- *
- * Provides a handler for connection via an HTTP proxy
- *
- * @package Requests\Proxy
- * @since 1.6
- */
-final class Http implements Proxy {
- /**
- * Proxy host and port
- *
- * Notation: "host:port" (eg 127.0.0.1:8080 or someproxy.com:3128)
- *
- * @var string
- */
- public $proxy;
-
- /**
- * Username
- *
- * @var string
- */
- public $user;
-
- /**
- * Password
- *
- * @var string
- */
- public $pass;
-
- /**
- * Do we need to authenticate? (ie username & password have been provided)
- *
- * @var boolean
- */
- public $use_authentication;
-
- /**
- * Constructor
- *
- * @since 1.6
- *
- * @param array|string|null $args Proxy as a string or an array of proxy, user and password.
- * When passed as an array, must have exactly one (proxy)
- * or three elements (proxy, user, password).
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array, a string or null.
- * @throws \WpOrg\Requests\Exception\ArgumentCount On incorrect number of arguments (`proxyhttpbadargs`)
- */
- public function __construct($args = null) {
- if (is_string($args)) {
- $this->proxy = $args;
- }
- elseif (is_array($args)) {
- if (count($args) === 1) {
- list($this->proxy) = $args;
- }
- elseif (count($args) === 3) {
- list($this->proxy, $this->user, $this->pass) = $args;
- $this->use_authentication = true;
- }
- else {
- throw ArgumentCount::create(
- 'an array with exactly one element or exactly three elements',
- count($args),
- 'proxyhttpbadargs'
- );
- }
- } elseif ($args !== null) {
- throw InvalidArgument::create(1, '$args', 'array|string|null', gettype($args));
- }
- }
-
- /**
- * Register the necessary callbacks
- *
- * @since 1.6
- * @see \WpOrg\Requests\Proxy\HTTP::curl_before_send()
- * @see \WpOrg\Requests\Proxy\HTTP::fsockopen_remote_socket()
- * @see \WpOrg\Requests\Proxy\HTTP::fsockopen_remote_host_path()
- * @see \WpOrg\Requests\Proxy\HTTP::fsockopen_header()
- * @param \WpOrg\Requests\Hooks $hooks Hook system
- */
- public function register(Hooks $hooks) {
- $hooks->register('curl.before_send', [$this, 'curl_before_send']);
-
- $hooks->register('fsockopen.remote_socket', [$this, 'fsockopen_remote_socket']);
- $hooks->register('fsockopen.remote_host_path', [$this, 'fsockopen_remote_host_path']);
- if ($this->use_authentication) {
- $hooks->register('fsockopen.after_headers', [$this, 'fsockopen_header']);
- }
- }
-
- /**
- * Set cURL parameters before the data is sent
- *
- * @since 1.6
- * @param resource|\CurlHandle $handle cURL handle
- */
- public function curl_before_send(&$handle) {
- curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
- curl_setopt($handle, CURLOPT_PROXY, $this->proxy);
-
- if ($this->use_authentication) {
- curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
- curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string());
- }
- }
-
- /**
- * Alter remote socket information before opening socket connection
- *
- * @since 1.6
- * @param string $remote_socket Socket connection string
- */
- public function fsockopen_remote_socket(&$remote_socket) {
- $remote_socket = $this->proxy;
- }
-
- /**
- * Alter remote path before getting stream data
- *
- * @since 1.6
- * @param string $path Path to send in HTTP request string ("GET ...")
- * @param string $url Full URL we're requesting
- */
- public function fsockopen_remote_host_path(&$path, $url) {
- $path = $url;
- }
-
- /**
- * Add extra headers to the request before sending
- *
- * @since 1.6
- * @param string $out HTTP header string
- */
- public function fsockopen_header(&$out) {
- $out .= sprintf("Proxy-Authorization: Basic %s\r\n", base64_encode($this->get_auth_string()));
- }
-
- /**
- * Get the authentication string (user:pass)
- *
- * @since 1.6
- * @return string
- */
- public function get_auth_string() {
- return $this->user . ':' . $this->pass;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsProxyphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Proxy.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Proxy.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Proxy.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,14 +2,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Proxy connection interface
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Proxy
- * @since 1.6
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Proxy
+ * @since 1.6
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Hooks;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Proxy connection interface
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -18,21 +15,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Parameters should be passed via the constructor where possible, as this
</span><span class="cx" style="display: block; padding: 0 10px"> * makes it much easier for users to use your provider.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Hooks
- *
- * @package Requests\Proxy
- * @since 1.6
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests_Hooks
+ * @package Requests
+ * @subpackage Proxy
+ * @since 1.6
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-interface Proxy {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+interface Requests_Proxy {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Register hooks as needed
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * This method is called in {@see \WpOrg\Requests\Requests::request()} when the user
- * has set an instance as the 'auth' option. Use this callback to register all the
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * This method is called in {@see Requests::request} when the user has set
+ * an instance as the 'auth' option. Use this callback to register all the
</ins><span class="cx" style="display: block; padding: 0 10px"> * hooks you'll need.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Hooks::register()
- * @param \WpOrg\Requests\Hooks $hooks Hook system
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests_Hooks::register
+ * @param Requests_Hooks $hooks Hook system
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function register(Hooks $hooks);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function register(Requests_Hooks $hooks);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsRequestsphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Requests.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Requests.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Requests.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,1079 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Requests for PHP
- *
- * Inspired by Requests for Python.
- *
- * Based on concepts from SimplePie_File, RequestCore and WP_Http.
- *
- * @package Requests
- */
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Auth\Basic;
-use WpOrg\Requests\Capability;
-use WpOrg\Requests\Cookie\Jar;
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Hooks;
-use WpOrg\Requests\IdnaEncoder;
-use WpOrg\Requests\Iri;
-use WpOrg\Requests\Proxy\Http;
-use WpOrg\Requests\Response;
-use WpOrg\Requests\Transport\Curl;
-use WpOrg\Requests\Transport\Fsockopen;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * Requests for PHP
- *
- * Inspired by Requests for Python.
- *
- * Based on concepts from SimplePie_File, RequestCore and WP_Http.
- *
- * @package Requests
- */
-class Requests {
- /**
- * POST method
- *
- * @var string
- */
- const POST = 'POST';
-
- /**
- * PUT method
- *
- * @var string
- */
- const PUT = 'PUT';
-
- /**
- * GET method
- *
- * @var string
- */
- const GET = 'GET';
-
- /**
- * HEAD method
- *
- * @var string
- */
- const HEAD = 'HEAD';
-
- /**
- * DELETE method
- *
- * @var string
- */
- const DELETE = 'DELETE';
-
- /**
- * OPTIONS method
- *
- * @var string
- */
- const OPTIONS = 'OPTIONS';
-
- /**
- * TRACE method
- *
- * @var string
- */
- const TRACE = 'TRACE';
-
- /**
- * PATCH method
- *
- * @link https://tools.ietf.org/html/rfc5789
- * @var string
- */
- const PATCH = 'PATCH';
-
- /**
- * Default size of buffer size to read streams
- *
- * @var integer
- */
- const BUFFER_SIZE = 1160;
-
- /**
- * Option defaults.
- *
- * @see \WpOrg\Requests\Requests::get_default_options()
- * @see \WpOrg\Requests\Requests::request() for values returned by this method
- *
- * @since 2.0.0
- *
- * @var array
- */
- const OPTION_DEFAULTS = [
- 'timeout' => 10,
- 'connect_timeout' => 10,
- 'useragent' => 'php-requests/' . self::VERSION,
- 'protocol_version' => 1.1,
- 'redirected' => 0,
- 'redirects' => 10,
- 'follow_redirects' => true,
- 'blocking' => true,
- 'type' => self::GET,
- 'filename' => false,
- 'auth' => false,
- 'proxy' => false,
- 'cookies' => false,
- 'max_bytes' => false,
- 'idn' => true,
- 'hooks' => null,
- 'transport' => null,
- 'verify' => null,
- 'verifyname' => true,
- ];
-
- /**
- * Default supported Transport classes.
- *
- * @since 2.0.0
- *
- * @var array
- */
- const DEFAULT_TRANSPORTS = [
- Curl::class => Curl::class,
- Fsockopen::class => Fsockopen::class,
- ];
-
- /**
- * Current version of Requests
- *
- * @var string
- */
- const VERSION = '2.0.0';
-
- /**
- * Selected transport name
- *
- * Use {@see \WpOrg\Requests\Requests::get_transport()} instead
- *
- * @var array
- */
- public static $transport = [];
-
- /**
- * Registered transport classes
- *
- * @var array
- */
- protected static $transports = [];
-
- /**
- * Default certificate path.
- *
- * @see \WpOrg\Requests\Requests::get_certificate_path()
- * @see \WpOrg\Requests\Requests::set_certificate_path()
- *
- * @var string
- */
- protected static $certificate_path = __DIR__ . '/../certificates/cacert.pem';
-
- /**
- * All (known) valid deflate, gzip header magic markers.
- *
- * These markers relate to different compression levels.
- *
- * @link https://stackoverflow.com/a/43170354/482864 Marker source.
- *
- * @since 2.0.0
- *
- * @var array
- */
- private static $magic_compression_headers = [
- "\x1f\x8b" => true, // Gzip marker.
- "\x78\x01" => true, // Zlib marker - level 1.
- "\x78\x5e" => true, // Zlib marker - level 2 to 5.
- "\x78\x9c" => true, // Zlib marker - level 6.
- "\x78\xda" => true, // Zlib marker - level 7 to 9.
- ];
-
- /**
- * This is a static class, do not instantiate it
- *
- * @codeCoverageIgnore
- */
- private function __construct() {}
-
- /**
- * Register a transport
- *
- * @param string $transport Transport class to add, must support the \WpOrg\Requests\Transport interface
- */
- public static function add_transport($transport) {
- if (empty(self::$transports)) {
- self::$transports = self::DEFAULT_TRANSPORTS;
- }
-
- self::$transports[$transport] = $transport;
- }
-
- /**
- * Get the fully qualified class name (FQCN) for a working transport.
- *
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return string FQCN of the transport to use, or an empty string if no transport was
- * found which provided the requested capabilities.
- */
- protected static function get_transport_class(array $capabilities = []) {
- // Caching code, don't bother testing coverage.
- // @codeCoverageIgnoreStart
- // Array of capabilities as a string to be used as an array key.
- ksort($capabilities);
- $cap_string = serialize($capabilities);
-
- // Don't search for a transport if it's already been done for these $capabilities.
- if (isset(self::$transport[$cap_string])) {
- return self::$transport[$cap_string];
- }
-
- // Ensure we will not run this same check again later on.
- self::$transport[$cap_string] = '';
- // @codeCoverageIgnoreEnd
-
- if (empty(self::$transports)) {
- self::$transports = self::DEFAULT_TRANSPORTS;
- }
-
- // Find us a working transport.
- foreach (self::$transports as $class) {
- if (!class_exists($class)) {
- continue;
- }
-
- $result = $class::test($capabilities);
- if ($result === true) {
- self::$transport[$cap_string] = $class;
- break;
- }
- }
-
- return self::$transport[$cap_string];
- }
-
- /**
- * Get a working transport.
- *
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return \WpOrg\Requests\Transport
- * @throws \WpOrg\Requests\Exception If no valid transport is found (`notransport`).
- */
- protected static function get_transport(array $capabilities = []) {
- $class = self::get_transport_class($capabilities);
-
- if ($class === '') {
- throw new Exception('No working transports found', 'notransport', self::$transports);
- }
-
- return new $class();
- }
-
- /**
- * Checks to see if we have a transport for the capabilities requested.
- *
- * Supported capabilities can be found in the {@see \WpOrg\Requests\Capability}
- * interface as constants.
- *
- * Example usage:
- * `Requests::has_capabilities([Capability::SSL => true])`.
- *
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return bool Whether the transport has the requested capabilities.
- */
- public static function has_capabilities(array $capabilities = []) {
- return self::get_transport_class($capabilities) !== '';
- }
-
- /**#@+
- * @see \WpOrg\Requests\Requests::request()
- * @param string $url
- * @param array $headers
- * @param array $options
- * @return \WpOrg\Requests\Response
- */
- /**
- * Send a GET request
- */
- public static function get($url, $headers = [], $options = []) {
- return self::request($url, $headers, null, self::GET, $options);
- }
-
- /**
- * Send a HEAD request
- */
- public static function head($url, $headers = [], $options = []) {
- return self::request($url, $headers, null, self::HEAD, $options);
- }
-
- /**
- * Send a DELETE request
- */
- public static function delete($url, $headers = [], $options = []) {
- return self::request($url, $headers, null, self::DELETE, $options);
- }
-
- /**
- * Send a TRACE request
- */
- public static function trace($url, $headers = [], $options = []) {
- return self::request($url, $headers, null, self::TRACE, $options);
- }
- /**#@-*/
-
- /**#@+
- * @see \WpOrg\Requests\Requests::request()
- * @param string $url
- * @param array $headers
- * @param array $data
- * @param array $options
- * @return \WpOrg\Requests\Response
- */
- /**
- * Send a POST request
- */
- public static function post($url, $headers = [], $data = [], $options = []) {
- return self::request($url, $headers, $data, self::POST, $options);
- }
- /**
- * Send a PUT request
- */
- public static function put($url, $headers = [], $data = [], $options = []) {
- return self::request($url, $headers, $data, self::PUT, $options);
- }
-
- /**
- * Send an OPTIONS request
- */
- public static function options($url, $headers = [], $data = [], $options = []) {
- return self::request($url, $headers, $data, self::OPTIONS, $options);
- }
-
- /**
- * Send a PATCH request
- *
- * Note: Unlike {@see \WpOrg\Requests\Requests::post()} and {@see \WpOrg\Requests\Requests::put()},
- * `$headers` is required, as the specification recommends that should send an ETag
- *
- * @link https://tools.ietf.org/html/rfc5789
- */
- public static function patch($url, $headers, $data = [], $options = []) {
- return self::request($url, $headers, $data, self::PATCH, $options);
- }
- /**#@-*/
-
- /**
- * Main interface for HTTP requests
- *
- * This method initiates a request and sends it via a transport before
- * parsing.
- *
- * The `$options` parameter takes an associative array with the following
- * options:
- *
- * - `timeout`: How long should we wait for a response?
- * Note: for cURL, a minimum of 1 second applies, as DNS resolution
- * operates at second-resolution only.
- * (float, seconds with a millisecond precision, default: 10, example: 0.01)
- * - `connect_timeout`: How long should we wait while trying to connect?
- * (float, seconds with a millisecond precision, default: 10, example: 0.01)
- * - `useragent`: Useragent to send to the server
- * (string, default: php-requests/$version)
- * - `follow_redirects`: Should we follow 3xx redirects?
- * (boolean, default: true)
- * - `redirects`: How many times should we redirect before erroring?
- * (integer, default: 10)
- * - `blocking`: Should we block processing on this request?
- * (boolean, default: true)
- * - `filename`: File to stream the body to instead.
- * (string|boolean, default: false)
- * - `auth`: Authentication handler or array of user/password details to use
- * for Basic authentication
- * (\WpOrg\Requests\Auth|array|boolean, default: false)
- * - `proxy`: Proxy details to use for proxy by-passing and authentication
- * (\WpOrg\Requests\Proxy|array|string|boolean, default: false)
- * - `max_bytes`: Limit for the response body size.
- * (integer|boolean, default: false)
- * - `idn`: Enable IDN parsing
- * (boolean, default: true)
- * - `transport`: Custom transport. Either a class name, or a
- * transport object. Defaults to the first working transport from
- * {@see \WpOrg\Requests\Requests::getTransport()}
- * (string|\WpOrg\Requests\Transport, default: {@see \WpOrg\Requests\Requests::getTransport()})
- * - `hooks`: Hooks handler.
- * (\WpOrg\Requests\HookManager, default: new WpOrg\Requests\Hooks())
- * - `verify`: Should we verify SSL certificates? Allows passing in a custom
- * certificate file as a string. (Using true uses the system-wide root
- * certificate store instead, but this may have different behaviour
- * across transports.)
- * (string|boolean, default: certificates/cacert.pem)
- * - `verifyname`: Should we verify the common name in the SSL certificate?
- * (boolean, default: true)
- * - `data_format`: How should we send the `$data` parameter?
- * (string, one of 'query' or 'body', default: 'query' for
- * HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH)
- *
- * @param string|Stringable $url URL to request
- * @param array $headers Extra headers to send with the request
- * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
- * @param string $type HTTP request type (use Requests constants)
- * @param array $options Options for the request (see description for more information)
- * @return \WpOrg\Requests\Response
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $type argument is not a string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- * @throws \WpOrg\Requests\Exception On invalid URLs (`nonhttp`)
- */
- public static function request($url, $headers = [], $data = [], $type = self::GET, $options = []) {
- if (InputValidator::is_string_or_stringable($url) === false) {
- throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url));
- }
-
- if (is_string($type) === false) {
- throw InvalidArgument::create(4, '$type', 'string', gettype($type));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(5, '$options', 'array', gettype($options));
- }
-
- if (empty($options['type'])) {
- $options['type'] = $type;
- }
- $options = array_merge(self::get_default_options(), $options);
-
- self::set_defaults($url, $headers, $data, $type, $options);
-
- $options['hooks']->dispatch('requests.before_request', [&$url, &$headers, &$data, &$type, &$options]);
-
- if (!empty($options['transport'])) {
- $transport = $options['transport'];
-
- if (is_string($options['transport'])) {
- $transport = new $transport();
- }
- }
- else {
- $need_ssl = (stripos($url, 'https://') === 0);
- $capabilities = [Capability::SSL => $need_ssl];
- $transport = self::get_transport($capabilities);
- }
- $response = $transport->request($url, $headers, $data, $options);
-
- $options['hooks']->dispatch('requests.before_parse', [&$response, $url, $headers, $data, $type, $options]);
-
- return self::parse_response($response, $url, $headers, $data, $options);
- }
-
- /**
- * Send multiple HTTP requests simultaneously
- *
- * The `$requests` parameter takes an associative or indexed array of
- * request fields. The key of each request can be used to match up the
- * request with the returned data, or with the request passed into your
- * `multiple.request.complete` callback.
- *
- * The request fields value is an associative array with the following keys:
- *
- * - `url`: Request URL Same as the `$url` parameter to
- * {@see \WpOrg\Requests\Requests::request()}
- * (string, required)
- * - `headers`: Associative array of header fields. Same as the `$headers`
- * parameter to {@see \WpOrg\Requests\Requests::request()}
- * (array, default: `array()`)
- * - `data`: Associative array of data fields or a string. Same as the
- * `$data` parameter to {@see \WpOrg\Requests\Requests::request()}
- * (array|string, default: `array()`)
- * - `type`: HTTP request type (use \WpOrg\Requests\Requests constants). Same as the `$type`
- * parameter to {@see \WpOrg\Requests\Requests::request()}
- * (string, default: `\WpOrg\Requests\Requests::GET`)
- * - `cookies`: Associative array of cookie name to value, or cookie jar.
- * (array|\WpOrg\Requests\Cookie\Jar)
- *
- * If the `$options` parameter is specified, individual requests will
- * inherit options from it. This can be used to use a single hooking system,
- * or set all the types to `\WpOrg\Requests\Requests::POST`, for example.
- *
- * In addition, the `$options` parameter takes the following global options:
- *
- * - `complete`: A callback for when a request is complete. Takes two
- * parameters, a \WpOrg\Requests\Response/\WpOrg\Requests\Exception reference, and the
- * ID from the request array (Note: this can also be overridden on a
- * per-request basis, although that's a little silly)
- * (callback)
- *
- * @param array $requests Requests data (see description for more information)
- * @param array $options Global and default options (see {@see \WpOrg\Requests\Requests::request()})
- * @return array Responses (either \WpOrg\Requests\Response or a \WpOrg\Requests\Exception object)
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- */
- public static function request_multiple($requests, $options = []) {
- if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
- throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(2, '$options', 'array', gettype($options));
- }
-
- $options = array_merge(self::get_default_options(true), $options);
-
- if (!empty($options['hooks'])) {
- $options['hooks']->register('transport.internal.parse_response', [static::class, 'parse_multiple']);
- if (!empty($options['complete'])) {
- $options['hooks']->register('multiple.request.complete', $options['complete']);
- }
- }
-
- foreach ($requests as $id => &$request) {
- if (!isset($request['headers'])) {
- $request['headers'] = [];
- }
- if (!isset($request['data'])) {
- $request['data'] = [];
- }
- if (!isset($request['type'])) {
- $request['type'] = self::GET;
- }
- if (!isset($request['options'])) {
- $request['options'] = $options;
- $request['options']['type'] = $request['type'];
- }
- else {
- if (empty($request['options']['type'])) {
- $request['options']['type'] = $request['type'];
- }
- $request['options'] = array_merge($options, $request['options']);
- }
-
- self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']);
-
- // Ensure we only hook in once
- if ($request['options']['hooks'] !== $options['hooks']) {
- $request['options']['hooks']->register('transport.internal.parse_response', [static::class, 'parse_multiple']);
- if (!empty($request['options']['complete'])) {
- $request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']);
- }
- }
- }
- unset($request);
-
- if (!empty($options['transport'])) {
- $transport = $options['transport'];
-
- if (is_string($options['transport'])) {
- $transport = new $transport();
- }
- }
- else {
- $transport = self::get_transport();
- }
- $responses = $transport->request_multiple($requests, $options);
-
- foreach ($responses as $id => &$response) {
- // If our hook got messed with somehow, ensure we end up with the
- // correct response
- if (is_string($response)) {
- $request = $requests[$id];
- self::parse_multiple($response, $request);
- $request['options']['hooks']->dispatch('multiple.request.complete', [&$response, $id]);
- }
- }
-
- return $responses;
- }
-
- /**
- * Get the default options
- *
- * @see \WpOrg\Requests\Requests::request() for values returned by this method
- * @param boolean $multirequest Is this a multirequest?
- * @return array Default option values
- */
- protected static function get_default_options($multirequest = false) {
- $defaults = static::OPTION_DEFAULTS;
- $defaults['verify'] = self::$certificate_path;
-
- if ($multirequest !== false) {
- $defaults['complete'] = null;
- }
- return $defaults;
- }
-
- /**
- * Get default certificate path.
- *
- * @return string Default certificate path.
- */
- public static function get_certificate_path() {
- return self::$certificate_path;
- }
-
- /**
- * Set default certificate path.
- *
- * @param string|Stringable|bool $path Certificate path, pointing to a PEM file.
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string, Stringable or boolean.
- */
- public static function set_certificate_path($path) {
- if (InputValidator::is_string_or_stringable($path) === false && is_bool($path) === false) {
- throw InvalidArgument::create(1, '$path', 'string|Stringable|bool', gettype($path));
- }
-
- self::$certificate_path = $path;
- }
-
- /**
- * Set the default values
- *
- * @param string $url URL to request
- * @param array $headers Extra headers to send with the request
- * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
- * @param string $type HTTP request type
- * @param array $options Options for the request
- * @return void $options is updated with the results
- *
- * @throws \WpOrg\Requests\Exception When the $url is not an http(s) URL.
- */
- protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) {
- if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) {
- throw new Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url);
- }
-
- if (empty($options['hooks'])) {
- $options['hooks'] = new Hooks();
- }
-
- if (is_array($options['auth'])) {
- $options['auth'] = new Basic($options['auth']);
- }
- if ($options['auth'] !== false) {
- $options['auth']->register($options['hooks']);
- }
-
- if (is_string($options['proxy']) || is_array($options['proxy'])) {
- $options['proxy'] = new Http($options['proxy']);
- }
- if ($options['proxy'] !== false) {
- $options['proxy']->register($options['hooks']);
- }
-
- if (is_array($options['cookies'])) {
- $options['cookies'] = new Jar($options['cookies']);
- }
- elseif (empty($options['cookies'])) {
- $options['cookies'] = new Jar();
- }
- if ($options['cookies'] !== false) {
- $options['cookies']->register($options['hooks']);
- }
-
- if ($options['idn'] !== false) {
- $iri = new Iri($url);
- $iri->host = IdnaEncoder::encode($iri->ihost);
- $url = $iri->uri;
- }
-
- // Massage the type to ensure we support it.
- $type = strtoupper($type);
-
- if (!isset($options['data_format'])) {
- if (in_array($type, [self::HEAD, self::GET, self::DELETE], true)) {
- $options['data_format'] = 'query';
- }
- else {
- $options['data_format'] = 'body';
- }
- }
- }
-
- /**
- * HTTP response parser
- *
- * @param string $headers Full response text including headers and body
- * @param string $url Original request URL
- * @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
- * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects
- * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects
- * @return \WpOrg\Requests\Response
- *
- * @throws \WpOrg\Requests\Exception On missing head/body separator (`requests.no_crlf_separator`)
- * @throws \WpOrg\Requests\Exception On missing head/body separator (`noversion`)
- * @throws \WpOrg\Requests\Exception On missing head/body separator (`toomanyredirects`)
- */
- protected static function parse_response($headers, $url, $req_headers, $req_data, $options) {
- $return = new Response();
- if (!$options['blocking']) {
- return $return;
- }
-
- $return->raw = $headers;
- $return->url = (string) $url;
- $return->body = '';
-
- if (!$options['filename']) {
- $pos = strpos($headers, "\r\n\r\n");
- if ($pos === false) {
- // Crap!
- throw new Exception('Missing header/body separator', 'requests.no_crlf_separator');
- }
-
- $headers = substr($return->raw, 0, $pos);
- // Headers will always be separated from the body by two new lines - `\n\r\n\r`.
- $body = substr($return->raw, $pos + 4);
- if (!empty($body)) {
- $return->body = $body;
- }
- }
- // Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
- $headers = str_replace("\r\n", "\n", $headers);
- // Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
- $headers = preg_replace('/\n[ \t]/', ' ', $headers);
- $headers = explode("\n", $headers);
- preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches);
- if (empty($matches)) {
- throw new Exception('Response could not be parsed', 'noversion', $headers);
- }
- $return->protocol_version = (float) $matches[1];
- $return->status_code = (int) $matches[2];
- if ($return->status_code >= 200 && $return->status_code < 300) {
- $return->success = true;
- }
-
- foreach ($headers as $header) {
- list($key, $value) = explode(':', $header, 2);
- $value = trim($value);
- preg_replace('#(\s+)#i', ' ', $value);
- $return->headers[$key] = $value;
- }
- if (isset($return->headers['transfer-encoding'])) {
- $return->body = self::decode_chunked($return->body);
- unset($return->headers['transfer-encoding']);
- }
- if (isset($return->headers['content-encoding'])) {
- $return->body = self::decompress($return->body);
- }
-
- //fsockopen and cURL compatibility
- if (isset($return->headers['connection'])) {
- unset($return->headers['connection']);
- }
-
- $options['hooks']->dispatch('requests.before_redirect_check', [&$return, $req_headers, $req_data, $options]);
-
- if ($return->is_redirect() && $options['follow_redirects'] === true) {
- if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
- if ($return->status_code === 303) {
- $options['type'] = self::GET;
- }
- $options['redirected']++;
- $location = $return->headers['location'];
- if (strpos($location, 'http://') !== 0 && strpos($location, 'https://') !== 0) {
- // relative redirect, for compatibility make it absolute
- $location = Iri::absolutize($url, $location);
- $location = $location->uri;
- }
-
- $hook_args = [
- &$location,
- &$req_headers,
- &$req_data,
- &$options,
- $return,
- ];
- $options['hooks']->dispatch('requests.before_redirect', $hook_args);
- $redirected = self::request($location, $req_headers, $req_data, $options['type'], $options);
- $redirected->history[] = $return;
- return $redirected;
- }
- elseif ($options['redirected'] >= $options['redirects']) {
- throw new Exception('Too many redirects', 'toomanyredirects', $return);
- }
- }
-
- $return->redirects = $options['redirected'];
-
- $options['hooks']->dispatch('requests.after_request', [&$return, $req_headers, $req_data, $options]);
- return $return;
- }
-
- /**
- * Callback for `transport.internal.parse_response`
- *
- * Internal use only. Converts a raw HTTP response to a \WpOrg\Requests\Response
- * while still executing a multiple request.
- *
- * @param string $response Full response text including headers and body (will be overwritten with Response instance)
- * @param array $request Request data as passed into {@see \WpOrg\Requests\Requests::request_multiple()}
- * @return void `$response` is either set to a \WpOrg\Requests\Response instance, or a \WpOrg\Requests\Exception object
- */
- public static function parse_multiple(&$response, $request) {
- try {
- $url = $request['url'];
- $headers = $request['headers'];
- $data = $request['data'];
- $options = $request['options'];
- $response = self::parse_response($response, $url, $headers, $data, $options);
- }
- catch (Exception $e) {
- $response = $e;
- }
- }
-
- /**
- * Decoded a chunked body as per RFC 2616
- *
- * @link https://tools.ietf.org/html/rfc2616#section-3.6.1
- * @param string $data Chunked body
- * @return string Decoded body
- */
- protected static function decode_chunked($data) {
- if (!preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', trim($data))) {
- return $data;
- }
-
- $decoded = '';
- $encoded = $data;
-
- while (true) {
- $is_chunked = (bool) preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', $encoded, $matches);
- if (!$is_chunked) {
- // Looks like it's not chunked after all
- return $data;
- }
-
- $length = hexdec(trim($matches[1]));
- if ($length === 0) {
- // Ignore trailer headers
- return $decoded;
- }
-
- $chunk_length = strlen($matches[0]);
- $decoded .= substr($encoded, $chunk_length, $length);
- $encoded = substr($encoded, $chunk_length + $length + 2);
-
- if (trim($encoded) === '0' || empty($encoded)) {
- return $decoded;
- }
- }
-
- // We'll never actually get down here
- // @codeCoverageIgnoreStart
- }
- // @codeCoverageIgnoreEnd
-
- /**
- * Convert a key => value array to a 'key: value' array for headers
- *
- * @param iterable $dictionary Dictionary of header values
- * @return array List of headers
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not iterable.
- */
- public static function flatten($dictionary) {
- if (InputValidator::is_iterable($dictionary) === false) {
- throw InvalidArgument::create(1, '$dictionary', 'iterable', gettype($dictionary));
- }
-
- $return = [];
- foreach ($dictionary as $key => $value) {
- $return[] = sprintf('%s: %s', $key, $value);
- }
- return $return;
- }
-
- /**
- * Decompress an encoded body
- *
- * Implements gzip, compress and deflate. Guesses which it is by attempting
- * to decode.
- *
- * @param string $data Compressed data in one of the above formats
- * @return string Decompressed string
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string.
- */
- public static function decompress($data) {
- if (is_string($data) === false) {
- throw InvalidArgument::create(1, '$data', 'string', gettype($data));
- }
-
- if (trim($data) === '') {
- // Empty body does not need further processing.
- return $data;
- }
-
- $marker = substr($data, 0, 2);
- if (!isset(self::$magic_compression_headers[$marker])) {
- // Not actually compressed. Probably cURL ruining this for us.
- return $data;
- }
-
- if (function_exists('gzdecode')) {
- $decoded = @gzdecode($data);
- if ($decoded !== false) {
- return $decoded;
- }
- }
-
- if (function_exists('gzinflate')) {
- $decoded = @gzinflate($data);
- if ($decoded !== false) {
- return $decoded;
- }
- }
-
- $decoded = self::compatible_gzinflate($data);
- if ($decoded !== false) {
- return $decoded;
- }
-
- if (function_exists('gzuncompress')) {
- $decoded = @gzuncompress($data);
- if ($decoded !== false) {
- return $decoded;
- }
- }
-
- return $data;
- }
-
- /**
- * Decompression of deflated string while staying compatible with the majority of servers.
- *
- * Certain Servers will return deflated data with headers which PHP's gzinflate()
- * function cannot handle out of the box. The following function has been created from
- * various snippets on the gzinflate() PHP documentation.
- *
- * Warning: Magic numbers within. Due to the potential different formats that the compressed
- * data may be returned in, some "magic offsets" are needed to ensure proper decompression
- * takes place. For a simple progmatic way to determine the magic offset in use, see:
- * https://core.trac.wordpress.org/ticket/18273
- *
- * @since 1.6.0
- * @link https://core.trac.wordpress.org/ticket/18273
- * @link https://www.php.net/gzinflate#70875
- * @link https://www.php.net/gzinflate#77336
- *
- * @param string $gz_data String to decompress.
- * @return string|bool False on failure.
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string.
- */
- public static function compatible_gzinflate($gz_data) {
- if (is_string($gz_data) === false) {
- throw InvalidArgument::create(1, '$gz_data', 'string', gettype($gz_data));
- }
-
- if (trim($gz_data) === '') {
- return false;
- }
-
- // Compressed data might contain a full zlib header, if so strip it for
- // gzinflate()
- if (substr($gz_data, 0, 3) === "\x1f\x8b\x08") {
- $i = 10;
- $flg = ord(substr($gz_data, 3, 1));
- if ($flg > 0) {
- if ($flg & 4) {
- list($xlen) = unpack('v', substr($gz_data, $i, 2));
- $i += 2 + $xlen;
- }
- if ($flg & 8) {
- $i = strpos($gz_data, "\0", $i) + 1;
- }
- if ($flg & 16) {
- $i = strpos($gz_data, "\0", $i) + 1;
- }
- if ($flg & 2) {
- $i += 2;
- }
- }
- $decompressed = self::compatible_gzinflate(substr($gz_data, $i));
- if ($decompressed !== false) {
- return $decompressed;
- }
- }
-
- // If the data is Huffman Encoded, we must first strip the leading 2
- // byte Huffman marker for gzinflate()
- // The response is Huffman coded by many compressors such as
- // java.util.zip.Deflater, Ruby's Zlib::Deflate, and .NET's
- // System.IO.Compression.DeflateStream.
- //
- // See https://decompres.blogspot.com/ for a quick explanation of this
- // data type
- $huffman_encoded = false;
-
- // low nibble of first byte should be 0x08
- list(, $first_nibble) = unpack('h', $gz_data);
-
- // First 2 bytes should be divisible by 0x1F
- list(, $first_two_bytes) = unpack('n', $gz_data);
-
- if ($first_nibble === 0x08 && ($first_two_bytes % 0x1F) === 0) {
- $huffman_encoded = true;
- }
-
- if ($huffman_encoded) {
- $decompressed = @gzinflate(substr($gz_data, 2));
- if ($decompressed !== false) {
- return $decompressed;
- }
- }
-
- if (substr($gz_data, 0, 4) === "\x50\x4b\x03\x04") {
- // ZIP file format header
- // Offset 6: 2 bytes, General-purpose field
- // Offset 26: 2 bytes, filename length
- // Offset 28: 2 bytes, optional field length
- // Offset 30: Filename field, followed by optional field, followed
- // immediately by data
- list(, $general_purpose_flag) = unpack('v', substr($gz_data, 6, 2));
-
- // If the file has been compressed on the fly, 0x08 bit is set of
- // the general purpose field. We can use this to differentiate
- // between a compressed document, and a ZIP file
- $zip_compressed_on_the_fly = ((0x08 & $general_purpose_flag) === 0x08);
-
- if (!$zip_compressed_on_the_fly) {
- // Don't attempt to decode a compressed zip file
- return $gz_data;
- }
-
- // Determine the first byte of data, based on the above ZIP header
- // offsets:
- $first_file_start = array_sum(unpack('v2', substr($gz_data, 26, 4)));
- $decompressed = @gzinflate(substr($gz_data, 30 + $first_file_start));
- if ($decompressed !== false) {
- return $decompressed;
- }
- return false;
- }
-
- // Finally fall back to straight gzinflate
- $decompressed = @gzinflate($gz_data);
- if ($decompressed !== false) {
- return $decompressed;
- }
-
- // Fallback for all above failing, not expected, but included for
- // debugging and preventing regressions and to track stats
- $decompressed = @gzinflate(substr($gz_data, 2));
- if ($decompressed !== false) {
- return $decompressed;
- }
-
- return false;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsResponseHeadersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Response/Headers.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Response/Headers.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Response/Headers.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5,86 +5,68 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Response;
-
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
-use WpOrg\Requests\Utility\FilteredIterator;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Case-insensitive dictionary, suitable for HTTP headers
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Headers extends CaseInsensitiveDictionary {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Response_Headers extends Requests_Utility_CaseInsensitiveDictionary {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get the given header
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Unlike {@see \WpOrg\Requests\Response\Headers::getValues()}, this returns a string. If there are
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Unlike {@see self::getValues()}, this returns a string. If there are
</ins><span class="cx" style="display: block; padding: 0 10px"> * multiple values, it concatenates them with a comma as per RFC2616.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Avoid using this where commas may be used unquoted in values, such as
</span><span class="cx" style="display: block; padding: 0 10px"> * Set-Cookie headers.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return string|null Header value
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function offsetGet($offset) {
- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
-
- if (!isset($this->data[$offset])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetGet($key) {
+ $key = strtolower($key);
+ if (!isset($this->data[$key])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->flatten($this->data[$offset]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $this->flatten($this->data[$key]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Set the given item
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
+ *
+ * @param string $key Item name
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $value Item value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function offsetSet($offset, $value) {
- if ($offset === null) {
- throw new Exception('Object is a dictionary, not a list', 'invalidset');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetSet($key, $value) {
+ if ($key === null) {
+ throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $key = strtolower($key);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!isset($this->data[$offset])) {
- $this->data[$offset] = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!isset($this->data[$key])) {
+ $this->data[$key] = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->data[$offset][] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->data[$key][] = $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get all values for a given header
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return array|null Header values
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not valid as an array key.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function getValues($offset) {
- if (!is_string($offset) && !is_int($offset)) {
- throw InvalidArgument::create(1, '$offset', 'string|int', gettype($offset));
- }
-
- $offset = strtolower($offset);
- if (!isset($this->data[$offset])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function getValues($key) {
+ $key = strtolower($key);
+ if (!isset($this->data[$key])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->data[$offset];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $this->data[$key];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -95,30 +77,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string|array $value Value to flatten
</span><span class="cx" style="display: block; padding: 0 10px"> * @return string Flattened value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or an array.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function flatten($value) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_string($value)) {
- return $value;
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> if (is_array($value)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return implode(',', $value);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $value = implode(',', $value);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw InvalidArgument::create(1, '$value', 'string|array', gettype($value));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get an iterator for the data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Converts the internally stored values to a comma-separated string if there is more
- * than one value for a key.
- *
- * @return \ArrayIterator
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Converts the internal
+ * @return ArrayIterator
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function getIterator() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return new FilteredIterator($this->data, [$this, 'flatten']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return new Requests_Utility_FilteredIterator($this->data, array($this, 'flatten'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsResponsephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Response.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Response.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Response.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,26 +2,24 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * HTTP response class
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Contains a response from \WpOrg\Requests\Requests::request()
- *
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Contains a response from Requests::request()
</ins><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Cookie\Jar;
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\Http;
-use WpOrg\Requests\Response\Headers;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * HTTP response class
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Contains a response from \WpOrg\Requests\Requests::request()
- *
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Contains a response from Requests::request()
</ins><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Response {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Response {
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->headers = new Requests_Response_Headers();
+ $this->cookies = new Requests_Cookie_Jar();
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Response body
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -40,9 +38,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Headers, as an associative array
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var \WpOrg\Requests\Response\Headers Array-like object representing headers
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var Requests_Response_Headers Array-like object representing headers
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $headers = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $headers = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Status code, false if non-blocking
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -82,26 +80,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Previous requests (from redirects)
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var array Array of \WpOrg\Requests\Response objects
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var array Array of Requests_Response objects
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $history = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $history = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Cookies from the request
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var \WpOrg\Requests\Cookie\Jar Array-like object representing a cookie jar
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var Requests_Cookie_Jar Array-like object representing a cookie jar
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $cookies = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $cookies = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Constructor
- */
- public function __construct() {
- $this->headers = new Headers();
- $this->cookies = new Jar();
- }
-
- /**
</del><span class="cx" style="display: block; padding: 0 10px"> * Is the response a redirect?
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @return boolean True if redirect (3xx status), false if not.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -108,59 +98,25 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function is_redirect() {
</span><span class="cx" style="display: block; padding: 0 10px"> $code = $this->status_code;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return in_array($code, [300, 301, 302, 303, 307], true) || $code > 307 && $code < 400;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return in_array($code, array(300, 301, 302, 303, 307), true) || $code > 307 && $code < 400;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Throws an exception if the request was not successful
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`)
+ * @throws Requests_Exception_HTTP On non-successful status code. Exception class corresponds to code (e.g. {@see Requests_Exception_HTTP_404})
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param boolean $allow_redirects Set to false to throw on a 3xx as well
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`)
- * @throws \WpOrg\Requests\Exception\Http On non-successful status code. Exception class corresponds to "Status" + code (e.g. {@see \WpOrg\Requests\Exception\Http\Status404})
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function throw_for_status($allow_redirects = true) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->is_redirect()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($allow_redirects !== true) {
- throw new Exception('Redirection not allowed', 'response.no_redirects', $this);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!$allow_redirects) {
+ throw new Requests_Exception('Redirection not allowed', 'response.no_redirects', $this);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> elseif (!$this->success) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $exception = Http::get_class($this->status_code);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $exception = Requests_Exception_HTTP::get_class($this->status_code);
</ins><span class="cx" style="display: block; padding: 0 10px"> throw new $exception(null, $this);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- /**
- * JSON decode the response body.
- *
- * The method parameters are the same as those for the PHP native `json_decode()` function.
- *
- * @link https://php.net/json-decode
- *
- * @param ?bool $associative Optional. When `true`, JSON objects will be returned as associative arrays;
- * When `false`, JSON objects will be returned as objects.
- * When `null`, JSON objects will be returned as associative arrays
- * or objects depending on whether `JSON_OBJECT_AS_ARRAY` is set in the flags.
- * Defaults to `true` (in contrast to the PHP native default of `null`).
- * @param int $depth Optional. Maximum nesting depth of the structure being decoded.
- * Defaults to `512`.
- * @param int $options Optional. Bitmask of JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE,
- * JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR.
- * Defaults to `0` (no options set).
- *
- * @return array
- *
- * @throws \WpOrg\Requests\Exception If `$this->body` is not valid json.
- */
- public function decode_body($associative = true, $depth = 512, $options = 0) {
- $data = json_decode($this->body, $associative, $depth, $options);
-
- if (json_last_error() !== JSON_ERROR_NONE) {
- $last_error = json_last_error_msg();
- throw new Exception('Unable to parse JSON data: ' . $last_error, 'response.invalid', $this);
- }
-
- return $data;
- }
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsSSLphpfromrev52243trunksrcwpincludesRequestsSSLphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/SSL.php (from rev 52243, trunk/src/wp-includes/Requests/SSL.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/SSL.php (rev 0)
+++ trunk/src/wp-includes/Requests/SSL.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,144 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * SSL utilities for Requests
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+
+/**
+ * SSL utilities for Requests
+ *
+ * Collection of utilities for working with and verifying SSL certificates.
+ *
+ * @package Requests
+ * @subpackage Utilities
+ */
+class Requests_SSL {
+ /**
+ * Verify the certificate against common name and subject alternative names
+ *
+ * Unfortunately, PHP doesn't check the certificate against the alternative
+ * names, leading things like 'https://www.github.com/' to be invalid.
+ *
+ * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
+ *
+ * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
+ * @param string $host Host name to verify against
+ * @param array $cert Certificate data from openssl_x509_parse()
+ * @return bool
+ */
+ public static function verify_certificate($host, $cert) {
+ $has_dns_alt = false;
+
+ // Check the subjectAltName
+ if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
+ $altnames = explode(',', $cert['extensions']['subjectAltName']);
+ foreach ($altnames as $altname) {
+ $altname = trim($altname);
+ if (strpos($altname, 'DNS:') !== 0) {
+ continue;
+ }
+
+ $has_dns_alt = true;
+
+ // Strip the 'DNS:' prefix and trim whitespace
+ $altname = trim(substr($altname, 4));
+
+ // Check for a match
+ if (self::match_domain($host, $altname) === true) {
+ return true;
+ }
+ }
+ }
+
+ // Fall back to checking the common name if we didn't get any dNSName
+ // alt names, as per RFC2818
+ if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
+ // Check for a match
+ if (self::match_domain($host, $cert['subject']['CN']) === true) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Verify that a reference name is valid
+ *
+ * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
+ * - Wildcards can only occur in a name with more than 3 components
+ * - Wildcards can only occur as the last character in the first
+ * component
+ * - Wildcards may be preceded by additional characters
+ *
+ * We modify these rules to be a bit stricter and only allow the wildcard
+ * character to be the full first component; that is, with the exclusion of
+ * the third rule.
+ *
+ * @param string $reference Reference dNSName
+ * @return boolean Is the name valid?
+ */
+ public static function verify_reference_name($reference) {
+ $parts = explode('.', $reference);
+
+ // Check the first part of the name
+ $first = array_shift($parts);
+
+ if (strpos($first, '*') !== false) {
+ // Check that the wildcard is the full part
+ if ($first !== '*') {
+ return false;
+ }
+
+ // Check that we have at least 3 components (including first)
+ if (count($parts) < 2) {
+ return false;
+ }
+ }
+
+ // Check the remaining parts
+ foreach ($parts as $part) {
+ if (strpos($part, '*') !== false) {
+ return false;
+ }
+ }
+
+ // Nothing found, verified!
+ return true;
+ }
+
+ /**
+ * Match a hostname against a dNSName reference
+ *
+ * @param string $host Requested host
+ * @param string $reference dNSName to match against
+ * @return boolean Does the domain match?
+ */
+ public static function match_domain($host, $reference) {
+ // Check if the reference is blocklisted first
+ if (self::verify_reference_name($reference) !== true) {
+ return false;
+ }
+
+ // Check for a direct match
+ if ($host === $reference) {
+ return true;
+ }
+
+ // Calculate the valid wildcard match if the host is not an IP address
+ // Also validates that the host has 3 parts or more, as per Firefox's
+ // ruleset.
+ if (ip2long($host) === false) {
+ $parts = explode('.', $host);
+ $parts[0] = '*';
+ $wildcard = implode('.', $parts);
+ if ($wildcard === $reference) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsSessionphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Session.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Session.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Session.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,17 +2,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Session handler for persistent requests and default parameters
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\SessionHandler
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Session Handler
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Cookie\Jar;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Iri;
-use WpOrg\Requests\Requests;
-use WpOrg\Requests\Utility\InputValidator;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Session handler for persistent requests and default parameters
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -21,9 +14,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * with all subrequests resolved from this. Base options can be set (including
</span><span class="cx" style="display: block; padding: 0 10px"> * a shared cookie jar), then overridden for individual requests.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\SessionHandler
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Session Handler
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Session {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Session {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Base URL for requests
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -38,7 +32,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $headers = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $headers = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Base data for requests
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -48,7 +42,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $data = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $data = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Base options for requests
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -61,38 +55,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public $options = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $options = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Create a new session
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string|Stringable|null $url Base URL for requests
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string|null $url Base URL for requests
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers Default headers for requests
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $data Default data for requests
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $options Default options for requests
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string, Stringable or null.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not an array.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct($url = null, $headers = [], $data = [], $options = []) {
- if ($url !== null && InputValidator::is_string_or_stringable($url) === false) {
- throw InvalidArgument::create(1, '$url', 'string|Stringable|null', gettype($url));
- }
-
- if (is_array($headers) === false) {
- throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
- }
-
- if (is_array($data) === false) {
- throw InvalidArgument::create(3, '$data', 'array', gettype($data));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(4, '$options', 'array', gettype($options));
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->url = $url;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->headers = $headers;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->data = $data;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -99,7 +72,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->options = $options;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($this->options['cookies'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->options['cookies'] = new Jar();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->options['cookies'] = new Requests_Cookie_Jar();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -106,12 +79,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get a property's value
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $name Property name.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Property key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return mixed|null Property value, null if none found
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __get($name) {
- if (isset($this->options[$name])) {
- return $this->options[$name];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __get($key) {
+ if (isset($this->options[$key])) {
+ return $this->options[$key];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return null;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,42 +93,44 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Set a property's value
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $name Property name.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Property key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param mixed $value Property value
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __set($name, $value) {
- $this->options[$name] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __set($key, $value) {
+ $this->options[$key] = $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Remove a property's value
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $name Property name.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Property key
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __isset($name) {
- return isset($this->options[$name]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __isset($key) {
+ return isset($this->options[$key]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Remove a property's value
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $name Property name.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Property key
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __unset($name) {
- unset($this->options[$name]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __unset($key) {
+ if (isset($this->options[$key])) {
+ unset($this->options[$key]);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**#@+
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Session::request()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see request()
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $url
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $options
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return \WpOrg\Requests\Response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return Requests_Response
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a GET request
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function get($url, $headers = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function get($url, $headers = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, null, Requests::GET, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -162,7 +137,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a HEAD request
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function head($url, $headers = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function head($url, $headers = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, null, Requests::HEAD, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -169,23 +144,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a DELETE request
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function delete($url, $headers = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function delete($url, $headers = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, null, Requests::DELETE, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> /**#@-*/
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**#@+
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Session::request()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see request()
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $url
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $data
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $options
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return \WpOrg\Requests\Response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return Requests_Response
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a POST request
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function post($url, $headers = [], $data = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function post($url, $headers = array(), $data = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, $data, Requests::POST, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -192,7 +167,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a PUT request
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function put($url, $headers = [], $data = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function put($url, $headers = array(), $data = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, $data, Requests::PUT, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -199,12 +174,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send a PATCH request
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Note: Unlike {@see \WpOrg\Requests\Session::post()} and {@see \WpOrg\Requests\Session::put()},
- * `$headers` is required, as the specification recommends that should send an ETag
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
+ * specification recommends that should send an ETag
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @link https://tools.ietf.org/html/rfc5789
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function patch($url, $headers, $data = [], $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function patch($url, $headers, $data = array(), $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->request($url, $headers, $data, Requests::PATCH, $options);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> /**#@-*/
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -215,18 +190,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * This method initiates a request and sends it via a transport before
</span><span class="cx" style="display: block; padding: 0 10px"> * parsing.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Requests::request()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests::request()
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On invalid URLs (`nonhttp`)
+ *
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $url URL to request
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers Extra headers to send with the request
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $type HTTP request type (use \WpOrg\Requests\Requests constants)
- * @param array $options Options for the request (see {@see \WpOrg\Requests\Requests::request()})
- * @return \WpOrg\Requests\Response
- *
- * @throws \WpOrg\Requests\Exception On invalid URLs (`nonhttp`)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $type HTTP request type (use Requests constants)
+ * @param array $options Options for the request (see {@see Requests::request})
+ * @return Requests_Response
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function request($url, $headers = [], $data = [], $type = Requests::GET, $options = []) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -235,24 +210,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send multiple HTTP requests simultaneously
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Requests::request_multiple()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests::request_multiple()
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param array $requests Requests data (see {@see \WpOrg\Requests\Requests::request_multiple()})
- * @param array $options Global and default options (see {@see \WpOrg\Requests\Requests::request()})
- * @return array Responses (either \WpOrg\Requests\Response or a \WpOrg\Requests\Exception object)
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array $requests Requests data (see {@see Requests::request_multiple})
+ * @param array $options Global and default options (see {@see Requests::request})
+ * @return array Responses (either Requests_Response or a Requests_Exception object)
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function request_multiple($requests, $options = []) {
- if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
- throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(2, '$options', 'array', gettype($options));
- }
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function request_multiple($requests, $options = array()) {
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($requests as $key => $request) {
</span><span class="cx" style="display: block; padding: 0 10px"> $requests[$key] = $this->merge_request($request, false);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -268,18 +232,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Merge a request's data with the default data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param array $request Request data (same form as {@see \WpOrg\Requests\Session::request_multiple()})
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array $request Request data (same form as {@see request_multiple})
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param boolean $merge_options Should we merge options as well?
</span><span class="cx" style="display: block; padding: 0 10px"> * @return array Request data
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function merge_request($request, $merge_options = true) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->url !== null) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $request['url'] = Iri::absolutize($this->url, $request['url']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
</ins><span class="cx" style="display: block; padding: 0 10px"> $request['url'] = $request['url']->uri;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($request['headers'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $request['headers'] = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $request['headers'] = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $request['headers'] = array_merge($this->headers, $request['headers']);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -292,7 +256,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $request['data'] = array_merge($this->data, $request['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($merge_options === true) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($merge_options !== false) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $request['options'] = array_merge($this->options, $request['options']);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Disallow forcing the type, as that's a per request setting
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsSslphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Ssl.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Ssl.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Ssl.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,182 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * SSL utilities for Requests
- *
- * @package Requests\Utilities
- */
-
-namespace WpOrg\Requests;
-
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * SSL utilities for Requests
- *
- * Collection of utilities for working with and verifying SSL certificates.
- *
- * @package Requests\Utilities
- */
-final class Ssl {
- /**
- * Verify the certificate against common name and subject alternative names
- *
- * Unfortunately, PHP doesn't check the certificate against the alternative
- * names, leading things like 'https://www.github.com/' to be invalid.
- *
- * @link https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
- *
- * @param string|Stringable $host Host name to verify against
- * @param array $cert Certificate data from openssl_x509_parse()
- * @return bool
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $host argument is not a string or a stringable object.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cert argument is not an array or array accessible.
- */
- public static function verify_certificate($host, $cert) {
- if (InputValidator::is_string_or_stringable($host) === false) {
- throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
- }
-
- if (InputValidator::has_array_access($cert) === false) {
- throw InvalidArgument::create(2, '$cert', 'array|ArrayAccess', gettype($cert));
- }
-
- $has_dns_alt = false;
-
- // Check the subjectAltName
- if (!empty($cert['extensions']['subjectAltName'])) {
- $altnames = explode(',', $cert['extensions']['subjectAltName']);
- foreach ($altnames as $altname) {
- $altname = trim($altname);
- if (strpos($altname, 'DNS:') !== 0) {
- continue;
- }
-
- $has_dns_alt = true;
-
- // Strip the 'DNS:' prefix and trim whitespace
- $altname = trim(substr($altname, 4));
-
- // Check for a match
- if (self::match_domain($host, $altname) === true) {
- return true;
- }
- }
-
- if ($has_dns_alt === true) {
- return false;
- }
- }
-
- // Fall back to checking the common name if we didn't get any dNSName
- // alt names, as per RFC2818
- if (!empty($cert['subject']['CN'])) {
- // Check for a match
- return (self::match_domain($host, $cert['subject']['CN']) === true);
- }
-
- return false;
- }
-
- /**
- * Verify that a reference name is valid
- *
- * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
- * - Wildcards can only occur in a name with more than 3 components
- * - Wildcards can only occur as the last character in the first
- * component
- * - Wildcards may be preceded by additional characters
- *
- * We modify these rules to be a bit stricter and only allow the wildcard
- * character to be the full first component; that is, with the exclusion of
- * the third rule.
- *
- * @param string|Stringable $reference Reference dNSName
- * @return boolean Is the name valid?
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
- */
- public static function verify_reference_name($reference) {
- if (InputValidator::is_string_or_stringable($reference) === false) {
- throw InvalidArgument::create(1, '$reference', 'string|Stringable', gettype($reference));
- }
-
- if ($reference === '') {
- return false;
- }
-
- if (preg_match('`\s`', $reference) > 0) {
- // Whitespace detected. This can never be a dNSName.
- return false;
- }
-
- $parts = explode('.', $reference);
- if ($parts !== array_filter($parts)) {
- // DNSName cannot contain two dots next to each other.
- return false;
- }
-
- // Check the first part of the name
- $first = array_shift($parts);
-
- if (strpos($first, '*') !== false) {
- // Check that the wildcard is the full part
- if ($first !== '*') {
- return false;
- }
-
- // Check that we have at least 3 components (including first)
- if (count($parts) < 2) {
- return false;
- }
- }
-
- // Check the remaining parts
- foreach ($parts as $part) {
- if (strpos($part, '*') !== false) {
- return false;
- }
- }
-
- // Nothing found, verified!
- return true;
- }
-
- /**
- * Match a hostname against a dNSName reference
- *
- * @param string|Stringable $host Requested host
- * @param string|Stringable $reference dNSName to match against
- * @return boolean Does the domain match?
- * @throws \WpOrg\Requests\Exception\InvalidArgument When either of the passed arguments is not a string or a stringable object.
- */
- public static function match_domain($host, $reference) {
- if (InputValidator::is_string_or_stringable($host) === false) {
- throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
- }
-
- // Check if the reference is blocklisted first
- if (self::verify_reference_name($reference) !== true) {
- return false;
- }
-
- // Check for a direct match
- if ((string) $host === (string) $reference) {
- return true;
- }
-
- // Calculate the valid wildcard match if the host is not an IP address
- // Also validates that the host has 3 parts or more, as per Firefox's ruleset,
- // as a wildcard reference is only allowed with 3 parts or more, so the
- // comparison will never match if host doesn't contain 3 parts or more as well.
- if (ip2long($host) === false) {
- $parts = explode('.', $host);
- $parts[0] = '*';
- $wildcard = implode('.', $parts);
- if ($wildcard === (string) $reference) {
- return true;
- }
- }
-
- return false;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsTransportCurlphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Transport/Curl.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Transport/Curl.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Transport/Curl.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,641 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * cURL HTTP transport
- *
- * @package Requests\Transport
- */
-
-namespace WpOrg\Requests\Transport;
-
-use RecursiveArrayIterator;
-use RecursiveIteratorIterator;
-use WpOrg\Requests\Capability;
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Exception\Transport\Curl as CurlException;
-use WpOrg\Requests\Requests;
-use WpOrg\Requests\Transport;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * cURL HTTP transport
- *
- * @package Requests\Transport
- */
-final class Curl implements Transport {
- const CURL_7_10_5 = 0x070A05;
- const CURL_7_16_2 = 0x071002;
-
- /**
- * Raw HTTP data
- *
- * @var string
- */
- public $headers = '';
-
- /**
- * Raw body data
- *
- * @var string
- */
- public $response_data = '';
-
- /**
- * Information on the current request
- *
- * @var array cURL information array, see {@link https://www.php.net/curl_getinfo}
- */
- public $info;
-
- /**
- * cURL version number
- *
- * @var int
- */
- public $version;
-
- /**
- * cURL handle
- *
- * @var resource|\CurlHandle Resource in PHP < 8.0, Instance of CurlHandle in PHP >= 8.0.
- */
- private $handle;
-
- /**
- * Hook dispatcher instance
- *
- * @var \WpOrg\Requests\Hooks
- */
- private $hooks;
-
- /**
- * Have we finished the headers yet?
- *
- * @var boolean
- */
- private $done_headers = false;
-
- /**
- * If streaming to a file, keep the file pointer
- *
- * @var resource
- */
- private $stream_handle;
-
- /**
- * How many bytes are in the response body?
- *
- * @var int
- */
- private $response_bytes;
-
- /**
- * What's the maximum number of bytes we should keep?
- *
- * @var int|bool Byte count, or false if no limit.
- */
- private $response_byte_limit;
-
- /**
- * Constructor
- */
- public function __construct() {
- $curl = curl_version();
- $this->version = $curl['version_number'];
- $this->handle = curl_init();
-
- curl_setopt($this->handle, CURLOPT_HEADER, false);
- curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
- if ($this->version >= self::CURL_7_10_5) {
- curl_setopt($this->handle, CURLOPT_ENCODING, '');
- }
- if (defined('CURLOPT_PROTOCOLS')) {
- // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_protocolsFound
- curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- }
- if (defined('CURLOPT_REDIR_PROTOCOLS')) {
- // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_redir_protocolsFound
- curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- }
- }
-
- /**
- * Destructor
- */
- public function __destruct() {
- if (is_resource($this->handle)) {
- curl_close($this->handle);
- }
- }
-
- /**
- * Perform a request
- *
- * @param string|Stringable $url URL to request
- * @param array $headers Associative array of request headers
- * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
- * @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- * @return string Raw HTTP result
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data parameter is not an array or string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- * @throws \WpOrg\Requests\Exception On a cURL error (`curlerror`)
- */
- public function request($url, $headers = [], $data = [], $options = []) {
- if (InputValidator::is_string_or_stringable($url) === false) {
- throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url));
- }
-
- if (is_array($headers) === false) {
- throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
- }
-
- if (!is_array($data) && !is_string($data)) {
- if ($data === null) {
- $data = '';
- } else {
- throw InvalidArgument::create(3, '$data', 'array|string', gettype($data));
- }
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(4, '$options', 'array', gettype($options));
- }
-
- $this->hooks = $options['hooks'];
-
- $this->setup_handle($url, $headers, $data, $options);
-
- $options['hooks']->dispatch('curl.before_send', [&$this->handle]);
-
- if ($options['filename'] !== false) {
- // phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silenced the PHP native warning in favour of throwing an exception.
- $this->stream_handle = @fopen($options['filename'], 'wb');
- if ($this->stream_handle === false) {
- $error = error_get_last();
- throw new Exception($error['message'], 'fopen');
- }
- }
-
- $this->response_data = '';
- $this->response_bytes = 0;
- $this->response_byte_limit = false;
- if ($options['max_bytes'] !== false) {
- $this->response_byte_limit = $options['max_bytes'];
- }
-
- if (isset($options['verify'])) {
- if ($options['verify'] === false) {
- curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
- curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
- }
- elseif (is_string($options['verify'])) {
- curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
- }
- }
-
- if (isset($options['verifyname']) && $options['verifyname'] === false) {
- curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
- }
-
- curl_exec($this->handle);
- $response = $this->response_data;
-
- $options['hooks']->dispatch('curl.after_send', []);
-
- if (curl_errno($this->handle) === CURLE_WRITE_ERROR || curl_errno($this->handle) === CURLE_BAD_CONTENT_ENCODING) {
- // Reset encoding and try again
- curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
-
- $this->response_data = '';
- $this->response_bytes = 0;
- curl_exec($this->handle);
- $response = $this->response_data;
- }
-
- $this->process_response($response, $options);
-
- // Need to remove the $this reference from the curl handle.
- // Otherwise \WpOrg\Requests\Transport\Curl won't be garbage collected and the curl_close() will never be called.
- curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
- curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
-
- return $this->headers;
- }
-
- /**
- * Send multiple requests simultaneously
- *
- * @param array $requests Request data
- * @param array $options Global options
- * @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- */
- public function request_multiple($requests, $options) {
- // If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
- if (empty($requests)) {
- return [];
- }
-
- if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
- throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(2, '$options', 'array', gettype($options));
- }
-
- $multihandle = curl_multi_init();
- $subrequests = [];
- $subhandles = [];
-
- $class = get_class($this);
- foreach ($requests as $id => $request) {
- $subrequests[$id] = new $class();
- $subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
- $request['options']['hooks']->dispatch('curl.before_multi_add', [&$subhandles[$id]]);
- curl_multi_add_handle($multihandle, $subhandles[$id]);
- }
-
- $completed = 0;
- $responses = [];
- $subrequestcount = count($subrequests);
-
- $request['options']['hooks']->dispatch('curl.before_multi_exec', [&$multihandle]);
-
- do {
- $active = 0;
-
- do {
- $status = curl_multi_exec($multihandle, $active);
- }
- while ($status === CURLM_CALL_MULTI_PERFORM);
-
- $to_process = [];
-
- // Read the information as needed
- while ($done = curl_multi_info_read($multihandle)) {
- $key = array_search($done['handle'], $subhandles, true);
- if (!isset($to_process[$key])) {
- $to_process[$key] = $done;
- }
- }
-
- // Parse the finished requests before we start getting the new ones
- foreach ($to_process as $key => $done) {
- $options = $requests[$key]['options'];
- if ($done['result'] !== CURLE_OK) {
- //get error string for handle.
- $reason = curl_error($done['handle']);
- $exception = new CurlException(
- $reason,
- CurlException::EASY,
- $done['handle'],
- $done['result']
- );
- $responses[$key] = $exception;
- $options['hooks']->dispatch('transport.internal.parse_error', [&$responses[$key], $requests[$key]]);
- }
- else {
- $responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
-
- $options['hooks']->dispatch('transport.internal.parse_response', [&$responses[$key], $requests[$key]]);
- }
-
- curl_multi_remove_handle($multihandle, $done['handle']);
- curl_close($done['handle']);
-
- if (!is_string($responses[$key])) {
- $options['hooks']->dispatch('multiple.request.complete', [&$responses[$key], $key]);
- }
- $completed++;
- }
- }
- while ($active || $completed < $subrequestcount);
-
- $request['options']['hooks']->dispatch('curl.after_multi_exec', [&$multihandle]);
-
- curl_multi_close($multihandle);
-
- return $responses;
- }
-
- /**
- * Get the cURL handle for use in a multi-request
- *
- * @param string $url URL to request
- * @param array $headers Associative array of request headers
- * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
- * @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- * @return resource|\CurlHandle Subrequest's cURL handle
- */
- public function &get_subrequest_handle($url, $headers, $data, $options) {
- $this->setup_handle($url, $headers, $data, $options);
-
- if ($options['filename'] !== false) {
- $this->stream_handle = fopen($options['filename'], 'wb');
- }
-
- $this->response_data = '';
- $this->response_bytes = 0;
- $this->response_byte_limit = false;
- if ($options['max_bytes'] !== false) {
- $this->response_byte_limit = $options['max_bytes'];
- }
- $this->hooks = $options['hooks'];
-
- return $this->handle;
- }
-
- /**
- * Setup the cURL handle for the given data
- *
- * @param string $url URL to request
- * @param array $headers Associative array of request headers
- * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
- * @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- */
- private function setup_handle($url, $headers, $data, $options) {
- $options['hooks']->dispatch('curl.before_request', [&$this->handle]);
-
- // Force closing the connection for old versions of cURL (<7.22).
- if (!isset($headers['Connection'])) {
- $headers['Connection'] = 'close';
- }
-
- /**
- * Add "Expect" header.
- *
- * By default, cURL adds a "Expect: 100-Continue" to most requests. This header can
- * add as much as a second to the time it takes for cURL to perform a request. To
- * prevent this, we need to set an empty "Expect" header. To match the behaviour of
- * Guzzle, we'll add the empty header to requests that are smaller than 1 MB and use
- * HTTP/1.1.
- *
- * https://curl.se/mail/lib-2017-07/0013.html
- */
- if (!isset($headers['Expect']) && $options['protocol_version'] === 1.1) {
- $headers['Expect'] = $this->get_expect_header($data);
- }
-
- $headers = Requests::flatten($headers);
-
- if (!empty($data)) {
- $data_format = $options['data_format'];
-
- if ($data_format === 'query') {
- $url = self::format_get($url, $data);
- $data = '';
- }
- elseif (!is_string($data)) {
- $data = http_build_query($data, '', '&');
- }
- }
-
- switch ($options['type']) {
- case Requests::POST:
- curl_setopt($this->handle, CURLOPT_POST, true);
- curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
- break;
- case Requests::HEAD:
- curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
- curl_setopt($this->handle, CURLOPT_NOBODY, true);
- break;
- case Requests::TRACE:
- curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
- break;
- case Requests::PATCH:
- case Requests::PUT:
- case Requests::DELETE:
- case Requests::OPTIONS:
- default:
- curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
- if (!empty($data)) {
- curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
- }
- }
-
- // cURL requires a minimum timeout of 1 second when using the system
- // DNS resolver, as it uses `alarm()`, which is second resolution only.
- // There's no way to detect which DNS resolver is being used from our
- // end, so we need to round up regardless of the supplied timeout.
- //
- // https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609
- $timeout = max($options['timeout'], 1);
-
- if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
- curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
- }
- else {
- // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_timeout_msFound
- curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
- }
-
- if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
- curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
- }
- else {
- // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_connecttimeout_msFound
- curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
- }
- curl_setopt($this->handle, CURLOPT_URL, $url);
- curl_setopt($this->handle, CURLOPT_USERAGENT, $options['useragent']);
- if (!empty($headers)) {
- curl_setopt($this->handle, CURLOPT_HTTPHEADER, $headers);
- }
- if ($options['protocol_version'] === 1.1) {
- curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- }
- else {
- curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- }
-
- if ($options['blocking'] === true) {
- curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, [$this, 'stream_headers']);
- curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, [$this, 'stream_body']);
- curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
- }
- }
-
- /**
- * Process a response
- *
- * @param string $response Response data from the body
- * @param array $options Request options
- * @return string|false HTTP response data including headers. False if non-blocking.
- * @throws \WpOrg\Requests\Exception
- */
- public function process_response($response, $options) {
- if ($options['blocking'] === false) {
- $fake_headers = '';
- $options['hooks']->dispatch('curl.after_request', [&$fake_headers]);
- return false;
- }
- if ($options['filename'] !== false && $this->stream_handle) {
- fclose($this->stream_handle);
- $this->headers = trim($this->headers);
- }
- else {
- $this->headers .= $response;
- }
-
- if (curl_errno($this->handle)) {
- $error = sprintf(
- 'cURL error %s: %s',
- curl_errno($this->handle),
- curl_error($this->handle)
- );
- throw new Exception($error, 'curlerror', $this->handle);
- }
- $this->info = curl_getinfo($this->handle);
-
- $options['hooks']->dispatch('curl.after_request', [&$this->headers, &$this->info]);
- return $this->headers;
- }
-
- /**
- * Collect the headers as they are received
- *
- * @param resource|\CurlHandle $handle cURL handle
- * @param string $headers Header string
- * @return integer Length of provided header
- */
- public function stream_headers($handle, $headers) {
- // Why do we do this? cURL will send both the final response and any
- // interim responses, such as a 100 Continue. We don't need that.
- // (We may want to keep this somewhere just in case)
- if ($this->done_headers) {
- $this->headers = '';
- $this->done_headers = false;
- }
- $this->headers .= $headers;
-
- if ($headers === "\r\n") {
- $this->done_headers = true;
- }
- return strlen($headers);
- }
-
- /**
- * Collect data as it's received
- *
- * @since 1.6.1
- *
- * @param resource|\CurlHandle $handle cURL handle
- * @param string $data Body data
- * @return integer Length of provided data
- */
- public function stream_body($handle, $data) {
- $this->hooks->dispatch('request.progress', [$data, $this->response_bytes, $this->response_byte_limit]);
- $data_length = strlen($data);
-
- // Are we limiting the response size?
- if ($this->response_byte_limit) {
- if ($this->response_bytes === $this->response_byte_limit) {
- // Already at maximum, move on
- return $data_length;
- }
-
- if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
- // Limit the length
- $limited_length = ($this->response_byte_limit - $this->response_bytes);
- $data = substr($data, 0, $limited_length);
- }
- }
-
- if ($this->stream_handle) {
- fwrite($this->stream_handle, $data);
- }
- else {
- $this->response_data .= $data;
- }
-
- $this->response_bytes += strlen($data);
- return $data_length;
- }
-
- /**
- * Format a URL given GET data
- *
- * @param string $url
- * @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query}
- * @return string URL with data
- */
- private static function format_get($url, $data) {
- if (!empty($data)) {
- $query = '';
- $url_parts = parse_url($url);
- if (empty($url_parts['query'])) {
- $url_parts['query'] = '';
- }
- else {
- $query = $url_parts['query'];
- }
-
- $query .= '&' . http_build_query($data, '', '&');
- $query = trim($query, '&');
-
- if (empty($url_parts['query'])) {
- $url .= '?' . $query;
- }
- else {
- $url = str_replace($url_parts['query'], $query, $url);
- }
- }
- return $url;
- }
-
- /**
- * Self-test whether the transport can be used.
- *
- * The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
- *
- * @codeCoverageIgnore
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return bool Whether the transport can be used.
- */
- public static function test($capabilities = []) {
- if (!function_exists('curl_init') || !function_exists('curl_exec')) {
- return false;
- }
-
- // If needed, check that our installed curl version supports SSL
- if (isset($capabilities[Capability::SSL]) && $capabilities[Capability::SSL]) {
- $curl_version = curl_version();
- if (!(CURL_VERSION_SSL & $curl_version['features'])) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Get the correct "Expect" header for the given request data.
- *
- * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD.
- * @return string The "Expect" header.
- */
- private function get_expect_header($data) {
- if (!is_array($data)) {
- return strlen((string) $data) >= 1048576 ? '100-Continue' : '';
- }
-
- $bytesize = 0;
- $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
-
- foreach ($iterator as $datum) {
- $bytesize += strlen((string) $datum);
-
- if ($bytesize >= 1048576) {
- return '100-Continue';
- }
- }
-
- return '';
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsTransportFsockopenphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Transport/Fsockopen.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Transport/Fsockopen.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Transport/Fsockopen.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,506 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * fsockopen HTTP transport
- *
- * @package Requests\Transport
- */
-
-namespace WpOrg\Requests\Transport;
-
-use WpOrg\Requests\Capability;
-use WpOrg\Requests\Exception;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Port;
-use WpOrg\Requests\Requests;
-use WpOrg\Requests\Ssl;
-use WpOrg\Requests\Transport;
-use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
-use WpOrg\Requests\Utility\InputValidator;
-
-/**
- * fsockopen HTTP transport
- *
- * @package Requests\Transport
- */
-final class Fsockopen implements Transport {
- /**
- * Second to microsecond conversion
- *
- * @var integer
- */
- const SECOND_IN_MICROSECONDS = 1000000;
-
- /**
- * Raw HTTP data
- *
- * @var string
- */
- public $headers = '';
-
- /**
- * Stream metadata
- *
- * @var array Associative array of properties, see {@link https://www.php.net/stream_get_meta_data}
- */
- public $info;
-
- /**
- * What's the maximum number of bytes we should keep?
- *
- * @var int|bool Byte count, or false if no limit.
- */
- private $max_bytes = false;
-
- private $connect_error = '';
-
- /**
- * Perform a request
- *
- * @param string|Stringable $url URL to request
- * @param array $headers Associative array of request headers
- * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
- * @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- * @return string Raw HTTP result
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data parameter is not an array or string.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- * @throws \WpOrg\Requests\Exception On failure to connect to socket (`fsockopenerror`)
- * @throws \WpOrg\Requests\Exception On socket timeout (`timeout`)
- */
- public function request($url, $headers = [], $data = [], $options = []) {
- if (InputValidator::is_string_or_stringable($url) === false) {
- throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url));
- }
-
- if (is_array($headers) === false) {
- throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
- }
-
- if (!is_array($data) && !is_string($data)) {
- if ($data === null) {
- $data = '';
- } else {
- throw InvalidArgument::create(3, '$data', 'array|string', gettype($data));
- }
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(4, '$options', 'array', gettype($options));
- }
-
- $options['hooks']->dispatch('fsockopen.before_request');
-
- $url_parts = parse_url($url);
- if (empty($url_parts)) {
- throw new Exception('Invalid URL.', 'invalidurl', $url);
- }
- $host = $url_parts['host'];
- $context = stream_context_create();
- $verifyname = false;
- $case_insensitive_headers = new CaseInsensitiveDictionary($headers);
-
- // HTTPS support
- if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
- $remote_socket = 'ssl://' . $host;
- if (!isset($url_parts['port'])) {
- $url_parts['port'] = Port::HTTPS;
- }
-
- $context_options = [
- 'verify_peer' => true,
- 'capture_peer_cert' => true,
- ];
- $verifyname = true;
-
- // SNI, if enabled (OpenSSL >=0.9.8j)
- // phpcs:ignore PHPCompatibility.Constants.NewConstants.openssl_tlsext_server_nameFound
- if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
- $context_options['SNI_enabled'] = true;
- if (isset($options['verifyname']) && $options['verifyname'] === false) {
- $context_options['SNI_enabled'] = false;
- }
- }
-
- if (isset($options['verify'])) {
- if ($options['verify'] === false) {
- $context_options['verify_peer'] = false;
- $context_options['verify_peer_name'] = false;
- $verifyname = false;
- }
- elseif (is_string($options['verify'])) {
- $context_options['cafile'] = $options['verify'];
- }
- }
-
- if (isset($options['verifyname']) && $options['verifyname'] === false) {
- $context_options['verify_peer_name'] = false;
- $verifyname = false;
- }
-
- stream_context_set_option($context, ['ssl' => $context_options]);
- }
- else {
- $remote_socket = 'tcp://' . $host;
- }
-
- $this->max_bytes = $options['max_bytes'];
-
- if (!isset($url_parts['port'])) {
- $url_parts['port'] = Port::HTTP;
- }
- $remote_socket .= ':' . $url_parts['port'];
-
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
- set_error_handler([$this, 'connect_error_handler'], E_WARNING | E_NOTICE);
-
- $options['hooks']->dispatch('fsockopen.remote_socket', [&$remote_socket]);
-
- $socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
-
- restore_error_handler();
-
- if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
- throw new Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
- }
-
- if (!$socket) {
- if ($errno === 0) {
- // Connection issue
- throw new Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
- }
-
- throw new Exception($errstr, 'fsockopenerror', null, $errno);
- }
-
- $data_format = $options['data_format'];
-
- if ($data_format === 'query') {
- $path = self::format_get($url_parts, $data);
- $data = '';
- }
- else {
- $path = self::format_get($url_parts, []);
- }
-
- $options['hooks']->dispatch('fsockopen.remote_host_path', [&$path, $url]);
-
- $request_body = '';
- $out = sprintf("%s %s HTTP/%.1F\r\n", $options['type'], $path, $options['protocol_version']);
-
- if ($options['type'] !== Requests::TRACE) {
- if (is_array($data)) {
- $request_body = http_build_query($data, '', '&');
- }
- else {
- $request_body = $data;
- }
-
- // Always include Content-length on POST requests to prevent
- // 411 errors from some servers when the body is empty.
- if (!empty($data) || $options['type'] === Requests::POST) {
- if (!isset($case_insensitive_headers['Content-Length'])) {
- $headers['Content-Length'] = strlen($request_body);
- }
-
- if (!isset($case_insensitive_headers['Content-Type'])) {
- $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
- }
- }
- }
-
- if (!isset($case_insensitive_headers['Host'])) {
- $out .= sprintf('Host: %s', $url_parts['host']);
- $scheme_lower = strtolower($url_parts['scheme']);
-
- if (($scheme_lower === 'http' && $url_parts['port'] !== Port::HTTP) || ($scheme_lower === 'https' && $url_parts['port'] !== Port::HTTPS)) {
- $out .= ':' . $url_parts['port'];
- }
- $out .= "\r\n";
- }
-
- if (!isset($case_insensitive_headers['User-Agent'])) {
- $out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
- }
-
- $accept_encoding = $this->accept_encoding();
- if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
- $out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
- }
-
- $headers = Requests::flatten($headers);
-
- if (!empty($headers)) {
- $out .= implode("\r\n", $headers) . "\r\n";
- }
-
- $options['hooks']->dispatch('fsockopen.after_headers', [&$out]);
-
- if (substr($out, -2) !== "\r\n") {
- $out .= "\r\n";
- }
-
- if (!isset($case_insensitive_headers['Connection'])) {
- $out .= "Connection: Close\r\n";
- }
-
- $out .= "\r\n" . $request_body;
-
- $options['hooks']->dispatch('fsockopen.before_send', [&$out]);
-
- fwrite($socket, $out);
- $options['hooks']->dispatch('fsockopen.after_send', [$out]);
-
- if (!$options['blocking']) {
- fclose($socket);
- $fake_headers = '';
- $options['hooks']->dispatch('fsockopen.after_request', [&$fake_headers]);
- return '';
- }
-
- $timeout_sec = (int) floor($options['timeout']);
- if ($timeout_sec === $options['timeout']) {
- $timeout_msec = 0;
- }
- else {
- $timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
- }
- stream_set_timeout($socket, $timeout_sec, $timeout_msec);
-
- $response = '';
- $body = '';
- $headers = '';
- $this->info = stream_get_meta_data($socket);
- $size = 0;
- $doingbody = false;
- $download = false;
- if ($options['filename']) {
- // phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silenced the PHP native warning in favour of throwing an exception.
- $download = @fopen($options['filename'], 'wb');
- if ($download === false) {
- $error = error_get_last();
- throw new Exception($error['message'], 'fopen');
- }
- }
-
- while (!feof($socket)) {
- $this->info = stream_get_meta_data($socket);
- if ($this->info['timed_out']) {
- throw new Exception('fsocket timed out', 'timeout');
- }
-
- $block = fread($socket, Requests::BUFFER_SIZE);
- if (!$doingbody) {
- $response .= $block;
- if (strpos($response, "\r\n\r\n")) {
- list($headers, $block) = explode("\r\n\r\n", $response, 2);
- $doingbody = true;
- }
- }
-
- // Are we in body mode now?
- if ($doingbody) {
- $options['hooks']->dispatch('request.progress', [$block, $size, $this->max_bytes]);
- $data_length = strlen($block);
- if ($this->max_bytes) {
- // Have we already hit a limit?
- if ($size === $this->max_bytes) {
- continue;
- }
- if (($size + $data_length) > $this->max_bytes) {
- // Limit the length
- $limited_length = ($this->max_bytes - $size);
- $block = substr($block, 0, $limited_length);
- }
- }
-
- $size += strlen($block);
- if ($download) {
- fwrite($download, $block);
- }
- else {
- $body .= $block;
- }
- }
- }
- $this->headers = $headers;
-
- if ($download) {
- fclose($download);
- }
- else {
- $this->headers .= "\r\n\r\n" . $body;
- }
- fclose($socket);
-
- $options['hooks']->dispatch('fsockopen.after_request', [&$this->headers, &$this->info]);
- return $this->headers;
- }
-
- /**
- * Send multiple requests simultaneously
- *
- * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see \WpOrg\Requests\Transport::request()}
- * @param array $options Global options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- * @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
- */
- public function request_multiple($requests, $options) {
- // If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
- if (empty($requests)) {
- return [];
- }
-
- if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
- throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
- }
-
- if (is_array($options) === false) {
- throw InvalidArgument::create(2, '$options', 'array', gettype($options));
- }
-
- $responses = [];
- $class = get_class($this);
- foreach ($requests as $id => $request) {
- try {
- $handler = new $class();
- $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
-
- $request['options']['hooks']->dispatch('transport.internal.parse_response', [&$responses[$id], $request]);
- }
- catch (Exception $e) {
- $responses[$id] = $e;
- }
-
- if (!is_string($responses[$id])) {
- $request['options']['hooks']->dispatch('multiple.request.complete', [&$responses[$id], $id]);
- }
- }
-
- return $responses;
- }
-
- /**
- * Retrieve the encodings we can accept
- *
- * @return string Accept-Encoding header value
- */
- private static function accept_encoding() {
- $type = [];
- if (function_exists('gzinflate')) {
- $type[] = 'deflate;q=1.0';
- }
-
- if (function_exists('gzuncompress')) {
- $type[] = 'compress;q=0.5';
- }
-
- $type[] = 'gzip;q=0.5';
-
- return implode(', ', $type);
- }
-
- /**
- * Format a URL given GET data
- *
- * @param array $url_parts
- * @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query}
- * @return string URL with data
- */
- private static function format_get($url_parts, $data) {
- if (!empty($data)) {
- if (empty($url_parts['query'])) {
- $url_parts['query'] = '';
- }
-
- $url_parts['query'] .= '&' . http_build_query($data, '', '&');
- $url_parts['query'] = trim($url_parts['query'], '&');
- }
- if (isset($url_parts['path'])) {
- if (isset($url_parts['query'])) {
- $get = $url_parts['path'] . '?' . $url_parts['query'];
- }
- else {
- $get = $url_parts['path'];
- }
- }
- else {
- $get = '/';
- }
- return $get;
- }
-
- /**
- * Error handler for stream_socket_client()
- *
- * @param int $errno Error number (e.g. E_WARNING)
- * @param string $errstr Error message
- */
- public function connect_error_handler($errno, $errstr) {
- // Double-check we can handle it
- if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
- // Return false to indicate the default error handler should engage
- return false;
- }
-
- $this->connect_error .= $errstr . "\n";
- return true;
- }
-
- /**
- * Verify the certificate against common name and subject alternative names
- *
- * Unfortunately, PHP doesn't check the certificate against the alternative
- * names, leading things like 'https://www.github.com/' to be invalid.
- * Instead
- *
- * @link https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
- *
- * @param string $host Host name to verify against
- * @param resource $context Stream context
- * @return bool
- *
- * @throws \WpOrg\Requests\Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
- * @throws \WpOrg\Requests\Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
- */
- public function verify_certificate_from_context($host, $context) {
- $meta = stream_context_get_options($context);
-
- // If we don't have SSL options, then we couldn't make the connection at
- // all
- if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
- throw new Exception(rtrim($this->connect_error), 'ssl.connect_error');
- }
-
- $cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
-
- return Ssl::verify_certificate($host, $cert);
- }
-
- /**
- * Self-test whether the transport can be used.
- *
- * The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
- *
- * @codeCoverageIgnore
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return bool Whether the transport can be used.
- */
- public static function test($capabilities = []) {
- if (!function_exists('fsockopen')) {
- return false;
- }
-
- // If needed, check that streams support SSL
- if (isset($capabilities[Capability::SSL]) && $capabilities[Capability::SSL]) {
- if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
- return false;
- }
- }
-
- return true;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesRequestsTransportcURLphpfromrev52243trunksrcwpincludesRequestsTransportcURLphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Transport/cURL.php (from rev 52243, trunk/src/wp-includes/Requests/Transport/cURL.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Transport/cURL.php (rev 0)
+++ trunk/src/wp-includes/Requests/Transport/cURL.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,589 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * cURL HTTP transport
+ *
+ * @package Requests
+ * @subpackage Transport
+ */
+
+/**
+ * cURL HTTP transport
+ *
+ * @package Requests
+ * @subpackage Transport
+ */
+class Requests_Transport_cURL implements Requests_Transport {
+ const CURL_7_10_5 = 0x070A05;
+ const CURL_7_16_2 = 0x071002;
+
+ /**
+ * Raw HTTP data
+ *
+ * @var string
+ */
+ public $headers = '';
+
+ /**
+ * Raw body data
+ *
+ * @var string
+ */
+ public $response_data = '';
+
+ /**
+ * Information on the current request
+ *
+ * @var array cURL information array, see {@see https://secure.php.net/curl_getinfo}
+ */
+ public $info;
+
+ /**
+ * cURL version number
+ *
+ * @var int
+ */
+ public $version;
+
+ /**
+ * cURL handle
+ *
+ * @var resource
+ */
+ protected $handle;
+
+ /**
+ * Hook dispatcher instance
+ *
+ * @var Requests_Hooks
+ */
+ protected $hooks;
+
+ /**
+ * Have we finished the headers yet?
+ *
+ * @var boolean
+ */
+ protected $done_headers = false;
+
+ /**
+ * If streaming to a file, keep the file pointer
+ *
+ * @var resource
+ */
+ protected $stream_handle;
+
+ /**
+ * How many bytes are in the response body?
+ *
+ * @var int
+ */
+ protected $response_bytes;
+
+ /**
+ * What's the maximum number of bytes we should keep?
+ *
+ * @var int|bool Byte count, or false if no limit.
+ */
+ protected $response_byte_limit;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $curl = curl_version();
+ $this->version = $curl['version_number'];
+ $this->handle = curl_init();
+
+ curl_setopt($this->handle, CURLOPT_HEADER, false);
+ curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
+ if ($this->version >= self::CURL_7_10_5) {
+ curl_setopt($this->handle, CURLOPT_ENCODING, '');
+ }
+ if (defined('CURLOPT_PROTOCOLS')) {
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_protocolsFound
+ curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+ }
+ if (defined('CURLOPT_REDIR_PROTOCOLS')) {
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_redir_protocolsFound
+ curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+ }
+ }
+
+ /**
+ * Destructor
+ */
+ public function __destruct() {
+ if (is_resource($this->handle)) {
+ curl_close($this->handle);
+ }
+ }
+
+ /**
+ * Perform a request
+ *
+ * @throws Requests_Exception On a cURL error (`curlerror`)
+ *
+ * @param string $url URL to request
+ * @param array $headers Associative array of request headers
+ * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
+ * @param array $options Request options, see {@see Requests::response()} for documentation
+ * @return string Raw HTTP result
+ */
+ public function request($url, $headers = array(), $data = array(), $options = array()) {
+ $this->hooks = $options['hooks'];
+
+ $this->setup_handle($url, $headers, $data, $options);
+
+ $options['hooks']->dispatch('curl.before_send', array(&$this->handle));
+
+ if ($options['filename'] !== false) {
+ $this->stream_handle = fopen($options['filename'], 'wb');
+ }
+
+ $this->response_data = '';
+ $this->response_bytes = 0;
+ $this->response_byte_limit = false;
+ if ($options['max_bytes'] !== false) {
+ $this->response_byte_limit = $options['max_bytes'];
+ }
+
+ if (isset($options['verify'])) {
+ if ($options['verify'] === false) {
+ curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
+ }
+ elseif (is_string($options['verify'])) {
+ curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
+ }
+ }
+
+ if (isset($options['verifyname']) && $options['verifyname'] === false) {
+ curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
+ }
+
+ curl_exec($this->handle);
+ $response = $this->response_data;
+
+ $options['hooks']->dispatch('curl.after_send', array());
+
+ if (curl_errno($this->handle) === 23 || curl_errno($this->handle) === 61) {
+ // Reset encoding and try again
+ curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
+
+ $this->response_data = '';
+ $this->response_bytes = 0;
+ curl_exec($this->handle);
+ $response = $this->response_data;
+ }
+
+ $this->process_response($response, $options);
+
+ // Need to remove the $this reference from the curl handle.
+ // Otherwise Requests_Transport_cURL wont be garbage collected and the curl_close() will never be called.
+ curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
+ curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
+
+ return $this->headers;
+ }
+
+ /**
+ * Send multiple requests simultaneously
+ *
+ * @param array $requests Request data
+ * @param array $options Global options
+ * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
+ */
+ public function request_multiple($requests, $options) {
+ // If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
+ if (empty($requests)) {
+ return array();
+ }
+
+ $multihandle = curl_multi_init();
+ $subrequests = array();
+ $subhandles = array();
+
+ $class = get_class($this);
+ foreach ($requests as $id => $request) {
+ $subrequests[$id] = new $class();
+ $subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
+ $request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id]));
+ curl_multi_add_handle($multihandle, $subhandles[$id]);
+ }
+
+ $completed = 0;
+ $responses = array();
+ $subrequestcount = count($subrequests);
+
+ $request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle));
+
+ do {
+ $active = 0;
+
+ do {
+ $status = curl_multi_exec($multihandle, $active);
+ }
+ while ($status === CURLM_CALL_MULTI_PERFORM);
+
+ $to_process = array();
+
+ // Read the information as needed
+ while ($done = curl_multi_info_read($multihandle)) {
+ $key = array_search($done['handle'], $subhandles, true);
+ if (!isset($to_process[$key])) {
+ $to_process[$key] = $done;
+ }
+ }
+
+ // Parse the finished requests before we start getting the new ones
+ foreach ($to_process as $key => $done) {
+ $options = $requests[$key]['options'];
+ if ($done['result'] !== CURLE_OK) {
+ //get error string for handle.
+ $reason = curl_error($done['handle']);
+ $exception = new Requests_Exception_Transport_cURL(
+ $reason,
+ Requests_Exception_Transport_cURL::EASY,
+ $done['handle'],
+ $done['result']
+ );
+ $responses[$key] = $exception;
+ $options['hooks']->dispatch('transport.internal.parse_error', array(&$responses[$key], $requests[$key]));
+ }
+ else {
+ $responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
+
+ $options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key]));
+ }
+
+ curl_multi_remove_handle($multihandle, $done['handle']);
+ curl_close($done['handle']);
+
+ if (!is_string($responses[$key])) {
+ $options['hooks']->dispatch('multiple.request.complete', array(&$responses[$key], $key));
+ }
+ $completed++;
+ }
+ }
+ while ($active || $completed < $subrequestcount);
+
+ $request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle));
+
+ curl_multi_close($multihandle);
+
+ return $responses;
+ }
+
+ /**
+ * Get the cURL handle for use in a multi-request
+ *
+ * @param string $url URL to request
+ * @param array $headers Associative array of request headers
+ * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
+ * @param array $options Request options, see {@see Requests::response()} for documentation
+ * @return resource Subrequest's cURL handle
+ */
+ public function &get_subrequest_handle($url, $headers, $data, $options) {
+ $this->setup_handle($url, $headers, $data, $options);
+
+ if ($options['filename'] !== false) {
+ $this->stream_handle = fopen($options['filename'], 'wb');
+ }
+
+ $this->response_data = '';
+ $this->response_bytes = 0;
+ $this->response_byte_limit = false;
+ if ($options['max_bytes'] !== false) {
+ $this->response_byte_limit = $options['max_bytes'];
+ }
+ $this->hooks = $options['hooks'];
+
+ return $this->handle;
+ }
+
+ /**
+ * Setup the cURL handle for the given data
+ *
+ * @param string $url URL to request
+ * @param array $headers Associative array of request headers
+ * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
+ * @param array $options Request options, see {@see Requests::response()} for documentation
+ */
+ protected function setup_handle($url, $headers, $data, $options) {
+ $options['hooks']->dispatch('curl.before_request', array(&$this->handle));
+
+ // Force closing the connection for old versions of cURL (<7.22).
+ if (!isset($headers['Connection'])) {
+ $headers['Connection'] = 'close';
+ }
+
+ /**
+ * Add "Expect" header.
+ *
+ * By default, cURL adds a "Expect: 100-Continue" to most requests. This header can
+ * add as much as a second to the time it takes for cURL to perform a request. To
+ * prevent this, we need to set an empty "Expect" header. To match the behaviour of
+ * Guzzle, we'll add the empty header to requests that are smaller than 1 MB and use
+ * HTTP/1.1.
+ *
+ * https://curl.se/mail/lib-2017-07/0013.html
+ */
+ if (!isset($headers['Expect']) && $options['protocol_version'] === 1.1) {
+ $headers['Expect'] = $this->get_expect_header($data);
+ }
+
+ $headers = Requests::flatten($headers);
+
+ if (!empty($data)) {
+ $data_format = $options['data_format'];
+
+ if ($data_format === 'query') {
+ $url = self::format_get($url, $data);
+ $data = '';
+ }
+ elseif (!is_string($data)) {
+ $data = http_build_query($data, null, '&');
+ }
+ }
+
+ switch ($options['type']) {
+ case Requests::POST:
+ curl_setopt($this->handle, CURLOPT_POST, true);
+ curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
+ break;
+ case Requests::HEAD:
+ curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
+ curl_setopt($this->handle, CURLOPT_NOBODY, true);
+ break;
+ case Requests::TRACE:
+ curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
+ break;
+ case Requests::PATCH:
+ case Requests::PUT:
+ case Requests::DELETE:
+ case Requests::OPTIONS:
+ default:
+ curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
+ if (!empty($data)) {
+ curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
+ }
+ }
+
+ // cURL requires a minimum timeout of 1 second when using the system
+ // DNS resolver, as it uses `alarm()`, which is second resolution only.
+ // There's no way to detect which DNS resolver is being used from our
+ // end, so we need to round up regardless of the supplied timeout.
+ //
+ // https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609
+ $timeout = max($options['timeout'], 1);
+
+ if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
+ curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
+ }
+ else {
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_timeout_msFound
+ curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
+ }
+
+ if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
+ curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
+ }
+ else {
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_connecttimeout_msFound
+ curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
+ }
+ curl_setopt($this->handle, CURLOPT_URL, $url);
+ curl_setopt($this->handle, CURLOPT_REFERER, $url);
+ curl_setopt($this->handle, CURLOPT_USERAGENT, $options['useragent']);
+ if (!empty($headers)) {
+ curl_setopt($this->handle, CURLOPT_HTTPHEADER, $headers);
+ }
+ if ($options['protocol_version'] === 1.1) {
+ curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ }
+ else {
+ curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ }
+
+ if ($options['blocking'] === true) {
+ curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array($this, 'stream_headers'));
+ curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, array($this, 'stream_body'));
+ curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
+ }
+ }
+
+ /**
+ * Process a response
+ *
+ * @param string $response Response data from the body
+ * @param array $options Request options
+ * @return string|false HTTP response data including headers. False if non-blocking.
+ * @throws Requests_Exception
+ */
+ public function process_response($response, $options) {
+ if ($options['blocking'] === false) {
+ $fake_headers = '';
+ $options['hooks']->dispatch('curl.after_request', array(&$fake_headers));
+ return false;
+ }
+ if ($options['filename'] !== false && $this->stream_handle) {
+ fclose($this->stream_handle);
+ $this->headers = trim($this->headers);
+ }
+ else {
+ $this->headers .= $response;
+ }
+
+ if (curl_errno($this->handle)) {
+ $error = sprintf(
+ 'cURL error %s: %s',
+ curl_errno($this->handle),
+ curl_error($this->handle)
+ );
+ throw new Requests_Exception($error, 'curlerror', $this->handle);
+ }
+ $this->info = curl_getinfo($this->handle);
+
+ $options['hooks']->dispatch('curl.after_request', array(&$this->headers, &$this->info));
+ return $this->headers;
+ }
+
+ /**
+ * Collect the headers as they are received
+ *
+ * @param resource $handle cURL resource
+ * @param string $headers Header string
+ * @return integer Length of provided header
+ */
+ public function stream_headers($handle, $headers) {
+ // Why do we do this? cURL will send both the final response and any
+ // interim responses, such as a 100 Continue. We don't need that.
+ // (We may want to keep this somewhere just in case)
+ if ($this->done_headers) {
+ $this->headers = '';
+ $this->done_headers = false;
+ }
+ $this->headers .= $headers;
+
+ if ($headers === "\r\n") {
+ $this->done_headers = true;
+ }
+ return strlen($headers);
+ }
+
+ /**
+ * Collect data as it's received
+ *
+ * @since 1.6.1
+ *
+ * @param resource $handle cURL resource
+ * @param string $data Body data
+ * @return integer Length of provided data
+ */
+ public function stream_body($handle, $data) {
+ $this->hooks->dispatch('request.progress', array($data, $this->response_bytes, $this->response_byte_limit));
+ $data_length = strlen($data);
+
+ // Are we limiting the response size?
+ if ($this->response_byte_limit) {
+ if ($this->response_bytes === $this->response_byte_limit) {
+ // Already at maximum, move on
+ return $data_length;
+ }
+
+ if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
+ // Limit the length
+ $limited_length = ($this->response_byte_limit - $this->response_bytes);
+ $data = substr($data, 0, $limited_length);
+ }
+ }
+
+ if ($this->stream_handle) {
+ fwrite($this->stream_handle, $data);
+ }
+ else {
+ $this->response_data .= $data;
+ }
+
+ $this->response_bytes += strlen($data);
+ return $data_length;
+ }
+
+ /**
+ * Format a URL given GET data
+ *
+ * @param string $url
+ * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
+ * @return string URL with data
+ */
+ protected static function format_get($url, $data) {
+ if (!empty($data)) {
+ $query = '';
+ $url_parts = parse_url($url);
+ if (empty($url_parts['query'])) {
+ $url_parts['query'] = '';
+ }
+ else {
+ $query = $url_parts['query'];
+ }
+
+ $query .= '&' . http_build_query($data, null, '&');
+ $query = trim($query, '&');
+
+ if (empty($url_parts['query'])) {
+ $url .= '?' . $query;
+ }
+ else {
+ $url = str_replace($url_parts['query'], $query, $url);
+ }
+ }
+ return $url;
+ }
+
+ /**
+ * Whether this transport is valid
+ *
+ * @codeCoverageIgnore
+ * @return boolean True if the transport is valid, false otherwise.
+ */
+ public static function test($capabilities = array()) {
+ if (!function_exists('curl_init') || !function_exists('curl_exec')) {
+ return false;
+ }
+
+ // If needed, check that our installed curl version supports SSL
+ if (isset($capabilities['ssl']) && $capabilities['ssl']) {
+ $curl_version = curl_version();
+ if (!(CURL_VERSION_SSL & $curl_version['features'])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the correct "Expect" header for the given request data.
+ *
+ * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD.
+ * @return string The "Expect" header.
+ */
+ protected function get_expect_header($data) {
+ if (!is_array($data)) {
+ return strlen((string) $data) >= 1048576 ? '100-Continue' : '';
+ }
+
+ $bytesize = 0;
+ $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
+
+ foreach ($iterator as $datum) {
+ $bytesize += strlen((string) $datum);
+
+ if ($bytesize >= 1048576) {
+ return '100-Continue';
+ }
+ }
+
+ return '';
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsTransportfsockopenphpfromrev52243trunksrcwpincludesRequestsTransportfsockopenphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/src/wp-includes/Requests/Transport/fsockopen.php (from rev 52243, trunk/src/wp-includes/Requests/Transport/fsockopen.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Transport/fsockopen.php (rev 0)
+++ trunk/src/wp-includes/Requests/Transport/fsockopen.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,451 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * fsockopen HTTP transport
+ *
+ * @package Requests
+ * @subpackage Transport
+ */
+
+/**
+ * fsockopen HTTP transport
+ *
+ * @package Requests
+ * @subpackage Transport
+ */
+class Requests_Transport_fsockopen implements Requests_Transport {
+ /**
+ * Second to microsecond conversion
+ *
+ * @var integer
+ */
+ const SECOND_IN_MICROSECONDS = 1000000;
+
+ /**
+ * Raw HTTP data
+ *
+ * @var string
+ */
+ public $headers = '';
+
+ /**
+ * Stream metadata
+ *
+ * @var array Associative array of properties, see {@see https://secure.php.net/stream_get_meta_data}
+ */
+ public $info;
+
+ /**
+ * What's the maximum number of bytes we should keep?
+ *
+ * @var int|bool Byte count, or false if no limit.
+ */
+ protected $max_bytes = false;
+
+ protected $connect_error = '';
+
+ /**
+ * Perform a request
+ *
+ * @throws Requests_Exception On failure to connect to socket (`fsockopenerror`)
+ * @throws Requests_Exception On socket timeout (`timeout`)
+ *
+ * @param string $url URL to request
+ * @param array $headers Associative array of request headers
+ * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
+ * @param array $options Request options, see {@see Requests::response()} for documentation
+ * @return string Raw HTTP result
+ */
+ public function request($url, $headers = array(), $data = array(), $options = array()) {
+ $options['hooks']->dispatch('fsockopen.before_request');
+
+ $url_parts = parse_url($url);
+ if (empty($url_parts)) {
+ throw new Requests_Exception('Invalid URL.', 'invalidurl', $url);
+ }
+ $host = $url_parts['host'];
+ $context = stream_context_create();
+ $verifyname = false;
+ $case_insensitive_headers = new Requests_Utility_CaseInsensitiveDictionary($headers);
+
+ // HTTPS support
+ if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
+ $remote_socket = 'ssl://' . $host;
+ if (!isset($url_parts['port'])) {
+ $url_parts['port'] = 443;
+ }
+
+ $context_options = array(
+ 'verify_peer' => true,
+ 'capture_peer_cert' => true,
+ );
+ $verifyname = true;
+
+ // SNI, if enabled (OpenSSL >=0.9.8j)
+ // phpcs:ignore PHPCompatibility.Constants.NewConstants.openssl_tlsext_server_nameFound
+ if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
+ $context_options['SNI_enabled'] = true;
+ if (isset($options['verifyname']) && $options['verifyname'] === false) {
+ $context_options['SNI_enabled'] = false;
+ }
+ }
+
+ if (isset($options['verify'])) {
+ if ($options['verify'] === false) {
+ $context_options['verify_peer'] = false;
+ $context_options['verify_peer_name'] = false;
+ $verifyname = false;
+ }
+ elseif (is_string($options['verify'])) {
+ $context_options['cafile'] = $options['verify'];
+ }
+ }
+
+ if (isset($options['verifyname']) && $options['verifyname'] === false) {
+ $context_options['verify_peer_name'] = false;
+ $verifyname = false;
+ }
+
+ stream_context_set_option($context, array('ssl' => $context_options));
+ }
+ else {
+ $remote_socket = 'tcp://' . $host;
+ }
+
+ $this->max_bytes = $options['max_bytes'];
+
+ if (!isset($url_parts['port'])) {
+ $url_parts['port'] = 80;
+ }
+ $remote_socket .= ':' . $url_parts['port'];
+
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
+ set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
+
+ $options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
+
+ $socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
+
+ restore_error_handler();
+
+ if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
+ throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
+ }
+
+ if (!$socket) {
+ if ($errno === 0) {
+ // Connection issue
+ throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
+ }
+
+ throw new Requests_Exception($errstr, 'fsockopenerror', null, $errno);
+ }
+
+ $data_format = $options['data_format'];
+
+ if ($data_format === 'query') {
+ $path = self::format_get($url_parts, $data);
+ $data = '';
+ }
+ else {
+ $path = self::format_get($url_parts, array());
+ }
+
+ $options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
+
+ $request_body = '';
+ $out = sprintf("%s %s HTTP/%.1F\r\n", $options['type'], $path, $options['protocol_version']);
+
+ if ($options['type'] !== Requests::TRACE) {
+ if (is_array($data)) {
+ $request_body = http_build_query($data, '', '&');
+ }
+ else {
+ $request_body = $data;
+ }
+
+ // Always include Content-length on POST requests to prevent
+ // 411 errors from some servers when the body is empty.
+ if (!empty($data) || $options['type'] === Requests::POST) {
+ if (!isset($case_insensitive_headers['Content-Length'])) {
+ $headers['Content-Length'] = strlen($request_body);
+ }
+
+ if (!isset($case_insensitive_headers['Content-Type'])) {
+ $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
+ }
+ }
+ }
+
+ if (!isset($case_insensitive_headers['Host'])) {
+ $out .= sprintf('Host: %s', $url_parts['host']);
+
+ if ((strtolower($url_parts['scheme']) === 'http' && $url_parts['port'] !== 80) || (strtolower($url_parts['scheme']) === 'https' && $url_parts['port'] !== 443)) {
+ $out .= ':' . $url_parts['port'];
+ }
+ $out .= "\r\n";
+ }
+
+ if (!isset($case_insensitive_headers['User-Agent'])) {
+ $out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
+ }
+
+ $accept_encoding = $this->accept_encoding();
+ if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
+ $out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
+ }
+
+ $headers = Requests::flatten($headers);
+
+ if (!empty($headers)) {
+ $out .= implode("\r\n", $headers) . "\r\n";
+ }
+
+ $options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
+
+ if (substr($out, -2) !== "\r\n") {
+ $out .= "\r\n";
+ }
+
+ if (!isset($case_insensitive_headers['Connection'])) {
+ $out .= "Connection: Close\r\n";
+ }
+
+ $out .= "\r\n" . $request_body;
+
+ $options['hooks']->dispatch('fsockopen.before_send', array(&$out));
+
+ fwrite($socket, $out);
+ $options['hooks']->dispatch('fsockopen.after_send', array($out));
+
+ if (!$options['blocking']) {
+ fclose($socket);
+ $fake_headers = '';
+ $options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
+ return '';
+ }
+
+ $timeout_sec = (int) floor($options['timeout']);
+ if ($timeout_sec === $options['timeout']) {
+ $timeout_msec = 0;
+ }
+ else {
+ $timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
+ }
+ stream_set_timeout($socket, $timeout_sec, $timeout_msec);
+
+ $response = '';
+ $body = '';
+ $headers = '';
+ $this->info = stream_get_meta_data($socket);
+ $size = 0;
+ $doingbody = false;
+ $download = false;
+ if ($options['filename']) {
+ $download = fopen($options['filename'], 'wb');
+ }
+
+ while (!feof($socket)) {
+ $this->info = stream_get_meta_data($socket);
+ if ($this->info['timed_out']) {
+ throw new Requests_Exception('fsocket timed out', 'timeout');
+ }
+
+ $block = fread($socket, Requests::BUFFER_SIZE);
+ if (!$doingbody) {
+ $response .= $block;
+ if (strpos($response, "\r\n\r\n")) {
+ list($headers, $block) = explode("\r\n\r\n", $response, 2);
+ $doingbody = true;
+ }
+ }
+
+ // Are we in body mode now?
+ if ($doingbody) {
+ $options['hooks']->dispatch('request.progress', array($block, $size, $this->max_bytes));
+ $data_length = strlen($block);
+ if ($this->max_bytes) {
+ // Have we already hit a limit?
+ if ($size === $this->max_bytes) {
+ continue;
+ }
+ if (($size + $data_length) > $this->max_bytes) {
+ // Limit the length
+ $limited_length = ($this->max_bytes - $size);
+ $block = substr($block, 0, $limited_length);
+ }
+ }
+
+ $size += strlen($block);
+ if ($download) {
+ fwrite($download, $block);
+ }
+ else {
+ $body .= $block;
+ }
+ }
+ }
+ $this->headers = $headers;
+
+ if ($download) {
+ fclose($download);
+ }
+ else {
+ $this->headers .= "\r\n\r\n" . $body;
+ }
+ fclose($socket);
+
+ $options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers, &$this->info));
+ return $this->headers;
+ }
+
+ /**
+ * Send multiple requests simultaneously
+ *
+ * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
+ * @param array $options Global options, see {@see Requests::response()} for documentation
+ * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
+ */
+ public function request_multiple($requests, $options) {
+ $responses = array();
+ $class = get_class($this);
+ foreach ($requests as $id => $request) {
+ try {
+ $handler = new $class();
+ $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
+
+ $request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
+ }
+ catch (Requests_Exception $e) {
+ $responses[$id] = $e;
+ }
+
+ if (!is_string($responses[$id])) {
+ $request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
+ }
+ }
+
+ return $responses;
+ }
+
+ /**
+ * Retrieve the encodings we can accept
+ *
+ * @return string Accept-Encoding header value
+ */
+ protected static function accept_encoding() {
+ $type = array();
+ if (function_exists('gzinflate')) {
+ $type[] = 'deflate;q=1.0';
+ }
+
+ if (function_exists('gzuncompress')) {
+ $type[] = 'compress;q=0.5';
+ }
+
+ $type[] = 'gzip;q=0.5';
+
+ return implode(', ', $type);
+ }
+
+ /**
+ * Format a URL given GET data
+ *
+ * @param array $url_parts
+ * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
+ * @return string URL with data
+ */
+ protected static function format_get($url_parts, $data) {
+ if (!empty($data)) {
+ if (empty($url_parts['query'])) {
+ $url_parts['query'] = '';
+ }
+
+ $url_parts['query'] .= '&' . http_build_query($data, '', '&');
+ $url_parts['query'] = trim($url_parts['query'], '&');
+ }
+ if (isset($url_parts['path'])) {
+ if (isset($url_parts['query'])) {
+ $get = $url_parts['path'] . '?' . $url_parts['query'];
+ }
+ else {
+ $get = $url_parts['path'];
+ }
+ }
+ else {
+ $get = '/';
+ }
+ return $get;
+ }
+
+ /**
+ * Error handler for stream_socket_client()
+ *
+ * @param int $errno Error number (e.g. E_WARNING)
+ * @param string $errstr Error message
+ */
+ public function connect_error_handler($errno, $errstr) {
+ // Double-check we can handle it
+ if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
+ // Return false to indicate the default error handler should engage
+ return false;
+ }
+
+ $this->connect_error .= $errstr . "\n";
+ return true;
+ }
+
+ /**
+ * Verify the certificate against common name and subject alternative names
+ *
+ * Unfortunately, PHP doesn't check the certificate against the alternative
+ * names, leading things like 'https://www.github.com/' to be invalid.
+ * Instead
+ *
+ * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
+ *
+ * @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
+ * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
+ * @param string $host Host name to verify against
+ * @param resource $context Stream context
+ * @return bool
+ */
+ public function verify_certificate_from_context($host, $context) {
+ $meta = stream_context_get_options($context);
+
+ // If we don't have SSL options, then we couldn't make the connection at
+ // all
+ if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
+ throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error');
+ }
+
+ $cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
+
+ return Requests_SSL::verify_certificate($host, $cert);
+ }
+
+ /**
+ * Whether this transport is valid
+ *
+ * @codeCoverageIgnore
+ * @return boolean True if the transport is valid, false otherwise.
+ */
+ public static function test($capabilities = array()) {
+ if (!function_exists('fsockopen')) {
+ return false;
+ }
+
+ // If needed, check that streams support SSL
+ if (isset($capabilities['ssl']) && $capabilities['ssl']) {
+ if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
+ return false;
+ }
+
+ // Currently broken, thanks to https://github.com/facebook/hhvm/issues/2156
+ if (defined('HHVM_VERSION')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesRequestsTransportphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Transport.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Transport.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Transport.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,17 +2,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Base HTTP transport
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Transport
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Transport
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Base HTTP transport
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Transport
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Transport
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-interface Transport {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+interface Requests_Transport {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Perform a request
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,27 +19,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $url URL to request
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers Associative array of request headers
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array $options Request options, see {@see Requests::response()} for documentation
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return string Raw HTTP result
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function request($url, $headers = [], $data = [], $options = []);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function request($url, $headers = array(), $data = array(), $options = array());
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Send multiple requests simultaneously
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see \WpOrg\Requests\Transport::request()}
- * @param array $options Global options, see {@see \WpOrg\Requests\Requests::response()} for documentation
- * @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
+ * @param array $options Global options, see {@see Requests::response()} for documentation
+ * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function request_multiple($requests, $options);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Self-test whether the transport can be used.
- *
- * The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
- *
- * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
- * @return bool Whether the transport can be used.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Self-test whether the transport can be used
+ * @return bool
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public static function test($capabilities = []);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function test();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsUtilityCaseInsensitiveDictionaryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,29 +2,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Case-insensitive dictionary, suitable for HTTP headers
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Utilities
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Utility;
-
-use ArrayAccess;
-use ArrayIterator;
-use IteratorAggregate;
-use ReturnTypeWillChange;
-use WpOrg\Requests\Exception;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Case-insensitive dictionary, suitable for HTTP headers
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Utilities
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class CaseInsensitiveDictionary implements ArrayAccess, IteratorAggregate {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Utility_CaseInsensitiveDictionary implements ArrayAccess, IteratorAggregate {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Actual item data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- protected $data = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected $data = array();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Creates a case insensitive dictionary.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -31,9 +25,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $data Dictionary/map to convert to case-insensitive
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct(array $data = []) {
- foreach ($data as $offset => $value) {
- $this->offsetSet($offset, $value);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct(array $data = array()) {
+ foreach ($data as $key => $value) {
+ $this->offsetSet($key, $value);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -40,78 +34,60 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Check if the given item exists
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item key
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Item key
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return boolean Does the item exist?
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetExists($offset) {
- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
-
- return isset($this->data[$offset]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetExists($key) {
+ $key = strtolower($key);
+ return isset($this->data[$key]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get the value for the item
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item key
- * @return string|null Item value (null if the item key doesn't exist)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key Item key
+ * @return string|null Item value (null if offsetExists is false)
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetGet($offset) {
- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
-
- if (!isset($this->data[$offset])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetGet($key) {
+ $key = strtolower($key);
+ if (!isset($this->data[$key])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->data[$offset];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $this->data[$key];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Set the given item
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset Item name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
+ *
+ * @param string $key Item name
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $value Item value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetSet($offset, $value) {
- if ($offset === null) {
- throw new Exception('Object is a dictionary, not a list', 'invalidset');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetSet($key, $value) {
+ if ($key === null) {
+ throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
-
- $this->data[$offset] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $key = strtolower($key);
+ $this->data[$key] = $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Unset the given header
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $offset
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $key
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function offsetUnset($offset) {
- if (is_string($offset)) {
- $offset = strtolower($offset);
- }
-
- unset($this->data[$offset]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function offsetUnset($key) {
+ unset($this->data[strtolower($key)]);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Get an iterator for the data
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return \ArrayIterator
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return ArrayIterator
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
</del><span class="cx" style="display: block; padding: 0 10px"> public function getIterator() {
</span><span class="cx" style="display: block; padding: 0 10px"> return new ArrayIterator($this->data);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsUtilityFilteredIteratorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/Requests/Utility/FilteredIterator.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Utility/FilteredIterator.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Utility/FilteredIterator.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,28 +2,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Iterator for arrays requiring filtered values
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Utilities
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-namespace WpOrg\Requests\Utility;
-
-use ArrayIterator;
-use ReturnTypeWillChange;
-use WpOrg\Requests\Exception\InvalidArgument;
-use WpOrg\Requests\Utility\InputValidator;
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Iterator for arrays requiring filtered values
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @package Requests\Utilities
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @package Requests
+ * @subpackage Utilities
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-final class FilteredIterator extends ArrayIterator {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests_Utility_FilteredIterator extends ArrayIterator {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Callback to run as a filter
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var callable
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- private $callback;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected $callback;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Create a new iterator
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -30,40 +25,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $data
</span><span class="cx" style="display: block; padding: 0 10px"> * @param callable $callback Callback to be called on each value
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not iterable.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function __construct($data, $callback) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (InputValidator::is_iterable($data) === false) {
- throw InvalidArgument::create(1, '$data', 'iterable', gettype($data));
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> parent::__construct($data);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (is_callable($callback)) {
- $this->callback = $callback;
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->callback = $callback;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @inheritdoc
- *
- * @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
- */
- #[ReturnTypeWillChange]
- public function __unserialize($data) {}
- // phpcs:enable
-
- public function __wakeup() {
- unset($this->callback);
- }
-
- /**
</del><span class="cx" style="display: block; padding: 0 10px"> * Get the current item's value after filtering
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @return string
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
</del><span class="cx" style="display: block; padding: 0 10px"> public function current() {
</span><span class="cx" style="display: block; padding: 0 10px"> $value = parent::current();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -77,6 +50,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * @inheritdoc
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- #[ReturnTypeWillChange]
- public function unserialize($data) {}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function unserialize($serialized) {}
+
+ /**
+ * @inheritdoc
+ *
+ * @phpcs:disable PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.MethodDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
+ */
+ public function __unserialize($serialized) {}
+
+ public function __wakeup() {
+ unset($this->callback);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesRequestsUtilityInputValidatorphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/src/wp-includes/Requests/Utility/InputValidator.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/Requests/Utility/InputValidator.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/Requests/Utility/InputValidator.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,109 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Input validation utilities.
- *
- * @package Requests\Utilities
- */
-
-namespace WpOrg\Requests\Utility;
-
-use ArrayAccess;
-use CurlHandle;
-use Traversable;
-
-/**
- * Input validation utilities.
- *
- * @package Requests\Utilities
- */
-final class InputValidator {
-
- /**
- * Verify that a received input parameter is of type string or is "stringable".
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function is_string_or_stringable($input) {
- return is_string($input) || self::is_stringable_object($input);
- }
-
- /**
- * Verify whether a received input parameter is usable as an integer array key.
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function is_numeric_array_key($input) {
- if (is_int($input)) {
- return true;
- }
-
- if (!is_string($input)) {
- return false;
- }
-
- return (bool) preg_match('`^-?[0-9]+$`', $input);
- }
-
- /**
- * Verify whether a received input parameter is "stringable".
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function is_stringable_object($input) {
- return is_object($input) && method_exists($input, '__toString');
- }
-
- /**
- * Verify whether a received input parameter is _accessible as if it were an array_.
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function has_array_access($input) {
- return is_array($input) || $input instanceof ArrayAccess;
- }
-
- /**
- * Verify whether a received input parameter is "iterable".
- *
- * @internal The PHP native `is_iterable()` function was only introduced in PHP 7.1
- * and this library still supports PHP 5.6.
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function is_iterable($input) {
- return is_array($input) || $input instanceof Traversable;
- }
-
- /**
- * Verify whether a received input parameter is a Curl handle.
- *
- * The PHP Curl extension worked with resources prior to PHP 8.0 and with
- * an instance of the `CurlHandle` class since PHP 8.0.
- * {@link https://www.php.net/manual/en/migration80.incompatible.php#migration80.incompatible.resource2object}
- *
- * @param mixed $input Input parameter to verify.
- *
- * @return bool
- */
- public static function is_curl_handle($input) {
- if (is_resource($input)) {
- return get_resource_type($input) === 'curl';
- }
-
- if (is_object($input)) {
- return $input instanceof CurlHandle;
- }
-
- return false;
- }
-}
</del></span></pre></div>
<a id="trunksrcwpincludesclassrequestsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-requests.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-requests.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/class-requests.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,31 +7,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Based on concepts from SimplePie_File, RequestCore and WP_Http.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @deprecated 5.9.0
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*
- * Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
- * by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
- * The constant needs to be defined before this class is required.
- */
-if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- trigger_error(
- 'The PSR-0 `Requests_...` class names in the Request library are deprecated.'
- . ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.',
- E_USER_DEPRECATED
- );
-
- // Prevent the deprecation notice from being thrown twice.
- if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
- define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
- }
-}
-
-require_once __DIR__ . '/Requests/Requests.php';
-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Requests for PHP
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -40,39 +17,985 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Based on concepts from SimplePie_File, RequestCore and WP_Http.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @package Requests
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *
- * @deprecated 5.9.0 Use `WpOrg\Requests\Requests` instead for the actual functionality and
- * use `WpOrg\Requests\Autoload` for the autoloading.
</del><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Requests extends WpOrg\Requests\Requests {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Requests {
+ /**
+ * POST method
+ *
+ * @var string
+ */
+ const POST = 'POST';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Deprecated autoloader for Requests.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * PUT method
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @deprecated 5.9.0 Use the `WpOrg\Requests\Autoload::load()` method instead.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var string
+ */
+ const PUT = 'PUT';
+
+ /**
+ * GET method
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var string
+ */
+ const GET = 'GET';
+
+ /**
+ * HEAD method
+ *
+ * @var string
+ */
+ const HEAD = 'HEAD';
+
+ /**
+ * DELETE method
+ *
+ * @var string
+ */
+ const DELETE = 'DELETE';
+
+ /**
+ * OPTIONS method
+ *
+ * @var string
+ */
+ const OPTIONS = 'OPTIONS';
+
+ /**
+ * TRACE method
+ *
+ * @var string
+ */
+ const TRACE = 'TRACE';
+
+ /**
+ * PATCH method
+ *
+ * @link https://tools.ietf.org/html/rfc5789
+ * @var string
+ */
+ const PATCH = 'PATCH';
+
+ /**
+ * Default size of buffer size to read streams
+ *
+ * @var integer
+ */
+ const BUFFER_SIZE = 1160;
+
+ /**
+ * Current version of Requests
+ *
+ * @var string
+ */
+ const VERSION = '1.8.1';
+
+ /**
+ * Registered transport classes
+ *
+ * @var array
+ */
+ protected static $transports = array();
+
+ /**
+ * Selected transport name
+ *
+ * Use {@see get_transport()} instead
+ *
+ * @var array
+ */
+ public static $transport = array();
+
+ /**
+ * Default certificate path.
+ *
+ * @see Requests::get_certificate_path()
+ * @see Requests::set_certificate_path()
+ *
+ * @var string
+ */
+ protected static $certificate_path;
+
+ /**
+ * This is a static class, do not instantiate it
+ *
</ins><span class="cx" style="display: block; padding: 0 10px"> * @codeCoverageIgnore
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ */
+ private function __construct() {}
+
+ /**
+ * Autoloader for Requests
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Register this with {@see register_autoloader()} if you'd like to avoid
+ * having to create your own.
+ *
+ * (You can also use `spl_autoload_register` directly if you'd prefer.)
+ *
+ * @codeCoverageIgnore
+ *
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $class Class name to load
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function autoloader($class) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (class_exists('WpOrg\Requests\Autoload') === false) {
- require_once __DIR__ . '/Requests/Autoload.php';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Check that the class starts with "Requests"
+ if (strpos($class, 'Requests') !== 0) {
+ return;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return WpOrg\Requests\Autoload::load($class);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $file = str_replace('_', '/', $class);
+ if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {
+ require_once dirname(__FILE__) . '/' . $file . '.php';
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Register the built-in autoloader
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @deprecated 5.9.0 Include the `WpOrg\Requests\Autoload` class and
- * call `WpOrg\Requests\Autoload::register()` instead.
- *
</del><span class="cx" style="display: block; padding: 0 10px"> * @codeCoverageIgnore
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function register_autoloader() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- require_once __DIR__ . '/Requests/Autoload.php';
- WpOrg\Requests\Autoload::register();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ spl_autoload_register(array('Requests', 'autoloader'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /**
+ * Register a transport
+ *
+ * @param string $transport Transport class to add, must support the Requests_Transport interface
+ */
+ public static function add_transport($transport) {
+ if (empty(self::$transports)) {
+ self::$transports = array(
+ 'Requests_Transport_cURL',
+ 'Requests_Transport_fsockopen',
+ );
+ }
+
+ self::$transports = array_merge(self::$transports, array($transport));
+ }
+
+ /**
+ * Get a working transport
+ *
+ * @throws Requests_Exception If no valid transport is found (`notransport`)
+ * @return Requests_Transport
+ */
+ protected static function get_transport($capabilities = array()) {
+ // Caching code, don't bother testing coverage
+ // @codeCoverageIgnoreStart
+ // array of capabilities as a string to be used as an array key
+ ksort($capabilities);
+ $cap_string = serialize($capabilities);
+
+ // Don't search for a transport if it's already been done for these $capabilities
+ if (isset(self::$transport[$cap_string]) && self::$transport[$cap_string] !== null) {
+ $class = self::$transport[$cap_string];
+ return new $class();
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (empty(self::$transports)) {
+ self::$transports = array(
+ 'Requests_Transport_cURL',
+ 'Requests_Transport_fsockopen',
+ );
+ }
+
+ // Find us a working transport
+ foreach (self::$transports as $class) {
+ if (!class_exists($class)) {
+ continue;
+ }
+
+ $result = call_user_func(array($class, 'test'), $capabilities);
+ if ($result) {
+ self::$transport[$cap_string] = $class;
+ break;
+ }
+ }
+ if (self::$transport[$cap_string] === null) {
+ throw new Requests_Exception('No working transports found', 'notransport', self::$transports);
+ }
+
+ $class = self::$transport[$cap_string];
+ return new $class();
+ }
+
+ /**#@+
+ * @see request()
+ * @param string $url
+ * @param array $headers
+ * @param array $options
+ * @return Requests_Response
+ */
+ /**
+ * Send a GET request
+ */
+ public static function get($url, $headers = array(), $options = array()) {
+ return self::request($url, $headers, null, self::GET, $options);
+ }
+
+ /**
+ * Send a HEAD request
+ */
+ public static function head($url, $headers = array(), $options = array()) {
+ return self::request($url, $headers, null, self::HEAD, $options);
+ }
+
+ /**
+ * Send a DELETE request
+ */
+ public static function delete($url, $headers = array(), $options = array()) {
+ return self::request($url, $headers, null, self::DELETE, $options);
+ }
+
+ /**
+ * Send a TRACE request
+ */
+ public static function trace($url, $headers = array(), $options = array()) {
+ return self::request($url, $headers, null, self::TRACE, $options);
+ }
+ /**#@-*/
+
+ /**#@+
+ * @see request()
+ * @param string $url
+ * @param array $headers
+ * @param array $data
+ * @param array $options
+ * @return Requests_Response
+ */
+ /**
+ * Send a POST request
+ */
+ public static function post($url, $headers = array(), $data = array(), $options = array()) {
+ return self::request($url, $headers, $data, self::POST, $options);
+ }
+ /**
+ * Send a PUT request
+ */
+ public static function put($url, $headers = array(), $data = array(), $options = array()) {
+ return self::request($url, $headers, $data, self::PUT, $options);
+ }
+
+ /**
+ * Send an OPTIONS request
+ */
+ public static function options($url, $headers = array(), $data = array(), $options = array()) {
+ return self::request($url, $headers, $data, self::OPTIONS, $options);
+ }
+
+ /**
+ * Send a PATCH request
+ *
+ * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
+ * specification recommends that should send an ETag
+ *
+ * @link https://tools.ietf.org/html/rfc5789
+ */
+ public static function patch($url, $headers, $data = array(), $options = array()) {
+ return self::request($url, $headers, $data, self::PATCH, $options);
+ }
+ /**#@-*/
+
+ /**
+ * Main interface for HTTP requests
+ *
+ * This method initiates a request and sends it via a transport before
+ * parsing.
+ *
+ * The `$options` parameter takes an associative array with the following
+ * options:
+ *
+ * - `timeout`: How long should we wait for a response?
+ * Note: for cURL, a minimum of 1 second applies, as DNS resolution
+ * operates at second-resolution only.
+ * (float, seconds with a millisecond precision, default: 10, example: 0.01)
+ * - `connect_timeout`: How long should we wait while trying to connect?
+ * (float, seconds with a millisecond precision, default: 10, example: 0.01)
+ * - `useragent`: Useragent to send to the server
+ * (string, default: php-requests/$version)
+ * - `follow_redirects`: Should we follow 3xx redirects?
+ * (boolean, default: true)
+ * - `redirects`: How many times should we redirect before erroring?
+ * (integer, default: 10)
+ * - `blocking`: Should we block processing on this request?
+ * (boolean, default: true)
+ * - `filename`: File to stream the body to instead.
+ * (string|boolean, default: false)
+ * - `auth`: Authentication handler or array of user/password details to use
+ * for Basic authentication
+ * (Requests_Auth|array|boolean, default: false)
+ * - `proxy`: Proxy details to use for proxy by-passing and authentication
+ * (Requests_Proxy|array|string|boolean, default: false)
+ * - `max_bytes`: Limit for the response body size.
+ * (integer|boolean, default: false)
+ * - `idn`: Enable IDN parsing
+ * (boolean, default: true)
+ * - `transport`: Custom transport. Either a class name, or a
+ * transport object. Defaults to the first working transport from
+ * {@see getTransport()}
+ * (string|Requests_Transport, default: {@see getTransport()})
+ * - `hooks`: Hooks handler.
+ * (Requests_Hooker, default: new Requests_Hooks())
+ * - `verify`: Should we verify SSL certificates? Allows passing in a custom
+ * certificate file as a string. (Using true uses the system-wide root
+ * certificate store instead, but this may have different behaviour
+ * across transports.)
+ * (string|boolean, default: library/Requests/Transport/cacert.pem)
+ * - `verifyname`: Should we verify the common name in the SSL certificate?
+ * (boolean, default: true)
+ * - `data_format`: How should we send the `$data` parameter?
+ * (string, one of 'query' or 'body', default: 'query' for
+ * HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH)
+ *
+ * @throws Requests_Exception On invalid URLs (`nonhttp`)
+ *
+ * @param string $url URL to request
+ * @param array $headers Extra headers to send with the request
+ * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
+ * @param string $type HTTP request type (use Requests constants)
+ * @param array $options Options for the request (see description for more information)
+ * @return Requests_Response
+ */
+ public static function request($url, $headers = array(), $data = array(), $type = self::GET, $options = array()) {
+ if (empty($options['type'])) {
+ $options['type'] = $type;
+ }
+ $options = array_merge(self::get_default_options(), $options);
+
+ self::set_defaults($url, $headers, $data, $type, $options);
+
+ $options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));
+
+ if (!empty($options['transport'])) {
+ $transport = $options['transport'];
+
+ if (is_string($options['transport'])) {
+ $transport = new $transport();
+ }
+ }
+ else {
+ $need_ssl = (stripos($url, 'https://') === 0);
+ $capabilities = array('ssl' => $need_ssl);
+ $transport = self::get_transport($capabilities);
+ }
+ $response = $transport->request($url, $headers, $data, $options);
+
+ $options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));
+
+ return self::parse_response($response, $url, $headers, $data, $options);
+ }
+
+ /**
+ * Send multiple HTTP requests simultaneously
+ *
+ * The `$requests` parameter takes an associative or indexed array of
+ * request fields. The key of each request can be used to match up the
+ * request with the returned data, or with the request passed into your
+ * `multiple.request.complete` callback.
+ *
+ * The request fields value is an associative array with the following keys:
+ *
+ * - `url`: Request URL Same as the `$url` parameter to
+ * {@see Requests::request}
+ * (string, required)
+ * - `headers`: Associative array of header fields. Same as the `$headers`
+ * parameter to {@see Requests::request}
+ * (array, default: `array()`)
+ * - `data`: Associative array of data fields or a string. Same as the
+ * `$data` parameter to {@see Requests::request}
+ * (array|string, default: `array()`)
+ * - `type`: HTTP request type (use Requests constants). Same as the `$type`
+ * parameter to {@see Requests::request}
+ * (string, default: `Requests::GET`)
+ * - `cookies`: Associative array of cookie name to value, or cookie jar.
+ * (array|Requests_Cookie_Jar)
+ *
+ * If the `$options` parameter is specified, individual requests will
+ * inherit options from it. This can be used to use a single hooking system,
+ * or set all the types to `Requests::POST`, for example.
+ *
+ * In addition, the `$options` parameter takes the following global options:
+ *
+ * - `complete`: A callback for when a request is complete. Takes two
+ * parameters, a Requests_Response/Requests_Exception reference, and the
+ * ID from the request array (Note: this can also be overridden on a
+ * per-request basis, although that's a little silly)
+ * (callback)
+ *
+ * @param array $requests Requests data (see description for more information)
+ * @param array $options Global and default options (see {@see Requests::request})
+ * @return array Responses (either Requests_Response or a Requests_Exception object)
+ */
+ public static function request_multiple($requests, $options = array()) {
+ $options = array_merge(self::get_default_options(true), $options);
+
+ if (!empty($options['hooks'])) {
+ $options['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
+ if (!empty($options['complete'])) {
+ $options['hooks']->register('multiple.request.complete', $options['complete']);
+ }
+ }
+
+ foreach ($requests as $id => &$request) {
+ if (!isset($request['headers'])) {
+ $request['headers'] = array();
+ }
+ if (!isset($request['data'])) {
+ $request['data'] = array();
+ }
+ if (!isset($request['type'])) {
+ $request['type'] = self::GET;
+ }
+ if (!isset($request['options'])) {
+ $request['options'] = $options;
+ $request['options']['type'] = $request['type'];
+ }
+ else {
+ if (empty($request['options']['type'])) {
+ $request['options']['type'] = $request['type'];
+ }
+ $request['options'] = array_merge($options, $request['options']);
+ }
+
+ self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']);
+
+ // Ensure we only hook in once
+ if ($request['options']['hooks'] !== $options['hooks']) {
+ $request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
+ if (!empty($request['options']['complete'])) {
+ $request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']);
+ }
+ }
+ }
+ unset($request);
+
+ if (!empty($options['transport'])) {
+ $transport = $options['transport'];
+
+ if (is_string($options['transport'])) {
+ $transport = new $transport();
+ }
+ }
+ else {
+ $transport = self::get_transport();
+ }
+ $responses = $transport->request_multiple($requests, $options);
+
+ foreach ($responses as $id => &$response) {
+ // If our hook got messed with somehow, ensure we end up with the
+ // correct response
+ if (is_string($response)) {
+ $request = $requests[$id];
+ self::parse_multiple($response, $request);
+ $request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id));
+ }
+ }
+
+ return $responses;
+ }
+
+ /**
+ * Get the default options
+ *
+ * @see Requests::request() for values returned by this method
+ * @param boolean $multirequest Is this a multirequest?
+ * @return array Default option values
+ */
+ protected static function get_default_options($multirequest = false) {
+ $defaults = array(
+ 'timeout' => 10,
+ 'connect_timeout' => 10,
+ 'useragent' => 'php-requests/' . self::VERSION,
+ 'protocol_version' => 1.1,
+ 'redirected' => 0,
+ 'redirects' => 10,
+ 'follow_redirects' => true,
+ 'blocking' => true,
+ 'type' => self::GET,
+ 'filename' => false,
+ 'auth' => false,
+ 'proxy' => false,
+ 'cookies' => false,
+ 'max_bytes' => false,
+ 'idn' => true,
+ 'hooks' => null,
+ 'transport' => null,
+ 'verify' => self::get_certificate_path(),
+ 'verifyname' => true,
+ );
+ if ($multirequest !== false) {
+ $defaults['complete'] = null;
+ }
+ return $defaults;
+ }
+
+ /**
+ * Get default certificate path.
+ *
+ * @return string Default certificate path.
+ */
+ public static function get_certificate_path() {
+ if (!empty(self::$certificate_path)) {
+ return self::$certificate_path;
+ }
+
+ return dirname(__FILE__) . '/Requests/Transport/cacert.pem';
+ }
+
+ /**
+ * Set default certificate path.
+ *
+ * @param string $path Certificate path, pointing to a PEM file.
+ */
+ public static function set_certificate_path($path) {
+ self::$certificate_path = $path;
+ }
+
+ /**
+ * Set the default values
+ *
+ * @param string $url URL to request
+ * @param array $headers Extra headers to send with the request
+ * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
+ * @param string $type HTTP request type
+ * @param array $options Options for the request
+ * @return array $options
+ */
+ protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) {
+ if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) {
+ throw new Requests_Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url);
+ }
+
+ if (empty($options['hooks'])) {
+ $options['hooks'] = new Requests_Hooks();
+ }
+
+ if (is_array($options['auth'])) {
+ $options['auth'] = new Requests_Auth_Basic($options['auth']);
+ }
+ if ($options['auth'] !== false) {
+ $options['auth']->register($options['hooks']);
+ }
+
+ if (is_string($options['proxy']) || is_array($options['proxy'])) {
+ $options['proxy'] = new Requests_Proxy_HTTP($options['proxy']);
+ }
+ if ($options['proxy'] !== false) {
+ $options['proxy']->register($options['hooks']);
+ }
+
+ if (is_array($options['cookies'])) {
+ $options['cookies'] = new Requests_Cookie_Jar($options['cookies']);
+ }
+ elseif (empty($options['cookies'])) {
+ $options['cookies'] = new Requests_Cookie_Jar();
+ }
+ if ($options['cookies'] !== false) {
+ $options['cookies']->register($options['hooks']);
+ }
+
+ if ($options['idn'] !== false) {
+ $iri = new Requests_IRI($url);
+ $iri->host = Requests_IDNAEncoder::encode($iri->ihost);
+ $url = $iri->uri;
+ }
+
+ // Massage the type to ensure we support it.
+ $type = strtoupper($type);
+
+ if (!isset($options['data_format'])) {
+ if (in_array($type, array(self::HEAD, self::GET, self::DELETE), true)) {
+ $options['data_format'] = 'query';
+ }
+ else {
+ $options['data_format'] = 'body';
+ }
+ }
+ }
+
+ /**
+ * HTTP response parser
+ *
+ * @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`)
+ * @throws Requests_Exception On missing head/body separator (`noversion`)
+ * @throws Requests_Exception On missing head/body separator (`toomanyredirects`)
+ *
+ * @param string $headers Full response text including headers and body
+ * @param string $url Original request URL
+ * @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
+ * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects
+ * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects
+ * @return Requests_Response
+ */
+ protected static function parse_response($headers, $url, $req_headers, $req_data, $options) {
+ $return = new Requests_Response();
+ if (!$options['blocking']) {
+ return $return;
+ }
+
+ $return->raw = $headers;
+ $return->url = (string) $url;
+ $return->body = '';
+
+ if (!$options['filename']) {
+ $pos = strpos($headers, "\r\n\r\n");
+ if ($pos === false) {
+ // Crap!
+ throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
+ }
+
+ $headers = substr($return->raw, 0, $pos);
+ // Headers will always be separated from the body by two new lines - `\n\r\n\r`.
+ $body = substr($return->raw, $pos + 4);
+ if (!empty($body)) {
+ $return->body = $body;
+ }
+ }
+ // Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
+ $headers = str_replace("\r\n", "\n", $headers);
+ // Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
+ $headers = preg_replace('/\n[ \t]/', ' ', $headers);
+ $headers = explode("\n", $headers);
+ preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches);
+ if (empty($matches)) {
+ throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
+ }
+ $return->protocol_version = (float) $matches[1];
+ $return->status_code = (int) $matches[2];
+ if ($return->status_code >= 200 && $return->status_code < 300) {
+ $return->success = true;
+ }
+
+ foreach ($headers as $header) {
+ list($key, $value) = explode(':', $header, 2);
+ $value = trim($value);
+ preg_replace('#(\s+)#i', ' ', $value);
+ $return->headers[$key] = $value;
+ }
+ if (isset($return->headers['transfer-encoding'])) {
+ $return->body = self::decode_chunked($return->body);
+ unset($return->headers['transfer-encoding']);
+ }
+ if (isset($return->headers['content-encoding'])) {
+ $return->body = self::decompress($return->body);
+ }
+
+ //fsockopen and cURL compatibility
+ if (isset($return->headers['connection'])) {
+ unset($return->headers['connection']);
+ }
+
+ $options['hooks']->dispatch('requests.before_redirect_check', array(&$return, $req_headers, $req_data, $options));
+
+ if ($return->is_redirect() && $options['follow_redirects'] === true) {
+ if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
+ if ($return->status_code === 303) {
+ $options['type'] = self::GET;
+ }
+ $options['redirected']++;
+ $location = $return->headers['location'];
+ if (strpos($location, 'http://') !== 0 && strpos($location, 'https://') !== 0) {
+ // relative redirect, for compatibility make it absolute
+ $location = Requests_IRI::absolutize($url, $location);
+ $location = $location->uri;
+ }
+
+ $hook_args = array(
+ &$location,
+ &$req_headers,
+ &$req_data,
+ &$options,
+ $return,
+ );
+ $options['hooks']->dispatch('requests.before_redirect', $hook_args);
+ $redirected = self::request($location, $req_headers, $req_data, $options['type'], $options);
+ $redirected->history[] = $return;
+ return $redirected;
+ }
+ elseif ($options['redirected'] >= $options['redirects']) {
+ throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);
+ }
+ }
+
+ $return->redirects = $options['redirected'];
+
+ $options['hooks']->dispatch('requests.after_request', array(&$return, $req_headers, $req_data, $options));
+ return $return;
+ }
+
+ /**
+ * Callback for `transport.internal.parse_response`
+ *
+ * Internal use only. Converts a raw HTTP response to a Requests_Response
+ * while still executing a multiple request.
+ *
+ * @param string $response Full response text including headers and body (will be overwritten with Response instance)
+ * @param array $request Request data as passed into {@see Requests::request_multiple()}
+ * @return null `$response` is either set to a Requests_Response instance, or a Requests_Exception object
+ */
+ public static function parse_multiple(&$response, $request) {
+ try {
+ $url = $request['url'];
+ $headers = $request['headers'];
+ $data = $request['data'];
+ $options = $request['options'];
+ $response = self::parse_response($response, $url, $headers, $data, $options);
+ }
+ catch (Requests_Exception $e) {
+ $response = $e;
+ }
+ }
+
+ /**
+ * Decoded a chunked body as per RFC 2616
+ *
+ * @see https://tools.ietf.org/html/rfc2616#section-3.6.1
+ * @param string $data Chunked body
+ * @return string Decoded body
+ */
+ protected static function decode_chunked($data) {
+ if (!preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', trim($data))) {
+ return $data;
+ }
+
+ $decoded = '';
+ $encoded = $data;
+
+ while (true) {
+ $is_chunked = (bool) preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', $encoded, $matches);
+ if (!$is_chunked) {
+ // Looks like it's not chunked after all
+ return $data;
+ }
+
+ $length = hexdec(trim($matches[1]));
+ if ($length === 0) {
+ // Ignore trailer headers
+ return $decoded;
+ }
+
+ $chunk_length = strlen($matches[0]);
+ $decoded .= substr($encoded, $chunk_length, $length);
+ $encoded = substr($encoded, $chunk_length + $length + 2);
+
+ if (trim($encoded) === '0' || empty($encoded)) {
+ return $decoded;
+ }
+ }
+
+ // We'll never actually get down here
+ // @codeCoverageIgnoreStart
+ }
+ // @codeCoverageIgnoreEnd
+
+ /**
+ * Convert a key => value array to a 'key: value' array for headers
+ *
+ * @param array $array Dictionary of header values
+ * @return array List of headers
+ */
+ public static function flatten($array) {
+ $return = array();
+ foreach ($array as $key => $value) {
+ $return[] = sprintf('%s: %s', $key, $value);
+ }
+ return $return;
+ }
+
+ /**
+ * Convert a key => value array to a 'key: value' array for headers
+ *
+ * @codeCoverageIgnore
+ * @deprecated Misspelling of {@see Requests::flatten}
+ * @param array $array Dictionary of header values
+ * @return array List of headers
+ */
+ public static function flattern($array) {
+ return self::flatten($array);
+ }
+
+ /**
+ * Decompress an encoded body
+ *
+ * Implements gzip, compress and deflate. Guesses which it is by attempting
+ * to decode.
+ *
+ * @param string $data Compressed data in one of the above formats
+ * @return string Decompressed string
+ */
+ public static function decompress($data) {
+ if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") {
+ // Not actually compressed. Probably cURL ruining this for us.
+ return $data;
+ }
+
+ if (function_exists('gzdecode')) {
+ // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gzdecodeFound -- Wrapped in function_exists() for PHP 5.2.
+ $decoded = @gzdecode($data);
+ if ($decoded !== false) {
+ return $decoded;
+ }
+ }
+
+ if (function_exists('gzinflate')) {
+ $decoded = @gzinflate($data);
+ if ($decoded !== false) {
+ return $decoded;
+ }
+ }
+
+ $decoded = self::compatible_gzinflate($data);
+ if ($decoded !== false) {
+ return $decoded;
+ }
+
+ if (function_exists('gzuncompress')) {
+ $decoded = @gzuncompress($data);
+ if ($decoded !== false) {
+ return $decoded;
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Decompression of deflated string while staying compatible with the majority of servers.
+ *
+ * Certain Servers will return deflated data with headers which PHP's gzinflate()
+ * function cannot handle out of the box. The following function has been created from
+ * various snippets on the gzinflate() PHP documentation.
+ *
+ * Warning: Magic numbers within. Due to the potential different formats that the compressed
+ * data may be returned in, some "magic offsets" are needed to ensure proper decompression
+ * takes place. For a simple progmatic way to determine the magic offset in use, see:
+ * https://core.trac.wordpress.org/ticket/18273
+ *
+ * @since 2.8.1
+ * @link https://core.trac.wordpress.org/ticket/18273
+ * @link https://secure.php.net/manual/en/function.gzinflate.php#70875
+ * @link https://secure.php.net/manual/en/function.gzinflate.php#77336
+ *
+ * @param string $gz_data String to decompress.
+ * @return string|bool False on failure.
+ */
+ public static function compatible_gzinflate($gz_data) {
+ // Compressed data might contain a full zlib header, if so strip it for
+ // gzinflate()
+ if (substr($gz_data, 0, 3) === "\x1f\x8b\x08") {
+ $i = 10;
+ $flg = ord(substr($gz_data, 3, 1));
+ if ($flg > 0) {
+ if ($flg & 4) {
+ list($xlen) = unpack('v', substr($gz_data, $i, 2));
+ $i += 2 + $xlen;
+ }
+ if ($flg & 8) {
+ $i = strpos($gz_data, "\0", $i) + 1;
+ }
+ if ($flg & 16) {
+ $i = strpos($gz_data, "\0", $i) + 1;
+ }
+ if ($flg & 2) {
+ $i += 2;
+ }
+ }
+ $decompressed = self::compatible_gzinflate(substr($gz_data, $i));
+ if ($decompressed !== false) {
+ return $decompressed;
+ }
+ }
+
+ // If the data is Huffman Encoded, we must first strip the leading 2
+ // byte Huffman marker for gzinflate()
+ // The response is Huffman coded by many compressors such as
+ // java.util.zip.Deflater, Ruby’s Zlib::Deflate, and .NET's
+ // System.IO.Compression.DeflateStream.
+ //
+ // See https://decompres.blogspot.com/ for a quick explanation of this
+ // data type
+ $huffman_encoded = false;
+
+ // low nibble of first byte should be 0x08
+ list(, $first_nibble) = unpack('h', $gz_data);
+
+ // First 2 bytes should be divisible by 0x1F
+ list(, $first_two_bytes) = unpack('n', $gz_data);
+
+ if ($first_nibble === 0x08 && ($first_two_bytes % 0x1F) === 0) {
+ $huffman_encoded = true;
+ }
+
+ if ($huffman_encoded) {
+ $decompressed = @gzinflate(substr($gz_data, 2));
+ if ($decompressed !== false) {
+ return $decompressed;
+ }
+ }
+
+ if (substr($gz_data, 0, 4) === "\x50\x4b\x03\x04") {
+ // ZIP file format header
+ // Offset 6: 2 bytes, General-purpose field
+ // Offset 26: 2 bytes, filename length
+ // Offset 28: 2 bytes, optional field length
+ // Offset 30: Filename field, followed by optional field, followed
+ // immediately by data
+ list(, $general_purpose_flag) = unpack('v', substr($gz_data, 6, 2));
+
+ // If the file has been compressed on the fly, 0x08 bit is set of
+ // the general purpose field. We can use this to differentiate
+ // between a compressed document, and a ZIP file
+ $zip_compressed_on_the_fly = ((0x08 & $general_purpose_flag) === 0x08);
+
+ if (!$zip_compressed_on_the_fly) {
+ // Don't attempt to decode a compressed zip file
+ return $gz_data;
+ }
+
+ // Determine the first byte of data, based on the above ZIP header
+ // offsets:
+ $first_file_start = array_sum(unpack('v2', substr($gz_data, 26, 4)));
+ $decompressed = @gzinflate(substr($gz_data, 30 + $first_file_start));
+ if ($decompressed !== false) {
+ return $decompressed;
+ }
+ return false;
+ }
+
+ // Finally fall back to straight gzinflate
+ $decompressed = @gzinflate($gz_data);
+ if ($decompressed !== false) {
+ return $decompressed;
+ }
+
+ // Fallback for all above failing, not expected, but included for
+ // debugging and preventing regressions and to track stats
+ $decompressed = @gzinflate(substr($gz_data, 2));
+ if ($decompressed !== false) {
+ return $decompressed;
+ }
+
+ return false;
+ }
+
+ public static function match_domain($host, $reference) {
+ // Check for a direct match
+ if ($host === $reference) {
+ return true;
+ }
+
+ // Calculate the valid wildcard match if the host is not an IP address
+ // Also validates that the host has 3 parts or more, as per Firefox's
+ // ruleset.
+ $parts = explode('.', $host);
+ if (ip2long($host) === false && count($parts) >= 3) {
+ $parts[0] = '*';
+ $wildcard = implode('.', $parts);
+ if ($wildcard === $reference) {
+ return true;
+ }
+ }
+
+ return false;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesclasswphttprequestshooksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-http-requests-hooks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-http-requests-hooks.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/class-wp-http-requests-hooks.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,9 +12,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.7.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see WpOrg\Requests\Hooks
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see Requests_Hooks
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class WP_HTTP_Requests_Hooks extends WpOrg\Requests\Hooks {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class WP_HTTP_Requests_Hooks extends Requests_Hooks {
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Requested URL.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span></span></pre></div>
<a id="trunksrcwpincludesclasswphttprequestsresponsephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-http-requests-response.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-http-requests-response.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/class-wp-http-requests-response.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -8,7 +8,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Core wrapper object for a WpOrg\Requests\Response for standardisation.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Core wrapper object for a Requests_Response for standardisation.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,7 +19,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Requests Response object.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var \WpOrg\Requests\Response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var Requests_Response
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected $response;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -36,10 +36,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param \WpOrg\Requests\Response $response HTTP response.
- * @param string $filename Optional. File name. Default empty.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param Requests_Response $response HTTP response.
+ * @param string $filename Optional. File name. Default empty.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct( WpOrg\Requests\Response $response, $filename = '' ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct( Requests_Response $response, $filename = '' ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->response = $response;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->filename = $filename;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -49,7 +49,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return WpOrg\Requests\Response HTTP response.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return Requests_Response HTTP response.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function get_response_object() {
</span><span class="cx" style="display: block; padding: 0 10px"> return $this->response;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -60,11 +60,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary Map of header name to header value.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return \Requests_Utility_CaseInsensitiveDictionary Map of header name to header value.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function get_headers() {
</span><span class="cx" style="display: block; padding: 0 10px"> // Ensure headers remain case-insensitive.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $converted = new WpOrg\Requests\Utility\CaseInsensitiveDictionary();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $converted = new Requests_Utility_CaseInsensitiveDictionary();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $this->response->headers->getAll() as $key => $value ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( count( $value ) === 1 ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -85,7 +85,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $headers Map of header name to header value.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function set_headers( $headers ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->response->headers = new WpOrg\Requests\Response\Headers( $headers );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->response->headers = new Requests_Response_Headers( $headers );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunksrcwpincludesclasswphttpphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-http.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-http.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/class-wp-http.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,11 +7,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 2.7.0
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-if ( ! class_exists( 'WpOrg\Requests\Autoload' ) ) {
- require ABSPATH . WPINC . '/Requests/Autoload.php';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+if ( ! class_exists( 'Requests' ) ) {
+ require ABSPATH . WPINC . '/class-requests.php';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- WpOrg\Requests\Autoload::register();
- WpOrg\Requests\Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ Requests::register_autoloader();
+ Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -274,7 +274,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( empty( $url ) || empty( $parsed_url['scheme'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $response = new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> /** This action is documented in wp-includes/class-wp-http.php */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
</ins><span class="cx" style="display: block; padding: 0 10px"> return $response;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -281,7 +281,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $this->block_request( $url ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $response = new WP_Error( 'http_request_not_executed', __( 'User has blocked requests through HTTP.' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> /** This action is documented in wp-includes/class-wp-http.php */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
</ins><span class="cx" style="display: block; padding: 0 10px"> return $response;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -298,7 +298,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! wp_is_writable( dirname( $parsed_args['filename'] ) ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $response = new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> /** This action is documented in wp-includes/class-wp-http.php */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
</ins><span class="cx" style="display: block; padding: 0 10px"> return $response;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -346,7 +346,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $options['max_bytes'] = $parsed_args['limit_response_size'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If we've got cookies, use and convert them to WpOrg\Requests\Cookie.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // If we've got cookies, use and convert them to Requests_Cookie.
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! empty( $parsed_args['cookies'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $options['cookies'] = WP_Http::normalize_cookies( $parsed_args['cookies'] );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -378,7 +378,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Check for proxies.
</span><span class="cx" style="display: block; padding: 0 10px"> $proxy = new WP_HTTP_Proxy();
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $options['proxy'] = new WpOrg\Requests\Proxy\HTTP( $proxy->host() . ':' . $proxy->port() );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $options['proxy'] = new Requests_Proxy_HTTP( $proxy->host() . ':' . $proxy->port() );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $proxy->use_authentication() ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $options['proxy']->use_authentication = true;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -391,7 +391,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> mbstring_binary_safe_encoding();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $requests_response = WpOrg\Requests\Requests::request( $url, $headers, $data, $type, $options );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $requests_response = Requests::request( $url, $headers, $data, $type, $options );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Convert the response into an array.
</span><span class="cx" style="display: block; padding: 0 10px"> $http_response = new WP_HTTP_Requests_Response( $requests_response, $parsed_args['filename'] );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -399,7 +399,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Add the original object to the array.
</span><span class="cx" style="display: block; padding: 0 10px"> $response['http_response'] = $http_response;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- } catch ( WpOrg\Requests\Exception $e ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } catch ( Requests_Exception $e ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $response = new WP_Error( 'http_request_failed', $e->getMessage() );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -416,7 +416,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $parsed_args HTTP request arguments.
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $url The request URL.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( is_wp_error( $response ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return $response;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -452,10 +452,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array $cookies Array of cookies to send with the request.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return WpOrg\Requests\Cookie\Jar Cookie holder object.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return Requests_Cookie_Jar Cookie holder object.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function normalize_cookies( $cookies ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookie_jar = new WpOrg\Requests\Cookie\Jar();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookie_jar = new Requests_Cookie_Jar();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( $cookies as $name => $value ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $value instanceof WP_Http_Cookie ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -465,9 +465,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return null !== $attr;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookie_jar[ $value->name ] = new WpOrg\Requests\Cookie( $value->name, $value->value, $attributes, array( 'host-only' => $value->host_only ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookie_jar[ $value->name ] = new Requests_Cookie( $value->name, $value->value, $attributes, array( 'host-only' => $value->host_only ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> } elseif ( is_scalar( $value ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cookie_jar[ $name ] = new WpOrg\Requests\Cookie( $name, (string) $value );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cookie_jar[ $name ] = new Requests_Cookie( $name, $value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -483,16 +483,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.6.0
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $location URL to redirect to.
- * @param array $headers Headers for the redirect.
- * @param string|array $data Body to send with the request.
- * @param array $options Redirect request options.
- * @param WpOrg\Requests\Response $original Response object.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $location URL to redirect to.
+ * @param array $headers Headers for the redirect.
+ * @param string|array $data Body to send with the request.
+ * @param array $options Redirect request options.
+ * @param Requests_Response $original Response object.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) {
</span><span class="cx" style="display: block; padding: 0 10px"> // Browser compatibility.
</span><span class="cx" style="display: block; padding: 0 10px"> if ( 302 === $original->status_code ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $options['type'] = WpOrg\Requests\Requests::GET;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $options['type'] = Requests::GET;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -501,12 +501,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 4.7.5
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @throws WpOrg\Requests\Exception On unsuccessful URL validation.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @throws Requests_Exception On unsuccessful URL validation.
</ins><span class="cx" style="display: block; padding: 0 10px"> * @param string $location URL to redirect to.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function validate_redirects( $location ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! wp_http_validate_url( $location ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new WpOrg\Requests\Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Requests_Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span></span></pre></div>
<a id="trunksrcwpincludeshttpphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/http.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/http.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/http.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -200,12 +200,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Retrieve only the headers from the raw response.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 2.7.0
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @since 4.6.0 Return value changed from an array to an WpOrg\Requests\Utility\CaseInsensitiveDictionary instance.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 4.6.0 Return value changed from an array to an Requests_Utility_CaseInsensitiveDictionary instance.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see \WpOrg\Requests\Utility\CaseInsensitiveDictionary
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see \Requests_Utility_CaseInsensitiveDictionary
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param array|WP_Error $response HTTP response.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return array|\WpOrg\Requests\Utility\CaseInsensitiveDictionary The headers of the response. Empty array if incorrect parameter given.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return array|\Requests_Utility_CaseInsensitiveDictionary The headers of the response. Empty array if incorrect parameter given.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_remote_retrieve_headers( $response ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
</span></span></pre></div>
<a id="trunksrcwpincludesrestapiphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/rest-api.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/rest-api.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/src/wp-includes/rest-api.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1390,7 +1390,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function rest_is_ip_address( $ip ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! preg_match( $ipv4_pattern, $ip ) && ! WpOrg\Requests\Ipv6::check_ipv6( $ip ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! preg_match( $ipv4_pattern, $ip ) && ! Requests_IPv6::check_ipv6( $ip ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span></span></pre></div>
<a id="trunktestsphpunittestsfeedwpSimplePieFilephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/feed/wpSimplePieFile.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/feed/wpSimplePieFile.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/feed/wpSimplePieFile.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -85,7 +85,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'headers' => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'headers' => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
</ins><span class="cx" style="display: block; padding: 0 10px"> 'body' => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
</span><span class="cx" style="display: block; padding: 0 10px"> 'response' => array(
</span><span class="cx" style="display: block; padding: 0 10px"> 'code' => 200,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -114,7 +114,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ),
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $response['headers'] = new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $multiple_value_headers );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $response['headers'] = new Requests_Utility_CaseInsensitiveDictionary( $multiple_value_headers );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return $response;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestsfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/functions.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/functions.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -364,9 +364,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function test_deserialize_request_utility_filtered_iterator_objects( $value ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $serialized = maybe_serialize( $value );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( get_class( $value ) === 'WpOrg\Requests\Utility\FilteredIterator' ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( get_class( $value ) === 'Requests_Utility_FilteredIterator' ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $new_value = unserialize( $serialized );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $property = ( new ReflectionClass( 'WpOrg\Requests\Utility\FilteredIterator' ) )->getProperty( 'callback' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $property = ( new ReflectionClass( 'Requests_Utility_FilteredIterator' ) )->getProperty( 'callback' );
</ins><span class="cx" style="display: block; padding: 0 10px"> $property->setAccessible( true );
</span><span class="cx" style="display: block; padding: 0 10px"> $callback_value = $property->getValue( $new_value );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->assertSame( null, $callback_value );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -377,8 +377,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public function data_serialize_deserialize_objects() {
</span><span class="cx" style="display: block; padding: 0 10px"> return array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- array( new WpOrg\Requests\Utility\FilteredIterator( array( 1 ), 'md5' ) ),
- array( new WpOrg\Requests\Utility\FilteredIterator( array( 1, 2 ), 'sha1' ) ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ array( new Requests_Utility_FilteredIterator( array( 1 ), 'md5' ) ),
+ array( new Requests_Utility_FilteredIterator( array( 1, 2 ), 'sha1' ) ),
</ins><span class="cx" style="display: block; padding: 0 10px"> array( new ArrayIterator( array( 1, 2, 3 ) ) ),
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestshttpfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/http/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/http/functions.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/http/functions.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -216,9 +216,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function test_get_cookie_host_only() {
</span><span class="cx" style="display: block; padding: 0 10px"> // Emulate WP_Http::request() internals.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $requests_response = new WpOrg\Requests\Response();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $requests_response = new Requests_Response();
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $requests_response->cookies['test'] = WpOrg\Requests\Cookie::parse( 'test=foo; domain=.wordpress.org' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $requests_response->cookies['test'] = Requests_Cookie::parse( 'test=foo; domain=.wordpress.org' );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $requests_response->cookies['test']->flags['host-only'] = false; // https://github.com/WordPress/Requests/issues/306
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -231,7 +231,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->assertSame( $cookie->domain, 'wordpress.org' );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->assertFalse( $cookie->host_only, 'host-only flag not set' );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Regurgitate (WpOrg\Requests\Cookie -> WP_Http_Cookie -> WpOrg\Requests\Cookie).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Regurgitate (Requests_Cookie -> WP_Http_Cookie -> Requests_Cookie).
</ins><span class="cx" style="display: block; padding: 0 10px"> $cookies = WP_Http::normalize_cookies( wp_remote_retrieve_cookies( $response ) );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->assertFalse( $cookies['test']->flags['host-only'], 'host-only flag data lost' );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestshttphttpphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/http/http.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/http/http.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/http/http.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -309,13 +309,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> )
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->assertInstanceOf( 'WpOrg\Requests\Cookie\Jar', $cookie_jar );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->assertInstanceOf( 'Requests_Cookie_Jar', $cookie_jar );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( array_keys( $cookies ) as $cookie ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( 'foo' === $cookie ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->assertArrayNotHasKey( $cookie, $cookie_jar );
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->assertInstanceOf( 'WpOrg\Requests\Cookie', $cookie_jar[ $cookie ] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->assertInstanceOf( 'Requests_Cookie', $cookie_jar[ $cookie ] );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestsrestapirestwidgetscontrollerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -416,7 +416,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'headers' => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'headers' => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
</ins><span class="cx" style="display: block; padding: 0 10px"> 'body' => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
</span><span class="cx" style="display: block; padding: 0 10px"> 'response' => array(
</span><span class="cx" style="display: block; padding: 0 10px"> 'code' => 200,
</span></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetRssphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/widgets/wpWidgetRss.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetRss.php 2021-12-06 18:29:24 UTC (rev 52327)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetRss.php 2021-12-06 21:29:00 UTC (rev 52328)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -106,7 +106,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'headers' => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'headers' => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
</ins><span class="cx" style="display: block; padding: 0 10px"> 'body' => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
</span><span class="cx" style="display: block; padding: 0 10px"> 'response' => array(
</span><span class="cx" style="display: block; padding: 0 10px"> 'code' => 200,
</span></span></pre>
</div>
</div>
</body>
</html>