Browse Source

Add backend support for alternate base dir (subdir/subpath) hosting

To use this, include a path in the `DOMAIN` URL, e.g.:

* `DOMAIN=https://example.com/custom-path`
* `DOMAIN=https://example.com/multiple/levels/are/ok`
Jeremy Lin 5 years ago
parent
commit
29a0795219

+ 8 - 4
src/api/admin.rs

@@ -52,6 +52,10 @@ const ADMIN_PATH: &str = "/admin";
 const BASE_TEMPLATE: &str = "admin/base";
 const VERSION: Option<&str> = option_env!("GIT_VERSION");
 
+fn admin_path() -> String {
+    format!("{}{}", CONFIG.domain_path(), ADMIN_PATH)
+}
+
 #[get("/", rank = 2)]
 fn admin_login(flash: Option<FlashMessage>) -> ApiResult<Html<String>> {
     // If there is an error, show it
@@ -76,7 +80,7 @@ fn post_admin_login(data: Form<LoginForm>, mut cookies: Cookies, ip: ClientIp) -
     if !_validate_token(&data.token) {
         error!("Invalid admin token. IP: {}", ip.ip);
         Err(Flash::error(
-            Redirect::to(ADMIN_PATH),
+            Redirect::to(admin_path()),
             "Invalid admin token, please try again.",
         ))
     } else {
@@ -85,14 +89,14 @@ fn post_admin_login(data: Form<LoginForm>, mut cookies: Cookies, ip: ClientIp) -
         let jwt = encode_jwt(&claims);
 
         let cookie = Cookie::build(COOKIE_NAME, jwt)
-            .path(ADMIN_PATH)
+            .path(admin_path())
             .max_age(chrono::Duration::minutes(20))
             .same_site(SameSite::Strict)
             .http_only(true)
             .finish();
 
         cookies.add(cookie);
-        Ok(Redirect::to(ADMIN_PATH))
+        Ok(Redirect::to(admin_path()))
     }
 }
 
@@ -167,7 +171,7 @@ fn invite_user(data: Json<InviteData>, _token: AdminToken, conn: DbConn) -> Empt
 #[get("/logout")]
 fn logout(mut cookies: Cookies) -> Result<Redirect, ()> {
     cookies.remove(Cookie::named(COOKIE_NAME));
-    Ok(Redirect::to(ADMIN_PATH))
+    Ok(Redirect::to(admin_path()))
 }
 
 #[get("/users")]

+ 1 - 1
src/api/core/mod.rs

@@ -172,7 +172,7 @@ fn hibp_breach(username: String) -> JsonResult {
             "BreachDate": "2019-08-18T00:00:00Z",
             "AddedDate": "2019-08-18T00:00:00Z",
             "Description": format!("Go to: <a href=\"https://haveibeenpwned.com/account/{account}\" target=\"_blank\" rel=\"noopener\">https://haveibeenpwned.com/account/{account}</a> for a manual check.<br/><br/>HaveIBeenPwned API key not set!<br/>Go to <a href=\"https://haveibeenpwned.com/API/Key\" target=\"_blank\" rel=\"noopener\">https://haveibeenpwned.com/API/Key</a> to purchase an API key from HaveIBeenPwned.<br/><br/>", account=username),
-            "LogoPath": "/bwrs_static/hibp.png",
+            "LogoPath": "bwrs_static/hibp.png",
             "PwnCount": 0,
             "DataClasses": [
                 "Error - No API key set!"

+ 12 - 2
src/api/web.rs

@@ -37,7 +37,17 @@ fn app_id() -> Cached<Content<Json<Value>>> {
             {
             "version": { "major": 1, "minor": 0 },
             "ids": [
-                &CONFIG.domain(),
+                // Per <https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html#determining-the-facetid-of-a-calling-application>:
+                //
+                // "In the Web case, the FacetID MUST be the Web Origin [RFC6454]
+                // of the web page triggering the FIDO operation, written as
+                // a URI with an empty path. Default ports are omitted and any
+                // path component is ignored."
+                //
+                // This leaves it unclear as to whether the path must be empty,
+                // or whether it can be non-empty and will be ignored. To be on
+                // the safe side, use a proper web origin (with empty path).
+                &CONFIG.domain_origin(),
                 "ios:bundle-id:com.8bit.bitwarden",
                 "android:apk-key-hash:dUGFzUzf3lmHSLBDBIv+WaFyZMI" ]
             }]
@@ -75,6 +85,6 @@ fn static_files(filename: String) -> Result<Content<&'static [u8]>, Error> {
         "bootstrap-native-v4.js" => Ok(Content(ContentType::JavaScript, include_bytes!("../static/scripts/bootstrap-native-v4.js"))),
         "md5.js" => Ok(Content(ContentType::JavaScript, include_bytes!("../static/scripts/md5.js"))),
         "identicon.js" => Ok(Content(ContentType::JavaScript, include_bytes!("../static/scripts/identicon.js"))),
-        _ => err!("Image not found"),
+        _ => err!(format!("Static file not found: {}", filename)),
     }
 }

