clientService = $clientService; $this->favicon = $favicon; $this->favicon->setCacheTimeout(0); $this->mimeDetector = $mimeDetector; $this->remoteHostValidator = $remoteHostValidator; } /** * Does this source query external services? * * @return bool */ #[\Override] public function isExternal(): bool { return true; } /** * @param string $email sender email address * @param AvatarFactory $factory * @return Avatar|null avatar URL if one can be found */ #[\Override] public function fetch(string $email, AvatarFactory $factory) { $horde = new Horde_Mail_Rfc822_Address($email); // TODO: fall back to insecure HTTP? $domain = 'https://' . $horde->host; if (!$this->remoteHostValidator->isValid($domain)) { return null; } $iconUrl = $this->favicon->get($domain); if ($iconUrl === false || empty($iconUrl)) { return null; } /** @var string $iconUrl */ $client = $this->clientService->newClient(); try { $response = $client->get($iconUrl); } catch (Exception $exception) { return null; } // Don't save 0 byte images $body = $response->getBody(); if (strlen($body) === 0) { return null; } $mime = $this->mimeDetector->detectString($body); return $factory->createExternal($iconUrl, $mime); } }