diff --git a/404.html b/404.html index 2571a89..62b050d 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/_next/data/-eqUGH_PmTLhFrYiCLemy/docs/quick-start/infrastructure/cloudformation.json b/_next/data/lGr0_SfWpPknc8cO6YpM_/docs/quick-start/infrastructure/cloudformation.json similarity index 100% rename from _next/data/-eqUGH_PmTLhFrYiCLemy/docs/quick-start/infrastructure/cloudformation.json rename to _next/data/lGr0_SfWpPknc8cO6YpM_/docs/quick-start/infrastructure/cloudformation.json diff --git a/_next/data/-eqUGH_PmTLhFrYiCLemy/docs/quick-start/infrastructure/terraform.json b/_next/data/lGr0_SfWpPknc8cO6YpM_/docs/quick-start/infrastructure/terraform.json similarity index 100% rename from _next/data/-eqUGH_PmTLhFrYiCLemy/docs/quick-start/infrastructure/terraform.json rename to _next/data/lGr0_SfWpPknc8cO6YpM_/docs/quick-start/infrastructure/terraform.json diff --git a/_next/static/chunks/nextra-data-en-US.json b/_next/static/chunks/nextra-data-en-US.json index 5634dd5..18381dc 100644 --- a/_next/static/chunks/nextra-data-en-US.json +++ b/_next/static/chunks/nextra-data-en-US.json @@ -1 +1 @@ -{"/about":{"title":"About","data":{"":"","iiif-in-the-cloud#IIIF in the Cloud":"Access is bursty by nature\nTile requests are at least an order of magnitude burstier\nVery hard to scale a server-based solution in a way that can handle the bursts without wasting capacity (and money)","solution#Solution":"","under-the-hood#Under the Hood":"","libvips#libvips":"“A demand-driven, horizontally threaded image processing library”\nVery fast and extremely lightweight\nCan perform more than 300 different image manipulation operations\nSupports a large number of image formats\nMost importantly (for our purposes), it supports multi-resolution images\nand tiling\nDocumentation ↗","sharp#sharp":"Fast native Node.js wrapper for libvips\nSupports seeking and streaming of image data without making a local copy\nDocumentation ↗","contributors#Contributors":"Michael B. Klein - Northwestern University Libraries\nJustin Gondron\nRob Kaufman - Notch 8\nEdward Silverton - Mnemoscene\nTrey Pendragon - Princeton University Libraries\nTheia Wolfe","license#License":"Serverless IIIF is available under the Apache 2.0 license."}},"/docs/advanced-usage/cors":{"title":"Cross-Origin Request Sharing (CORS)","data":{"":"For security reasons, web browsers have built in limits on what sort of requests can be made to a given domain from a page hosted under a different domain. Since this is a common use case for IIIF (resources embedded in pages whose domains differ from that of the server), IIIF interactions are particularly susceptible to these limits.The mechanism for determining which of these requests should be allowed or blocked is known as Cross-Origin Resource Sharing, or CORS. A full explanation of CORS is beyond the scope of this project, but the SAM deploy template contains five parameters relating to how the IIIF server handles CORS:\nCorsAllowCredentials contains the value that will be returned in the Access-Control-Allow-Credentials response header.\nCorsAllowHeaders contains the value that will be returned in the Access-Control-Allow-Headers response header.\nCorsAllowOrigin contains the value that will be returned in the Access-Control-Allow-Origin response header. In addition, a special value, REFLECT_ORIGIN, instructs the IIIF server to copy the value of the incoming request's Origin header into the Access-Control-Allow-Origin response header.\nCorsExposeHeaders contains the value that will be returned in the Access-Control-Expose-Headers response header.\nCorsMaxAge contains the value that will be returned in the Access-Control-Max-Age response header.\n\nThe default values will work in most circumstances, but if you need the IIIF server to accept requests that include credentials or other potentially sensitive information (e.g., Authorization and/or Cookie headers), you'll need to set CorsAllowOrigin to REFLECT_ORIGIN and CorsAllowCredentials to true. Other settings allow further customization."}},"/docs/advanced-usage/request-response-functions":{"title":"Request Response Functions","data":{"":"","requestresponse-functions#Request/Response Functions":"The IIIF service can be heavily customized through the use of CloudFront Functions or Lambda@Edge Functions 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.\nA viewer-request function will be called on every request, cached or not. This is the appropriate place to attach\na function that performs authorization, authentication, or anything else whose result should not be cached.\nAn origin-request function will only be called when CloudFront refreshes the content from the origin (e.g., the IIIF server).\nIt's the appropriate place to attach a function that should be cached, such as S3 file resolution or the retrieval of\nimage dimensions.\nSimilarly, the origin-response and viewer-response functions are called after the IIIF server returns its response\nand before CloudFront passes it on to the viewer, respectively. They can be used to alter the response in a way that is\neither cached or ephemeral.","examples#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#Simple Authorization":"function handler(event) {\nif (notAuthorized) { // based on something in the event.request\nreturn {\nstatusCode: 403,\nstatusDescription: 'Unauthorized'\n};\n};\nreturn event.request;\n}","custom-file-location--image-dimensions#Custom File Location / Image Dimensions":"function handler(event) {\nvar request = event.request;\nrequest.headers['x-preflight-location'] = {value: 's3://image-bucket/path/to/correct/image.tif'};\nrequest.headers['x-preflight-dimensions'] = {value: JSON.stringify({ width: 640, height: 480 })};\nreturn request;\n}\nThe x-preflight-dimensions header can take several shapes:\n{ width, height } (or [{ width, height }]) - a straightforward, single-resolution image\n[{ width, height }, { width, height }, ...] - a multi-resolution image with pages of the specified sizes\n{ width, height, pages } - a multi-resolution image with the specified number of pages, each half the size of the one before\n{ width, height, limit } - a multi-resolution image in which the smallest width and height are both less than the specified limit\n\nFor example, the following dimension values would all describe the same pyramidal image:\n[{ width: 2048, height: 1536 }, { width: 1024, height: 768 }, { width: 512, height: 384 }]\n{ width: 2048, height: 1536, pages: 3 }\n{ width: 2048, height: 1536, limit: 480 }\n\nThe 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 }.\nIf 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."}},"/docs/communities/iiif":{"title":"Iiif","data":{"":""}},"/docs/communities/samvera":{"title":"Samvera","data":{"":""}},"/docs/contributors":{"title":"Contributors","data":{"":"Michael B. Klein\nJustin Gondron\nRob Kaufman\nEdward Silverton\nTrey Pendragon\nTheia Wolfe"}},"/docs/custom-sharp-layer":{"title":"Custom Sharp Layer","data":{"":"This lambda uses the Sharp layer from https://github.com/samvera/lambda-layer-sharp-jp2/releases in order to get a version of Sharp with jp2 support.You can build your own local version using that code and then deploy your own layer and set that layer in your SAM template."}},"/docs/how-to-contribute":{"title":"How to Contribute?","data":{"":"If you're working on a PR for this project, create a feature branch off of main.This repository follows the Samvera Community Code of Conduct and language recommendations. Please do not create a branch called master for this repository or as part of your pull request; the branch will either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository."}},"/docs":{"title":"serverless-iiif","data":{"":"","description#Description":"A cost-effective, infinitely scalable IIIF 2.1 and 3.0 image API compliant service packaged as an AWS Serverless Application with minimum setup and no maintenance. Suitable for large institutional collections or small digital humanities projects.","components#Components":"A simple Lambda Function wrapper for the iiif-processor module.\nA Lambda Function URL that is used to invoke the IIIF API via HTTPS.\nA Lambda Layer containing all the dependencies for the Lambda Function.","prerequisites#Prerequisites":"Some basic knowledge of AWS.\nAn Amazon Web Services account with permissions to create resources via the console and/or command line.\nAn Amazon S3 bucket to hold the source images to be served via IIIF.\n\n\nNote: The Lambda Function will be granted read access to this bucket.","license#License":"serverless-iiif is available under the Apache 2.0 license."}},"/docs/notes":{"title":"Notes","data":{"":"Lambda Function URLs have a payload (request/response body) size limit of approximately 6MB in both directions. To overcome this limitation, the Lambda URL is configured behind an AWS CloudFront distribution with two origins - the API and a cache bucket. Responses larger than 6MB are saved to the cache bucket at the same relative path as the request, and the Lambda returns a 404 Not Found response to CloudFront. CloudFront then fails over to the second origin (the cache bucket), where it finds the actual response and returns it.The cache bucket uses an S3 lifecycle rule to expire cached responses in 1 day."}},"/docs/quick-start/deleting-the-app":{"title":"Deleting the application","data":{"":"If you deployed the application on its own, the easiest way to delete the application is either from the Lambda Applications Console or by deleting its CloudFormation Stack.If you deployed from the command line, you can also use the npm run delete command.If you deployed using an infrastructure tool such as AWS CloudFormation or Terraform, you should use that tool's destroy/teardown functionality to remove the IIIF stack as well."}},"/docs/quick-start/deployment-command-line":{"title":"Deploying via the Command Line","data":{"":"","prerequisites#Prerequisites":"Docker\nAWS CLI\nAWS SAM CLI v1.91 or greater","step-1#Step 1":"Make sure the AWS CLI is properly configured with credentials that have sufficient access to manage IAM, S3, and Lambda resources.","step-2#Step 2":"Clone this repository.","step-3#Step 3":"Copy deploy.yml.example to deploy.yml. Update the various values under parameter_overrides within.","step-4#Step 4":"Build the application:\n$ npm run build","step-5#Step 5":"Deploy the application using one of the following:\n# To be prompted for all configuration values before deploying\n$ npm run deploy-guided\n\n# To deploy using the current configuration, prompting only for changeset confirmation\n$ npm run deploy\nIf you use the guided deploy, you'll be prompted for various configuration parameters, confirmations, and acknowledgments of specific issues (particularly the creation of IAM resources and the deployment of an open/unauthenticated Lambda Function URL). Otherwise, you'll simply be asked to confirm the calculated changeset.","step-6#Step 6":"Follow the prompts to complete the deployment process and get the resulting endpoint."}},"/docs/quick-start/deployment-sam":{"title":"Deploying via the AWS Serverless Application Repository","data":{"":"serverless-iiif is distributed and deployed via the AWS Serverless Application Repository. To deploy it using the AWS Console:","step-1#Step 1":"Find the serverless-iiif application in the AWS Serverless Application Repository.","step-2#Step 2":"Make sure your currently selected region (in the console's top navigation bar) is the one you want to deploy to.","step-3#Step 3":"Scroll down to the Application settings section.","step-4#Step 4":"Configure the deploy template:\nGive your stack a unique Application name\nEnter the name of the SourceBucket the service will serve images from\nCheck the box acknowledging that the app will create a custom IAM roles and resource policies (and if deploying the Caching version, that it will also deploy a nested application)\nOptional: Enter or change any other parameters that apply to your desired configuration.","step-5#Step 5":"Click Deploy.","step-6#Step 6":"When all the resources are properly created and configured, the new stack should be in the CREATE_COMPLETE stage. If there's an error, it will delete all the resources it created, roll back any changes it made, and eventually reach the ROLLBACK_COMPLETE stage.","step-7#Step 7":"Click the CloudFormation stack link.","step-8#Step 8":"Click the Outputs tab to see (and copy) the IIIF Endpoint URL."}},"/docs/quick-start":{"title":"Index","data":{"":"serverless-iiif is deployed as a Lambda Function URL, in the lambda-url.AWS_REGION.on.aws domain (e.g., https://fu90293j0pj902j902c32j902.lambda-url.us-east-1.on.aws/iiif/2/). In order to use a custom domain name, or other features like caching and pre/post-processing functions, you'll have to set up a CloudFront distribution."}},"/docs/quick-start/infrastructure":{"title":"Deploying via Infrastructure Tools","data":{"":"You will most likely want to deploy serverless-iiif as part of a larger infrastructure stack. This stack might include a caching layer (AWS CloudFront), functions to customize the services behavior, a custom domain name, and more. This section provides documentation and examples of how to deploy the service using AWS CloudFormation or Terraform."}},"/docs/source-images":{"title":"Source Images","data":{"":"The S3 key of any given file, minus the extension, is its IIIF ID. For example, if you want to access the image manifest for the file at abcdef.tif, you would get https://.../iiif/2/abcdef/info.json. If your key contains slashes, they must be URL-encoded: e.g., ab/cd/ef/gh.tif would be at https://.../iiif/2/ab%2Fcd%2Fef%2Fgh/info.json. (This limitation could easily be fixed by encoding only the necessary slashes in the incoming URL before handing it off to the IIIF processor, but that's beyond the scope of the demo.)iiif-processor can use any image format natively supported by libvips, including JPEG 2000 (.jp2), but best results will come from using tiled, multi-resolution TIFFs. The Lambda Function wrapper included in this application assumes a .tif extension unless you set ResolverTemplate in your .env file.","creating-tiled-tiffs#Creating tiled TIFFs":"","using-vips#Using VIPS":"vips tiffsave source_image.tif output_image.tif --tile --pyramid --compression jpeg --tile-width 256 --tile-height 256","using-imagemagick#Using ImageMagick":"convert source_image.tif -define tiff:tile-geometry=256x256 -compress jpeg 'ptif:output_image.tif'"}},"/docs/testing":{"title":"Testing","data":{"":"","testing#Testing":"If tests are run locally they will start in \"watch\" mode. If a CI environment is detected they will only run once. From the project root run:\nnpm test\nTo generate a code coverage report run:\nnpm test --coverage"}},"/":{"title":"Serverless IIIF – Serve images via IIIF","data":{"":""}},"/docs/quick-start/infrastructure/cloudformation":{"title":"Cloudformation","data":{"":"Installing serverless-iiif as part of a CloudFormation template makes it easy to integrate the service with other components. Please refer to the example and the CloudFormation documentation for more information on how you might tailor these templates to your own needs and deploy them to AWS.","syntax#Syntax":"To declare this entity in your AWS CloudFormation template, use the following syntax:","properties#Properties":"","example#Example":"This example template will deploy a full application stack consisting of:\nA serverless-iiif image server\nA CloudFront distribution with a custom hostname and SSL certificate"}},"/docs/quick-start/infrastructure/terraform":{"title":"Terraform","data":{"":"The serverless-iiif GitHub repository includes a that can be used as a drop-in component in any\nTerraform manifest. Please refer to the documentation and examples below, as well as the Terraform documentation\nfor more information on how you might use these tools to deploy your own custom stack to AWS.","required-inputs#Required Inputs":"These variables must be set in the module block when using this module.","optional-inputs#Optional Inputs":"These variables have default values and don't have to be set to use this module. You may set these variables to override their default\nvalues.","minimal-example#Minimal Example":"module \"serverless_iiif\" {\nsource = \"github.com/samvera/serverless-iiif//extras/terraform\"\n\nsource_bucket = \"iiif-images\"\nstack_name = \"my-iiif-service\"\n}","almost-full-example#(Almost) Full Example":"module \"serverless_iiif\" {\nsource = \"github.com/samvera/serverless-iiif//extras/terraform\"\n\nsource_bucket = \"iiif-images\"\nstack_name = \"my-iiif-service\"\ncors_allow_credentials = true\ncors_allow_headers = \"X-Custom-Header,Upgrade-Insecure-Requests\"\ncors_allow_origin = \"REFLECT_ORIGIN\"\ncors_expose_headers = \"Content-Encoding\"\ncors_max_age = 600\nforce_host = \"iiif.my-domain.edu\"\niiif_lambda_memory = 2048\niiif_lambda_timeout = 120\npixel_density = 600\npreflight = true\nresolver_template = \"iiif/%s.tif\"\n\ntags = {\nProject = \"my-image-service\"\n}\n}"}}} \ No newline at end of file +{"/about":{"title":"About","data":{"":"","iiif-in-the-cloud#IIIF in the Cloud":"Access is bursty by nature\nTile requests are at least an order of magnitude burstier\nVery hard to scale a server-based solution in a way that can handle the bursts without wasting capacity (and money)","solution#Solution":"","under-the-hood#Under the Hood":"","libvips#libvips":"“A demand-driven, horizontally threaded image processing library”\nVery fast and extremely lightweight\nCan perform more than 300 different image manipulation operations\nSupports a large number of image formats\nMost importantly (for our purposes), it supports multi-resolution images\nand tiling\nDocumentation ↗","sharp#sharp":"Fast native Node.js wrapper for libvips\nSupports seeking and streaming of image data without making a local copy\nDocumentation ↗","contributors#Contributors":"Michael B. Klein - Northwestern University Libraries\nJustin Gondron\nRob Kaufman - Notch 8\nEdward Silverton - Mnemoscene\nTrey Pendragon - Princeton University Libraries\nTheia Wolfe","license#License":"Serverless IIIF is available under the Apache 2.0 license."}},"/docs/advanced-usage/cors":{"title":"Cross-Origin Request Sharing (CORS)","data":{"":"For security reasons, web browsers have built in limits on what sort of requests can be made to a given domain from a page hosted under a different domain. Since this is a common use case for IIIF (resources embedded in pages whose domains differ from that of the server), IIIF interactions are particularly susceptible to these limits.The mechanism for determining which of these requests should be allowed or blocked is known as Cross-Origin Resource Sharing, or CORS. A full explanation of CORS is beyond the scope of this project, but the SAM deploy template contains five parameters relating to how the IIIF server handles CORS:\nCorsAllowCredentials contains the value that will be returned in the Access-Control-Allow-Credentials response header.\nCorsAllowHeaders contains the value that will be returned in the Access-Control-Allow-Headers response header.\nCorsAllowOrigin contains the value that will be returned in the Access-Control-Allow-Origin response header. In addition, a special value, REFLECT_ORIGIN, instructs the IIIF server to copy the value of the incoming request's Origin header into the Access-Control-Allow-Origin response header.\nCorsExposeHeaders contains the value that will be returned in the Access-Control-Expose-Headers response header.\nCorsMaxAge contains the value that will be returned in the Access-Control-Max-Age response header.\n\nThe default values will work in most circumstances, but if you need the IIIF server to accept requests that include credentials or other potentially sensitive information (e.g., Authorization and/or Cookie headers), you'll need to set CorsAllowOrigin to REFLECT_ORIGIN and CorsAllowCredentials to true. Other settings allow further customization."}},"/docs/advanced-usage/request-response-functions":{"title":"Request Response Functions","data":{"":"","requestresponse-functions#Request/Response Functions":"The IIIF service can be heavily customized through the use of CloudFront Functions or Lambda@Edge Functions 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.\nA viewer-request function will be called on every request, cached or not. This is the appropriate place to attach\na function that performs authorization, authentication, or anything else whose result should not be cached.\nAn origin-request function will only be called when CloudFront refreshes the content from the origin (e.g., the IIIF server).\nIt's the appropriate place to attach a function that should be cached, such as S3 file resolution or the retrieval of\nimage dimensions.\nSimilarly, the origin-response and viewer-response functions are called after the IIIF server returns its response\nand before CloudFront passes it on to the viewer, respectively. They can be used to alter the response in a way that is\neither cached or ephemeral.","examples#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#Simple Authorization":"function handler(event) {\nif (notAuthorized) { // based on something in the event.request\nreturn {\nstatusCode: 403,\nstatusDescription: 'Unauthorized'\n};\n};\nreturn event.request;\n}","custom-file-location--image-dimensions#Custom File Location / Image Dimensions":"function handler(event) {\nvar request = event.request;\nrequest.headers['x-preflight-location'] = [{value: 's3://image-bucket/path/to/correct/image.tif'}];\nrequest.headers['x-preflight-dimensions'] = [{value: JSON.stringify({ width: 640, height: 480 })}];\nreturn request;\n}\nThe x-preflight-dimensions header can take several shapes:\n{ width, height } (or [{ width, height }]) - a straightforward, single-resolution image\n[{ width, height }, { width, height }, ...] - a multi-resolution image with pages of the specified sizes\n{ width, height, pages } - a multi-resolution image with the specified number of pages, each half the size of the one before\n{ width, height, limit } - a multi-resolution image in which the smallest width and height are both less than the specified limit\n\nFor example, the following dimension values would all describe the same pyramidal image:\n[{ width: 2048, height: 1536 }, { width: 1024, height: 768 }, { width: 512, height: 384 }]\n{ width: 2048, height: 1536, pages: 3 }\n{ width: 2048, height: 1536, limit: 480 }\n\nThe 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 }.\nIf 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."}},"/docs/communities/iiif":{"title":"Iiif","data":{"":""}},"/docs/communities/samvera":{"title":"Samvera","data":{"":""}},"/docs/custom-sharp-layer":{"title":"Custom Sharp Layer","data":{"":"This lambda uses the Sharp layer from https://github.com/samvera/lambda-layer-sharp-jp2/releases in order to get a version of Sharp with jp2 support.You can build your own local version using that code and then deploy your own layer and set that layer in your SAM template."}},"/docs/contributors":{"title":"Contributors","data":{"":"Michael B. Klein\nJustin Gondron\nRob Kaufman\nEdward Silverton\nTrey Pendragon\nTheia Wolfe"}},"/docs/how-to-contribute":{"title":"How to Contribute?","data":{"":"If you're working on a PR for this project, create a feature branch off of main.This repository follows the Samvera Community Code of Conduct and language recommendations. Please do not create a branch called master for this repository or as part of your pull request; the branch will either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository."}},"/docs":{"title":"serverless-iiif","data":{"":"","description#Description":"A cost-effective, infinitely scalable IIIF 2.1 and 3.0 image API compliant service packaged as an AWS Serverless Application with minimum setup and no maintenance. Suitable for large institutional collections or small digital humanities projects.","components#Components":"A simple Lambda Function wrapper for the iiif-processor module.\nA Lambda Function URL that is used to invoke the IIIF API via HTTPS.\nA Lambda Layer containing all the dependencies for the Lambda Function.","prerequisites#Prerequisites":"Some basic knowledge of AWS.\nAn Amazon Web Services account with permissions to create resources via the console and/or command line.\nAn Amazon S3 bucket to hold the source images to be served via IIIF.\n\n\nNote: The Lambda Function will be granted read access to this bucket.","license#License":"serverless-iiif is available under the Apache 2.0 license."}},"/docs/notes":{"title":"Notes","data":{"":"Lambda Function URLs have a payload (request/response body) size limit of approximately 6MB in both directions. To overcome this limitation, the Lambda URL is configured behind an AWS CloudFront distribution with two origins - the API and a cache bucket. Responses larger than 6MB are saved to the cache bucket at the same relative path as the request, and the Lambda returns a 404 Not Found response to CloudFront. CloudFront then fails over to the second origin (the cache bucket), where it finds the actual response and returns it.The cache bucket uses an S3 lifecycle rule to expire cached responses in 1 day."}},"/docs/quick-start/deleting-the-app":{"title":"Deleting the application","data":{"":"If you deployed the application on its own, the easiest way to delete the application is either from the Lambda Applications Console or by deleting its CloudFormation Stack.If you deployed from the command line, you can also use the npm run delete command.If you deployed using an infrastructure tool such as AWS CloudFormation or Terraform, you should use that tool's destroy/teardown functionality to remove the IIIF stack as well."}},"/docs/quick-start/deployment-command-line":{"title":"Deploying via the Command Line","data":{"":"","prerequisites#Prerequisites":"Docker\nAWS CLI\nAWS SAM CLI v1.91 or greater","step-1#Step 1":"Make sure the AWS CLI is properly configured with credentials that have sufficient access to manage IAM, S3, and Lambda resources.","step-2#Step 2":"Clone this repository.","step-3#Step 3":"Copy deploy.yml.example to deploy.yml. Update the various values under parameter_overrides within.","step-4#Step 4":"Build the application:\n$ npm run build","step-5#Step 5":"Deploy the application using one of the following:\n# To be prompted for all configuration values before deploying\n$ npm run deploy-guided\n\n# To deploy using the current configuration, prompting only for changeset confirmation\n$ npm run deploy\nIf you use the guided deploy, you'll be prompted for various configuration parameters, confirmations, and acknowledgments of specific issues (particularly the creation of IAM resources and the deployment of an open/unauthenticated Lambda Function URL). Otherwise, you'll simply be asked to confirm the calculated changeset.","step-6#Step 6":"Follow the prompts to complete the deployment process and get the resulting endpoint."}},"/docs/quick-start/deployment-sam":{"title":"Deploying via the AWS Serverless Application Repository","data":{"":"serverless-iiif is distributed and deployed via the AWS Serverless Application Repository. To deploy it using the AWS Console:","step-1#Step 1":"Find the serverless-iiif application in the AWS Serverless Application Repository.","step-2#Step 2":"Make sure your currently selected region (in the console's top navigation bar) is the one you want to deploy to.","step-3#Step 3":"Scroll down to the Application settings section.","step-4#Step 4":"Configure the deploy template:\nGive your stack a unique Application name\nEnter the name of the SourceBucket the service will serve images from\nCheck the box acknowledging that the app will create a custom IAM roles and resource policies (and if deploying the Caching version, that it will also deploy a nested application)\nOptional: Enter or change any other parameters that apply to your desired configuration.","step-5#Step 5":"Click Deploy.","step-6#Step 6":"When all the resources are properly created and configured, the new stack should be in the CREATE_COMPLETE stage. If there's an error, it will delete all the resources it created, roll back any changes it made, and eventually reach the ROLLBACK_COMPLETE stage.","step-7#Step 7":"Click the CloudFormation stack link.","step-8#Step 8":"Click the Outputs tab to see (and copy) the IIIF Endpoint URL."}},"/docs/quick-start":{"title":"Index","data":{"":"serverless-iiif is deployed as a Lambda Function URL, in the lambda-url.AWS_REGION.on.aws domain (e.g., https://fu90293j0pj902j902c32j902.lambda-url.us-east-1.on.aws/iiif/2/). In order to use a custom domain name, or other features like caching and pre/post-processing functions, you'll have to set up a CloudFront distribution."}},"/docs/quick-start/infrastructure":{"title":"Deploying via Infrastructure Tools","data":{"":"You will most likely want to deploy serverless-iiif as part of a larger infrastructure stack. This stack might include a caching layer (AWS CloudFront), functions to customize the services behavior, a custom domain name, and more. This section provides documentation and examples of how to deploy the service using AWS CloudFormation or Terraform."}},"/docs/source-images":{"title":"Source Images","data":{"":"The S3 key of any given file, minus the extension, is its IIIF ID. For example, if you want to access the image manifest for the file at abcdef.tif, you would get https://.../iiif/2/abcdef/info.json. If your key contains slashes, they must be URL-encoded: e.g., ab/cd/ef/gh.tif would be at https://.../iiif/2/ab%2Fcd%2Fef%2Fgh/info.json. (This limitation could easily be fixed by encoding only the necessary slashes in the incoming URL before handing it off to the IIIF processor, but that's beyond the scope of the demo.)iiif-processor can use any image format natively supported by libvips, including JPEG 2000 (.jp2), but best results will come from using tiled, multi-resolution TIFFs. The Lambda Function wrapper included in this application assumes a .tif extension unless you set ResolverTemplate in your .env file.","creating-tiled-tiffs#Creating tiled TIFFs":"","using-vips#Using VIPS":"vips tiffsave source_image.tif output_image.tif --tile --pyramid --compression jpeg --tile-width 256 --tile-height 256","using-imagemagick#Using ImageMagick":"convert source_image.tif -define tiff:tile-geometry=256x256 -compress jpeg 'ptif:output_image.tif'"}},"/docs/testing":{"title":"Testing","data":{"":"","testing#Testing":"If tests are run locally they will start in \"watch\" mode. If a CI environment is detected they will only run once. From the project root run:\nnpm test\nTo generate a code coverage report run:\nnpm test --coverage"}},"/":{"title":"Serverless IIIF – Serve images via IIIF","data":{"":""}},"/docs/quick-start/infrastructure/cloudformation":{"title":"Cloudformation","data":{"":"Installing serverless-iiif as part of a CloudFormation template makes it easy to integrate the service with other components. Please refer to the example and the CloudFormation documentation for more information on how you might tailor these templates to your own needs and deploy them to AWS.","syntax#Syntax":"To declare this entity in your AWS CloudFormation template, use the following syntax:","properties#Properties":"","example#Example":"This example template will deploy a full application stack consisting of:\nA serverless-iiif image server\nA CloudFront distribution with a custom hostname and SSL certificate"}},"/docs/quick-start/infrastructure/terraform":{"title":"Terraform","data":{"":"The serverless-iiif GitHub repository includes a that can be used as a drop-in component in any\nTerraform manifest. Please refer to the documentation and examples below, as well as the Terraform documentation\nfor more information on how you might use these tools to deploy your own custom stack to AWS.","required-inputs#Required Inputs":"These variables must be set in the module block when using this module.","optional-inputs#Optional Inputs":"These variables have default values and don't have to be set to use this module. You may set these variables to override their default\nvalues.","minimal-example#Minimal Example":"module \"serverless_iiif\" {\nsource = \"github.com/samvera/serverless-iiif//extras/terraform\"\n\nsource_bucket = \"iiif-images\"\nstack_name = \"my-iiif-service\"\n}","almost-full-example#(Almost) Full Example":"module \"serverless_iiif\" {\nsource = \"github.com/samvera/serverless-iiif//extras/terraform\"\n\nsource_bucket = \"iiif-images\"\nstack_name = \"my-iiif-service\"\ncors_allow_credentials = true\ncors_allow_headers = \"X-Custom-Header,Upgrade-Insecure-Requests\"\ncors_allow_origin = \"REFLECT_ORIGIN\"\ncors_expose_headers = \"Content-Encoding\"\ncors_max_age = 600\nforce_host = \"iiif.my-domain.edu\"\niiif_lambda_memory = 2048\niiif_lambda_timeout = 120\npixel_density = 600\npreflight = true\nresolver_template = \"iiif/%s.tif\"\n\ntags = {\nProject = \"my-image-service\"\n}\n}"}}} \ No newline at end of file diff --git a/_next/static/chunks/pages/docs/advanced-usage/request-response-functions-83039ab58ea7145b.js b/_next/static/chunks/pages/docs/advanced-usage/request-response-functions-e138ebc00c0d846c.js similarity index 85% rename from _next/static/chunks/pages/docs/advanced-usage/request-response-functions-83039ab58ea7145b.js rename to _next/static/chunks/pages/docs/advanced-usage/request-response-functions-e138ebc00c0d846c.js index bf5641e..2c34181 100644 --- a/_next/static/chunks/pages/docs/advanced-usage/request-response-functions-83039ab58ea7145b.js +++ b/_next/static/chunks/pages/docs/advanced-usage/request-response-functions-e138ebc00c0d846c.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[945],{2829:function(e,s,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/docs/advanced-usage/request-response-functions",function(){return t(5914)}])},2093:function(e,s,t){"use strict";t.d(s,{Z:function(){return o}});var i=t(5893),n=t(6465),a=t.n(n),r=t(1163),o={footer:{text:(0,i.jsxs)("span",{children:["MIT ",new Date().getFullYear()," \xa9 ",(0,i.jsx)("a",{href:"#",children:"Serverless IIIF"}),"."]})},head:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("meta",{property:"og:title",content:"Serverless IIIF"}),(0,i.jsx)("meta",{property:"og:description",content:"Serve images via IIIF"}),(0,i.jsx)("link",{rel:"shortcut icon",type:"image/png",href:"/favicon.png"})]}),logo:(0,i.jsx)(function(){return(0,i.jsxs)("span",{className:"jsx-6558685ef54f338d",children:[(0,i.jsxs)("svg",{id:"serverless-iiif-logo",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 635.01 75.82",className:"jsx-6558685ef54f338d",children:[(0,i.jsx)("path",{fill:"currentColor",d:"m23.41,61.94c4.03,0,6.92-.73,8.68-2.18,1.75-1.46,2.63-3.19,2.63-5.21,0-1.87-.69-3.38-2.07-4.54-1.38-1.16-3.42-2.15-6.1-2.97l-5.94-1.9c-4.03-1.34-7.6-2.84-10.7-4.48-3.1-1.64-5.49-3.77-7.17-6.38C1.06,31.66.22,28.34.22,24.3c0-6.2,2.35-11.12,7.06-14.78,4.7-3.66,11.24-5.49,19.6-5.49,4.26,0,8.04.41,11.37,1.23,3.32.82,5.94,2.04,7.84,3.64,1.9,1.61,2.86,3.57,2.86,5.88,0,1.72-.39,3.19-1.18,4.42s-1.77,2.3-2.97,3.19c-1.72-1.19-4-2.22-6.83-3.08-2.84-.86-5.97-1.29-9.41-1.29s-6.27.58-8.06,1.74c-1.79,1.16-2.69,2.67-2.69,4.54,0,1.49.6,2.71,1.79,3.64,1.19.93,2.99,1.77,5.38,2.52l6.16,1.9c6.79,2.09,12.02,4.87,15.68,8.34,3.66,3.47,5.49,8.12,5.49,13.94,0,6.27-2.43,11.37-7.28,15.29-4.85,3.92-11.87,5.88-21.06,5.88-4.56,0-8.62-.49-12.21-1.46-3.58-.97-6.44-2.39-8.57-4.26-2.13-1.87-3.19-4.03-3.19-6.5,0-1.94.58-3.6,1.74-4.98,1.16-1.38,2.44-2.41,3.86-3.08,2.02,1.64,4.54,3.12,7.56,4.42,3.02,1.31,6.44,1.96,10.25,1.96Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m66.98,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.63-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.64,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m133.17,34.61v14h-16.58v-16.02c0-2.09.5-3.86,1.51-5.32,1.01-1.46,2.41-2.74,4.2-3.86,2.46-1.49,5.43-2.67,8.9-3.53,3.47-.86,7.11-1.29,10.92-1.29,7.62,0,11.42,2.54,11.42,7.62,0,1.2-.17,2.31-.5,3.36-.34,1.05-.73,1.94-1.18,2.69-.75-.15-1.66-.28-2.74-.39-1.08-.11-2.26-.17-3.53-.17-2.24,0-4.48.26-6.72.78-2.24.52-4.14,1.23-5.71,2.13Zm-16.58,9.74l16.58.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.43-.56-6.89-1.68s-2.18-3.14-2.18-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m200.59,19.04c2.31,0,4.24.5,5.77,1.51,1.53,1.01,2.3,2.71,2.3,5.1,0,1.34-.37,3.44-1.12,6.27-.75,2.84-1.74,6.12-2.97,9.86-1.23,3.73-2.6,7.54-4.09,11.42-1.49,3.88-2.99,7.52-4.48,10.92-1.49,3.4-2.84,6.22-4.03,8.46-.82.6-2.13,1.14-3.92,1.62-1.79.48-3.77.73-5.94.73-2.54,0-4.72-.34-6.55-1.01-1.83-.67-3.12-1.72-3.86-3.14-.82-1.57-1.83-3.77-3.02-6.61-1.2-2.84-2.46-6.07-3.81-9.69-1.34-3.62-2.69-7.37-4.03-11.26-1.34-3.88-2.58-7.62-3.7-11.2-1.12-3.58-2.02-6.72-2.69-9.41.97-.97,2.22-1.81,3.75-2.52,1.53-.71,3.19-1.06,4.98-1.06,2.31,0,4.22.49,5.71,1.46,1.49.97,2.58,2.8,3.25,5.49l5.04,17.81c.6,2.09,1.21,4.18,1.85,6.27.63,2.09,1.21,4.03,1.74,5.82.52,1.79.97,3.32,1.34,4.59h.45c1.79-6.05,3.6-12.52,5.43-19.43,1.83-6.91,3.45-13.64,4.87-20.22,2.24-1.19,4.82-1.79,7.73-1.79Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m222.54,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.63-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.64,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m288.73,34.61v14h-16.58v-16.02c0-2.09.5-3.86,1.51-5.32,1.01-1.46,2.41-2.74,4.2-3.86,2.46-1.49,5.43-2.67,8.9-3.53,3.47-.86,7.11-1.29,10.92-1.29,7.62,0,11.42,2.54,11.42,7.62,0,1.2-.17,2.31-.5,3.36-.34,1.05-.73,1.94-1.18,2.69-.75-.15-1.66-.28-2.74-.39-1.08-.11-2.26-.17-3.53-.17-2.24,0-4.48.26-6.72.78-2.24.52-4.14,1.23-5.71,2.13Zm-16.58,9.74l16.58.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.43-.56-6.89-1.68s-2.18-3.14-2.18-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m331.29,53.31l-16.69-.34V1.01c.75-.22,1.79-.45,3.14-.67,1.34-.22,2.8-.34,4.37-.34,3.21,0,5.54.56,7,1.68,1.46,1.12,2.18,3.17,2.18,6.16v45.47Zm-16.69-8.96l16.69.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.45-.56-6.94-1.68-1.49-1.12-2.24-3.14-2.24-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m349.21,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.62-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.63,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m442.39,58.24c0,5.45-2.05,9.73-6.16,12.82-4.11,3.1-10.08,4.65-17.92,4.65-6.12,0-11.16-.9-15.12-2.69-3.96-1.79-5.94-4.44-5.94-7.95,0-1.57.34-2.93,1.01-4.09.67-1.16,1.53-2.07,2.58-2.74,2.09,1.2,4.54,2.3,7.34,3.3,2.8,1.01,5.99,1.51,9.58,1.51,5.45,0,8.18-1.57,8.18-4.7,0-1.34-.49-2.41-1.46-3.19-.97-.78-2.58-1.36-4.82-1.74l-4.7-1.12c-5.97-1.27-10.44-3.23-13.38-5.88-2.95-2.65-4.42-6.29-4.42-10.92,0-5.23,2.11-9.39,6.33-12.49,4.22-3.1,9.91-4.65,17.08-4.65,3.58,0,6.85.35,9.8,1.06,2.95.71,5.28,1.79,7,3.25,1.72,1.46,2.58,3.27,2.58,5.43,0,1.49-.3,2.8-.9,3.92-.6,1.12-1.38,2.05-2.35,2.8-.82-.52-2.07-1.08-3.75-1.68-1.68-.6-3.51-1.08-5.49-1.46-1.98-.37-3.83-.56-5.54-.56-2.69,0-4.78.36-6.27,1.06-1.49.71-2.24,1.81-2.24,3.3,0,.97.43,1.81,1.29,2.52.86.71,2.37,1.29,4.54,1.74l4.48,1.12c6.64,1.49,11.42,3.64,14.34,6.44,2.91,2.8,4.37,6.44,4.37,10.92Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m493.35,58.1c0,5.5-2.07,9.81-6.21,12.94-4.14,3.12-10.17,4.69-18.08,4.69-6.18,0-11.26-.9-15.25-2.71-3.99-1.81-5.99-4.48-5.99-8.02,0-1.58.34-2.96,1.02-4.12.68-1.17,1.54-2.09,2.6-2.77,2.11,1.21,4.58,2.32,7.4,3.33,2.83,1.02,6.05,1.53,9.66,1.53,5.5,0,8.25-1.58,8.25-4.75,0-1.36-.49-2.43-1.47-3.22-.98-.79-2.6-1.37-4.86-1.75l-4.75-1.13c-6.03-1.28-10.53-3.26-13.5-5.93-2.98-2.67-4.46-6.35-4.46-11.02,0-5.27,2.13-9.47,6.38-12.6,4.26-3.13,10-4.69,17.23-4.69,3.62,0,6.91.36,9.89,1.07,2.98.72,5.33,1.81,7.06,3.28,1.73,1.47,2.6,3.3,2.6,5.48,0,1.51-.3,2.82-.9,3.95-.6,1.13-1.39,2.07-2.37,2.83-.83-.53-2.09-1.09-3.79-1.69-1.7-.6-3.54-1.09-5.54-1.47-2-.38-3.86-.56-5.59-.56-2.71,0-4.82.36-6.33,1.07-1.51.72-2.26,1.83-2.26,3.33,0,.98.43,1.83,1.3,2.54.86.72,2.39,1.3,4.58,1.75l4.52,1.13c6.7,1.51,11.53,3.67,14.46,6.5,2.94,2.82,4.41,6.5,4.41,11.02Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m523.12,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m549.11,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m575.09,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m600.96,46.37l-9.07-.11V10.75c0-1.49.45-2.69,1.34-3.58.9-.9,2.09-1.34,3.58-1.34.82,0,1.64.11,2.46.34.82.22,1.38.41,1.68.56v39.65Zm-9.07-12.32h9.18v39.76c-.38.08-.95.2-1.74.39-.78.19-1.59.28-2.41.28-1.64,0-2.89-.34-3.75-1.01-.86-.67-1.29-1.68-1.29-3.02v-36.4Zm4.93-20.5v-7.73h37.18c.22.3.45.78.67,1.46.22.67.34,1.38.34,2.13,0,1.2-.3,2.18-.9,2.97-.6.78-1.46,1.18-2.58,1.18h-34.72Zm0,31.02v-7.73h33.26c.22.37.45.88.67,1.51.22.64.34,1.33.34,2.07,0,1.19-.3,2.18-.9,2.97-.6.78-1.46,1.18-2.58,1.18h-30.8Z",className:"jsx-6558685ef54f338d"})]}),(0,i.jsx)(a(),{id:"6558685ef54f338d",children:"svg.jsx-6558685ef54f338d{height:1rem}span.jsx-6558685ef54f338d{padding:.5rem .5rem .5rem 0;-webkit-mask-image:-webkit-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-webkit-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-moz-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-o-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:linear-gradient(60deg,black 25%,rgba(0,0,0,.2)50%,black 75%);-webkit-mask-size:400%;mask-size:400%;-webkit-mask-position:0%;mask-position:0%}span.jsx-6558685ef54f338d:hover{-webkit-mask-position:100%;mask-position:100%;-webkit-transition:mask-position 1s ease,-webkit-mask-position 1s ease;-moz-transition:mask-position 1s ease,-webkit-mask-position 1s ease;-o-transition:mask-position 1s ease,-webkit-mask-position 1s ease;transition:mask-position 1s ease,-webkit-mask-position 1s ease}"})]})},{}),primaryHue:209,project:{link:"https://github.com/samvera/serverless-iiif"},sidebar:{autoCollapse:!0,defaultMenuCollapseLevel:1},useNextSeoProps(){let{asPath:e}=(0,r.useRouter)();if("/"!==e)return{titleTemplate:"%s – Serverless IIIF"}}}},5914:function(e,s,t){"use strict";t.r(s);var i=t(5893),n=t(6997),a=t(7370),r=t(2093);t(9966);var o=t(1151);t(5675);var l=t(9013);let c={MDXContent:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,o.ah)(),e.components);return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)},pageOpts:{filePath:"pages/docs/advanced-usage/request-response-functions.mdx",route:"/docs/advanced-usage/request-response-functions",headings:[{depth:3,value:"Request/Response Functions",id:"requestresponse-functions"},{depth:4,value:"Examples",id:"examples"},{depth:5,value:"Simple Authorization",id:"simple-authorization"},{depth:5,value:"Custom File Location / Image Dimensions",id:"custom-file-location--image-dimensions"}],pageMap:[{kind:"Meta",data:{index:{type:"page",title:"Serverless IIIF",display:"hidden",theme:{layout:"raw"}},docs:{type:"page",title:"Documentation"},about:{type:"page",title:"About",theme:{typesetting:"article"}},contact:{title:"IIIF Image API ↗",type:"page",href:"https://iiif.io/api/image/2.1/",newWindow:!0}}},{kind:"MdxPage",name:"about",route:"/about"},{kind:"Folder",name:"docs",route:"/docs",children:[{kind:"Meta",data:{index:"Introduction","quick-start":"Quick Start","source-images":"Source Images","custom-sharp-layer":"Custom Sharp Layer","advanced-usage":"Advanced Usage",testing:"Testing",notes:"Notes","-- Contributing":{type:"separator",title:"Contributing"},"how-to-contribute":"Guide",contributors:"Contributors",communities:"Communities"}},{kind:"Folder",name:"advanced-usage",route:"/docs/advanced-usage",children:[{kind:"Meta",data:{cors:"Cross-Origin Request Sharing (CORS)","request-response-functions":"Request Response Functions"}},{kind:"MdxPage",name:"cors",route:"/docs/advanced-usage/cors"},{kind:"MdxPage",name:"request-response-functions",route:"/docs/advanced-usage/request-response-functions"}]},{kind:"Folder",name:"communities",route:"/docs/communities",children:[{kind:"MdxPage",name:"iiif",route:"/docs/communities/iiif"},{kind:"MdxPage",name:"samvera",route:"/docs/communities/samvera"},{kind:"Meta",data:{iiif:"Iiif",samvera:"Samvera"}}]},{kind:"MdxPage",name:"contributors",route:"/docs/contributors"},{kind:"MdxPage",name:"custom-sharp-layer",route:"/docs/custom-sharp-layer"},{kind:"MdxPage",name:"how-to-contribute",route:"/docs/how-to-contribute"},{kind:"MdxPage",name:"index",route:"/docs"},{kind:"MdxPage",name:"notes",route:"/docs/notes"},{kind:"Folder",name:"quick-start",route:"/docs/quick-start",children:[{kind:"Meta",data:{index:"Options","deployment-sam":"Deploying via the AWS Serverless Application Repository","deployment-command-line":"Deploying via the Command Line",infrastructure:"Deploying via Infrastructure Tools","deleting-the-app":"Deleting the App"}},{kind:"MdxPage",name:"deleting-the-app",route:"/docs/quick-start/deleting-the-app"},{kind:"MdxPage",name:"deployment-command-line",route:"/docs/quick-start/deployment-command-line"},{kind:"MdxPage",name:"deployment-sam",route:"/docs/quick-start/deployment-sam"},{kind:"MdxPage",name:"index",route:"/docs/quick-start"},{kind:"Folder",name:"infrastructure",route:"/docs/quick-start/infrastructure",children:[{kind:"Meta",data:{index:"Introduction",cloudformation:"AWS CloudFormation",terraform:"Terraform"}},{kind:"MdxPage",name:"cloudformation",route:"/docs/quick-start/infrastructure/cloudformation"},{kind:"MdxPage",name:"index",route:"/docs/quick-start/infrastructure"},{kind:"MdxPage",name:"terraform",route:"/docs/quick-start/infrastructure/terraform"}]}]},{kind:"MdxPage",name:"source-images",route:"/docs/source-images"},{kind:"MdxPage",name:"testing",route:"/docs/testing"}]},{kind:"MdxPage",name:"index",route:"/",frontMatter:{title:"Serverless IIIF – Serve images via IIIF"}}],flexsearch:{codeblocks:!0},title:"Request Response Functions"},pageNextRoute:"/docs/advanced-usage/request-response-functions",nextraLayout:a.ZP,themeConfig:r.Z};function d(e){let s=Object.assign({h3:"h3",p:"p",a:"a",ul:"ul",li:"li",code:"code",em:"em",h4:"h4",h5:"h5",pre:"pre",span:"span"},(0,o.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h3,{id:"requestresponse-functions",children:"Request/Response Functions"}),"\n",(0,i.jsxs)(s.p,{children:["The IIIF service can be heavily customized through the use of ",(0,i.jsx)(s.a,{href:"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html",children:"CloudFront Functions"})," or ",(0,i.jsx)(s.a,{href:"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html",children:"Lambda@Edge Functions"})," 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."]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["A ",(0,i.jsx)(s.code,{children:"viewer-request"})," function will be called on every request, cached or not. This is the appropriate place to attach\na function that performs authorization, authentication, or anything else whose result should ",(0,i.jsx)(s.em,{children:"not"})," be cached."]}),"\n",(0,i.jsxs)(s.li,{children:["An ",(0,i.jsx)(s.code,{children:"origin-request"})," function will only be called when CloudFront refreshes the content from the origin (e.g., the IIIF server).\nIt's the appropriate place to attach a function that ",(0,i.jsx)(s.em,{children:"should"})," be cached, such as S3 file resolution or the retrieval of\nimage dimensions."]}),"\n",(0,i.jsxs)(s.li,{children:["Similarly, the ",(0,i.jsx)(s.code,{children:"origin-response"})," and ",(0,i.jsx)(s.code,{children:"viewer-response"})," functions are called after the IIIF server returns its response\nand before CloudFront passes it on to the viewer, respectively. They can be used to alter the response in a way that is\neither cached or ephemeral."]}),"\n"]}),"\n",(0,i.jsx)(s.h4,{id:"examples",children:"Examples"}),"\n",(0,i.jsx)(s.p,{children:"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."}),"\n",(0,i.jsx)(s.h5,{id:"simple-authorization",children:"Simple Authorization"}),"\n",(0,i.jsx)(s.pre,{"data-language":"JavaScript","data-theme":"default",children:(0,i.jsxs)(s.code,{"data-language":"JavaScript","data-theme":"default",children:[(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"function handler(event) {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" if (notAuthorized) { // based on something in the event.request"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" statusCode: 403,"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" statusDescription: 'Unauthorized'"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" };"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" };"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return event.request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,i.jsx)(s.h5,{id:"custom-file-location--image-dimensions",children:"Custom File Location / Image Dimensions"}),"\n",(0,i.jsx)(s.pre,{"data-language":"JavaScript","data-theme":"default",children:(0,i.jsxs)(s.code,{"data-language":"JavaScript","data-theme":"default",children:[(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"function handler(event) {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" var request = event.request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" request.headers['x-preflight-location'] = {value: 's3://image-bucket/path/to/correct/image.tif'};"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" request.headers['x-preflight-dimensions'] = {value: JSON.stringify({ width: 640, height: 480 })};"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"x-preflight-dimensions"})," header can take several shapes:"]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height }"})," (or ",(0,i.jsx)(s.code,{children:"[{ width, height }]"}),") - a straightforward, single-resolution image"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"[{ width, height }, { width, height }, ...]"})," - a multi-resolution image with pages of the specified sizes"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height, pages }"})," - a multi-resolution image with the specified number of ",(0,i.jsx)(s.code,{children:"pages"}),", each half the size of the one before"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height, limit }"})," - a multi-resolution image in which the smallest width and height are both less than the specified ",(0,i.jsx)(s.code,{children:"limit"})]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"For example, the following dimension values would all describe the same pyramidal image:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"[{ width: 2048, height: 1536 }, { width: 1024, height: 768 }, { width: 512, height: 384 }]"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"{ width: 2048, height: 1536, pages: 3 }"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"{ width: 2048, height: 1536, limit: 480 }"})}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"limit"})," calculator will keep going until both dimensions are ",(0,i.jsx)(s.em,{children:"less than"})," the limit, not ",(0,i.jsx)(s.em,{children:"less than or equal to"}),". So a ",(0,i.jsx)(s.code,{children:"limit: 512"})," on the third example above would generate a fourth page at ",(0,i.jsx)(s.code,{children:"{ width: 256, height: 192 }"}),"."]}),"\n",(0,i.jsx)(l.UW,{children:(0,i.jsxs)(s.p,{children:["If you plan to use CloudFront functions to add either of the above ",(0,i.jsx)(s.code,{children:"x-preflight-"})," headers to incoming requests, you ",(0,i.jsx)(s.em,{children:"must"})," set the value of the ",(0,i.jsx)(s.code,{children:"Preflight"})," parameter to ",(0,i.jsx)(s.code,{children:"true"})," when deploying ",(0,i.jsx)(s.code,{children:"serverless-iiif"}),". The function will ",(0,i.jsx)(s.em,{children:"only"})," look for the preflight headers if this environment variable is ",(0,i.jsx)(s.code,{children:"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 ",(0,i.jsx)(s.code,{children:"x-preflight-location"})," and ",(0,i.jsx)(s.code,{children:"x-preflight-dimensions"})," headers that it doesn't set itself."]})})]})}s.default=(0,n.j)(c)}},function(e){e.O(0,[774,797,888,179],function(){return e(e.s=2829)}),_N_E=e.O()}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[945],{2829:function(e,s,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/docs/advanced-usage/request-response-functions",function(){return t(5914)}])},2093:function(e,s,t){"use strict";t.d(s,{Z:function(){return o}});var i=t(5893),n=t(6465),a=t.n(n),r=t(1163),o={footer:{text:(0,i.jsxs)("span",{children:["MIT ",new Date().getFullYear()," \xa9 ",(0,i.jsx)("a",{href:"#",children:"Serverless IIIF"}),"."]})},head:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("meta",{property:"og:title",content:"Serverless IIIF"}),(0,i.jsx)("meta",{property:"og:description",content:"Serve images via IIIF"}),(0,i.jsx)("link",{rel:"shortcut icon",type:"image/png",href:"/favicon.png"})]}),logo:(0,i.jsx)(function(){return(0,i.jsxs)("span",{className:"jsx-6558685ef54f338d",children:[(0,i.jsxs)("svg",{id:"serverless-iiif-logo",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 635.01 75.82",className:"jsx-6558685ef54f338d",children:[(0,i.jsx)("path",{fill:"currentColor",d:"m23.41,61.94c4.03,0,6.92-.73,8.68-2.18,1.75-1.46,2.63-3.19,2.63-5.21,0-1.87-.69-3.38-2.07-4.54-1.38-1.16-3.42-2.15-6.1-2.97l-5.94-1.9c-4.03-1.34-7.6-2.84-10.7-4.48-3.1-1.64-5.49-3.77-7.17-6.38C1.06,31.66.22,28.34.22,24.3c0-6.2,2.35-11.12,7.06-14.78,4.7-3.66,11.24-5.49,19.6-5.49,4.26,0,8.04.41,11.37,1.23,3.32.82,5.94,2.04,7.84,3.64,1.9,1.61,2.86,3.57,2.86,5.88,0,1.72-.39,3.19-1.18,4.42s-1.77,2.3-2.97,3.19c-1.72-1.19-4-2.22-6.83-3.08-2.84-.86-5.97-1.29-9.41-1.29s-6.27.58-8.06,1.74c-1.79,1.16-2.69,2.67-2.69,4.54,0,1.49.6,2.71,1.79,3.64,1.19.93,2.99,1.77,5.38,2.52l6.16,1.9c6.79,2.09,12.02,4.87,15.68,8.34,3.66,3.47,5.49,8.12,5.49,13.94,0,6.27-2.43,11.37-7.28,15.29-4.85,3.92-11.87,5.88-21.06,5.88-4.56,0-8.62-.49-12.21-1.46-3.58-.97-6.44-2.39-8.57-4.26-2.13-1.87-3.19-4.03-3.19-6.5,0-1.94.58-3.6,1.74-4.98,1.16-1.38,2.44-2.41,3.86-3.08,2.02,1.64,4.54,3.12,7.56,4.42,3.02,1.31,6.44,1.96,10.25,1.96Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m66.98,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.63-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.64,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m133.17,34.61v14h-16.58v-16.02c0-2.09.5-3.86,1.51-5.32,1.01-1.46,2.41-2.74,4.2-3.86,2.46-1.49,5.43-2.67,8.9-3.53,3.47-.86,7.11-1.29,10.92-1.29,7.62,0,11.42,2.54,11.42,7.62,0,1.2-.17,2.31-.5,3.36-.34,1.05-.73,1.94-1.18,2.69-.75-.15-1.66-.28-2.74-.39-1.08-.11-2.26-.17-3.53-.17-2.24,0-4.48.26-6.72.78-2.24.52-4.14,1.23-5.71,2.13Zm-16.58,9.74l16.58.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.43-.56-6.89-1.68s-2.18-3.14-2.18-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m200.59,19.04c2.31,0,4.24.5,5.77,1.51,1.53,1.01,2.3,2.71,2.3,5.1,0,1.34-.37,3.44-1.12,6.27-.75,2.84-1.74,6.12-2.97,9.86-1.23,3.73-2.6,7.54-4.09,11.42-1.49,3.88-2.99,7.52-4.48,10.92-1.49,3.4-2.84,6.22-4.03,8.46-.82.6-2.13,1.14-3.92,1.62-1.79.48-3.77.73-5.94.73-2.54,0-4.72-.34-6.55-1.01-1.83-.67-3.12-1.72-3.86-3.14-.82-1.57-1.83-3.77-3.02-6.61-1.2-2.84-2.46-6.07-3.81-9.69-1.34-3.62-2.69-7.37-4.03-11.26-1.34-3.88-2.58-7.62-3.7-11.2-1.12-3.58-2.02-6.72-2.69-9.41.97-.97,2.22-1.81,3.75-2.52,1.53-.71,3.19-1.06,4.98-1.06,2.31,0,4.22.49,5.71,1.46,1.49.97,2.58,2.8,3.25,5.49l5.04,17.81c.6,2.09,1.21,4.18,1.85,6.27.63,2.09,1.21,4.03,1.74,5.82.52,1.79.97,3.32,1.34,4.59h.45c1.79-6.05,3.6-12.52,5.43-19.43,1.83-6.91,3.45-13.64,4.87-20.22,2.24-1.19,4.82-1.79,7.73-1.79Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m222.54,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.63-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.64,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m288.73,34.61v14h-16.58v-16.02c0-2.09.5-3.86,1.51-5.32,1.01-1.46,2.41-2.74,4.2-3.86,2.46-1.49,5.43-2.67,8.9-3.53,3.47-.86,7.11-1.29,10.92-1.29,7.62,0,11.42,2.54,11.42,7.62,0,1.2-.17,2.31-.5,3.36-.34,1.05-.73,1.94-1.18,2.69-.75-.15-1.66-.28-2.74-.39-1.08-.11-2.26-.17-3.53-.17-2.24,0-4.48.26-6.72.78-2.24.52-4.14,1.23-5.71,2.13Zm-16.58,9.74l16.58.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.43-.56-6.89-1.68s-2.18-3.14-2.18-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m331.29,53.31l-16.69-.34V1.01c.75-.22,1.79-.45,3.14-.67,1.34-.22,2.8-.34,4.37-.34,3.21,0,5.54.56,7,1.68,1.46,1.12,2.18,3.17,2.18,6.16v45.47Zm-16.69-8.96l16.69.34v29.12c-.75.22-1.79.43-3.14.62-1.34.19-2.8.28-4.37.28-3.14,0-5.45-.56-6.94-1.68-1.49-1.12-2.24-3.14-2.24-6.05v-22.62Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m349.21,54.88l-.67-11.2,27.78-4.37c-.15-2.09-1.05-4.03-2.69-5.82-1.64-1.79-4.07-2.69-7.28-2.69s-6.16,1.14-8.4,3.42c-2.24,2.28-3.44,5.51-3.58,9.69l.56,7.73c.67,4.11,2.43,7.04,5.26,8.79,2.84,1.76,6.2,2.63,10.08,2.63,3.14,0,6.08-.45,8.85-1.34,2.76-.9,5-1.83,6.72-2.8,1.12.67,2.03,1.61,2.74,2.8.71,1.2,1.06,2.46,1.06,3.81,0,2.24-.88,4.11-2.63,5.6-1.76,1.49-4.18,2.61-7.28,3.36-3.1.75-6.63,1.12-10.58,1.12-5.75,0-10.92-1.08-15.51-3.25-4.59-2.17-8.2-5.41-10.81-9.74-2.61-4.33-3.92-9.74-3.92-16.24,0-4.78.76-8.92,2.3-12.43,1.53-3.51,3.58-6.4,6.16-8.68,2.58-2.28,5.49-3.98,8.74-5.1,3.25-1.12,6.62-1.68,10.14-1.68,5.15,0,9.65,1.03,13.5,3.08,3.84,2.05,6.85,4.83,9.02,8.34,2.17,3.51,3.25,7.58,3.25,12.21,0,2.32-.63,4.07-1.9,5.26-1.27,1.2-3.02,1.94-5.26,2.24l-35.62,5.26Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m442.39,58.24c0,5.45-2.05,9.73-6.16,12.82-4.11,3.1-10.08,4.65-17.92,4.65-6.12,0-11.16-.9-15.12-2.69-3.96-1.79-5.94-4.44-5.94-7.95,0-1.57.34-2.93,1.01-4.09.67-1.16,1.53-2.07,2.58-2.74,2.09,1.2,4.54,2.3,7.34,3.3,2.8,1.01,5.99,1.51,9.58,1.51,5.45,0,8.18-1.57,8.18-4.7,0-1.34-.49-2.41-1.46-3.19-.97-.78-2.58-1.36-4.82-1.74l-4.7-1.12c-5.97-1.27-10.44-3.23-13.38-5.88-2.95-2.65-4.42-6.29-4.42-10.92,0-5.23,2.11-9.39,6.33-12.49,4.22-3.1,9.91-4.65,17.08-4.65,3.58,0,6.85.35,9.8,1.06,2.95.71,5.28,1.79,7,3.25,1.72,1.46,2.58,3.27,2.58,5.43,0,1.49-.3,2.8-.9,3.92-.6,1.12-1.38,2.05-2.35,2.8-.82-.52-2.07-1.08-3.75-1.68-1.68-.6-3.51-1.08-5.49-1.46-1.98-.37-3.83-.56-5.54-.56-2.69,0-4.78.36-6.27,1.06-1.49.71-2.24,1.81-2.24,3.3,0,.97.43,1.81,1.29,2.52.86.71,2.37,1.29,4.54,1.74l4.48,1.12c6.64,1.49,11.42,3.64,14.34,6.44,2.91,2.8,4.37,6.44,4.37,10.92Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m493.35,58.1c0,5.5-2.07,9.81-6.21,12.94-4.14,3.12-10.17,4.69-18.08,4.69-6.18,0-11.26-.9-15.25-2.71-3.99-1.81-5.99-4.48-5.99-8.02,0-1.58.34-2.96,1.02-4.12.68-1.17,1.54-2.09,2.6-2.77,2.11,1.21,4.58,2.32,7.4,3.33,2.83,1.02,6.05,1.53,9.66,1.53,5.5,0,8.25-1.58,8.25-4.75,0-1.36-.49-2.43-1.47-3.22-.98-.79-2.6-1.37-4.86-1.75l-4.75-1.13c-6.03-1.28-10.53-3.26-13.5-5.93-2.98-2.67-4.46-6.35-4.46-11.02,0-5.27,2.13-9.47,6.38-12.6,4.26-3.13,10-4.69,17.23-4.69,3.62,0,6.91.36,9.89,1.07,2.98.72,5.33,1.81,7.06,3.28,1.73,1.47,2.6,3.3,2.6,5.48,0,1.51-.3,2.82-.9,3.95-.6,1.13-1.39,2.07-2.37,2.83-.83-.53-2.09-1.09-3.79-1.69-1.7-.6-3.54-1.09-5.54-1.47-2-.38-3.86-.56-5.59-.56-2.71,0-4.82.36-6.33,1.07-1.51.72-2.26,1.83-2.26,3.33,0,.98.43,1.83,1.3,2.54.86.72,2.39,1.3,4.58,1.75l4.52,1.13c6.7,1.51,11.53,3.67,14.46,6.5,2.94,2.82,4.41,6.5,4.41,11.02Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m523.12,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m549.11,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m575.09,40.77h-9.07V6.05c.37-.15.95-.32,1.74-.5.78-.19,1.62-.28,2.52-.28,1.64,0,2.86.32,3.64.95.78.64,1.18,1.7,1.18,3.19v31.36Zm-9.07-7.5h9.07v40.43c-.38.15-.93.32-1.68.5-.75.19-1.57.28-2.46.28-1.64,0-2.88-.34-3.7-1.01-.82-.67-1.23-1.72-1.23-3.14v-37.07Z",className:"jsx-6558685ef54f338d"}),(0,i.jsx)("path",{fill:"currentColor",d:"m600.96,46.37l-9.07-.11V10.75c0-1.49.45-2.69,1.34-3.58.9-.9,2.09-1.34,3.58-1.34.82,0,1.64.11,2.46.34.82.22,1.38.41,1.68.56v39.65Zm-9.07-12.32h9.18v39.76c-.38.08-.95.2-1.74.39-.78.19-1.59.28-2.41.28-1.64,0-2.89-.34-3.75-1.01-.86-.67-1.29-1.68-1.29-3.02v-36.4Zm4.93-20.5v-7.73h37.18c.22.3.45.78.67,1.46.22.67.34,1.38.34,2.13,0,1.2-.3,2.18-.9,2.97-.6.78-1.46,1.18-2.58,1.18h-34.72Zm0,31.02v-7.73h33.26c.22.37.45.88.67,1.51.22.64.34,1.33.34,2.07,0,1.19-.3,2.18-.9,2.97-.6.78-1.46,1.18-2.58,1.18h-30.8Z",className:"jsx-6558685ef54f338d"})]}),(0,i.jsx)(a(),{id:"6558685ef54f338d",children:"svg.jsx-6558685ef54f338d{height:1rem}span.jsx-6558685ef54f338d{padding:.5rem .5rem .5rem 0;-webkit-mask-image:-webkit-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-webkit-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-moz-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:-o-linear-gradient(30deg,black 25%,rgba(0,0,0,.2)50%,black 75%);mask-image:linear-gradient(60deg,black 25%,rgba(0,0,0,.2)50%,black 75%);-webkit-mask-size:400%;mask-size:400%;-webkit-mask-position:0%;mask-position:0%}span.jsx-6558685ef54f338d:hover{-webkit-mask-position:100%;mask-position:100%;-webkit-transition:mask-position 1s ease,-webkit-mask-position 1s ease;-moz-transition:mask-position 1s ease,-webkit-mask-position 1s ease;-o-transition:mask-position 1s ease,-webkit-mask-position 1s ease;transition:mask-position 1s ease,-webkit-mask-position 1s ease}"})]})},{}),primaryHue:209,project:{link:"https://github.com/samvera/serverless-iiif"},sidebar:{autoCollapse:!0,defaultMenuCollapseLevel:1},useNextSeoProps(){let{asPath:e}=(0,r.useRouter)();if("/"!==e)return{titleTemplate:"%s – Serverless IIIF"}}}},5914:function(e,s,t){"use strict";t.r(s);var i=t(5893),n=t(6997),a=t(7370),r=t(2093);t(9966);var o=t(1151);t(5675);var l=t(9013);let c={MDXContent:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,o.ah)(),e.components);return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)},pageOpts:{filePath:"pages/docs/advanced-usage/request-response-functions.mdx",route:"/docs/advanced-usage/request-response-functions",headings:[{depth:3,value:"Request/Response Functions",id:"requestresponse-functions"},{depth:4,value:"Examples",id:"examples"},{depth:5,value:"Simple Authorization",id:"simple-authorization"},{depth:5,value:"Custom File Location / Image Dimensions",id:"custom-file-location--image-dimensions"}],pageMap:[{kind:"Meta",data:{index:{type:"page",title:"Serverless IIIF",display:"hidden",theme:{layout:"raw"}},docs:{type:"page",title:"Documentation"},about:{type:"page",title:"About",theme:{typesetting:"article"}},contact:{title:"IIIF Image API ↗",type:"page",href:"https://iiif.io/api/image/2.1/",newWindow:!0}}},{kind:"MdxPage",name:"about",route:"/about"},{kind:"Folder",name:"docs",route:"/docs",children:[{kind:"Meta",data:{index:"Introduction","quick-start":"Quick Start","source-images":"Source Images","custom-sharp-layer":"Custom Sharp Layer","advanced-usage":"Advanced Usage",testing:"Testing",notes:"Notes","-- Contributing":{type:"separator",title:"Contributing"},"how-to-contribute":"Guide",contributors:"Contributors",communities:"Communities"}},{kind:"Folder",name:"advanced-usage",route:"/docs/advanced-usage",children:[{kind:"Meta",data:{cors:"Cross-Origin Request Sharing (CORS)","request-response-functions":"Request Response Functions"}},{kind:"MdxPage",name:"cors",route:"/docs/advanced-usage/cors"},{kind:"MdxPage",name:"request-response-functions",route:"/docs/advanced-usage/request-response-functions"}]},{kind:"Folder",name:"communities",route:"/docs/communities",children:[{kind:"MdxPage",name:"iiif",route:"/docs/communities/iiif"},{kind:"MdxPage",name:"samvera",route:"/docs/communities/samvera"},{kind:"Meta",data:{iiif:"Iiif",samvera:"Samvera"}}]},{kind:"MdxPage",name:"contributors",route:"/docs/contributors"},{kind:"MdxPage",name:"custom-sharp-layer",route:"/docs/custom-sharp-layer"},{kind:"MdxPage",name:"how-to-contribute",route:"/docs/how-to-contribute"},{kind:"MdxPage",name:"index",route:"/docs"},{kind:"MdxPage",name:"notes",route:"/docs/notes"},{kind:"Folder",name:"quick-start",route:"/docs/quick-start",children:[{kind:"Meta",data:{index:"Options","deployment-sam":"Deploying via the AWS Serverless Application Repository","deployment-command-line":"Deploying via the Command Line",infrastructure:"Deploying via Infrastructure Tools","deleting-the-app":"Deleting the App"}},{kind:"MdxPage",name:"deleting-the-app",route:"/docs/quick-start/deleting-the-app"},{kind:"MdxPage",name:"deployment-command-line",route:"/docs/quick-start/deployment-command-line"},{kind:"MdxPage",name:"deployment-sam",route:"/docs/quick-start/deployment-sam"},{kind:"MdxPage",name:"index",route:"/docs/quick-start"},{kind:"Folder",name:"infrastructure",route:"/docs/quick-start/infrastructure",children:[{kind:"Meta",data:{index:"Introduction",cloudformation:"AWS CloudFormation",terraform:"Terraform"}},{kind:"MdxPage",name:"cloudformation",route:"/docs/quick-start/infrastructure/cloudformation"},{kind:"MdxPage",name:"index",route:"/docs/quick-start/infrastructure"},{kind:"MdxPage",name:"terraform",route:"/docs/quick-start/infrastructure/terraform"}]}]},{kind:"MdxPage",name:"source-images",route:"/docs/source-images"},{kind:"MdxPage",name:"testing",route:"/docs/testing"}]},{kind:"MdxPage",name:"index",route:"/",frontMatter:{title:"Serverless IIIF – Serve images via IIIF"}}],flexsearch:{codeblocks:!0},title:"Request Response Functions"},pageNextRoute:"/docs/advanced-usage/request-response-functions",nextraLayout:a.ZP,themeConfig:r.Z};function d(e){let s=Object.assign({h3:"h3",p:"p",a:"a",ul:"ul",li:"li",code:"code",em:"em",h4:"h4",h5:"h5",pre:"pre",span:"span"},(0,o.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h3,{id:"requestresponse-functions",children:"Request/Response Functions"}),"\n",(0,i.jsxs)(s.p,{children:["The IIIF service can be heavily customized through the use of ",(0,i.jsx)(s.a,{href:"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html",children:"CloudFront Functions"})," or ",(0,i.jsx)(s.a,{href:"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html",children:"Lambda@Edge Functions"})," 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."]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["A ",(0,i.jsx)(s.code,{children:"viewer-request"})," function will be called on every request, cached or not. This is the appropriate place to attach\na function that performs authorization, authentication, or anything else whose result should ",(0,i.jsx)(s.em,{children:"not"})," be cached."]}),"\n",(0,i.jsxs)(s.li,{children:["An ",(0,i.jsx)(s.code,{children:"origin-request"})," function will only be called when CloudFront refreshes the content from the origin (e.g., the IIIF server).\nIt's the appropriate place to attach a function that ",(0,i.jsx)(s.em,{children:"should"})," be cached, such as S3 file resolution or the retrieval of\nimage dimensions."]}),"\n",(0,i.jsxs)(s.li,{children:["Similarly, the ",(0,i.jsx)(s.code,{children:"origin-response"})," and ",(0,i.jsx)(s.code,{children:"viewer-response"})," functions are called after the IIIF server returns its response\nand before CloudFront passes it on to the viewer, respectively. They can be used to alter the response in a way that is\neither cached or ephemeral."]}),"\n"]}),"\n",(0,i.jsx)(s.h4,{id:"examples",children:"Examples"}),"\n",(0,i.jsx)(s.p,{children:"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."}),"\n",(0,i.jsx)(s.h5,{id:"simple-authorization",children:"Simple Authorization"}),"\n",(0,i.jsx)(s.pre,{"data-language":"JavaScript","data-theme":"default",children:(0,i.jsxs)(s.code,{"data-language":"JavaScript","data-theme":"default",children:[(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"function handler(event) {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" if (notAuthorized) { // based on something in the event.request"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" statusCode: 403,"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" statusDescription: 'Unauthorized'"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" };"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" };"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return event.request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,i.jsx)(s.h5,{id:"custom-file-location--image-dimensions",children:"Custom File Location / Image Dimensions"}),"\n",(0,i.jsx)(s.pre,{"data-language":"JavaScript","data-theme":"default",children:(0,i.jsxs)(s.code,{"data-language":"JavaScript","data-theme":"default",children:[(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"function handler(event) {"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" var request = event.request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" request.headers['x-preflight-location'] = [{value: 's3://image-bucket/path/to/correct/image.tif'}];"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" request.headers['x-preflight-dimensions'] = [{value: JSON.stringify({ width: 640, height: 480 })}];"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" return request;"})}),"\n",(0,i.jsx)(s.span,{className:"line",children:(0,i.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"x-preflight-dimensions"})," header can take several shapes:"]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height }"})," (or ",(0,i.jsx)(s.code,{children:"[{ width, height }]"}),") - a straightforward, single-resolution image"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"[{ width, height }, { width, height }, ...]"})," - a multi-resolution image with pages of the specified sizes"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height, pages }"})," - a multi-resolution image with the specified number of ",(0,i.jsx)(s.code,{children:"pages"}),", each half the size of the one before"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"{ width, height, limit }"})," - a multi-resolution image in which the smallest width and height are both less than the specified ",(0,i.jsx)(s.code,{children:"limit"})]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"For example, the following dimension values would all describe the same pyramidal image:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"[{ width: 2048, height: 1536 }, { width: 1024, height: 768 }, { width: 512, height: 384 }]"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"{ width: 2048, height: 1536, pages: 3 }"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"{ width: 2048, height: 1536, limit: 480 }"})}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"limit"})," calculator will keep going until both dimensions are ",(0,i.jsx)(s.em,{children:"less than"})," the limit, not ",(0,i.jsx)(s.em,{children:"less than or equal to"}),". So a ",(0,i.jsx)(s.code,{children:"limit: 512"})," on the third example above would generate a fourth page at ",(0,i.jsx)(s.code,{children:"{ width: 256, height: 192 }"}),"."]}),"\n",(0,i.jsx)(l.UW,{children:(0,i.jsxs)(s.p,{children:["If you plan to use CloudFront functions to add either of the above ",(0,i.jsx)(s.code,{children:"x-preflight-"})," headers to incoming requests, you ",(0,i.jsx)(s.em,{children:"must"})," set the value of the ",(0,i.jsx)(s.code,{children:"Preflight"})," parameter to ",(0,i.jsx)(s.code,{children:"true"})," when deploying ",(0,i.jsx)(s.code,{children:"serverless-iiif"}),". The function will ",(0,i.jsx)(s.em,{children:"only"})," look for the preflight headers if this environment variable is ",(0,i.jsx)(s.code,{children:"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 ",(0,i.jsx)(s.code,{children:"x-preflight-location"})," and ",(0,i.jsx)(s.code,{children:"x-preflight-dimensions"})," headers that it doesn't set itself."]})})]})}s.default=(0,n.j)(c)}},function(e){e.O(0,[774,797,888,179],function(){return e(e.s=2829)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/_next/static/-eqUGH_PmTLhFrYiCLemy/_buildManifest.js b/_next/static/lGr0_SfWpPknc8cO6YpM_/_buildManifest.js similarity index 97% rename from _next/static/-eqUGH_PmTLhFrYiCLemy/_buildManifest.js rename to _next/static/lGr0_SfWpPknc8cO6YpM_/_buildManifest.js index 2ab9773..ee369da 100644 --- a/_next/static/-eqUGH_PmTLhFrYiCLemy/_buildManifest.js +++ b/_next/static/lGr0_SfWpPknc8cO6YpM_/_buildManifest.js @@ -1 +1 @@ -self.__BUILD_MANIFEST=function(s,c,t,a){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,c,"static/css/e0e7c22adcdbef21.css","static/chunks/pages/index-b062a586561c5988.js"],"/_error":["static/chunks/pages/_error-3986dd5834f581dc.js"],"/about":[s,c,"static/css/e7f1e959babc9570.css","static/chunks/pages/about-e662bd8f70c38c72.js"],"/docs":[s,c,"static/css/a328a878aafba2bc.css","static/chunks/pages/docs-46629c768c19fc59.js"],"/docs/advanced-usage/cors":[s,c,"static/chunks/pages/docs/advanced-usage/cors-a9faf9093272b15b.js"],"/docs/advanced-usage/request-response-functions":[s,c,"static/chunks/pages/docs/advanced-usage/request-response-functions-83039ab58ea7145b.js"],"/docs/communities/iiif":[s,c,"static/chunks/pages/docs/communities/iiif-c3927a1c9260d3b6.js"],"/docs/communities/samvera":[s,c,"static/chunks/pages/docs/communities/samvera-3161149847eedfd4.js"],"/docs/contributors":[s,c,"static/chunks/pages/docs/contributors-69d9377700444bd8.js"],"/docs/custom-sharp-layer":[s,c,"static/chunks/pages/docs/custom-sharp-layer-d361db2698530a51.js"],"/docs/how-to-contribute":[s,c,"static/chunks/pages/docs/how-to-contribute-2cebc410a768d885.js"],"/docs/notes":[s,c,"static/chunks/pages/docs/notes-264d5568aa5525ee.js"],"/docs/quick-start":[s,c,"static/chunks/pages/docs/quick-start-5012cae04aed3794.js"],"/docs/quick-start/deleting-the-app":[s,c,"static/chunks/pages/docs/quick-start/deleting-the-app-11ed476e975ee197.js"],"/docs/quick-start/deployment-command-line":[s,c,"static/chunks/pages/docs/quick-start/deployment-command-line-f74d9fd6127a5f28.js"],"/docs/quick-start/deployment-sam":[s,c,"static/chunks/pages/docs/quick-start/deployment-sam-6de0eb275bb2c58f.js"],"/docs/quick-start/infrastructure":[s,c,"static/chunks/pages/docs/quick-start/infrastructure-37ee25d6e5baed6a.js"],"/docs/quick-start/infrastructure/cloudformation":[s,c,t,a,"static/chunks/pages/docs/quick-start/infrastructure/cloudformation-a4993a2455d98be1.js"],"/docs/quick-start/infrastructure/terraform":[s,c,t,a,"static/chunks/pages/docs/quick-start/infrastructure/terraform-b4ca1a226e0b8ee4.js"],"/docs/source-images":[s,c,"static/chunks/pages/docs/source-images-72b43f64ab58c2f3.js"],"/docs/testing":[s,c,"static/chunks/pages/docs/testing-68cda51fcbcb1d9f.js"],sortedPages:["/","/_app","/_error","/about","/docs","/docs/advanced-usage/cors","/docs/advanced-usage/request-response-functions","/docs/communities/iiif","/docs/communities/samvera","/docs/contributors","/docs/custom-sharp-layer","/docs/how-to-contribute","/docs/notes","/docs/quick-start","/docs/quick-start/deleting-the-app","/docs/quick-start/deployment-command-line","/docs/quick-start/deployment-sam","/docs/quick-start/infrastructure","/docs/quick-start/infrastructure/cloudformation","/docs/quick-start/infrastructure/terraform","/docs/source-images","/docs/testing"]}}("static/css/75660a9d0f8e50cc.css","static/chunks/797-6c3e90f4c1329391.js","static/chunks/160-d5400c1a13bec5f8.js","static/css/2799bd547bb37cdf.css"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file +self.__BUILD_MANIFEST=function(s,c,t,a){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,c,"static/css/e0e7c22adcdbef21.css","static/chunks/pages/index-b062a586561c5988.js"],"/_error":["static/chunks/pages/_error-3986dd5834f581dc.js"],"/about":[s,c,"static/css/e7f1e959babc9570.css","static/chunks/pages/about-e662bd8f70c38c72.js"],"/docs":[s,c,"static/css/a328a878aafba2bc.css","static/chunks/pages/docs-46629c768c19fc59.js"],"/docs/advanced-usage/cors":[s,c,"static/chunks/pages/docs/advanced-usage/cors-a9faf9093272b15b.js"],"/docs/advanced-usage/request-response-functions":[s,c,"static/chunks/pages/docs/advanced-usage/request-response-functions-e138ebc00c0d846c.js"],"/docs/communities/iiif":[s,c,"static/chunks/pages/docs/communities/iiif-c3927a1c9260d3b6.js"],"/docs/communities/samvera":[s,c,"static/chunks/pages/docs/communities/samvera-3161149847eedfd4.js"],"/docs/contributors":[s,c,"static/chunks/pages/docs/contributors-69d9377700444bd8.js"],"/docs/custom-sharp-layer":[s,c,"static/chunks/pages/docs/custom-sharp-layer-d361db2698530a51.js"],"/docs/how-to-contribute":[s,c,"static/chunks/pages/docs/how-to-contribute-2cebc410a768d885.js"],"/docs/notes":[s,c,"static/chunks/pages/docs/notes-264d5568aa5525ee.js"],"/docs/quick-start":[s,c,"static/chunks/pages/docs/quick-start-5012cae04aed3794.js"],"/docs/quick-start/deleting-the-app":[s,c,"static/chunks/pages/docs/quick-start/deleting-the-app-11ed476e975ee197.js"],"/docs/quick-start/deployment-command-line":[s,c,"static/chunks/pages/docs/quick-start/deployment-command-line-f74d9fd6127a5f28.js"],"/docs/quick-start/deployment-sam":[s,c,"static/chunks/pages/docs/quick-start/deployment-sam-6de0eb275bb2c58f.js"],"/docs/quick-start/infrastructure":[s,c,"static/chunks/pages/docs/quick-start/infrastructure-37ee25d6e5baed6a.js"],"/docs/quick-start/infrastructure/cloudformation":[s,c,t,a,"static/chunks/pages/docs/quick-start/infrastructure/cloudformation-a4993a2455d98be1.js"],"/docs/quick-start/infrastructure/terraform":[s,c,t,a,"static/chunks/pages/docs/quick-start/infrastructure/terraform-b4ca1a226e0b8ee4.js"],"/docs/source-images":[s,c,"static/chunks/pages/docs/source-images-72b43f64ab58c2f3.js"],"/docs/testing":[s,c,"static/chunks/pages/docs/testing-68cda51fcbcb1d9f.js"],sortedPages:["/","/_app","/_error","/about","/docs","/docs/advanced-usage/cors","/docs/advanced-usage/request-response-functions","/docs/communities/iiif","/docs/communities/samvera","/docs/contributors","/docs/custom-sharp-layer","/docs/how-to-contribute","/docs/notes","/docs/quick-start","/docs/quick-start/deleting-the-app","/docs/quick-start/deployment-command-line","/docs/quick-start/deployment-sam","/docs/quick-start/infrastructure","/docs/quick-start/infrastructure/cloudformation","/docs/quick-start/infrastructure/terraform","/docs/source-images","/docs/testing"]}}("static/css/75660a9d0f8e50cc.css","static/chunks/797-6c3e90f4c1329391.js","static/chunks/160-d5400c1a13bec5f8.js","static/css/2799bd547bb37cdf.css"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/_next/static/-eqUGH_PmTLhFrYiCLemy/_ssgManifest.js b/_next/static/lGr0_SfWpPknc8cO6YpM_/_ssgManifest.js similarity index 100% rename from _next/static/-eqUGH_PmTLhFrYiCLemy/_ssgManifest.js rename to _next/static/lGr0_SfWpPknc8cO6YpM_/_ssgManifest.js diff --git a/about.html b/about.html index 78d35e1..552c733 100644 --- a/about.html +++ b/about.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -

About

+
\ No newline at end of file +

Serverless IIIF is available under the Apache 2.0 license.

\ No newline at end of file diff --git a/docs.html b/docs.html index c5b79c0..c549df9 100644 --- a/docs.html +++ b/docs.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Introduction

serverless-iiif

+

License

-

serverless-iiif is available under the Apache 2.0 license.

\ No newline at end of file +

serverless-iiif is available under the Apache 2.0 license.

Options
\ No newline at end of file diff --git a/docs/advanced-usage/cors.html b/docs/advanced-usage/cors.html index e39b314..33198f3 100644 --- a/docs/advanced-usage/cors.html +++ b/docs/advanced-usage/cors.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Advanced Usage
Cross-Origin Request Sharing (CORS)

Cross-Origin Request Sharing (CORS)

+
Documentation
Advanced Usage
Cross-Origin Request Sharing (CORS)

Cross-Origin Request Sharing (CORS)

For security reasons, web browsers have built in limits on what sort of requests can be made to a given domain from a page hosted under a different domain. Since this is a common use case for IIIF (resources embedded in pages whose domains differ from that of the server), IIIF interactions are particularly susceptible to these limits.

The mechanism for determining which of these requests should be allowed or blocked is known as Cross-Origin Resource Sharing, or CORS (opens in a new tab). A full explanation of CORS is beyond the scope of this project, but the SAM deploy template contains five parameters relating to how the IIIF server handles CORS:

    @@ -19,4 +19,4 @@
  • CorsExposeHeaders contains the value that will be returned in the Access-Control-Expose-Headers response header.
  • CorsMaxAge contains the value that will be returned in the Access-Control-Max-Age response header.
-

The default values will work in most circumstances, but if you need the IIIF server to accept requests that include credentials or other potentially sensitive information (e.g., Authorization and/or Cookie headers), you'll need to set CorsAllowOrigin to REFLECT_ORIGIN and CorsAllowCredentials to true. Other settings allow further customization.

\ No newline at end of file +

The default values will work in most circumstances, but if you need the IIIF server to accept requests that include credentials or other potentially sensitive information (e.g., Authorization and/or Cookie headers), you'll need to set CorsAllowOrigin to REFLECT_ORIGIN and CorsAllowCredentials to true. Other settings allow further customization.

\ No newline at end of file diff --git a/docs/advanced-usage/request-response-functions.html b/docs/advanced-usage/request-response-functions.html index ef41882..137900f 100644 --- a/docs/advanced-usage/request-response-functions.html +++ b/docs/advanced-usage/request-response-functions.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Advanced Usage
Request Response Functions

Request/Response Functions

+
Documentation
Advanced Usage
Request Response Functions

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 @@ -36,8 +36,8 @@
    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 })};
    +  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:

    @@ -54,4 +54,4 @@
    { 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.

\ No newline at end of file +
💡

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.

\ No newline at end of file diff --git a/docs/communities/iiif.html b/docs/communities/iiif.html index 10466e4..db10400 100644 --- a/docs/communities/iiif.html +++ b/docs/communities/iiif.html @@ -9,4 +9,4 @@ .dark { --nextra-primary-hue: 209deg; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/communities/samvera.html b/docs/communities/samvera.html index c8d1a29..e181868 100644 --- a/docs/communities/samvera.html +++ b/docs/communities/samvera.html @@ -9,4 +9,4 @@ .dark { --nextra-primary-hue: 209deg; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/contributors.html b/docs/contributors.html index 6c6a604..ebf4d1d 100644 --- a/docs/contributors.html +++ b/docs/contributors.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Contributors

Contributors

+
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/custom-sharp-layer.html b/docs/custom-sharp-layer.html index 543cb45..30e6c5c 100644 --- a/docs/custom-sharp-layer.html +++ b/docs/custom-sharp-layer.html @@ -9,6 +9,6 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Custom Sharp Layer

Custom Sharp Layer

+
\ No newline at end of file +

You can build your own local version using that code and then deploy your own layer and set that layer in your SAM template.

\ No newline at end of file diff --git a/docs/how-to-contribute.html b/docs/how-to-contribute.html index 449a2ae..7a8b39f 100644 --- a/docs/how-to-contribute.html +++ b/docs/how-to-contribute.html @@ -9,6 +9,6 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Guide

How to Contribute?

+
Documentation
Guide

How to Contribute?

If you're working on a PR (opens in a new tab) for this project, create a feature branch off of main.

-

This repository follows the Samvera Community Code of Conduct (opens in a new tab) and language recommendations (opens in a new tab). Please do not create a branch called master for this repository or as part of your pull request; the branch will either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository.

\ No newline at end of file +

This repository follows the Samvera Community Code of Conduct (opens in a new tab) and language recommendations (opens in a new tab). Please do not create a branch called master for this repository or as part of your pull request; the branch will either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository.

\ No newline at end of file diff --git a/docs/notes.html b/docs/notes.html index 5036779..74ef7ec 100644 --- a/docs/notes.html +++ b/docs/notes.html @@ -9,6 +9,6 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Notes

Notes

+
Documentation
Notes

Notes

Lambda Function URLs have a payload (request/response body) size limit of approximately 6MB in both directions. To overcome this limitation, the Lambda URL is configured behind an AWS CloudFront distribution with two origins - the API and a cache bucket. Responses larger than 6MB are saved to the cache bucket at the same relative path as the request, and the Lambda returns a 404 Not Found response to CloudFront. CloudFront then fails over to the second origin (the cache bucket), where it finds the actual response and returns it.

-

The cache bucket uses an S3 lifecycle rule to expire cached responses in 1 day.

\ No newline at end of file +

The cache bucket uses an S3 lifecycle rule to expire cached responses in 1 day.

\ No newline at end of file diff --git a/docs/quick-start.html b/docs/quick-start.html index 73cfe7b..f0fd470 100644 --- a/docs/quick-start.html +++ b/docs/quick-start.html @@ -9,4 +9,4 @@ .dark { --nextra-primary-hue: 209deg; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/quick-start/deleting-the-app.html b/docs/quick-start/deleting-the-app.html index c895304..5fec018 100644 --- a/docs/quick-start/deleting-the-app.html +++ b/docs/quick-start/deleting-the-app.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deleting the App

Deleting the application

+
Documentation
Quick Start
Deleting the App

Deleting the application

If you deployed the application on its own, the easiest way to delete the application is either from the Lambda Applications Console (opens in a new tab) or by deleting its CloudFormation Stack (opens in a new tab).

If you deployed from the command line, you can also use the npm run delete command.

-

If you deployed using an infrastructure tool such as AWS CloudFormation or Terraform, you should use that tool's destroy/teardown functionality to remove the IIIF stack as well.

\ No newline at end of file +

If you deployed using an infrastructure tool such as AWS CloudFormation or Terraform, you should use that tool's destroy/teardown functionality to remove the IIIF stack as well.

\ No newline at end of file diff --git a/docs/quick-start/deployment-command-line.html b/docs/quick-start/deployment-command-line.html index 6b12450..921ac40 100644 --- a/docs/quick-start/deployment-command-line.html +++ b/docs/quick-start/deployment-command-line.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deploying via the Command Line

Deploying via the Command Line

+

If you use the guided deploy, you'll be prompted for various configuration parameters, confirmations, and acknowledgments of specific issues (particularly the creation of IAM resources and the deployment of an open/unauthenticated Lambda Function URL). Otherwise, you'll simply be asked to confirm the calculated changeset.

Step 6

Follow the prompts to complete the deployment process and get the resulting endpoint.

\ No newline at end of file +$ npm run deploy

If you use the guided deploy, you'll be prompted for various configuration parameters, confirmations, and acknowledgments of specific issues (particularly the creation of IAM resources and the deployment of an open/unauthenticated Lambda Function URL). Otherwise, you'll simply be asked to confirm the calculated changeset.

Step 6

Follow the prompts to complete the deployment process and get the resulting endpoint.

Deploying via the AWS Serverless Application RepositoryIntroduction
\ No newline at end of file diff --git a/docs/quick-start/deployment-sam.html b/docs/quick-start/deployment-sam.html index 52ffae0..ef4e25e 100644 --- a/docs/quick-start/deployment-sam.html +++ b/docs/quick-start/deployment-sam.html @@ -9,11 +9,11 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deploying via the AWS Serverless Application Repository

Deploying via the AWS Serverless Application Repository

+
Documentation
Quick Start
Deploying via the AWS Serverless Application Repository

Deploying via the AWS Serverless Application Repository

serverless-iiif is distributed and deployed via the AWS Serverless Application Repository (opens in a new tab). To deploy it using the AWS Console:

Step 1

Find the serverless-iiif application (opens in a new tab) in the AWS Serverless Application Repository.

Step 2

Make sure your currently selected region (in the console's top navigation bar) is the one you want to deploy to.

Step 3

Scroll down to the Application settings section.

Step 4

Configure the deploy template:

  • Give your stack a unique Application name
  • Enter the name of the SourceBucket the service will serve images from
  • Check the box acknowledging that the app will create a custom IAM roles and resource policies (and if deploying the Caching version, that it will also deploy a nested application)
  • Optional: Enter or change any other parameters that apply to your desired configuration.
  • -

Step 5

Click Deploy.

Step 6

When all the resources are properly created and configured, the new stack should be in the CREATE_COMPLETE stage. If there's an error, it will delete all the resources it created, roll back any changes it made, and eventually reach the ROLLBACK_COMPLETE stage.

Step 7

Click the CloudFormation stack link.

Step 8

Click the Outputs tab to see (and copy) the IIIF Endpoint URL.

\ No newline at end of file +

Step 5

Click Deploy.

Step 6

When all the resources are properly created and configured, the new stack should be in the CREATE_COMPLETE stage. If there's an error, it will delete all the resources it created, roll back any changes it made, and eventually reach the ROLLBACK_COMPLETE stage.

Step 7

Click the CloudFormation stack link.

Step 8

Click the Outputs tab to see (and copy) the IIIF Endpoint URL.

\ No newline at end of file diff --git a/docs/quick-start/infrastructure.html b/docs/quick-start/infrastructure.html index 3703571..ac737a1 100644 --- a/docs/quick-start/infrastructure.html +++ b/docs/quick-start/infrastructure.html @@ -9,5 +9,5 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deploying via Infrastructure Tools
Introduction

Deploying via Infrastructure Tools

-

You will most likely want to deploy serverless-iiif as part of a larger infrastructure stack. This stack might include a caching layer (AWS CloudFront), functions to customize the services behavior, a custom domain name, and more. This section provides documentation and examples of how to deploy the service using AWS CloudFormation or Terraform.

\ No newline at end of file +
Documentation
Quick Start
Deploying via Infrastructure Tools
Introduction

Deploying via Infrastructure Tools

+

You will most likely want to deploy serverless-iiif as part of a larger infrastructure stack. This stack might include a caching layer (AWS CloudFront), functions to customize the services behavior, a custom domain name, and more. This section provides documentation and examples of how to deploy the service using AWS CloudFormation or Terraform.

\ No newline at end of file diff --git a/docs/quick-start/infrastructure/cloudformation.html b/docs/quick-start/infrastructure/cloudformation.html index 4275158..5307e17 100644 --- a/docs/quick-start/infrastructure/cloudformation.html +++ b/docs/quick-start/infrastructure/cloudformation.html @@ -9,7 +9,7 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deploying via Infrastructure Tools
AWS CloudFormation

Installing serverless-iiif as part of a CloudFormation (opens in a new tab) template makes it easy to integrate the service with other components. Please refer to the example and the CloudFormation documentation (opens in a new tab) for more information on how you might tailor these templates to your own needs and deploy them to AWS.

+
Documentation
Quick Start
Deploying via Infrastructure Tools
AWS CloudFormation

Installing serverless-iiif as part of a CloudFormation (opens in a new tab) template makes it easy to integrate the service with other components. Please refer to the example and the CloudFormation documentation (opens in a new tab) for more information on how you might tailor these templates to your own needs and deploy them to AWS.

Syntax

To declare this entity in your AWS CloudFormation template, use the following syntax:

Type: AWS::Serverless::Application
@@ -146,4 +146,4 @@ 

Value: !Ref CachingEndpoint Export: Name: !Sub "${AWS::StackName}:DistributionId" -

\ No newline at end of file +
IntroductionTerraform
\ No newline at end of file diff --git a/docs/quick-start/infrastructure/terraform.html b/docs/quick-start/infrastructure/terraform.html index 51ad7b8..b68a2e7 100644 --- a/docs/quick-start/infrastructure/terraform.html +++ b/docs/quick-start/infrastructure/terraform.html @@ -9,8 +9,8 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Quick Start
Deploying via Infrastructure Tools
Terraform

The serverless-iiif GitHub repository includes a Terraform Module (opens in a new tab) that can be used as a drop-in component in any +

Documentation
Quick Start
Deploying via Infrastructure Tools
Terraform

The serverless-iiif GitHub repository includes a Terraform Module (opens in a new tab) that can be used as a drop-in component in any Terraform manifest. Please refer to the documentation and examples below, as well as the Terraform documentation (opens in a new tab) for more information on how you might use these tools to deploy your own custom stack to AWS.

Required Inputs


These variables must be set in the module block when using this module.

source_bucket string

Description: Name of bucket containing source images

Optional Inputs


These variables have default values and don't have to be set to use this module. You may set these variables to override their default -values.

cors_allow_headers string

Description: Value of the CORS Access-Control-Allow-Headers response header

Default: *

cors_allow_origin string

Description: Value of the CORS Access-Control-Allow-Origin response header. Use the special value REFLECT_ORIGIN to copy the value from the Origin request header (required to emulate * for XHR requests using Authorization and/or Cookie headers).

Default: *

cors_expose_headers string

Description: Value of the CORS Access-Control-Expose-Headers response header

Default: cache-control,content-language,content-length,content-type,date,expires,last-modified,pragma

cors_max_age number

Description: Value of the CORS Access-Control-MaxAge response header

Default: 3600

force_host string

Description: Forced hostname to use in responses

Default: ""

iiif_lambda_memory number

Description: The memory provisioned for the lambda.

Default: 3008

iiif_lambda_timeout number

Description: The timeout for the lambda.

Default: 10

pixel_density number

Description: Hardcoded DPI/Pixel Density/Resolution to encode in output images

Default: 0

pyramid_limit number

Description: Smallest pyramid image dimension. Set to 0 to prevent server from auto-calculating pyramid page sizes.

Default: 256

resolver_template string

Description: A printf-style format string that determines the location of source image within the bucket given the image ID

Default: %s.tif

sharp_layer string

Description: ARN of a custom AWS Lambda Layer containing the sharp and libvips dependencies. Use the special value JP2 to use the managed JPEG2000-compatible layer, or INTERNAL to use the built-in dependencies (without JPEG2000 support).

Default: JP2

\ No newline at end of file +values.

cors_allow_headers string

Description: Value of the CORS Access-Control-Allow-Headers response header

Default: *

cors_allow_origin string

Description: Value of the CORS Access-Control-Allow-Origin response header. Use the special value REFLECT_ORIGIN to copy the value from the Origin request header (required to emulate * for XHR requests using Authorization and/or Cookie headers).

Default: *

cors_expose_headers string

Description: Value of the CORS Access-Control-Expose-Headers response header

Default: cache-control,content-language,content-length,content-type,date,expires,last-modified,pragma

cors_max_age number

Description: Value of the CORS Access-Control-MaxAge response header

Default: 3600

force_host string

Description: Forced hostname to use in responses

Default: ""

iiif_lambda_memory number

Description: The memory provisioned for the lambda.

Default: 3008

iiif_lambda_timeout number

Description: The timeout for the lambda.

Default: 10

pixel_density number

Description: Hardcoded DPI/Pixel Density/Resolution to encode in output images

Default: 0

pyramid_limit number

Description: Smallest pyramid image dimension. Set to 0 to prevent server from auto-calculating pyramid page sizes.

Default: 256

resolver_template string

Description: A printf-style format string that determines the location of source image within the bucket given the image ID

Default: %s.tif

sharp_layer string

Description: ARN of a custom AWS Lambda Layer containing the sharp and libvips dependencies. Use the special value JP2 to use the managed JPEG2000-compatible layer, or INTERNAL to use the built-in dependencies (without JPEG2000 support).

Default: JP2

AWS CloudFormationDeleting the App
\ No newline at end of file diff --git a/docs/source-images.html b/docs/source-images.html index 68d62ef..ca6884c 100644 --- a/docs/source-images.html +++ b/docs/source-images.html @@ -9,11 +9,11 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Source Images

Source Images

+
Documentation
Source Images

Source Images

The S3 key of any given file, minus the extension, is its IIIF ID. For example, if you want to access the image manifest for the file at abcdef.tif, you would get https://.../iiif/2/abcdef/info.json. If your key contains slashes, they must be URL-encoded: e.g., ab/cd/ef/gh.tif would be at https://.../iiif/2/ab%2Fcd%2Fef%2Fgh/info.json. (This limitation could easily be fixed by encoding only the necessary slashes in the incoming URL before handing it off to the IIIF processor, but that's beyond the scope of the demo.)

iiif-processor can use any image format natively supported by libvips (opens in a new tab), including JPEG 2000 (.jp2), but best results will come from using tiled, multi-resolution TIFFs. The Lambda Function wrapper included in this application assumes a .tif extension unless you set ResolverTemplate in your .env file.

Creating tiled TIFFs

Using VIPS

vips tiffsave source_image.tif output_image.tif --tile --pyramid --compression jpeg --tile-width 256 --tile-height 256

Using ImageMagick

-
convert source_image.tif -define tiff:tile-geometry=256x256 -compress jpeg 'ptif:output_image.tif'
\ No newline at end of file +
convert source_image.tif -define tiff:tile-geometry=256x256 -compress jpeg 'ptif:output_image.tif'
\ No newline at end of file diff --git a/docs/testing.html b/docs/testing.html index 75f2334..aeb3dbc 100644 --- a/docs/testing.html +++ b/docs/testing.html @@ -9,8 +9,8 @@ .dark { --nextra-primary-hue: 209deg; } -
Documentation
Testing

Testing

+
\ No newline at end of file +
npm test --coverage
\ No newline at end of file diff --git a/index.html b/index.html index e4ffdd8..05d6c2b 100644 --- a/index.html +++ b/index.html @@ -9,4 +9,4 @@ .dark { --nextra-primary-hue: 209deg; } -

Fast, zoomable images without servers

A cost-effective, infinitely scalable IIIF Image API v2.1 and v3.0 compliant service packaged as an AWS Serverless Application with minimum setup and no maintenance. Suitable for large institutional collections or small digital humanities projects.
Community Driven. Open Source.

Deploy Now  Read the Docs IIIF Image API
\ No newline at end of file +

Fast, zoomable images without servers

A cost-effective, infinitely scalable IIIF Image API v2.1 and v3.0 compliant service packaged as an AWS Serverless Application with minimum setup and no maintenance. Suitable for large institutional collections or small digital humanities projects.
Community Driven. Open Source.

Deploy Now  Read the Docs IIIF Image API
\ No newline at end of file