@@ -21,7 +21,7 @@ import {
21
21
} from "../../core/routing/util" ;
22
22
import type { MiddlewareOutputEvent } from "../../core/routingHandler" ;
23
23
24
- const CloudFrontBlacklistedHeaders = [
24
+ const cloudfrontBlacklistedHeaders = [
25
25
// Disallowed headers, see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-function-restrictions-all.html#function-restrictions-disallowed-headers
26
26
"connection" ,
27
27
"expect" ,
@@ -65,15 +65,27 @@ const cloudfrontReadOnlyHeaders = [
65
65
"via" ,
66
66
] ;
67
67
68
+ const cloudfrontHeaderToNextHeader : Record < string , string > = {
69
+ "x-open-next-city" : "x-vercel-ip-city" ,
70
+ "x-open-next-country" : "x-vercel-ip-country" ,
71
+ "x-open-next-region" : "x-vercel-ip-country-region" ,
72
+ "x-open-next-latitude" : "x-vercel-ip-latitude" ,
73
+ "x-open-next-longitude" : "x-vercel-ip-longitude" ,
74
+ } ;
75
+
68
76
function normalizeCloudFrontRequestEventHeaders (
69
77
rawHeaders : CloudFrontHeaders ,
70
78
) : Record < string , string > {
71
79
const headers : Record < string , string > = { } ;
72
80
73
- for ( const [ key , values ] of Object . entries ( rawHeaders ) ) {
81
+ for ( const [ rawKey , values ] of Object . entries ( rawHeaders ) ) {
74
82
for ( const { value } of values ) {
75
83
if ( value ) {
76
- headers [ key . toLowerCase ( ) ] = value ;
84
+ const key = rawKey . toLowerCase ( ) ;
85
+ headers [ key ] = value ;
86
+ if ( key in cloudfrontHeaderToNextHeader ) {
87
+ headers [ cloudfrontHeaderToNextHeader [ key ] ] = value ;
88
+ }
77
89
}
78
90
}
79
91
}
@@ -84,8 +96,16 @@ function normalizeCloudFrontRequestEventHeaders(
84
96
async function convertFromCloudFrontRequestEvent (
85
97
event : CloudFrontRequestEvent ,
86
98
) : Promise < InternalEvent > {
87
- const { method, uri, querystring, body, headers, clientIp } =
88
- event . Records [ 0 ] . cf . request ;
99
+ const {
100
+ method,
101
+ uri,
102
+ querystring,
103
+ body,
104
+ headers : rawHeaders ,
105
+ clientIp,
106
+ } = event . Records [ 0 ] . cf . request ;
107
+ const headers = normalizeCloudFrontRequestEventHeaders ( rawHeaders ) ;
108
+
89
109
return {
90
110
type : "core" ,
91
111
method,
@@ -95,11 +115,11 @@ async function convertFromCloudFrontRequestEvent(
95
115
body ?. data ?? "" ,
96
116
body ?. encoding === "base64" ? "base64" : "utf8" ,
97
117
) ,
98
- headers : normalizeCloudFrontRequestEventHeaders ( headers ) ,
118
+ headers,
99
119
remoteAddress : clientIp ,
100
120
query : convertToQuery ( querystring ) ,
101
121
cookies :
102
- headers . cookie ?. reduce ( ( acc , cur ) => {
122
+ rawHeaders . cookie ?. reduce ( ( acc , cur ) => {
103
123
const { key, value } = cur ;
104
124
return { ...acc , [ key ?? "" ] : value } ;
105
125
} , { } ) ?? { } ,
@@ -119,7 +139,7 @@ function convertToCloudfrontHeaders(
119
139
. map ( ( [ key , value ] ) => [ key . toLowerCase ( ) , value ] as const )
120
140
. filter (
121
141
( [ key ] ) =>
122
- ! CloudFrontBlacklistedHeaders . some ( ( header ) =>
142
+ ! cloudfrontBlacklistedHeaders . some ( ( header ) =>
123
143
typeof header === "string" ? header === key : header . test ( key ) ,
124
144
) &&
125
145
// Only remove read-only headers when directly responding in lambda@edge
0 commit comments