HST Binary Content Resource Serving (BinariesServlet)
1. Introduction
BinariesServlet serves binary resources from the repository. Binary resources can be stored in nodes. BinariesServlet has many features to control HTTP headers and cache controls.
With the default configuration, if the request URI is like ' /site/binaries/content/gallery/images/screenshot_cms_small.jpg' (where the context path is ' /site', the servlet path for BinariesServlet is ' /binaries', and the remaining is the path info), then BinariesServlet will read binary content from nodes under ' /content/gallery/images/screenshot_cms_small.jpg' in the repository and write a stream output to the client. In preview context, the binaries are fetched from the repository by the preview siteuser (more precisely in CMS preview a security delegate between site preview user and the logged in cms user). For the live website, the binaries are fetched by the live site user, and in case of subject-based rendering, by the user that is authenticated. The userID is part of the cache key that is used to cache the fetched binaries internally.
2. Configuration
BinariesServlet is configured in web.xml like the following example:
<servlet> <servlet-name>BinariesServlet</servlet-name> <servlet-class>org.hippoecm.hst.servlet.BinariesServlet</servlet-class> </servlet> <!-- SNIP --> <servlet-mapping> <servlet-name>BinariesServlet</servlet-name> <url-pattern>/binaries/*</url-pattern> </servlet-mapping>
BinariesServlet can have the following init parameters.
Init parameter name |
Example value |
Default value |
Description |
Since |
baseBinariesContentPath |
/binarycontents
|
When this is set, the node path will be prefixed by this parameter to find the binary content. |
||
binaryDataPropName |
jcr:data |
The name of the JCR node property containing binary contents. |
||
binaryMimeTypePropName |
jcr:mimeType |
The name of the JCR node property containing content type of the binary contents. |
||
binaryLastModifiedPropName |
jcr:lastModified |
The name of the JCR node property containing the last modified date. |
||
binaryResourceNodeType |
hippo:resource |
The name of the primary node type after which the binary content node should be typed. |
||
contentDispositionContentTypes |
application/pdf, application/rtf, application/excel or application/* |
Set this parameter when you want to configure which mime types are able to do content dispositioning. If a binary content has a mime type in this configured mime type set, then BinariesServlet will add content disposition header (" Content-Disposition") to specify attachment and file name attribute. You can also use '*' to configure multiple mime types. |
||
contentDispositionFilenameProperty |
demosite:filename |
The name of the JCR node property containing the file name attribute for the binary content node. By default, file name attribute is not added when content dispositioning is used for the content. If you want to set file name attribute, then you should define a JCR property, configure the property name with this parameter and set the property values for each binary contents. |
||
contentDispositionFilenameEncoding |
user-agent-specific |
user-agent-agnostic |
When content dispositioning is used for the content with a file name attribute, you can specify which encoding strategy should be used. With " user-agent-specific", the file name attribute for the content will be encoded properly based on the user agent. With " user-agent-agnostic", the file name attribute for the content will be encoded with US-ASCII codes only. |
|
cache-name |
defaultBinariesCache |
BinariesServlet uses a cache internally. This parameter specifies the bean component name of the internal cache. The default cache component named " defaultBinariesCache" can be found in SpringComponentManager-cache.xml which is packaged in hst-core library. |
||
cache-max-object-size-bytes |
262144 |
When this parameter is set to a positive value, a binary content containing data not more than this configured size can be cached. If a binary content contains data more than this size, it will not be cached. The default value is 262144 bytes (256 KB). |
||
validity-check-interval-seconds |
180 |
Basically, each cache item is validated against the last modified property of the content node. However, it is not efficient to try to validate on every request. So, this parameter enables to configure the validation checking interval. For optimization, the default validation checking interval is set to 180 seconds. |
||
set-expires-headers |
true |
Flag whether to set expires HTTP headers. |
||
set-content-length-header |
true |
Flag whether to set the Content-Length HTTP header. |
2.20.04+ and 2.21.01+ |
.
3. Cache component configuration
By default, the " defaultBinariesCache" component bean is defined as follows:
<!-- The ehcache manager component --> <!-- By default, this component will try to read ehcache.xml from the classpath. --> <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> </bean> <!-- abstract base cache component bean definition with default property configuration --> <bean id="abstractEhCacheBase" abstract="true"> <property name="cacheManager" ref="ehCacheManager" /> <property name="maxEntriesLocalHeap" value="256" /> <property name="maxElementsOnDisk" value="0" /> <property name="eternal" value="false" /> <property name="overflowToDisk" value="false" /> <!-- time to live in seconds. default 1 day --> <property name="timeToLive" value="86400" /> <!-- time to idle in seconds. default 1 day --> <property name="timeToIdle" value="86400" /> <property name="diskPersistent" value="false" /> <property name="diskExpiryThreadIntervalSeconds" value="120" /> </bean> <!-- abstract non-blocking cache component bean definition --> <bean id="abstractEhCache" abstract="true" parent="abstractEhCacheBase" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> </bean> <!-- abstract blocking cache component bean definition --> <bean id="abstractBlockingEhCache" abstract="true" parent="abstractEhCacheBase" class="org.hippoecm.hst.site.container.BlockingEhCacheFactoryBean"> </bean> <!-- the default cache component bean definition for BinariesServlet --> <bean id="defaultBinariesCache" class="org.hippoecm.hst.cache.CompositeHstCache"> <constructor-arg> <bean parent="abstractBlockingEhCache"> <property name="cacheName" value="binariesCache" /> <!-- time to idle in seconds. default 1 day --> <property name="timeToLive" value="86400" /> <!-- To avoid concurrency issues, use blocking cache --> <property name="blocking" value="true" /> </bean> </constructor-arg> </bean>
Customize the default cache configuration
In most cases, the default bean configuration above would be good enough, but you can also override the default bean definitions by adding bean definition configuration XML files into classpath:/META-INF/hst-assembly/overrides/.
Depending on the requirements there are different ways of creating custom configuration for the cache.
Option 1: Creating a custom cache from Spring
Create a file called binaries-cache.xml (you can choose any name) in your local project folder: site/src/main/resources/META-INF/hst-assembly/overrides.
As an example the content of the file could look like:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <import resource= "classpath:/org/hippoecm/hst/site/container/SpringComponentManager-cache.xml" /> <bean id="customBinariesCache" class="org.hippoecm.hst.cache.CompositeHstCache"> <constructor-arg> <bean parent="abstractBlockingEhCache"> <property name="cacheName" value="customBinariesCache" /> <property name="maxEntriesLocalHeap" value="1024"/> <property name="overflowToDisk" value="true"/> <!-- time to idle in seconds. default 1 day --> <property name="timeToLive" value="86400" /> <property name="blocking" value="true" /> </bean> </constructor-arg> <property name="statisticsEnabled" value="${default.binaries.cache.statistics.enabled}"/> </bean> </beans>
Now you only need to instruct the BinariesServlet to use the new cache called customBinariesCache.
<servlet> <servlet-name>BinariesServlet</servlet-name> <servlet-class>org.hippoecm.hst.servlet.BinariesServlet</servlet-class> <init-param> <param-name>cache-name</param-name> <param-value>customBinariesCache</param-value> </init-param> </servlet>
Option 2: Externalizing the cache configuration
By default the cache configuration is packaged in the deployed war file. Sometimes you might want to externalize the cache configuration so that you can tweak the configuration without having to modify the Spring configuration inside the war (which might require a new deployment).
It's quite easy to do this by changing the configLocation of the ehCacheManagerbean.
You can use the same file as mentioned above ( binaries-cache.xml) to redefine the ehCacheManager.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <import resource= "classpath:/org/hippoecm/hst/site/container /SpringComponentManager-cache.xml" /> <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="file:${catalina.base}/conf/ehcache.xml"/> </bean> </beans>
In the example configuration above we use the ehcache.xml file stored in the conf directory of the application container.
Here is an example ehcache.xml file which reflects the default Spring configured binariesCache:
<ehcache updateCheck="false"> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <!-- default settings copied from abstractEhCacheBase --> <!-- time to live in seconds. default 1 day --> <cache name="binariesCache" maxElementsInMemory="256" maxElementsOnDisk="0" eternal="false" overflowToDisk="false" timeToIdleSeconds="86400" timeToLiveSeconds="86400" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> </cache> </ehcache>
If the named Cache instance is found in the ehcache.xml file, the properties set by Spring will be ignored and the Cache instance will be retrieved from the CacheManager.