+ 5 - 5
src/auth.rs

@@ -16,11 +16,11 @@ const JWT_ALGORITHM: Algorithm = Algorithm::RS256;
 lazy_static! {
     pub static ref DEFAULT_VALIDITY: Duration = Duration::hours(2);
     static ref JWT_HEADER: Header = Header::new(JWT_ALGORITHM);
-    pub static ref JWT_LOGIN_ISSUER: String = format!("{}|login", CONFIG.domain());
-    pub static ref JWT_INVITE_ISSUER: String = format!("{}|invite", CONFIG.domain());
-    pub static ref JWT_DELETE_ISSUER: String = format!("{}|delete", CONFIG.domain());
-    pub static ref JWT_VERIFYEMAIL_ISSUER: String = format!("{}|verifyemail", CONFIG.domain());
-    pub static ref JWT_ADMIN_ISSUER: String = format!("{}|admin", CONFIG.domain());
+    pub static ref JWT_LOGIN_ISSUER: String = format!("{}|login", CONFIG.domain_origin());
+    pub static ref JWT_INVITE_ISSUER: String = format!("{}|invite", CONFIG.domain_origin());
+    pub static ref JWT_DELETE_ISSUER: String = format!("{}|delete", CONFIG.domain_origin());
+    pub static ref JWT_VERIFYEMAIL_ISSUER: String = format!("{}|verifyemail", CONFIG.domain_origin());
+    pub static ref JWT_ADMIN_ISSUER: String = format!("{}|admin", CONFIG.domain_origin());
     static ref PRIVATE_RSA_KEY: Vec<u8> = match read_file(&CONFIG.private_rsa_key()) {
         Ok(key) => key,
         Err(e) => panic!("Error loading private RSA Key.\n Error: {}", e),

+ 21 - 0
src/config.rs

@@ -1,6 +1,8 @@
 use std::process::exit;
 use std::sync::RwLock;
 
+use reqwest::Url;
+
 use crate::error::Error;
 use crate::util::{get_env, get_env_bool};
 
@@ -240,6 +242,10 @@ make_config! {
         domain:                 String, true,   def,    "http://localhost".to_string();
         /// Domain Set |> Indicates if the domain is set by the admin. Otherwise the default will be used.
         domain_set:             bool,   false,  def,    false;
+        /// Domain origin |> Domain URL origin (in https://example.com:8443/path, https://example.com:8443 is the origin)
+        domain_origin:          String, false,  auto,   |c| extract_url_origin(&c.domain);
+        /// Domain path |> Domain URL path (in https://example.com:8443/path, /path is the path)
+        domain_path:            String, false,  auto,   |c| extract_url_path(&c.domain);
         /// Enable web vault
         web_vault_enabled:      bool,   false,  def,    true;
 
@@ -457,6 +463,21 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
     Ok(())
 }
 
+/// Extracts an RFC 6454 web origin from a URL.
+fn extract_url_origin(url: &str) -> String {
+    let url = Url::parse(url).expect("valid URL");
+
+    url.origin().ascii_serialization()
+}
+
+/// Extracts the path from a URL.
+/// All trailing '/' chars are trimmed, even if the path is a lone '/'.
+fn extract_url_path(url: &str) -> String {
+    let url = Url::parse(url).expect("valid URL");
+
+    url.path().trim_end_matches('/').to_string()
+}
+
 impl Config {
     pub fn load() -> Result<Self, Error> {
         // Loading from env and file

+ 10 - 8
src/main.rs

@@ -255,18 +255,20 @@ mod migrations {
 }
 
 fn launch_rocket(extra_debug: bool) {
-    // Create Rocket object, this stores current log level and sets it's own
+    // Create Rocket object, this stores current log level and sets its own
     let rocket = rocket::ignite();
 
-    // If addding more base paths here, consider also adding them to
+    let basepath = &CONFIG.domain_path();
+
+    // If adding more paths here, consider also adding them to
     // crate::utils::LOGGED_ROUTES to make sure they appear in the log
     let rocket = rocket
-        .mount("/", api::web_routes())
-        .mount("/api", api::core_routes())
-        .mount("/admin", api::admin_routes())
-        .mount("/identity", api::identity_routes())
-        .mount("/icons", api::icons_routes())
-        .mount("/notifications", api::notifications_routes())
+        .mount(&[basepath, "/"].concat(), api::web_routes())
+        .mount(&[basepath, "/api"].concat(), api::core_routes())
+        .mount(&[basepath, "/admin"].concat(), api::admin_routes())
+        .mount(&[basepath, "/identity"].concat(), api::identity_routes())
+        .mount(&[basepath, "/icons"].concat(), api::icons_routes())
+        .mount(&[basepath, "/notifications"].concat(), api::notifications_routes())
         .manage(db::init_pool())
         .manage(api::start_notification_server())
         .attach(util::AppHeaders())

+ 8 - 8
src/static/templates/admin/base.hbs

@@ -6,10 +6,10 @@
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <title>Bitwarden_rs Admin Panel</title>
 
-    <link rel="stylesheet" href="/bwrs_static/bootstrap.css" />
-    <script src="/bwrs_static/bootstrap-native-v4.js"></script>
-    <script src="/bwrs_static/md5.js"></script>
-    <script src="/bwrs_static/identicon.js"></script>
+    <link rel="stylesheet" href="bwrs_static/bootstrap.css" />
+    <script src="bwrs_static/bootstrap-native-v4.js"></script>
+    <script src="bwrs_static/md5.js"></script>
+    <script src="bwrs_static/identicon.js"></script>
     <style>
         body {
             padding-top: 70px;
@@ -38,10 +38,10 @@
         <div class="navbar-collapse">
             <ul class="navbar-nav">
                 <li class="nav-item active">
-                    <a class="nav-link" href="/admin">Admin Panel</a>
+                    <a class="nav-link" href="admin">Admin Panel</a>
                 </li>
                 <li class="nav-item">
-                    <a class="nav-link" href="/">Vault</a>
+                    <a class="nav-link" href=".">Vault</a>
                 </li>
             </ul>
         </div>
@@ -55,7 +55,7 @@
 
             {{#if logged_in}}
             <li class="nav-item">
-                <a class="nav-link" href="/admin/logout">Log Out</a>
+                <a class="nav-link" href="admin/logout">Log Out</a>
             </li>
             {{/if}}
         </ul>
@@ -64,4 +64,4 @@
     {{> (page_content) }}
 </body>
 
-</html>
+</html>

+ 9 - 9
src/static/templates/admin/page.hbs

@@ -225,7 +225,7 @@
         var input_mail = prompt("To delete user '" + mail + "', please type the email below")
         if (input_mail != null) {
             if (input_mail == mail) {
-                _post("/admin/users/" + id + "/delete",
+                _post("admin/users/" + id + "/delete",
                     "User deleted correctly",
                     "Error deleting user");
             } else {
@@ -235,19 +235,19 @@
         return false;
     }
     function remove2fa(id) {
-        _post("/admin/users/" + id + "/remove-2fa",
+        _post("admin/users/" + id + "/remove-2fa",
             "2FA removed correctly",
             "Error removing 2FA");
         return false;
     }
     function deauthUser(id) {
-        _post("/admin/users/" + id + "/deauth",
+        _post("admin/users/" + id + "/deauth",
             "Sessions deauthorized correctly",
             "Error deauthorizing sessions");
         return false;
     }
     function updateRevisions() {
-        _post("/admin/users/update_revision",
+        _post("admin/users/update_revision",
             "Success, clients will sync next time they connect",
             "Error forcing clients to sync");
         return false;
@@ -256,7 +256,7 @@
         inv = document.getElementById("email-invite");
         data = JSON.stringify({ "email": inv.value });
         inv.value = "";
-        _post("/admin/invite/", "User invited correctly",
+        _post("admin/invite/", "User invited correctly",
             "Error inviting user", data);
         return false;
     }
@@ -278,7 +278,7 @@
     }
     function saveConfig() {
         data = JSON.stringify(getFormData());
-        _post("/admin/config/", "Config saved correctly",
+        _post("admin/config/", "Config saved correctly",
             "Error saving config", data);
         return false;
     }
@@ -286,7 +286,7 @@
         var input = prompt("This will remove all user configurations, and restore the defaults and the " +
             "values set by the environment. This operation could be dangerous. Type 'DELETE' to proceed:");
         if (input === "DELETE") {
-            _post("/admin/config/delete",
+            _post("admin/config/delete",
                 "Config deleted correctly",
                 "Error deleting config");
         } else {
@@ -296,7 +296,7 @@
         return false;
     }
     function backupDatabase() {
-        _post("/admin/config/backup_db",
+        _post("admin/config/backup_db",
             "Backup created successfully",
             "Error creating backup");
         return false;
@@ -336,4 +336,4 @@
     // {{#each config}} {{#if grouptoggle}}
     masterCheck("input_{{grouptoggle}}", "#g_{{group}} input");
     // {{/if}} {{/each}}
-</script>
+</script>

+ 1 - 1
src/static/templates/email/invite_accepted.hbs

@@ -3,6 +3,6 @@ Invitation accepted
 <html>
 <p>
     Your invitation for <b>{{email}}</b> to join <b>{{org_name}}</b> was accepted.
-    Please <a href="{{url}}">log in</a> to the bitwarden_rs server and confirm them from the organization management page.
+    Please <a href="{{url}}/">log in</a> to the bitwarden_rs server and confirm them from the organization management page.
 </p>
 </html>

+ 1 - 1
src/static/templates/email/invite_accepted.html.hbs

@@ -101,7 +101,7 @@ Invitation accepted
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
-                                          Please <a href="{{url}}">log in</a> to the bitwarden_rs server and confirm them from the organization management page.
+                                          Please <a href="{{url}}/">log in</a> to the bitwarden_rs server and confirm them from the organization management page.
                                        </td>
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">

+ 1 - 1
src/static/templates/email/invite_confirmed.hbs

@@ -3,6 +3,6 @@ Invitation to {{org_name}} confirmed
 <html>
 <p>
     Your invitation to join <b>{{org_name}}</b> was confirmed.
-    It will now appear under the Organizations the next time you <a href="{{url}}">log in</a> to the web vault.
+    It will now appear under the Organizations the next time you <a href="{{url}}/">log in</a> to the web vault.
 </p>
 </html>

+ 1 - 1
src/static/templates/email/invite_confirmed.html.hbs

@@ -102,7 +102,7 @@ Invitation to {{org_name}} confirmed
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
                                           Any collections and logins being shared with you by this organization will now appear in your Bitwarden vault. <br>
-                                          <a href="{{url}}">Log in</a>
+                                          <a href="{{url}}/">Log in</a>
                                        </td>
                                     </tr>
                                  </table>

+ 1 - 1
src/static/templates/email/new_device_logged_in.hbs

@@ -9,6 +9,6 @@ New Device Logged In From {{device}}
    Device Type: {{device}}
 
    You can deauthorize all devices that have access to your account from the
-    <a href="{{url}}">web vault</a> under Settings > My Account > Deauthorize Sessions.
+    <a href="{{url}}/">web vault</a> under Settings > My Account > Deauthorize Sessions.
 </p>
 </html>

+ 1 - 1
src/static/templates/email/new_device_logged_in.html.hbs

@@ -116,7 +116,7 @@ New Device Logged In From {{device}}
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none;" valign="top">
-                                           You can deauthorize all devices that have access to your account from the <a href="{{url}}">web vault</a> under Settings > My Account > Deauthorize Sessions.
+                                           You can deauthorize all devices that have access to your account from the <a href="{{url}}/">web vault</a> under Settings > My Account > Deauthorize Sessions.
                                        </td>
                                     </tr>
                                  </table>

+ 1 - 1
src/static/templates/email/pw_hint_some.hbs

@@ -3,7 +3,7 @@ Your master password hint
 You (or someone) recently requested your master password hint.
 
 Your hint is: "{{hint}}"
-Log in: <a href="{{url}}">Web Vault</a>
+Log in: <a href="{{url}}/">Web Vault</a>
 
 If you cannot remember your master password, there is no way to recover your data. The only option to gain access to your account again is to <a href="{{url}}/#/recover-delete">delete the account</a> so that you can register again and start over. All data associated with your account will be deleted.
 

+ 1 - 1
src/static/templates/email/pw_hint_some.html.hbs

@@ -102,7 +102,7 @@ Your master password hint
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
                                           Your hint is: "{{hint}}"<br style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;" />
-                                          Log in: <a href="{{url}}">Web Vault</a>
+                                          Log in: <a href="{{url}}/">Web Vault</a>
                                        </td>
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">

+ 1 - 1
src/static/templates/email/welcome.hbs

@@ -2,7 +2,7 @@ Welcome
 <!---------------->
 <html>
 <p>
-Thank you for creating an account at <a href="{{url}}">{{url}}</a>. You may now log in with your new account.
+Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. You may now log in with your new account.
 </p>
 <p>If you did not request to create an account, you can safely ignore this email.</p>
 </html>

+ 1 - 1
src/static/templates/email/welcome.html.hbs

@@ -96,7 +96,7 @@ Welcome
                                  <table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none; text-align: center;" valign="top" align="center">
-                                          Thank you for creating an account at <a href="{{url}}">{{url}}</a>. You may now log in with your new account.
+                                          Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. You may now log in with your new account.
                                        </td>
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">

+ 1 - 1
src/static/templates/email/welcome_must_verify.hbs

@@ -2,7 +2,7 @@ Welcome
 <!---------------->
 <html>
 <p>
-Thank you for creating an account at <a href="{{url}}">{{url}}</a>. Before you can login with your new account, you must verify this email address by clicking the link below.
+Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. Before you can login with your new account, you must verify this email address by clicking the link below.
 <br>
 <br>
 <a href="{{url}}/#/verify-email/?userId={{user_id}}&token={{token}}">

+ 1 - 1
src/static/templates/email/welcome_must_verify.html.hbs

@@ -96,7 +96,7 @@ Welcome
                                  <table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
                                        <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none; text-align: center;" valign="top" align="center">
-                                          Thank you for creating an account at <a href="{{url}}">{{url}}</a>. Before you can login with your new account, you must verify this email address by clicking the link below.
+                                          Thank you for creating an account at <a href="{{url}}/">{{url}}</a>. Before you can login with your new account, you must verify this email address by clicking the link below.
                                        </td>
                                     </tr>
                                     <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">

+ 9 - 4
src/util.rs

@@ -109,7 +109,7 @@ impl<'r, R: Responder<'r>> Responder<'r> for Cached<R> {
     }
 }
 
-// Log all the routes from the main base paths list, and the attachments endoint
+// Log all the routes from the main paths list, and the attachments endpoint
 // Effectively ignores, any static file route, and the alive endpoint
 const LOGGED_ROUTES: [&str; 6] = [
     "/api",
@@ -157,7 +157,10 @@ impl Fairing for BetterLogging {
         }
         let uri = request.uri();
         let uri_path = uri.path();
-        if self.0 || LOGGED_ROUTES.iter().any(|r| uri_path.starts_with(r)) {
+        // FIXME: trim_start_matches() could result in over-trimming in pathological cases;
+        // strip_prefix() would be a better option once it's stable.
+        let uri_subpath = uri_path.trim_start_matches(&CONFIG.domain_path());
+        if self.0 || LOGGED_ROUTES.iter().any(|r| uri_subpath.starts_with(r)) {
             match uri.query() {
                 Some(q) => info!(target: "request", "{} {}?{}", method, uri_path, &q[..q.len().min(30)]),
                 None => info!(target: "request", "{} {}", method, uri_path),
@@ -169,8 +172,10 @@ impl Fairing for BetterLogging {
         if !self.0 && request.method() == Method::Options {
             return;
         }
-        let uri_path = request.uri().path();
-        if self.0 || LOGGED_ROUTES.iter().any(|r| uri_path.starts_with(r)) {
+        // FIXME: trim_start_matches() could result in over-trimming in pathological cases;
+        // strip_prefix() would be a better option once it's stable.
+        let uri_subpath = request.uri().path().trim_start_matches(&CONFIG.domain_path());
+        if self.0 || LOGGED_ROUTES.iter().any(|r| uri_subpath.starts_with(r)) {
             let status = response.status();
             if let Some(ref route) = request.route() {
                 info!(target: "response", "{} => {} {}", route, status.code, status.reason)