Skip to content

Commit eece80a

Browse files
Accept env bools for image optimizer settings
1 parent 9fd838c commit eece80a

1 file changed

Lines changed: 133 additions & 2 deletions

File tree

crates/trusted-server-core/src/settings.rs

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,10 @@ impl S3SigV4AuthConfig {
496496
#[derive(Debug, Clone, Deserialize, Serialize)]
497497
pub struct AssetImageOptimizerConfig {
498498
/// Enables Image Optimizer for this route when the table is present.
499-
#[serde(default = "default_asset_image_optimizer_enabled")]
499+
#[serde(
500+
default = "default_asset_image_optimizer_enabled",
501+
deserialize_with = "bool_from_bool_or_str"
502+
)]
500503
pub enabled: bool,
501504
/// Image Optimizer processing region.
502505
pub region: String,
@@ -730,7 +733,10 @@ pub enum MissingCropOffsetMode {
730733
#[derive(Debug, Clone, Deserialize, Serialize)]
731734
pub struct ImageOptimizerCropOffsetsConfig {
732735
/// Enable crop offset normalization.
733-
#[serde(default = "default_asset_image_optimizer_enabled")]
736+
#[serde(
737+
default = "default_asset_image_optimizer_enabled",
738+
deserialize_with = "bool_from_bool_or_str"
739+
)]
734740
pub enabled: bool,
735741
/// Query parameter containing the x-axis offset.
736742
#[serde(default = "default_crop_offset_x_param")]
@@ -1706,6 +1712,23 @@ where
17061712
}
17071713
}
17081714

1715+
pub(crate) fn bool_from_bool_or_str<'de, D>(deserializer: D) -> Result<bool, D::Error>
1716+
where
1717+
D: Deserializer<'de>,
1718+
{
1719+
let value = JsonValue::deserialize(deserializer)?;
1720+
match value {
1721+
JsonValue::Bool(value) => Ok(value),
1722+
JsonValue::String(value) => value
1723+
.trim()
1724+
.parse::<bool>()
1725+
.map_err(serde::de::Error::custom),
1726+
other => Err(serde::de::Error::custom(format!(
1727+
"expected bool or parseable bool string, got {other}"
1728+
))),
1729+
}
1730+
}
1731+
17091732
pub(crate) fn vec_from_seq_or_map<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
17101733
where
17111734
D: Deserializer<'de>,
@@ -2993,6 +3016,114 @@ mod tests {
29933016
}
29943017
}
29953018

3019+
#[test]
3020+
fn proxy_asset_route_image_optimizer_env_accepts_nested_bool_strings_and_arrays() {
3021+
let toml_str = crate_test_settings_str();
3022+
let separator = ENVIRONMENT_VARIABLE_SEPARATOR;
3023+
let vars = [
3024+
(
3025+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}PREFIX"),
3026+
Some("/.image/"),
3027+
),
3028+
(
3029+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}ORIGIN_URL"),
3030+
Some("https://bucket.s3.us-west-2.amazonaws.com"),
3031+
),
3032+
(
3033+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}AUTH{separator}TYPE"),
3034+
Some("s3_sigv4"),
3035+
),
3036+
(
3037+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}AUTH{separator}REGION"),
3038+
Some("us-west-2"),
3039+
),
3040+
(
3041+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}AUTH{separator}ORIGIN_QUERY"),
3042+
Some("strip"),
3043+
),
3044+
(
3045+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}IMAGE_OPTIMIZER{separator}ENABLED"),
3046+
Some("true"),
3047+
),
3048+
(
3049+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}IMAGE_OPTIMIZER{separator}REGION"),
3050+
Some("us_west"),
3051+
),
3052+
(
3053+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}PROXY{separator}ASSET_ROUTES{separator}0{separator}IMAGE_OPTIMIZER{separator}PROFILE_SET"),
3054+
Some("default_images"),
3055+
),
3056+
(
3057+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}BASE_PARAMS"),
3058+
Some("quality=70&resize-filter=bicubic"),
3059+
),
3060+
(
3061+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}DEFAULT_PROFILE"),
3062+
Some("w828"),
3063+
),
3064+
(
3065+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}PROFILES{separator}W828"),
3066+
Some("format=auto&width=828"),
3067+
),
3068+
(
3069+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}PROFILES{separator}W1536"),
3070+
Some("format=auto&width=1536"),
3071+
),
3072+
(
3073+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}ASPECT_RATIOS{separator}ALLOWED"),
3074+
Some("[\"1-1\",\"16-9\"]"),
3075+
),
3076+
(
3077+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}ASPECT_RATIOS{separator}PROFILES"),
3078+
Some("[\"w828\",\"w1536\"]"),
3079+
),
3080+
(
3081+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}CROP_OFFSETS{separator}ENABLED"),
3082+
Some("true"),
3083+
),
3084+
(
3085+
format!("{ENVIRONMENT_VARIABLE_PREFIX}{separator}IMAGE_OPTIMIZER{separator}PROFILE_SETS{separator}DEFAULT_IMAGES{separator}CROP_OFFSETS{separator}BUCKETS"),
3086+
Some("[10,30,50,70,90]"),
3087+
),
3088+
];
3089+
3090+
temp_env::with_vars(vars, || {
3091+
let settings = Settings::from_toml_and_env(&toml_str)
3092+
.expect("should parse image optimizer env overrides");
3093+
let route = settings
3094+
.asset_route_for_path("/.image/id/example.jpg")
3095+
.expect("should match image optimizer asset route");
3096+
assert!(route.image_optimizer_enabled());
3097+
3098+
let image_optimizer = route
3099+
.image_optimizer
3100+
.as_ref()
3101+
.expect("should configure image optimizer");
3102+
assert!(image_optimizer.enabled);
3103+
assert_eq!(image_optimizer.region, "us_west");
3104+
assert_eq!(image_optimizer.profile_set, "default_images");
3105+
3106+
let profile_set = settings
3107+
.image_optimizer
3108+
.profile_sets
3109+
.get("default_images")
3110+
.expect("should configure default image profiles");
3111+
assert_eq!(profile_set.profiles["w828"], "format=auto&width=828");
3112+
let aspect_ratios = profile_set
3113+
.aspect_ratios
3114+
.as_ref()
3115+
.expect("should configure aspect ratios");
3116+
assert_eq!(aspect_ratios.allowed, vec!["1-1", "16-9"]);
3117+
assert_eq!(aspect_ratios.profiles, vec!["w828", "w1536"]);
3118+
let crop_offsets = profile_set
3119+
.crop_offsets
3120+
.as_ref()
3121+
.expect("should configure crop offsets");
3122+
assert!(crop_offsets.enabled);
3123+
assert_eq!(crop_offsets.buckets, vec![10, 30, 50, 70, 90]);
3124+
});
3125+
}
3126+
29963127
#[test]
29973128
fn proxy_asset_route_validation_rejects_image_optimizer_preserve_query() {
29983129
let toml_str = crate_test_settings_str()

0 commit comments

Comments
 (0)