Request/Response Functions
The IIIF service can be heavily customized through the use of CloudFront Functions (opens in a new tab) or Lambda@Edge Functions (opens in a new tab) attached to a CloudFront distribution in front of the service. It's important to understand the four stages of CloudFront processing in order to know where a given type of customization belongs.
- A
viewer-request
function will be called on every request, cached or not. This is the appropriate place to attach a function that performs authorization, authentication, or anything else whose result should not be cached. - An
origin-request
function will only be called when CloudFront refreshes the content from the origin (e.g., the IIIF server). It's the appropriate place to attach a function that should be cached, such as S3 file resolution or the retrieval of image dimensions. - Similarly, the
origin-response
andviewer-response
functions are called after the IIIF server returns its response and before CloudFront passes it on to the viewer, respectively. They can be used to alter the response in a way that is either cached or ephemeral.
Examples
These examples use CloudFront Functions. Lambda@Edge functions are slightly more complicated in terms of the event structure but the basic idea is the same.
Simple Authorization
function handler(event) {
if (notAuthorized) { // based on something in the event.request
return {
statusCode: 403,
statusDescription: 'Unauthorized'
};
};
return event.request;
}
Custom File Location / Image Dimensions
function handler(event) {
var request = event.request;
request.headers['x-preflight-location'] = [{value: 's3://image-bucket/path/to/correct/image.tif'}];
request.headers['x-preflight-dimensions'] = [{value: JSON.stringify({ width: 640, height: 480 })}];
return request;
}
The x-preflight-dimensions
header can take several shapes:
{ width, height }
(or[{ width, height }]
) - a straightforward, single-resolution image[{ width, height }, { width, height }, ...]
- a multi-resolution image with pages of the specified sizes{ width, height, pages }
- a multi-resolution image with the specified number ofpages
, each half the size of the one before{ width, height, limit }
- a multi-resolution image in which the smallest width and height are both less than the specifiedlimit
For example, the following dimension values would all describe the same pyramidal image:
[{ width: 2048, height: 1536 }, { width: 1024, height: 768 }, { width: 512, height: 384 }]
{ width: 2048, height: 1536, pages: 3 }
{ width: 2048, height: 1536, limit: 480 }
The limit
calculator will keep going until both dimensions are less than the limit, not less than or equal to. So a limit: 512
on the third example above would generate a fourth page at { width: 256, height: 192 }
.
If you plan to use CloudFront functions to add either of the above x-preflight-
headers to incoming requests, you must set the value of the Preflight
parameter to true
when deploying serverless-iiif
. The function will only look for the preflight headers if this environment variable is true
. This prevents requests from including those headers directly if no preflight function is present. If you do use a preflight function, make sure it strips out any x-preflight-location
and x-preflight-dimensions
headers that it doesn't set itself.