From ab16b69a6914f8f0922abaa9ef772e74dfc62b46 Mon Sep 17 00:00:00 2001 From: Scott Strong Date: Tue, 9 Jun 2026 15:54:24 -0700 Subject: [PATCH 1/2] add org avatar rule --- devservices/proxy.yaml | 7 +++++++ example_config_proxy.yaml | 9 +++++++++ proxy/src/route_actions.rs | 41 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/devservices/proxy.yaml b/devservices/proxy.yaml index cd8a49f..3ddfb09 100644 --- a/devservices/proxy.yaml +++ b/devservices/proxy.yaml @@ -28,6 +28,13 @@ proxy: cell_to_upstream: "--monolith--": sentry-dev-monolith default: sentry-dev-monolith + - match: + path: /organization-avatar/{organization}/{avatar_id} + action: + resolver: cell_from_organization + cell_to_upstream: + "--monolith--": sentry-dev-monolith + default: sentry-dev-monolith metrics: statsd_host: "127.0.0.1" diff --git a/example_config_proxy.yaml b/example_config_proxy.yaml index a8c3fca..fb845f6 100644 --- a/example_config_proxy.yaml +++ b/example_config_proxy.yaml @@ -44,6 +44,15 @@ proxy: us1: us1-getsentry us2: us2-getsentry default: us1-getsentry + - match: + host: us.sentry.io + path: /organization-avatar/{organization}/{avatar_id} + action: + resolver: cell_from_organization + cell_to_upstream: + us1: us1-getsentry + us2: us2-getsentry + default: us1-getsentry - match: host: us.sentry.io path: /api/0/cell/{cell_id}/* diff --git a/proxy/src/route_actions.rs b/proxy/src/route_actions.rs index 6e56e61..8201778 100644 --- a/proxy/src/route_actions.rs +++ b/proxy/src/route_actions.rs @@ -371,4 +371,45 @@ mod tests { }) ); } + + #[test] + fn test_organization_avatar_slug_locator() { + // route on first segment after static prefix; org avatars are + // served from /organization-avatar/{slug}/{id} + // (the avatar id is captured but ignored) + let config = RouteConfig { + r#match: crate::config::Match { + host: None, + path: Some("/organization-avatar/{organization}/{avatar_id}".to_string()), + }, + action: crate::config::Action::Dynamic { + resolver: crate::config::Resolver::CellFromOrganization, + cell_to_upstream: HashMap::new(), + default: None, + }, + }; + + let route = Route::try_from(config.clone()).unwrap(); + + assert_eq!( + route.matches(None, "/organization-avatar/my-org/abc123/"), + Some(RouteMatch { + params: HashMap::from([ + ("organization".to_string(), "my-org".to_string()), + ("avatar_id".to_string(), "abc123".to_string()), + ]), + action: config.action.clone(), + }), + "captures the slug as `organization`, not the avatar id" + ); + + // the explicit two-segment org segment must not match + // deprecated, slug-less form (/organization-avatar/{id}) + assert!( + route + .matches(None, "/organization-avatar/abc123/") + .is_none(), + "deprecated slug-less form must not match the slug locator" + ); + } } From c14e3287a189938c04bf645e0a2a35618d090adc Mon Sep 17 00:00:00 2001 From: Scott Strong Date: Tue, 9 Jun 2026 16:06:11 -0700 Subject: [PATCH 2/2] lint --- proxy/src/route_actions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/src/route_actions.rs b/proxy/src/route_actions.rs index 8201778..1da882f 100644 --- a/proxy/src/route_actions.rs +++ b/proxy/src/route_actions.rs @@ -374,7 +374,7 @@ mod tests { #[test] fn test_organization_avatar_slug_locator() { - // route on first segment after static prefix; org avatars are + // route on first segment after static prefix; org avatars are // served from /organization-avatar/{slug}/{id} // (the avatar id is captured but ignored) let config = RouteConfig {