Skip to content

Commit e984ded

Browse files
committed
Add example files
1 parent 945d1ea commit e984ded

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

examples/complete/ab-testing.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function handler(event) {
2+
// A/B testing function using CloudFront Functions
3+
// Assigns users to test groups and routes to different origin paths
4+
5+
var request = event.request;
6+
var headers = request.headers;
7+
var cookies = request.cookies;
8+
9+
// Check if user already has an A/B test cookie
10+
var abTestGroup = null;
11+
12+
if (cookies['ab-test-group']) {
13+
abTestGroup = cookies['ab-test-group'].value;
14+
} else {
15+
// Assign new users to a test group (50/50 split)
16+
// Use CloudFront viewer ID for consistent assignment
17+
var viewerId = event.viewer.address;
18+
var hash = 0;
19+
20+
for (var i = 0; i < viewerId.length; i++) {
21+
hash = ((hash << 5) - hash) + viewerId.charCodeAt(i);
22+
hash = hash & hash; // Convert to 32bit integer
23+
}
24+
25+
abTestGroup = (Math.abs(hash) % 2 === 0) ? 'A' : 'B';
26+
27+
// Note: CloudFront Functions cannot set cookies
28+
// You would set this cookie in the response (using viewer-response function)
29+
// or via JavaScript on the client side
30+
}
31+
32+
// Route to different paths based on test group
33+
var uri = request.uri;
34+
35+
if (abTestGroup === 'B' && !uri.startsWith('/variant-b/')) {
36+
// Rewrite path for variant B users
37+
request.uri = '/variant-b' + uri;
38+
}
39+
40+
// Add header for origin to know which variant was served
41+
headers['x-ab-test-group'] = {
42+
value: abTestGroup
43+
};
44+
45+
return request;
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function handler(event) {
2+
// CloudFront Function with KeyValueStore integration
3+
// Uses KV store for dynamic URL redirects and feature flags
4+
5+
var request = event.request;
6+
var uri = request.uri;
7+
8+
// Note: To use KeyValueStore, associate the KV store ARN with this function
9+
// Example: key_value_store_associations = ["arn:aws:cloudfront::123456789012:key-value-store/redirects"]
10+
11+
// Uncomment when KV store is associated:
12+
/*
13+
var kvsHandle = event.context.kvs;
14+
15+
// Look up redirect mapping in KeyValueStore
16+
var redirectTarget = kvsHandle.get(uri);
17+
18+
if (redirectTarget) {
19+
// Redirect to target URL from KV store
20+
var response = {
21+
statusCode: 301,
22+
statusDescription: 'Moved Permanently',
23+
headers: {
24+
'location': { value: redirectTarget },
25+
'cache-control': { value: 'max-age=3600' }
26+
}
27+
};
28+
return response;
29+
}
30+
31+
// Check feature flags in KV store
32+
var featureFlags = kvsHandle.get('feature-flags');
33+
if (featureFlags) {
34+
var flags = JSON.parse(featureFlags);
35+
36+
// Add feature flag headers for origin
37+
if (flags.enableNewUI) {
38+
request.headers['x-feature-new-ui'] = { value: 'true' };
39+
}
40+
}
41+
*/
42+
43+
// For now, return request as-is
44+
// When KV store is configured, uncomment the code above
45+
return request;
46+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function handler(event) {
2+
// Viewer request function to add security headers and normalize cache keys
3+
// This function runs before CloudFront checks the cache
4+
5+
var request = event.request;
6+
var headers = request.headers;
7+
8+
// Normalize Host header for consistent caching
9+
if (headers.host) {
10+
headers.host.value = headers.host.value.toLowerCase();
11+
}
12+
13+
// Remove query parameters that don't affect content (for better cache hit ratio)
14+
var uri = request.uri;
15+
var querystring = request.querystring;
16+
17+
// Example: Remove tracking parameters but keep content-affecting ones
18+
var allowedParams = ['id', 'page', 'category'];
19+
var newQuerystring = {};
20+
21+
for (var param in querystring) {
22+
if (allowedParams.includes(param)) {
23+
newQuerystring[param] = querystring[param];
24+
}
25+
}
26+
27+
request.querystring = newQuerystring;
28+
29+
// Add custom header for logging/debugging
30+
headers['x-viewer-country'] = {
31+
value: event.viewer.country || 'unknown'
32+
};
33+
34+
return request;
35+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
function handler(event) {
2+
// Viewer response function to add security and performance headers
3+
// This function runs after CloudFront receives the response from origin
4+
5+
var response = event.response;
6+
var headers = response.headers;
7+
8+
// Add security headers
9+
headers['strict-transport-security'] = {
10+
value: 'max-age=63072000; includeSubdomains; preload'
11+
};
12+
13+
headers['x-content-type-options'] = {
14+
value: 'nosniff'
15+
};
16+
17+
headers['x-frame-options'] = {
18+
value: 'DENY'
19+
};
20+
21+
headers['x-xss-protection'] = {
22+
value: '1; mode=block'
23+
};
24+
25+
headers['referrer-policy'] = {
26+
value: 'strict-origin-when-cross-origin'
27+
};
28+
29+
// Add cache control for static assets
30+
if (event.request.uri.match(/\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$/)) {
31+
headers['cache-control'] = {
32+
value: 'public, max-age=31536000, immutable'
33+
};
34+
}
35+
36+
// Add custom header to identify CloudFront Functions processing
37+
headers['x-cloudfront-function'] = {
38+
value: 'viewer-response-headers'
39+
};
40+
41+
return response;
42+
}

0 commit comments

Comments
 (0)