| Server IP : 167.99.224.18 / Your IP : 216.73.216.136 Web Server : Apache/2.4.41 (Ubuntu) System : Linux wordpress-ubuntu-s-1vcpu-1gb-nyc1-01 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 User : root ( 0) PHP Version : 8.0.25 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/html/wp-content/plugins-old/plausible-analytics/src/Client/lib/ |
Upload File : |
<?php
/**
* HeaderSelector
* PHP version 7.4
*
* @category Class
* @package Plausible\Analytics\WP\Client
* @author OpenAPI Generator team
* @link https://openapi-generator.tech
*/
/**
* Plausible Plugins API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0-rc
* Generated by: https://openapi-generator.tech
* OpenAPI Generator version: 7.0.1
*/
/**
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
namespace Plausible\Analytics\WP\Client;
/**
* HeaderSelector Class Doc Comment
*
* @category Class
* @package Plausible\Analytics\WP\Client
* @author OpenAPI Generator team
* @link https://openapi-generator.tech
*/
class HeaderSelector {
/**
* @param string[] $accept
* @param string $contentType
* @param bool $isMultipart
*
* @return string[]
*/
public function selectHeaders( array $accept, string $contentType, bool $isMultipart ): array {
$headers = [];
$accept = $this->selectAcceptHeader( $accept );
if ( $accept !== null ) {
$headers[ 'Accept' ] = $accept;
}
if ( ! $isMultipart ) {
if ( $contentType === '' ) {
$contentType = 'application/json';
}
$headers[ 'Content-Type' ] = $contentType;
}
return $headers;
}
/**
* Return the header 'Accept' based on an array of Accept provided.
*
* @param string[] $accept Array of header
*
* @return null|string Accept (e.g. application/json)
*/
private function selectAcceptHeader( array $accept ): ?string {
# filter out empty entries
$accept = array_filter( $accept );
if ( count( $accept ) === 0 ) {
return null;
}
# If there's only one Accept header, just use it
if ( count( $accept ) === 1 ) {
return reset( $accept );
}
# If none of the available Accept headers is of type "json", then just use all them
$headersWithJson = preg_grep( '~(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$~', $accept );
if ( count( $headersWithJson ) === 0 ) {
return implode( ',', $accept );
}
# If we got here, then we need add quality values (weight), as described in IETF RFC 9110, Items 12.4.2/12.5.1,
# to give the highest priority to json-like headers - recalculating the existing ones, if needed
return $this->getAcceptHeaderWithAdjustedWeight( $accept, $headersWithJson );
}
/**
* Create an Accept header string from the given "Accept" headers array, recalculating all weights
*
* @param string[] $accept Array of Accept Headers
* @param string[] $headersWithJson Array of Accept Headers of type "json"
*
* @return string "Accept" Header (e.g. "application/json, text/html; q=0.9")
*/
private function getAcceptHeaderWithAdjustedWeight( array $accept, array $headersWithJson ): string {
$processedHeaders = [
'withApplicationJson' => [],
'withJson' => [],
'withoutJson' => [],
];
foreach ( $accept as $header ) {
$headerData = $this->getHeaderAndWeight( $header );
if ( stripos( $headerData[ 'header' ], 'application/json' ) === 0 ) {
$processedHeaders[ 'withApplicationJson' ][] = $headerData;
} elseif ( in_array( $header, $headersWithJson, true ) ) {
$processedHeaders[ 'withJson' ][] = $headerData;
} else {
$processedHeaders[ 'withoutJson' ][] = $headerData;
}
}
$acceptHeaders = [];
$currentWeight = 1000;
$hasMoreThan28Headers = count( $accept ) > 28;
foreach ( $processedHeaders as $headers ) {
if ( count( $headers ) > 0 ) {
$acceptHeaders[] = $this->adjustWeight( $headers, $currentWeight, $hasMoreThan28Headers );
}
}
$acceptHeaders = array_merge( ...$acceptHeaders );
return implode( ',', $acceptHeaders );
}
/**
* Given an Accept header, returns an associative array splitting the header and its weight
*
* @param string $header "Accept" Header
*
* @return array with the header and its weight
*/
private function getHeaderAndWeight( string $header ): array {
# matches headers with weight, splitting the header and the weight in $outputArray
if ( preg_match( '/(.*);\s*q=(1(?:\.0+)?|0\.\d+)$/', $header, $outputArray ) === 1 ) {
$headerData = [
'header' => $outputArray[ 1 ],
'weight' => (int) ( $outputArray[ 2 ] * 1000 ),
];
} else {
$headerData = [
'header' => trim( $header ),
'weight' => 1000,
];
}
return $headerData;
}
/**
* @param array[] $headers
* @param float $currentWeight
* @param bool $hasMoreThan28Headers
*
* @return string[] array of adjusted "Accept" headers
*/
private function adjustWeight( array $headers, float &$currentWeight, bool $hasMoreThan28Headers ): array {
usort(
$headers,
function ( array $a, array $b ) {
return $b[ 'weight' ] - $a[ 'weight' ];
}
);
$acceptHeaders = [];
foreach ( $headers as $index => $header ) {
if ( $index > 0 && $headers[ $index - 1 ][ 'weight' ] > $header[ 'weight' ] ) {
$currentWeight = $this->getNextWeight( $currentWeight, $hasMoreThan28Headers );
}
$weight = $currentWeight;
$acceptHeaders[] = $this->buildAcceptHeader( $header[ 'header' ], $weight );
}
$currentWeight = $this->getNextWeight( $currentWeight, $hasMoreThan28Headers );
return $acceptHeaders;
}
/**
* Calculate the next weight, based on the current one.
*
* If there are less than 28 "Accept" headers, the weights will be decreased by 1 on its highest significant digit, using the
* following formula:
*
* next weight = current weight - 10 ^ (floor(log(current weight - 1)))
*
* ( current weight minus ( 10 raised to the power of ( floor of (log to the base 10 of ( current weight minus 1 ) ) ) ) )
*
* Starting from 1000, this generates the following series:
*
* 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
*
* The resulting quality codes are closer to the average "normal" usage of them (like "q=0.9", "q=0.8" and so on), but it only works
* if there is a maximum of 28 "Accept" headers. If we have more than that (which is extremely unlikely), then we fall back to a 1-by-1
* decrement rule, which will result in quality codes like "q=0.999", "q=0.998" etc.
*
* @param int $currentWeight varying from 1 to 1000 (will be divided by 1000 to build the quality value)
* @param bool $hasMoreThan28Headers
*
* @return int
*/
public function getNextWeight( int $currentWeight, bool $hasMoreThan28Headers ): int {
if ( $currentWeight <= 1 ) {
return 1;
}
if ( $hasMoreThan28Headers ) {
return $currentWeight - 1;
}
return $currentWeight - 10 ** floor( log10( $currentWeight - 1 ) );
}
/**
* @param string $header
* @param int $weight
*
* @return string
*/
private function buildAcceptHeader( string $header, int $weight ): string {
if ( $weight === 1000 ) {
return $header;
}
return trim( $header, '; ' ) . ';q=' . rtrim( sprintf( '%0.3f', $weight / 1000 ), '0' );
}
}