mirror of
https://github.com/friendica/friendica
synced 2025-04-28 19:44:23 +02:00
Improved user agent string
This commit is contained in:
parent
0ae91b59ca
commit
afff2b949f
18 changed files with 181 additions and 84 deletions
|
@ -95,10 +95,11 @@ interface ICanSendHttpRequests
|
|||
* @param mixed $params POST variables (if an array is passed, it will automatically set as formular parameters)
|
||||
* @param array $headers HTTP headers
|
||||
* @param int $timeout The timeout in seconds, default system config value or 60 seconds
|
||||
* @param string $request The type of the request. This is set in the user agent string
|
||||
*
|
||||
* @return ICanHandleHttpResponses The content
|
||||
*/
|
||||
public function post(string $url, $params, array $headers = [], int $timeout = 0): ICanHandleHttpResponses;
|
||||
public function post(string $url, $params, array $headers = [], int $timeout = 0, string $request = ''): ICanHandleHttpResponses;
|
||||
|
||||
/**
|
||||
* Sends an HTTP request to a given url
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
namespace Friendica\Network\HTTPClient\Client;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Network\HTTPClient\Response\CurlResult;
|
||||
use Friendica\Network\HTTPClient\Response\GuzzleResponse;
|
||||
|
@ -51,13 +52,16 @@ class HttpClient implements ICanSendHttpRequests
|
|||
private $client;
|
||||
/** @var URLResolver */
|
||||
private $resolver;
|
||||
/** @var App\BaseURL */
|
||||
private $baseUrl;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Profiler $profiler, Client $client, URLResolver $resolver)
|
||||
public function __construct(LoggerInterface $logger, Profiler $profiler, Client $client, URLResolver $resolver, App\BaseURL $baseUrl)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->profiler = $profiler;
|
||||
$this->client = $client;
|
||||
$this->resolver = $resolver;
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +77,7 @@ class HttpClient implements ICanSendHttpRequests
|
|||
throw new \InvalidArgumentException('Unable to retrieve the host in URL: ' . $url);
|
||||
}
|
||||
|
||||
if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A) && !@dns_get_record($host . '.', DNS_AAAA)) {
|
||||
if (!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A) && !@dns_get_record($host . '.', DNS_AAAA)) {
|
||||
$this->logger->debug('URL cannot be resolved.', ['url' => $url]);
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl($this->logger, $url);
|
||||
|
@ -115,7 +119,7 @@ class HttpClient implements ICanSendHttpRequests
|
|||
$conf[RequestOptions::COOKIES] = $jar;
|
||||
}
|
||||
|
||||
$headers = [];
|
||||
$headers = ['User-Agent' => $this->getUserAgent($opts[HttpClientOptions::REQUEST] ?? '')];
|
||||
|
||||
if (!empty($opts[HttpClientOptions::ACCEPT_CONTENT])) {
|
||||
$headers['Accept'] = $opts[HttpClientOptions::ACCEPT_CONTENT];
|
||||
|
@ -153,8 +157,10 @@ class HttpClient implements ICanSendHttpRequests
|
|||
}
|
||||
|
||||
$conf[RequestOptions::ON_HEADERS] = function (ResponseInterface $response) use ($opts) {
|
||||
if (!empty($opts[HttpClientOptions::CONTENT_LENGTH]) &&
|
||||
(int)$response->getHeaderLine('Content-Length') > $opts[HttpClientOptions::CONTENT_LENGTH]) {
|
||||
if (
|
||||
!empty($opts[HttpClientOptions::CONTENT_LENGTH]) &&
|
||||
(int)$response->getHeaderLine('Content-Length') > $opts[HttpClientOptions::CONTENT_LENGTH]
|
||||
) {
|
||||
throw new TransferException('The file is too big!');
|
||||
}
|
||||
};
|
||||
|
@ -172,8 +178,10 @@ class HttpClient implements ICanSendHttpRequests
|
|||
$response = $this->client->request($method, $url, $conf);
|
||||
return new GuzzleResponse($response, $url);
|
||||
} catch (TransferException $exception) {
|
||||
if ($exception instanceof RequestException &&
|
||||
$exception->hasResponse()) {
|
||||
if (
|
||||
$exception instanceof RequestException &&
|
||||
$exception->hasResponse()
|
||||
) {
|
||||
return new GuzzleResponse($exception->getResponse(), $url, $exception->getCode(), '');
|
||||
} else {
|
||||
return new CurlResult($this->logger, $url, '', ['http_code' => 500], $exception->getCode(), '');
|
||||
|
@ -209,7 +217,7 @@ class HttpClient implements ICanSendHttpRequests
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function post(string $url, $params, array $headers = [], int $timeout = 0): ICanHandleHttpResponses
|
||||
public function post(string $url, $params, array $headers = [], int $timeout = 0, string $request = ''): ICanHandleHttpResponses
|
||||
{
|
||||
$opts = [];
|
||||
|
||||
|
@ -227,6 +235,10 @@ class HttpClient implements ICanSendHttpRequests
|
|||
$opts[HttpClientOptions::TIMEOUT] = $timeout;
|
||||
}
|
||||
|
||||
if (!empty($request)) {
|
||||
$opts[HttpClientOptions::REQUEST] = $request;
|
||||
}
|
||||
|
||||
return $this->request('post', $url, $opts);
|
||||
}
|
||||
|
||||
|
@ -255,6 +267,7 @@ class HttpClient implements ICanSendHttpRequests
|
|||
|
||||
$url = trim($url, "'");
|
||||
|
||||
$this->resolver->setUserAgent($this->getUserAgent(HttpClientRequest::RESOLVER));
|
||||
$urlResult = $this->resolver->resolveURL($url);
|
||||
|
||||
if ($urlResult->didErrorOccur()) {
|
||||
|
@ -288,4 +301,15 @@ class HttpClient implements ICanSendHttpRequests
|
|||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function getUserAgent(string $type = ''): string
|
||||
{
|
||||
// @see https://developers.whatismybrowser.com/learn/browser-detection/user-agents/user-agent-best-practices
|
||||
$userAgent = App::PLATFORM . '/' . App::VERSION . ' DatabaseVersion/' . DB_UPDATE_VERSION;
|
||||
if ($type != '') {
|
||||
$userAgent .= ' Request/' . $type;
|
||||
}
|
||||
$userAgent .= ' +' . $this->baseUrl;
|
||||
return $userAgent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ class HttpClientOptions
|
|||
* content_length: (int) maximum File content length
|
||||
*/
|
||||
const CONTENT_LENGTH = 'content_length';
|
||||
|
||||
/**
|
||||
* Request: (string) Type of request (ActivityPub, Diaspora, server discovery, ...)
|
||||
*/
|
||||
const REQUEST = 'request';
|
||||
/**
|
||||
* verify: (bool|string, default=true) Describes the SSL certificate
|
||||
*/
|
||||
|
|
39
src/Network/HTTPClient/Client/HttpClientRequest.php
Normal file
39
src/Network/HTTPClient/Client/HttpClientRequest.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Network\HTTPClient\Client;
|
||||
|
||||
/**
|
||||
* This class contains a list of request types that are set in the user agent string
|
||||
*/
|
||||
class HttpClientRequest
|
||||
{
|
||||
public const ACTIVITYPUB = 'ActivityPub/1';
|
||||
public const CONTENTTYPE = 'ContentTypeChecker/1';
|
||||
public const DFRN = 'DFRN/1';
|
||||
public const DIASPORA = 'Diaspora/1';
|
||||
public const MAGICAUTH = 'MagicAuth/1';
|
||||
public const MEDIAPROXY = 'MediaProxy/1';
|
||||
public const SALMON = 'Salmon/1';
|
||||
public const PUBSUB = 'PubSub/1';
|
||||
public const RESOLVER = 'URLResolver/1';
|
||||
public const VERIFIER = 'URLVerifier/1';
|
||||
}
|
|
@ -86,12 +86,6 @@ class HttpClient extends BaseFactory
|
|||
$logger->info('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri, 'method' => $request->getMethod()]);
|
||||
};
|
||||
|
||||
$userAgent = App::PLATFORM . " '" .
|
||||
App::CODENAME . "' " .
|
||||
App::VERSION . '-' .
|
||||
DB_UPDATE_VERSION . '; ' .
|
||||
$this->baseUrl;
|
||||
|
||||
$guzzle = new GuzzleHttp\Client([
|
||||
RequestOptions::ALLOW_REDIRECTS => [
|
||||
'max' => 8,
|
||||
|
@ -112,22 +106,19 @@ class HttpClient extends BaseFactory
|
|||
// but it can be overridden
|
||||
RequestOptions::VERIFY => (bool)$this->config->get('system', 'verifyssl'),
|
||||
RequestOptions::PROXY => $proxy,
|
||||
RequestOptions::HEADERS => [
|
||||
'User-Agent' => $userAgent,
|
||||
],
|
||||
RequestOptions::HEADERS => [],
|
||||
'handler' => $handlerStack ?? HandlerStack::create(),
|
||||
]);
|
||||
|
||||
$resolver = new URLResolver();
|
||||
$resolver->setUserAgent($userAgent);
|
||||
$resolver->setMaxRedirects(10);
|
||||
$resolver->setRequestTimeout(10);
|
||||
// if the file is too large then exit
|
||||
$resolver->setMaxResponseDataSize($this->config->get('performance', 'max_response_data_size', 1000000));
|
||||
// Designate a temporary file that will store cookies during the session.
|
||||
// Some websites test the browser for cookie support, so this enhances results.
|
||||
$resolver->setCookieJar(System::getTempPath() .'/resolver-cookie-' . Strings::getRandomName(10));
|
||||
$resolver->setCookieJar(System::getTempPath() . '/resolver-cookie-' . Strings::getRandomName(10));
|
||||
|
||||
return new Client\HttpClient($logger, $this->profiler, $guzzle, $resolver);
|
||||
return new Client\HttpClient($logger, $this->profiler, $guzzle, $resolver, $this->baseUrl);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue