3 * @copyright Copyright (C) 2010-2022, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Network\HTTPClient\Factory;
25 use Friendica\BaseFactory;
26 use Friendica\Core\Config\Capability\IManageConfigValues;
27 use Friendica\Core\System;
28 use Friendica\Network\HTTPClient\Client;
29 use Friendica\Network\HTTPClient\Capability\ICanSendHttpRequests;
30 use Friendica\Util\Profiler;
31 use Friendica\Util\Strings;
33 use GuzzleHttp\HandlerStack;
34 use GuzzleHttp\RequestOptions;
35 use mattwright\URLResolver;
36 use Psr\Http\Message\RequestInterface;
37 use Psr\Http\Message\ResponseInterface;
38 use Psr\Http\Message\UriInterface;
39 use Psr\Log\LoggerInterface;
41 require_once __DIR__ . '/../../../../static/dbstructure.config.php';
43 class HttpClient extends BaseFactory
45 /** @var IManageConfigValues */
49 /** @var App\BaseURL */
52 public function __construct(LoggerInterface $logger, IManageConfigValues $config, Profiler $profiler, App\BaseURL $baseUrl)
54 parent::__construct($logger);
55 $this->config = $config;
56 $this->profiler = $profiler;
57 $this->baseUrl = $baseUrl;
61 * Creates a IHTTPClient for communications with HTTP endpoints
63 * @param HandlerStack|null $handlerStack (optional) A handler replacement (just usefull at test environments)
65 * @return ICanSendHttpRequests
67 public function createClient(HandlerStack $handlerStack = null): ICanSendHttpRequests
69 $proxy = $this->config->get('system', 'proxy');
72 $proxyUser = $this->config->get('system', 'proxyuser');
74 if (!empty($proxyUser)) {
75 $proxy = $proxyUser . '@' . $proxy;
79 $logger = $this->logger;
81 $onRedirect = function (
82 RequestInterface $request,
83 ResponseInterface $response,
86 $logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri, 'method' => $request->getMethod()]);
89 $userAgent = FRIENDICA_PLATFORM . " '" .
90 FRIENDICA_CODENAME . "' " .
91 FRIENDICA_VERSION . '-' .
92 DB_UPDATE_VERSION . '; ' .
93 $this->baseUrl->get();
95 $guzzle = new GuzzleHttp\Client([
96 RequestOptions::ALLOW_REDIRECTS => [
98 'on_redirect' => $onRedirect,
99 'track_redirects' => true,
103 RequestOptions::HTTP_ERRORS => false,
104 // Without this setting it seems as if some webservers send compressed content
105 // This seems to confuse curl so that it shows this uncompressed.
106 /// @todo We could possibly set this value to "gzip" or something similar
107 RequestOptions::DECODE_CONTENT => '',
108 RequestOptions::FORCE_IP_RESOLVE => ($this->config->get('system', 'ipv4_resolve') ? 'v4' : null),
109 RequestOptions::CONNECT_TIMEOUT => 10,
110 RequestOptions::TIMEOUT => $this->config->get('system', 'curl_timeout', 60),
111 // by default, we will allow self-signed certs,
112 // but it can be overridden
113 RequestOptions::VERIFY => (bool)$this->config->get('system', 'verifyssl'),
114 RequestOptions::PROXY => $proxy,
115 RequestOptions::HEADERS => [
116 'User-Agent' => $userAgent,
118 'handler' => $handlerStack ?? HandlerStack::create(),
121 $resolver = new URLResolver();
122 $resolver->setUserAgent($userAgent);
123 $resolver->setMaxRedirects(10);
124 $resolver->setRequestTimeout(10);
125 // if the file is too large then exit
126 $resolver->setMaxResponseDataSize(1000000);
127 // Designate a temporary file that will store cookies during the session.
128 // Some websites test the browser for cookie support, so this enhances results.
129 $resolver->setCookieJar(System::getTempPath() .'/resolver-cookie-' . Strings::getRandomName(10));
131 return new Client\HttpClient($logger, $this->profiler, $guzzle, $resolver);