From a16c65677006f1b7b50d508a173a71d94bbf8753 Mon Sep 17 00:00:00 2001
From: Jeremy Lin <jeremy.lin@gmail.com>
Date: Sat, 8 Jan 2022 23:40:35 -0800
Subject: [PATCH] Add support for legacy HTTP 301/302 redirects for external
 icons

At least on Android, it seems the Bitwarden mobile client responds to
HTTP 307, but not to HTTP 308 for some reason.
---
 .env.template    |  7 ++++---
 src/api/icons.rs |  4 +++-
 src/config.rs    | 11 ++++++-----
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/.env.template b/.env.template
index fecac220..1f4c937f 100644
--- a/.env.template
+++ b/.env.template
@@ -144,10 +144,11 @@
 
 ## Icon redirect code
 ## The HTTP status code to use for redirects to an external icon service.
-## The supported codes are 307 (temporary) and 308 (permanent).
+## The supported codes are 301 (legacy permanent), 302 (legacy temporary), 307 (temporary), and 308 (permanent).
 ## Temporary redirects are useful while testing different icon services, but once a service
-## has been decided on, consider using permanent redirects for cacheability.
-# ICON_REDIRECT_CODE=307
+## has been decided on, consider using permanent redirects for cacheability. The legacy codes
+## are currently better supported by the Bitwarden clients.
+# ICON_REDIRECT_CODE=302
 
 ## Disable icon downloading
 ## Set to true to disable icon downloading in the internal icon service.
diff --git a/src/api/icons.rs b/src/api/icons.rs
index 4e8c753a..a2e5cc3a 100644
--- a/src/api/icons.rs
+++ b/src/api/icons.rs
@@ -72,8 +72,10 @@ fn icon_redirect(domain: &str, template: &str) -> Option<Redirect> {
 
     let url = template.replace("{}", domain);
     match CONFIG.icon_redirect_code() {
-        308 => Some(Redirect::permanent(url)),
+        301 => Some(Redirect::moved(url)), // legacy permanent redirect
+        302 => Some(Redirect::found(url)), // legacy temporary redirect
         307 => Some(Redirect::temporary(url)),
+        308 => Some(Redirect::permanent(url)),
         _ => {
             error!("Unexpected redirect code {}", CONFIG.icon_redirect_code());
             None
diff --git a/src/config.rs b/src/config.rs
index 9554aee3..92fe8b9d 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -458,10 +458,11 @@ make_config! {
         /// corresponding icon at the external service.
         icon_service:           String, false,  def,    "internal".to_string();
         /// Icon redirect code |> The HTTP status code to use for redirects to an external icon service.
-        /// The supported codes are 307 (temporary) and 308 (permanent).
+        /// The supported codes are 301 (legacy permanent), 302 (legacy temporary), 307 (temporary), and 308 (permanent).
         /// Temporary redirects are useful while testing different icon services, but once a service
-        /// has been decided on, consider using permanent redirects for cacheability.
-        icon_redirect_code:     u32,    true,   def,    307;
+        /// has been decided on, consider using permanent redirects for cacheability. The legacy codes
+        /// are currently better supported by the Bitwarden clients.
+        icon_redirect_code:     u32,    true,   def,    302;
         /// Positive icon cache expiry |> Number of seconds to consider that an already cached icon is fresh. After this period, the icon will be redownloaded
         icon_cache_ttl:         u64,    true,   def,    2_592_000;
         /// Negative icon cache expiry |> Number of seconds before trying to download an icon that failed again.
@@ -700,8 +701,8 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
 
     // Check if the icon redirect code is valid
     match cfg.icon_redirect_code {
-        307 | 308 => (),
-        _ => err!("Only HTTP 307/308 redirects are supported"),
+        301 | 302 | 307 | 308 => (),
+        _ => err!("Only HTTP 301/302 and 307/308 redirects are supported"),
     }
 
     Ok(())