فهرست منبع

Improve favicon hash (#7505)

* Favicon hash proxy
Content provided through a proxy may be completely different, so the feed hash must account for that

* Fix typing

* Hash of Web site in priority for favicons

* Continue

* Revert some minor changes
Alexandre Alapetite 11 ماه پیش
والد
کامیت
3776e1e48f
1فایلهای تغییر یافته به همراه44 افزوده شده و 12 حذف شده
  1. 44 12
      app/Models/Feed.php

+ 44 - 12
app/Models/Feed.php

@@ -63,6 +63,7 @@ class FreshRSS_Feed extends Minz_Model {
 	private int $ttl = self::TTL_DEFAULT;
 	private bool $mute = false;
 	private string $hash = '';
+	private string $hashFavicon = '';
 	private string $lockPath = '';
 	private string $hubUrl = '';
 	private string $selfUrl = '';
@@ -91,11 +92,31 @@ class FreshRSS_Feed extends Minz_Model {
 	public function hash(): string {
 		if ($this->hash == '') {
 			$salt = FreshRSS_Context::systemConf()->salt;
-			$this->hash = hash('crc32b', $salt . $this->url);
+			$params = $this->url;
+			$curl_params = $this->attributeArray('curl_params');
+			if (is_array($curl_params)) {
+				// Content provided through a proxy may be completely different
+				$params .= is_string($curl_params[CURLOPT_PROXY] ?? null) ? $curl_params[CURLOPT_PROXY] : '';
+			}
+			$this->hash = sha1($salt . $params);
 		}
 		return $this->hash;
 	}
 
+	public function hashFavicon(): string {
+		if ($this->hashFavicon == '') {
+			$salt = FreshRSS_Context::systemConf()->salt;
+			$params = $this->website(fallback: true);
+			$curl_params = $this->attributeArray('curl_params');
+			if (is_array($curl_params)) {
+				// Content provided through a proxy may be completely different
+				$params .= is_string($curl_params[CURLOPT_PROXY] ?? null) ? $curl_params[CURLOPT_PROXY] : '';
+			}
+			$this->hashFavicon = hash('crc32b', $salt . $params);
+		}
+		return $this->hashFavicon;
+	}
+
 	public function url(bool $includeCredentials = true): string {
 		return $includeCredentials ? $this->url : \SimplePie\Misc::url_remove_credentials($this->url);
 	}
@@ -133,10 +154,19 @@ class FreshRSS_Feed extends Minz_Model {
 	public function name(bool $raw = false): string {
 		return $raw || $this->name != '' ? $this->name : (preg_replace('%^https?://(www[.])?%i', '', $this->url) ?? '');
 	}
-	/** @return string HTML-encoded URL of the Web site of the feed */
-	public function website(): string {
-		return $this->website;
+
+	/**
+	 * @param bool $fallback true to return the URL of the feed if the Web site is blank
+	 * @return string HTML-encoded URL of the Web site of the feed
+	 */
+	public function website(bool $fallback = false): string {
+		$url = $this->website;
+		if ($fallback && !preg_match('%^https?://.%i', $url)) {
+			$url = $this->url;
+		}
+		return $url;
 	}
+
 	public function description(): string {
 		return $this->description;
 	}
@@ -227,16 +257,13 @@ class FreshRSS_Feed extends Minz_Model {
 
 	public function faviconPrepare(bool $force = false): void {
 		require_once(LIB_PATH . '/favicons.php');
-		$url = $this->website;
-		if ($url == '') {
-			$url = $this->url;
-		}
-		$txt = FAVICONS_DIR . $this->hash() . '.txt';
+		$url = $this->website(fallback: true);
+		$txt = FAVICONS_DIR . $this->hashFavicon() . '.txt';
 		if (@file_get_contents($txt) !== $url) {
 			file_put_contents($txt, $url);
 		}
 		if (FreshRSS_Context::$isCli || $force) {
-			$ico = FAVICONS_DIR . $this->hash() . '.ico';
+			$ico = FAVICONS_DIR . $this->hashFavicon() . '.ico';
 			$ico_mtime = @filemtime($ico);
 			$txt_mtime = @filemtime($txt);
 			if ($txt_mtime != false &&
@@ -251,12 +278,15 @@ class FreshRSS_Feed extends Minz_Model {
 	}
 
 	public static function faviconDelete(string $hash): void {
+		if (!ctype_xdigit($hash)) {
+			return;
+		}
 		$path = DATA_PATH . '/favicons/' . $hash;
 		@unlink($path . '.ico');
 		@unlink($path . '.txt');
 	}
 	public function favicon(): string {
-		return Minz_Url::display('/f.php?' . $this->hash());
+		return Minz_Url::display('/f.php?' . $this->hashFavicon());
 	}
 
 	public function _id(int $value): void {
@@ -268,6 +298,7 @@ class FreshRSS_Feed extends Minz_Model {
 	 */
 	public function _url(string $value, bool $validate = true): void {
 		$this->hash = '';
+		$this->hashFavicon = '';
 		$url = $value;
 		if ($validate) {
 			$url = checkUrl($url);
@@ -297,6 +328,7 @@ class FreshRSS_Feed extends Minz_Model {
 		$this->name = $value == '' ? '' : trim($value);
 	}
 	public function _website(string $value, bool $validate = true): void {
+		$this->hashFavicon = '';
 		if ($validate) {
 			$value = checkUrl($value);
 		}
@@ -1037,7 +1069,7 @@ class FreshRSS_Feed extends Minz_Model {
 	}
 
 	private function faviconRebuild(): void {
-		FreshRSS_Feed::faviconDelete($this->hash());
+		FreshRSS_Feed::faviconDelete($this->hashFavicon());
 		$this->faviconPrepare(true);
 	}