All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
- #514: remove support for legacy path-based URL syntax
- #510: ensure search parameters are used in passthrough URL
- #508: bypass JS processing when no transformation parameters supplied
- #505: serve original image untransformed when no manipulation parameters are defined
- #253: add LastModified header to items returned from cache
- #479: set content-length header after gzipping
- Update dependencies: mime, concat-stream
- #472: remove dependency incompatible with ARM64 architecture
- Removes invalid configuration samples
- #449: ensure responses for all status codes are allowed to complete before taking action
- Remove the default behaviour of responding with progressize JPEGs
- Handle requests for gzip encoding better, checking for "gzip" anywhere in the Accept-Encoding header
- Remove defaults for authentication and token signing credentials, requires user to set them explicitly
- Accept full configuration block at internal mgmt endpoints
- #378: support progressive JPEGs - add
?progressive=true
to a URL - #447: use a base URL for status endpoint checks, configure with
publicUrl
- #437: allow override of local image directory in multi-domain
- #451: replace exif-reader package with a forked+patched version
- Add support for Node.js 10
- #398: add 'Vary: Accept-Encoding' header to responses
- #439: reload domain configs on directory changes
- #351: add
assets.remote.allowFullURL
configuration parameter - #406: return JSON response when URL is incomplete
- #434: return file size attributes for the image pre and post transforms
- Sharp image dependency updated to 0.21.0
- #424: PNG compression honours quality parameter setting, mapping the
quality
parameter inversely to a compression level between 1 and 9 - #431: don't assume JPG extension when no extension is supplied
- #412: modify regex for "CSS" to search from beginning of URL
- #400: support for conditional formats
- #405: support for default files
- With #405, the
/
route doesn't respond with a plain text 200 response. In order to check that CDN is online, send a request to/hello
- removed package lock file to allow latest dependencies
- updated dependencies
- #394: performance improvements.
- work queue added, ensures if multiple requests are made for the same resource before the first one has finished processing, remaining requests wait for the result of the first one instead of requesting a new computation each time. When the processing for the first request finishes, all waiting requests are served and the request is removed from the work queue.
- #388: fix issue where not all chunks from a remote HTTP call were passed to the calling function.
- #372: add proper support for range requests, enabling seekable content such as audio and video to be served correctly.
- changed
.npmignore
to correctly exclude any files and directories used for development purposes only.
- #369: fix issue where
devicePixelRatio
was ignored when a resize style other thancrop
was used; change default resize style toaspectfill
whenwidth
,height
andgravity
are supplied.
Full public release of Release Candidate 4.
- The file upload function in CDN was recently removed. We came to the conclusion that CDN should remain a delivery tool - how a user gets their assets to their storage location for CDN to serve should be up to them. There are a great number of ways to do that, including via DADI API (see https://docs.dadi.tech/api/latest).
- #346: add basic GIF support
- #356: add Digital Ocean Spaces support
- #360 and #363: cache 404 responses using the
caching.cache404
config property
- #347: gracefully handle case where domains directory does not exist
- #354: include all image options in cache key
- #355: return fallback image when remote server returns 404
- #357: make config properties overridable at domain level
- #358: update
@dadi/cache
to version 2.0.0 - #359: update
supertest
to version 3.1.0 - #365: update
babel-preset-minify
to version 0.4.3
- Allow
remote.enabled
to be overridden at domain level.
- #345: stop requiring the existence of the domains directory if multi-domain is not enabled and handle it gracefully with an informative error message if it is enabled and the directory doesn't exist
- #254: ability to define full remote URLs at recipe level
- #313: add config export
- #314: allow controller plugins to set X-Cache header
- #326: use domain as part of cache key
- #327: return 404 if multi-domain is enabled and a request is made for a domain that is not configured
- #330: add file monitors to domain-specific workspace directories
- #331: make
/api/recipes
and/api/routes
endpoints work with multiple domains - #336: flush cache by domain
- Plugin support
- On-demand JavaScript transpiling (experimental)
- Support for any type of asset
- #259 WebP image support
- Simplified paths for non-image assets
- #255: default value for the
resizeStyle
property is nowaspectfit
, except when an explicit ratio is defined (i.e.width
andheight
orratio
are defined) - #282: deliver the fallback image even when crop is present
- #283: use correct dimensions when original or calculated size is above the configured security limit
- #291: cache JSON response of images, in the same way as the actual images are
- refactor parts of the code base to use ES6 features
- fix an issue where the
gravity
URL parameter was not applied correctly - fix an issue whereby it was not possible to minify JavaScript files that contain ES6 code
- begin removal of Underscore.js dependency
- #276: ensure images can be processed with no sharpening
- fix an issue where the aspect ratio was not respected when maxWidth/maxHeight resizes were being made
- #260: update finalhandler to version 1.1.0
- #264: update request to version 2.83.0
- #267: make options from recipe take precedence in Image handler
- #272: update should to version 13.1.2
- #270: cropping modifications to make it behave more intuitively. DevicePixelRatio is now respected, along with distorting images by providing both width & height. These changes only affect resize style
crop
. See the documentation for more information.
The image processor used in CDN has been replaced. We are currently pinned to Node.js 6.9.2 for most CDN installations, as lwip will not build on more recent (and less vulnerable) versions of Node.js.
We’ve now implemented Sharp in CDN. It is much faster than lwip: running a test using a Buffer as both input and output, Sharp averages 29.08 operations per second, while lwip manages just 1.87 operations per second - that's around 15 times faster.
Other than improved performance, Sharp offers us a smoother transition into adding plugin support to CDN and being able to offer features such as dynamic text and image compositing.
#243: remove restriction on configuration file names #247: respond with error when loading from a URL returns no image data
- Remote image requests that followed a redirect sometimes return a redirect header that is a path only, without protocol and hostname. Updated the
wget-improved
dependency to handle this case
- #209: Add post install script to copy a sample development configuration file to the application root
- #218: Set a default file extension of JPG for remote image requests that don't include an extension
- #223: Ensure that querystring parameters on remote URLs are retained and passed to the remote request
- Return 403 errors from remote requests (c31a980)
- package.json to reduce vulnerabilities (728d4ea3)
- return file with extension when url is extension-less (5d5774c1)
-
add a new configuration parameter (
images.remote.allowFullURL
) which toggles the use of remote images from a full URL (e.g.https://cdn.com/https://another-full-url.com/image.jpg
). Allowing images to be loaded from anywhere means that people can, in theory, use my instance of CDN to load, manipulate and deliver their images on their site, so I think it should be something I actively choose to enable. (1fbde477) -
add three additional environment variables:
PORT
: specifies the server portCACHE_ENABLE_DIRECTORY
: toggles directory-based cachingCACHE_ENABLE_REDIS
: toggles Redis caching
- ensure uploaded files have safe filenames (6b9fea42)
- load js files and json files in workspace (ba5b4a92)
- #84: Fix bug where the first part of the path was interpreted as a recipe/route/processor
- #130: Add image upload support, allowing configuration of CDN to accept image uploads. See documentation at http://docs.dadi.tech/cdn/concepts/upload
- #151: Add external image support. See documentation at http://docs.dadi.tech/cdn/
- #153: CDN can be configured to respond to the route
/robots.txt
. Specify the path to a robots.txt file in the configuration file:
"robots": "path/to/robots.txt"
- #155: @dadi/cache module now used in place of custom caching
- #160: Fix: image is now returned even if no query is specified
- #177: Fix compression when changing formats from PNG to JPG
- #181: Removed node-canvas dependency, which was only used for determining the primary colour of an image. This is now handled by node-vibrant. Removing node-canvas simplifies the install process. If interested, you can compare results from the new module with color-thief's demo page at http://lokeshdhakar.com/projects/color-thief/.
- #182: Fix crash when caching is enabled and a JSON response is requested (e.g.
/test.jpg?format=json
). - Modified package dependencies to include the
lwip
dependency using the same identifying string as used bysmartcrop-lwip
. This fixes the problem where NPM treated the two dependencies as separate and compiled them both when installing, extending the installation process. - validation added to route and recipe names, to ensure they are 5 or more characters and only a mix of letters, dashes and underscores
- creating a Recipe by sending a POST request must now be sent to
/api/recipes
, not/api/recipes/new
- replaced Bluebird Promises with native Promises
- removed Redis dependencies, as these are now handled in @dadi/cache
When specifying only two crop coordinates, the crop rectangle wasn't being correctly set.
Using v2 of the request format, cropped images should be requested as follows:
Format of parameters: ?resize=crop&crop=top,left,bottom,right
- specifying the full crop rectangle: http://cdn.example.com/images/taylor_swift.jpg?resize=crop&crop=0,225,312,567
- the image is not resized; the resulting image will be 312px x 342px
- specifying the top left corner of the crop rectangle: http://cdn.example.com/images/taylor_swift.jpg?resize=crop&crop=0,225
- the size of the crop rectangle is determined by the size of the image; if the original image is 800px x 600px, the crop rectangle and resulting image size will be 575px x 600px
Adding width=400
will cause CDN to resize the image after cropping.