@@ -13,10 +13,10 @@ import { HttpError, InternalServerError } from './errors/http';
1313import { FunctionSet } from './function-set' ;
1414import { asyncMiddleware , cloudfrontPost } from './middlewares' ;
1515import { CloudFrontLifecycle , Origin , CacheService } from './services' ;
16- import { ServerlessInstance , ServerlessOptions } from './types' ;
16+ import { CFDistribution , ServerlessInstance , ServerlessOptions } from './types' ;
1717import {
1818 buildConfig , buildContext , CloudFrontHeadersHelper , ConfigBuilder ,
19- convertToCloudFrontEvent , IncomingMessageWithBodyAndCookies
19+ convertToCloudFrontEvent , getOriginFromCfDistribution , IncomingMessageWithBodyAndCookies
2020} from './utils' ;
2121
2222
@@ -30,6 +30,7 @@ export class BehaviorRouter {
3030 private builder : ConfigBuilder ;
3131 private context : Context ;
3232 private behaviors = new Map < string , FunctionSet > ( ) ;
33+ private cfResources : Record < string , CFDistribution > ;
3334
3435 private cacheDir : string ;
3536 private fileDir : string ;
@@ -51,6 +52,7 @@ export class BehaviorRouter {
5152 this . builder = buildConfig ( serverless ) ;
5253 this . context = buildContext ( ) ;
5354
55+ this . cfResources = serverless . service ?. resources ?. Resources || { } ;
5456 this . cacheDir = path . resolve ( options . cacheDir || path . join ( os . tmpdir ( ) , 'edge-lambda' ) ) ;
5557 this . fileDir = path . resolve ( options . fileDir || path . join ( os . tmpdir ( ) , 'edge-lambda' ) ) ;
5658 this . path = this . serverless . service . custom . offlineEdgeLambda . path || '' ;
@@ -143,16 +145,22 @@ export class BehaviorRouter {
143145 }
144146
145147 const handler = this . match ( req ) ;
146- const cfEvent = convertToCloudFrontEvent ( req , this . builder ( 'viewer-request' ) ) ;
147148
148149 if ( ! handler ) {
149150 res . statusCode = StatusCodes . NOT_FOUND ;
150151 res . end ( ) ;
151152 return ;
152153 }
153154
155+ const customOrigin = handler . distribution in this . cfResources ?
156+ getOriginFromCfDistribution ( handler . pattern , this . cfResources [ handler . distribution ] ) :
157+ null ;
158+
159+ const cfEvent = convertToCloudFrontEvent ( req , this . builder ( 'viewer-request' ) ) ;
160+
154161 try {
155- const lifecycle = new CloudFrontLifecycle ( this . serverless , this . options , cfEvent , this . context , this . cacheService , handler ) ;
162+ const lifecycle = new CloudFrontLifecycle ( this . serverless , this . options , cfEvent ,
163+ this . context , this . cacheService , handler , customOrigin ) ;
156164 const response = await lifecycle . run ( req . url as string ) ;
157165
158166 if ( ! response ) {
@@ -230,20 +238,30 @@ export class BehaviorRouter {
230238 behaviors . clear ( ) ;
231239
232240 for await ( const [ , def ] of lambdaDefs ) {
241+
233242 const pattern = def . lambdaAtEdge . pathPattern || '*' ;
243+ const distribution = def . lambdaAtEdge . distribution || '' ;
234244
235245 if ( ! behaviors . has ( pattern ) ) {
236246 const origin = this . origins . get ( pattern ) ;
237- behaviors . set ( pattern , new FunctionSet ( pattern , this . log , origin ) ) ;
247+ behaviors . set ( pattern , new FunctionSet ( pattern , distribution , this . log , origin ) ) ;
238248 }
239249
240250 const fnSet = behaviors . get ( pattern ) as FunctionSet ;
241251
252+ // Don't try to register distributions that come from other sources
253+ if ( fnSet . distribution !== distribution ) {
254+ this . log ( `Warning: pattern ${ pattern } has registered handlers for cf distributions ${ fnSet . distribution } ` +
255+ ` and ${ distribution } . There is no way to tell which distribution should be used so only ${ fnSet . distribution } ` +
256+ ` has been registered.` ) ;
257+ continue ;
258+ }
259+
242260 await fnSet . setHandler ( def . lambdaAtEdge . eventType , path . join ( this . path , def . handler ) ) ;
243261 }
244262
245263 if ( ! behaviors . has ( '*' ) ) {
246- behaviors . set ( '*' , new FunctionSet ( '*' , this . log , this . origins . get ( '*' ) ) ) ;
264+ behaviors . set ( '*' , new FunctionSet ( '*' , '' , this . log , this . origins . get ( '*' ) ) ) ;
247265 }
248266 }
249267
@@ -261,7 +279,10 @@ export class BehaviorRouter {
261279
262280 private logBehaviors ( ) {
263281 this . behaviors . forEach ( ( behavior , key ) => {
264- this . log ( `Lambdas for path pattern ${ key } : ` ) ;
282+
283+ this . log ( `Lambdas for path pattern ${ key } ` +
284+ ( behavior . distribution === '' ? ':' : ` on ${ behavior . distribution } :` )
285+ ) ;
265286
266287 behavior . viewerRequest && this . log ( `viewer-request => ${ behavior . viewerRequest . path || '' } ` ) ;
267288 behavior . originRequest && this . log ( `origin-request => ${ behavior . originRequest . path || '' } ` ) ;
0 commit comments