3 namespace Friendica\Factory;
6 use Friendica\BaseFactory;
7 use Friendica\Core\Config\IConfig;
8 use Friendica\Network\HTTPClient;
9 use Friendica\Network\IHTTPClient;
10 use Friendica\Util\Profiler;
11 use Friendica\Util\Strings;
12 use GuzzleHttp\Client;
13 use GuzzleHttp\HandlerStack;
14 use GuzzleHttp\RequestOptions;
15 use mattwright\URLResolver;
16 use Psr\Http\Message\RequestInterface;
17 use Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\UriInterface;
19 use Psr\Log\LoggerInterface;
21 require_once __DIR__ . '/../../static/dbstructure.config.php';
23 class HTTPClientFactory extends BaseFactory
29 /** @var App\BaseURL */
32 public function __construct(LoggerInterface $logger, IConfig $config, Profiler $profiler, App\BaseURL $baseUrl)
34 parent::__construct($logger);
35 $this->config = $config;
36 $this->profiler = $profiler;
37 $this->baseUrl = $baseUrl;
41 * Creates a IHTTPClient for communications with HTTP endpoints
43 * @param HandlerStack|null $handlerStack (optional) A handler replacement (just usefull at test environments)
47 public function createClient(HandlerStack $handlerStack = null): IHTTPClient
49 $proxy = $this->config->get('system', 'proxy');
52 $proxyuser = $this->config->get('system', 'proxyuser');
54 if (!empty($proxyuser)) {
55 $proxy = $proxyuser . '@' . $proxy;
59 $logger = $this->logger;
61 $onRedirect = function (
62 RequestInterface $request,
63 ResponseInterface $response,
66 $logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri, 'method' => $request->getMethod()]);
69 $userAgent = FRIENDICA_PLATFORM . " '" .
70 FRIENDICA_CODENAME . "' " .
71 FRIENDICA_VERSION . '-' .
72 DB_UPDATE_VERSION . '; ' .
73 $this->baseUrl->get();
75 $guzzle = new Client([
76 RequestOptions::ALLOW_REDIRECTS => [
78 'on_redirect' => $onRedirect,
79 'track_redirect' => true,
83 RequestOptions::HTTP_ERRORS => false,
84 // Without this setting it seems as if some webservers send compressed content
85 // This seems to confuse curl so that it shows this uncompressed.
86 /// @todo We could possibly set this value to "gzip" or something similar
87 RequestOptions::DECODE_CONTENT => '',
88 RequestOptions::FORCE_IP_RESOLVE => ($this->config->get('system', 'ipv4_resolve') ? 'v4' : null),
89 RequestOptions::CONNECT_TIMEOUT => 10,
90 RequestOptions::TIMEOUT => $this->config->get('system', 'curl_timeout', 60),
91 // by default we will allow self-signed certs
92 // but it can be overridden
93 RequestOptions::VERIFY => (bool)$this->config->get('system', 'verifyssl'),
94 RequestOptions::PROXY => $proxy,
95 RequestOptions::HEADERS => [
96 'User-Agent' => $userAgent,
98 'handler' => $handlerStack ?? HandlerStack::create(),
101 $resolver = new URLResolver();
102 $resolver->setUserAgent($userAgent);
103 $resolver->setMaxRedirects(10);
104 $resolver->setRequestTimeout(10);
105 // if the file is too large then exit
106 $resolver->setMaxResponseDataSize(1000000);
107 // Designate a temporary file that will store cookies during the session.
108 // Some websites test the browser for cookie support, so this enhances results.
109 $resolver->setCookieJar(get_temppath() .'/resolver-cookie-' . Strings::getRandomName(10));
111 return new HTTPClient($logger, $this->profiler, $guzzle, $resolver);