]> git.mxchange.org Git - friendica.git/blob - src/Network/HTTPClient/Factory/HttpClient.php
Merge remote-tracking branch 'upstream/2022.05-rc' into ap-endpoint-cache
[friendica.git] / src / Network / HTTPClient / Factory / HttpClient.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2022, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
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.
11  *
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.
16  *
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/>.
19  *
20  */
21
22 namespace Friendica\Network\HTTPClient\Factory;
23
24 use Friendica\App;
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;
32 use GuzzleHttp;
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;
40
41 require_once __DIR__ . '/../../../../static/dbstructure.config.php';
42
43 class HttpClient extends BaseFactory
44 {
45         /** @var IManageConfigValues */
46         private $config;
47         /** @var Profiler */
48         private $profiler;
49         /** @var App\BaseURL */
50         private $baseUrl;
51
52         public function __construct(LoggerInterface $logger, IManageConfigValues $config, Profiler $profiler, App\BaseURL $baseUrl)
53         {
54                 parent::__construct($logger);
55                 $this->config   = $config;
56                 $this->profiler = $profiler;
57                 $this->baseUrl  = $baseUrl;
58         }
59
60         /**
61          * Creates a IHTTPClient for communications with HTTP endpoints
62          *
63          * @param HandlerStack|null $handlerStack (optional) A handler replacement (just usefull at test environments)
64          *
65          * @return ICanSendHttpRequests
66          */
67         public function createClient(HandlerStack $handlerStack = null): ICanSendHttpRequests
68         {
69                 $proxy = $this->config->get('system', 'proxy');
70
71                 if (!empty($proxy)) {
72                         $proxyUser = $this->config->get('system', 'proxyuser');
73
74                         if (!empty($proxyUser)) {
75                                 $proxy = $proxyUser . '@' . $proxy;
76                         }
77                 }
78
79                 $logger = $this->logger;
80
81                 $onRedirect = function (
82                         RequestInterface $request,
83                         ResponseInterface $response,
84                         UriInterface $uri
85                 ) use ($logger) {
86                         $logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri, 'method' => $request->getMethod()]);
87                 };
88
89                 $userAgent = FRIENDICA_PLATFORM . " '" .
90                                          FRIENDICA_CODENAME . "' " .
91                                          FRIENDICA_VERSION . '-' .
92                                          DB_UPDATE_VERSION . '; ' .
93                                          $this->baseUrl->get();
94
95                 $guzzle = new GuzzleHttp\Client([
96                         RequestOptions::ALLOW_REDIRECTS => [
97                                 'max'            => 8,
98                                 'on_redirect'    => $onRedirect,
99                                 'track_redirect' => true,
100                                 'strict'         => true,
101                                 'referer'        => true,
102                         ],
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,
117                         ],
118                         'handler' => $handlerStack ?? HandlerStack::create(),
119                 ]);
120
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));
130
131                 return new Client\HttpClient($logger, $this->profiler, $guzzle, $resolver);
132         }
133 }