}
}
+ /**
+ * Updates the poll URL of a contact. This is the right function to call if there is a redirect.
+ *
+ * @param integer $id contact id
+ * @param string $url The new URL to use for polling
+ *
+ * @throws \Exception
+ */
+ public static function updatePollUrl(int $id, string $url)
+ {
+ self::update(['poll', $url], ['id' => $id]);
+ }
+
/**
* Helper function for "updateFromProbe". Updates personal and public contact
*
public function getUrl(): string;
/**
+ * If the request was redirected to another URL, gets the final URL requested
* @return string
*/
public function getRedirectUrl(): string;
+ /**
+ * If the request was redirected to another URL, indicates if the redirect is permanent.
+ * If the request was not redirected, returns false.
+ * If the request was redirected multiple times, returns true only if all of the redirects were permanent.
+ *
+ * @return bool True if the redirect is permanent
+ */
+ public function redirectIsPermanent(): bool;
+
/**
* Getter for body
*
*/
private $isRedirectUrl;
+ /**
+ * @var boolean true if the URL has a permanent redirect
+ */
+ private $redirectIsPermanent;
+
/**
* @var boolean true if the curl request timed out
*/
$this->redirectUrl = $this->info['url'];
}
- if ($this->returnCode == 301 || $this->returnCode == 302 || $this->returnCode == 303 || $this->returnCode == 307) {
+ if ($this->returnCode == 301 || $this->returnCode == 302 || $this->returnCode == 303 || $this->returnCode == 307 || $this->returnCode == 308) {
$redirect_parts = parse_url($this->info['redirect_url'] ?? '');
if (empty($redirect_parts)) {
$redirect_parts = [];
}
$this->redirectUrl = (string)Uri::fromParts((array)$redirect_parts);
-
$this->isRedirectUrl = true;
+ $this->redirectIsPermanent = $this->returnCode == 301 or $this->returnCode == 308;
} else {
$this->isRedirectUrl = false;
+ $this->redirectIsPermanent = false;
}
}
return $this->isRedirectUrl;
}
+ /** {@inheritDoc} */
+ public function redirectIsPermanent(): bool
+ {
+ return $this->redirectIsPermanent;
+ }
+
/** {@inheritDoc} */
public function getErrorNumber(): int
{
private $redirectUrl = '';
/** @var bool */
private $isRedirectUrl = false;
+ /** @var bool */
+ private $redirectIsPermanent = false;
public function __construct(ResponseInterface $response, string $url, $errorNumber = 0, $error = '')
{
if (count($headersRedirect) > 0) {
$this->redirectUrl = $headersRedirect[0];
$this->isRedirectUrl = true;
+
+ $this->redirectIsPermanent = true;
+ foreach (($response->getHeader(RedirectMiddleware::STATUS_HISTORY_HEADER) ?? []) as $history) {
+ if (preg_match('/30(2|3|4|7)/', $history)) {
+ $this->redirectIsPermanent = false;
+ }
+ }
}
}
return $this->isRedirectUrl;
}
+ /** {@inheritDoc} */
+ public function redirectIsPermanent(): bool
+ {
+ return $this->redirectIsPermanent;
+ }
+
/** {@inheritDoc} */
public function getErrorNumber(): int
{
$cookiejar = tempnam(System::getTempPath(), 'cookiejar-onepoll-');
$curlResult = DI::httpClient()->get($contact['poll'], HttpClientAccept::FEED_XML, [HttpClientOptions::COOKIEJAR => $cookiejar, HttpClientOptions::REQUEST => HttpClientRequest::FEEDFETCHER]);
unlink($cookiejar);
+ Logger::debug('Polled feed', ['url' => $contact['poll'], 'http-code' => $curlResult->getReturnCode(), 'redirect-url' => $curlResult->getRedirectUrl()]);
if ($curlResult->isTimeout()) {
Logger::notice('Polling timed out', ['id' => $contact['id'], 'url' => $contact['poll']]);
return false;
}
+ if ($curlResult->redirectIsPermanent()) {
+ Logger::notice('Poll address permanently changed', [
+ 'id' => $contact['id'],
+ 'uid' => $contact['uid'],
+ 'old' => $contact['poll'],
+ 'new' => $curlResult->getRedirectUrl(),
+ ]);
+ $success = Contact::updatePollUrl($contact['id'], $curlResult->getRedirectUrl());
+ }
+
$xml = $curlResult->getBodyString();
if (empty($xml)) {
Logger::notice('Empty content', ['id' => $contact['id'], 'url' => $contact['poll']]);