Skip to content

Commit c4ecded

Browse files
fvsnippetsFederico Valido
authored andcommitted
Removing "accept" header from cache/originRequest policy when AutoWebP is disabled. This will improve cloudfront's cache hit ratio, and stop sending unnecesary header to origin.
1 parent 29fe1e7 commit c4ecded

File tree

4 files changed

+122
-27
lines changed

4 files changed

+122
-27
lines changed

source/constructs/lib/back-end/back-end-construct.ts

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import * as path from "path";
55
import { LambdaRestApiProps, RestApi } from "aws-cdk-lib/aws-apigateway";
66
import {
77
AllowedMethods,
8-
CacheHeaderBehavior,
9-
CachePolicy,
10-
CacheQueryStringBehavior,
8+
CfnCachePolicy,
9+
CfnOriginRequestPolicy,
1110
DistributionProps,
11+
ICachePolicy,
1212
IOrigin,
13-
OriginRequestPolicy,
13+
IOriginRequestPolicy,
1414
OriginSslPolicy,
1515
PriceClass,
1616
ViewerProtocolPolicy,
@@ -21,11 +21,12 @@ import { Runtime } from "aws-cdk-lib/aws-lambda";
2121
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
2222
import { LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
2323
import { IBucket } from "aws-cdk-lib/aws-s3";
24-
import { ArnFormat, Aws, Duration, Lazy, Stack } from "aws-cdk-lib";
24+
import { ArnFormat, Aws, Duration, Lazy, Resource, Stack } from "aws-cdk-lib";
2525
import { Construct } from "constructs";
2626
import { CloudFrontToApiGatewayToLambda } from "@aws-solutions-constructs/aws-cloudfront-apigateway-lambda";
2727

2828
import { addCfnSuppressRules } from "../../utils/utils";
29+
import { Conditions } from "../common-resources/common-resources-construct";
2930
import { SolutionConstructProps } from "../types";
3031

3132
export interface BackEndProps extends SolutionConstructProps {
@@ -35,6 +36,7 @@ export interface BackEndProps extends SolutionConstructProps {
3536
readonly logsBucket: IBucket;
3637
readonly uuid: string;
3738
readonly cloudFrontPriceClass: string;
39+
readonly conditions: Conditions;
3840
}
3941

4042
export class BackEnd extends Construct {
@@ -135,21 +137,9 @@ export class BackEnd extends Construct {
135137
},
136138
]);
137139

138-
const cachePolicy = new CachePolicy(this, "CachePolicy", {
139-
cachePolicyName: `ServerlessImageHandler-${props.uuid}`,
140-
defaultTtl: Duration.days(1),
141-
minTtl: Duration.seconds(1),
142-
maxTtl: Duration.days(365),
143-
enableAcceptEncodingGzip: true,
144-
headerBehavior: CacheHeaderBehavior.allowList("origin", "accept"),
145-
queryStringBehavior: CacheQueryStringBehavior.allowList("signature"),
146-
});
140+
const cachePolicy = new CustomBackEndCachePolicy(this, "CachePolicy", props);
147141

148-
const originRequestPolicy = new OriginRequestPolicy(this, "OriginRequestPolicy", {
149-
originRequestPolicyName: `ServerlessImageHandler-${props.uuid}`,
150-
headerBehavior: CacheHeaderBehavior.allowList("origin", "accept"),
151-
queryStringBehavior: CacheQueryStringBehavior.allowList("signature"),
152-
});
142+
const originRequestPolicy = new CustomBackEndOriginRequestPolicy(this, "OriginRequestPolicy", props);
153143

154144
const apiGatewayRestApi = RestApi.fromRestApiId(
155145
this,
@@ -215,3 +205,79 @@ export class BackEnd extends Construct {
215205
this.domainName = imageHandlerCloudFrontApiGatewayLambda.cloudFrontWebDistribution.distributionDomainName;
216206
}
217207
}
208+
209+
class CustomBackEndCachePolicy extends Resource implements ICachePolicy {
210+
public readonly cachePolicyId: string;
211+
212+
constructor(scope: Construct, id: string, props: BackEndProps) {
213+
super(scope, id, {
214+
physicalName: `ServerlessImageHandler-${props.uuid}`,
215+
});
216+
217+
const cachePolicy = new CfnCachePolicy(this, "Resource", {
218+
cachePolicyConfig: {
219+
name: `ServerlessImageHandler-${props.uuid}`,
220+
defaultTtl: Duration.days(1).toSeconds(),
221+
minTtl: Duration.seconds(1).toSeconds(),
222+
maxTtl: Duration.days(365).toSeconds(),
223+
parametersInCacheKeyAndForwardedToOrigin: {
224+
enableAcceptEncodingGzip: true,
225+
enableAcceptEncodingBrotli: false,
226+
queryStringsConfig: {
227+
queryStringBehavior: "whitelist",
228+
queryStrings: ["signature"],
229+
},
230+
headersConfig: {
231+
headerBehavior: "whitelist",
232+
},
233+
cookiesConfig: {
234+
cookieBehavior: "none",
235+
},
236+
},
237+
},
238+
});
239+
240+
// https://github.com/aws/aws-cdk/issues/8396#issuecomment-857690411
241+
cachePolicy.addOverride(
242+
"Properties.CachePolicyConfig.ParametersInCacheKeyAndForwardedToOrigin.HeadersConfig.Headers",
243+
{
244+
"Fn::If": [props.conditions.enableAutoWebPCondition.logicalId, ["origin", "accept"], ["origin"]],
245+
}
246+
);
247+
248+
this.cachePolicyId = cachePolicy.ref;
249+
}
250+
}
251+
252+
class CustomBackEndOriginRequestPolicy extends Resource implements IOriginRequestPolicy {
253+
public readonly originRequestPolicyId: string;
254+
255+
constructor(scope: Construct, id: string, props: BackEndProps) {
256+
super(scope, id, {
257+
physicalName: `ServerlessImageHandler-${props.uuid}`,
258+
});
259+
260+
const originRequestPolicy = new CfnOriginRequestPolicy(this, "Resource", {
261+
originRequestPolicyConfig: {
262+
name: `ServerlessImageHandler-${props.uuid}`,
263+
headersConfig: {
264+
headerBehavior: "whitelist",
265+
},
266+
queryStringsConfig: {
267+
queryStringBehavior: "whitelist",
268+
queryStrings: ["signature"],
269+
},
270+
cookiesConfig: {
271+
cookieBehavior: "none",
272+
},
273+
},
274+
});
275+
276+
// https://github.com/aws/aws-cdk/issues/8396#issuecomment-857690411
277+
originRequestPolicy.addOverride("Properties.OriginRequestPolicyConfig.HeadersConfig.Headers", {
278+
"Fn::If": [props.conditions.enableAutoWebPCondition.logicalId, ["origin", "accept"], ["origin"]],
279+
});
280+
281+
this.originRequestPolicyId = originRequestPolicy.ref;
282+
}
283+
}

source/constructs/lib/common-resources/common-resources-construct.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface Conditions {
2121
readonly enableSignatureCondition: CfnCondition;
2222
readonly enableDefaultFallbackImageCondition: CfnCondition;
2323
readonly enableCorsCondition: CfnCondition;
24+
readonly enableAutoWebPCondition: CfnCondition;
2425
}
2526

2627
export interface AppRegistryApplicationProps {
@@ -55,6 +56,9 @@ export class CommonResources extends Construct {
5556
enableCorsCondition: new CfnCondition(this, "EnableCorsCondition", {
5657
expression: Fn.conditionEquals(props.corsEnabled, "Yes"),
5758
}),
59+
enableAutoWebPCondition: new CfnCondition(this, "EnableAutoWebPCondition", {
60+
expression: Fn.conditionEquals(props.autoWebP, "Yes"),
61+
}),
5862
};
5963

6064
this.secretsManagerPolicy = new Policy(this, "SecretsManagerPolicy", {

source/constructs/lib/serverless-image-stack.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export class ServerlessImageHandlerStack extends Stack {
177177
logsBucket: commonResources.logsBucket,
178178
uuid: commonResources.customResources.uuid,
179179
cloudFrontPriceClass: cloudFrontPriceClassParameter.valueAsString,
180+
conditions: commonResources.conditions,
180181
...solutionConstructProps,
181182
});
182183

source/constructs/test/__snapshots__/constructs.test.ts.snap

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ exports[`Serverless Image Handler Stack Snapshot 1`] = `
1111
"Yes",
1212
],
1313
},
14+
"CommonResourcesEnableAutoWebPCondition68405A08": {
15+
"Fn::Equals": [
16+
{
17+
"Ref": "AutoWebPParameter",
18+
},
19+
"Yes",
20+
],
21+
},
1422
"CommonResourcesEnableCorsConditionA0615348": {
1523
"Fn::Equals": [
1624
{
@@ -398,10 +406,18 @@ exports[`Serverless Image Handler Stack Snapshot 1`] = `
398406
"EnableAcceptEncodingGzip": true,
399407
"HeadersConfig": {
400408
"HeaderBehavior": "whitelist",
401-
"Headers": [
402-
"origin",
403-
"accept",
404-
],
409+
"Headers": {
410+
"Fn::If": [
411+
"CommonResourcesEnableAutoWebPCondition68405A08",
412+
[
413+
"origin",
414+
"accept",
415+
],
416+
[
417+
"origin",
418+
],
419+
],
420+
},
405421
},
406422
"QueryStringsConfig": {
407423
"QueryStringBehavior": "whitelist",
@@ -1254,10 +1270,18 @@ exports[`Serverless Image Handler Stack Snapshot 1`] = `
12541270
},
12551271
"HeadersConfig": {
12561272
"HeaderBehavior": "whitelist",
1257-
"Headers": [
1258-
"origin",
1259-
"accept",
1260-
],
1273+
"Headers": {
1274+
"Fn::If": [
1275+
"CommonResourcesEnableAutoWebPCondition68405A08",
1276+
[
1277+
"origin",
1278+
"accept",
1279+
],
1280+
[
1281+
"origin",
1282+
],
1283+
],
1284+
},
12611285
},
12621286
"Name": {
12631287
"Fn::Join": [

0 commit comments

Comments
 (0)