From 1c4c82d61f2525f5b1dcb9fc3d1b0a2532eb3f1b Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Mon, 3 Aug 2020 20:06:01 +0100 Subject: [PATCH] feat(cloudfront): Behaviors support cached methods, compression, viewer protocol, and smooth streaming (#9411) Adds support for many of the missing properties for controlling behaviors on the new Distribution construct. Also removed (currently unavailable) properties from the README. The remaining properties will come in a follow-up PR. They were not included in this PR due to either being blocked by the latest CloudFormation spec merge, or are still being prioritized (e.g., fieldLevelEncryption). related #7086 related #9107 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cloudfront/README.md | 4 +- .../aws-cloudfront/lib/distribution.ts | 47 ++++++++++++++++++- .../lib/private/cache-behavior.ts | 7 ++- .../test/private/cache-behavior.test.ts | 11 ++++- 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/README.md b/packages/@aws-cdk/aws-cloudfront/README.md index 44bfe03e680eb..f71cf9f971391 100644 --- a/packages/@aws-cdk/aws-cloudfront/README.md +++ b/packages/@aws-cdk/aws-cloudfront/README.md @@ -133,12 +133,11 @@ const myWebDistribution = new cloudfront.Distribution(this, 'myDist', { Additional behaviors can be specified at creation, or added after the initial creation. Each additional behavior is associated with an origin, and enable customization for a specific set of resources based on a URL path pattern. For example, we can add a behavior to `myWebDistribution` to -override the default time-to-live (TTL) for all of the images. +override the default viewer protocol policy for all of the images. ```ts myWebDistribution.addBehavior('/images/*.jpg', new origins.S3Origin(myBucket), { viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - defaultTtl: cdk.Duration.days(7), }); ``` @@ -156,7 +155,6 @@ new cloudfront.Distribution(this, 'myDist', { '/images/*.jpg': { origin: bucketOrigin, viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - defaultTtl: cdk.Duration.days(7), }, }, }); diff --git a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts index 157f0c7535229..81cb0e7470ec4 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts @@ -376,6 +376,21 @@ export class AllowedMethods { private constructor(methods: string[]) { this.methods = methods; } } +/** + * The HTTP methods that the Behavior will cache requests on. + */ +export class CachedMethods { + /** HEAD and GET */ + public static readonly CACHE_GET_HEAD = new CachedMethods(['GET', 'HEAD']); + /** HEAD, GET, and OPTIONS */ + public static readonly CACHE_GET_HEAD_OPTIONS = new CachedMethods(['GET', 'HEAD', 'OPTIONS']); + + /** HTTP methods supported */ + public readonly methods: string[]; + + private constructor(methods: string[]) { this.methods = methods; } +} + /** * Options for configuring custom error responses. * @@ -461,10 +476,26 @@ export interface AddBehaviorOptions { /** * HTTP methods to allow for this behavior. * - * @default - GET and HEAD + * @default AllowedMethods.ALLOW_GET_HEAD */ readonly allowedMethods?: AllowedMethods; + /** + * HTTP methods to cache for this behavior. + * + * @default CachedMethods.CACHE_GET_HEAD + */ + readonly cachedMethods?: CachedMethods; + + /** + * Whether you want CloudFront to automatically compress certain files for this cache behavior. + * See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types + * for file types CloudFront will compress. + * + * @default false + */ + readonly compress?: boolean; + /** * Whether CloudFront will forward query strings to the origin. * If this is set to true, CloudFront will forward all query parameters to the origin, and cache @@ -482,6 +513,20 @@ export interface AddBehaviorOptions { */ readonly forwardQueryStringCacheKeys?: string[]; + /** + * Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior. + * + * @default false + */ + readonly smoothStreaming?: boolean; + + /** + * The protocol that viewers can use to access the files controlled by this behavior. + * + * @default ViewerProtocolPolicy.ALLOW_ALL + */ + readonly viewerProtocolPolicy?: ViewerProtocolPolicy; + /** * The Lambda@Edge functions to invoke before serving the contents. * diff --git a/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts b/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts index 2e44abcfc05c0..6461d0fd54b0a 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts @@ -38,12 +38,15 @@ export class CacheBehavior { return { pathPattern: this.props.pathPattern, targetOriginId: this.originId, - allowedMethods: this.props.allowedMethods?.methods ?? undefined, + allowedMethods: this.props.allowedMethods?.methods, + cachedMethods: this.props.cachedMethods?.methods, + compress: this.props.compress, forwardedValues: { queryString: this.props.forwardQueryString ?? false, queryStringCacheKeys: this.props.forwardQueryStringCacheKeys, }, - viewerProtocolPolicy: ViewerProtocolPolicy.ALLOW_ALL, + smoothStreaming: this.props.smoothStreaming, + viewerProtocolPolicy: this.props.viewerProtocolPolicy ?? ViewerProtocolPolicy.ALLOW_ALL, lambdaFunctionAssociations: this.props.edgeLambdas ? this.props.edgeLambdas.map(edgeLambda => { if (edgeLambda.functionVersion.version === '$LATEST') { diff --git a/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts b/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts index 4477a411cf790..2570e889d8587 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/private/cache-behavior.test.ts @@ -1,6 +1,6 @@ import '@aws-cdk/assert/jest'; import { App, Stack } from '@aws-cdk/core'; -import { AllowedMethods } from '../../lib'; +import { AllowedMethods, CachedMethods, ViewerProtocolPolicy } from '../../lib'; import { CacheBehavior } from '../../lib/private/cache-behavior'; let app: App; @@ -29,18 +29,25 @@ test('renders with all properties specified', () => { const behavior = new CacheBehavior('origin_id', { pathPattern: '*', allowedMethods: AllowedMethods.ALLOW_ALL, + cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS, + compress: true, forwardQueryString: true, forwardQueryStringCacheKeys: ['user_id', 'auth'], + smoothStreaming: true, + viewerProtocolPolicy: ViewerProtocolPolicy.HTTPS_ONLY, }); expect(behavior._renderBehavior()).toEqual({ targetOriginId: 'origin_id', pathPattern: '*', allowedMethods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'PATCH', 'POST', 'DELETE'], + cachedMethods: ['GET', 'HEAD', 'OPTIONS'], + compress: true, forwardedValues: { queryString: true, queryStringCacheKeys: ['user_id', 'auth'], }, - viewerProtocolPolicy: 'allow-all', + smoothStreaming: true, + viewerProtocolPolicy: 'https-only', }); });