This chapter describes the Edge Side Includes (ESI) tags provided for content assembly of dynamic fragments.
ESI is an open specification co-authored by Oracle. Its purpose is to develop a uniform programming model to assemble dynamic pages in a dynamic content cache deployed as a surrogate or proxy between clients and origin servers.
ESI is an XML-like markup language that enables dynamic content assembly of fragments by Oracle Web Cache. A template page is configured with ESI markup tags that fetch and include dynamic HTML fragments. The fragments themselves can also contain ESI markup. You can assign caching rules to the template page and HTML fragments. By enabling page assembly in Oracle Web Cache rather than in the origin server, you can increase cache hit rates and improve performance.
This chapter includes the following topics:
Section 11.1, "Introduction to ESI for Partial Page Caching"
Section 11.2, "Enabling Dynamic Assembly of Content and Partial Page Caching"
See http://www.esi.org
for the ESI language release 1.0 specification.
Oracle Web Cache provides dynamic assembly of Web pages with both cacheable and non-cacheable page fragments. It provides for assembly by enabling Web pages to be divided into fragments of differing caching profiles. These fragments are maintained as separate elements in the cache. The fragments are assembled into HTML pages as appropriate when requested by end users.
By enabling dynamic assembly of Web pages on Oracle Web Cache rather than on the origin servers, you can choose to cache some fragments of assembled pages. With partial page caching, much more HTML content can be cached, and then assembled and delivered by Oracle Web Cache when requested. Furthermore, page assembly can be conditional, based on information provided in HTTP request headers or end-user cookies.
The basic structure that an application developer uses to create content for partial-page caching is a template page containing fragments. As depicted in Figure 11-1, the template consists of common elements, such as a logo, navigation bars, framework, and other "look and feel" elements of the page. The fragments represent dynamic subsections of the page.
The template page is associated with the URL that end users request. To include the fragments, the template page is configured with ESI markup tags that instruct Oracle Web Cache to fetch and include the HTML fragments. The fragments themselves are HTML files containing discrete text or other objects.
Each included fragment is a separate object with its own caching policy. Content providers may want to cache the template for several days, but only cache a particular fragment, such as an advertisement or stock quote, for a matter of seconds or minutes. Other fragments (such as a user's bank account total) may be declared non-cacheable.
Table 11-1 provides a summary of the main ESI tags.
Table 11-1 Summary of ESI Tags
Tag | Description |
---|---|
|
Performs conditional processing based on Boolean expressions |
|
Specifies comments not be included in the output |
|
Allows variable access from an HTTP response |
|
Includes an HTML fragment |
|
Marks a fragment as a separately cacheable fragment, embedded in the HTTP response of another object |
|
Specifies an invalidation request within the response of a browser page |
|
Specifies non-ESI markup if ESI processing is not enabled |
|
Specifies alternate processing when a request fails because the origin server is not accessible |
|
Permits variable substitution for environment variables |
Example 11-1 shows the ESI markup language for the template page shown in Figure 11-1.
<HTML> <HEAD> <TITLE> Company.com </TITLE> </HEAD> <BODY> ... <!-- The following <esi:comment> tags are removed if this page is processed by an ESI processor. --> <!--esi <esi:comment text="This is the HTML source when ESI is enabled." /> <esi:comment text="Start: The quick link section. You cannot use the standard HTML comments because the end of that comment tag would disrupt the HTML comment tag with 'esi' following the two '-'." /> <esi:comment text="The URI query string parameter 'sessionID' is used to carry session identifiers, The session ID is encoded in all links." /> <esi:comment text="'Profile' refers to environment variables stored in GetProfile.jsp. GetProfile.jsp enables access to 'PersonalInterest.' 'zipcode,' 'tickers,' and 'address' environment variables." /> <esi:environment src="/GetProfile.jsp?sessionID=$(QUERY_STRING{sessionID})" name="Profile" /> <esi:vars> <A HREF="/shopping.jsp?sessionID=$(QUERY_STRING{sessionID})"> <IMG SRC="/img/shopping.gif"> </A> <A HREF="/news.jsp?sessionID=$(QUERY_STRING{sessionID})"> <IMG SRC="/img/news.gif"> </A> <A HREF="/sports.jsp?sessionID=$(QUERY_STRING{sessionID})"> <IMG SRC="/img/sports.gif"> </A> <A HREF="/fun.jsp?sessionID=$(QUERY_STRING{sessionID})"> <img src="/img/fun.gif"> </A> <A HREF="/about.jsp?sessionID=$(QUERY_STRING{sessionID})"> <iMG SRC="/img/about.gif"> </A> </esi:vars> <esi:comment text="End: The quick link section" /> ... <H3>Local Weather</H3> <esi:include src="/weather.jsp?sessionID=$(QUERY_STRING{sessionID})&zipcode=$(Profile{zipcode})" /> ... <H3>Stock Quotes</H3> <esi:try> <esi:attempt> <esi:include src="/CompanyStock.jsp?sessionID=$(QUERY_ STRING{sessionID})&tickers=$(Profiles{tickers})" /> </esi:attempt> <esi:except> The company stock quote is temporarily unavailable. </esi:except> </esi:try> ... <H3>What's New at Company</H3> <!-- This section is a static file that does not carry session information --> <esi:include src="/whatisnew.html" /> ... <H3>Today's News</h3> <esi:choose> <esi:when test="$(Profile{PersonalInterests}) == 'Sports'"> <H4>Sport News</H4> <esi:include src="/SportNews.jsp?sessionID=$(QUERY_STRING{sessionID})" /> </esi:when> <esi:when test="$(Profile{PersonalInterests}) == 'Career'"> <H4>Financial News</H4> <esi:include src="/FinancialNews.jsp?sessionID=$(QUERY_STRING{sessionID})" /> </esi:when> <esi:otherwise> <H4>General News</H4> <esi:include src="/DefaultNews.jsp?sessionID=$(QUERY_STRING{sessionID})" /> </esi:otherwise> </esi:choose> ... --> <!-- This is the HTML source when ESI is disabled. --> <esi:remove> Alternative HTML source that does not use ESI goes here. This tag enables you to disable ESI on the fly without redeveloping or redeploying a different version of the page. </esi:remove> ... </BODY> </HTML>
Example 11-2 shows the XML response of GetProfile.jsp
, which provides access to profile environment variables.
Example 11-2 GetProfile.jsp XML Response
<?xml version=1.0?> <esi:environment esiversion="ORAESI/9.0.4"> <PersonalInterests>Sports</PersonalInterests> <zipcode>94065</zipcode> <tickers>ORCL,YHOO</tickers> <address>500 Oracle Parkway, Redwood Shores, CA 94065</address> </esi:environment>
ESI can be used with HTML, XML, JSP, ASP, and any Web programming technology. The ESI language includes the following features:
Inclusion
An ESI processor assembles HTTP or HTTPS fragments of dynamic content, retrieved from the network, into aggregate pages to output to the user. Each fragment can have its own caching rules.
Support of variables
ESI supports the use of variables based on HTTP request attributes, as well as custom variables from included HTML fragments. Variables can be used by ESI statements during processing or can be output directly into the processed markup.
Conditional processing
ESI allows use of Boolean comparisons for conditional logic in determining how pages are processed.
Error handling and alternative processing
Some ESI tags support specification of a default resource or an alternative resource, such as an alternate Web page, if the primary resource cannot be found. Further, it provides an explicit exception-handling statement block.
Character set conversion
ESI fragments in different character sets are converted to one character set. This way, all partial pages are assembled in a fixed character set. Character set conversion works in the following manner:
Oracle Web Cache receives a request for a template page.
Oracle Web Cache fetches the fragments, and converts all of the fragments to the template's character set. The default character set is ISO-8859-1.
Oracle Web Cache does not perform character set conversion for non-ESI pages.
XML conversion to HTML
Oracle Web Cache uses XSL Transformations (XSLT) to transform XML fragments into HTML.
Oracle Web Cache provides the JESI tag library as a convenient interface to ESI tags and functionality. In addition, you can deploy the JESI tag library on Oracle WebLogic Server. Developers have the option of using ESI tags directly in any Web application, but JESI tags provide additional convenience in a JSP environment.
Because ESI and JESI are open standards, you can use the JESI tag library in any standard JSP environment if an ESI processor, such as Oracle Web Cache, is available.
Even though JSP developers can always use ESI, JESI provides an even easier way for JSP developers to express the modularity of pages and the cacheability of those modules, without requiring developers to learn a new syntax.
For further information about using JESI with Oracle WebLogic Server, see:
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/webcache/index.html
Oracle Web Cache supports the ESI language tags, elements, and attributes listed in Table 11-2. The rightmost column specifies, for each ESI tag, attribute, or element, all the feature sets that support it. For example, the <esi:invalidate>
tag is only supported by the "ESI-INV/1.0"
feature set. To enable the correct processing in Oracle Web Cache, specify all the feature sets that an ESI template uses in the content
control directive of the Surrogate-Control
response header. However, you do have to specify features sets used within an ESI fragment directly or indirectly included in the template. For example, if an ESI template uses an <esi:invalidate>
and an <esi:environment>
tag with an <esi:log>
element, the content
control directive must include "ESI-INV/1.0"
and "ORAESI/9.0.4"
, as follows:
Surrogate-Control: content="ESI-INV/1.0 ORAESI/9.0.4"
See Section 6.10 for further information about configuring the Surrogate-Control
response header.
Table 11-2 ESI Language Features
ESI Language Feature | See Also | content="value" Control Directive in Surrogate-Control Response Header Supporting Feature |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See http://www.esi.org/spec.html
for the ESI Language Specification 1.0 and the Edge Architecture Specification.
To enable Oracle Web Cache to process ESI tags, you set an HTTP Surrogate-Control
response-header field in the HTTP response message of the pages that use ESI tags.
Surrogate-Control: content="ESI-INV/1.0 ORAESI/9.0.4"
For each requested object from the cache, Oracle Web Cache appends a Surrogate-Capability
request-header field to an object's HTTP request message. The Surrogate-Capability
request-header serves the following purposes:
Enables applications to detect Oracle Web Cache
Identifies the types of ESI operations that Oracle Web Cache can perform
The Surrogate-Capability
request-header enables Oracle Web Cache to identify the operations it can perform to origin servers acting as caches. The Surrogate-Capability
request-header field supports the following syntax:
Surrogate-Capability: orcl="operation_value operation_value ..."
where "operation_value
" is one or more of the following:
"ORAESI/9.0.4"
to process ESI tags with Oracle-proprietary additions for content assembly and partial page caching. "ORAESI/9.0.4"
supports all the ESI tags provided by Oracle Web Cache in 10g (9.0.4) and later releases.
"ORAESI/9.0.2"
to process ESI tags with Oracle proprietary additions for content assembly and partial page caching. "ORAESI/9.0.2"
supports all the ESI tags provided by Oracle Web Cache in Release 2 (9.0.2 and 9.0.3).
"ESI/1.0"
to process standard ESI tags for content assembly and partial page caching
"webcache/1.0"
to process the <!-- WEBCACHETAG-->
and <!-- WEBCACHEEND-->
tags for personalized attributes
The values "ORAESI/9.0.2"
, "ESI/1.0"
, and "ESI-Inline/1.0"
are subsets of "ORAESI/9.0.4"
. For this release, you specify only "ORAESI/9.0.4"
for ESI assembly, "ESI-INV/1.0"
for inline invalidation, or "webcache/1.0"
for personalized attributes.
See Table 11-3 or further information about the ESI tags supported for each operation_value
.
ESI elements and attributes adhere to XML syntax but can be embedded in other objects, such as HTML or XML objects. When Oracle Web Cache processes the page, the ESI elements themselves are stripped from the output.
ESI syntax generally adheres to XML syntax rules. Keep the following in mind when using the tags:
ESI tags and attributes are case sensitive.
They are generally lowercase.
Supported CGI environment variables are case sensitive.
They are generally uppercase.
ESI does not support the use of whitespace next to the equal sign (=
) or between the "<
" and "esi:
"
The following shows an invalid construction:
<esi:include src = "www.foo.com"/>
The following shows the correct form:
<esi:include src="www.foo.com"/>
As shown in Example 11-3, an ESI tag can contain nested ESI elements and other HTML markup.
Example 11-3 Nested ESI Elements
<esi:choose> <esi:when test="$(HTTP_HOST) == 'www.company.com'"> <esi:include src="/company.html" /> <h4>Another</h4> <esi:include src="/another.html" /> </esi:when> <esi:when test="$(HTTP_COOKIE{fragment) == 'First Fragment'"> <esi:try> <esi:attempt> <esi:include src="/fragment1.html" /> </esi:attempt> <esi:except> <esi:choose> <esi:when test="$(HTTP_COOKIE{otherchoice}) == 'image'" > <img src="/img/TheImage.gif"> </esi:when> <esi:otherwise> The fragment is unavailable. </esi:otherwise> </esi:choose> </esi:except> </esi:try> </esi:when> <esi:otherwise> The default selection. </esi:otherwise> </esi:choose>
ESI supports the HTTP request variables and environment variables used with the <esi:environment>
tag.
This section contains the following topics:
See Section 11.4.3 for instructions on including custom variables
To refer to a variable, prefix it with a dollar sign and surround the variable name with parentheses:
$(VARIABLE_NAME)
For example:
$(HTTP_HOST)
Variables are accessed by a key as follows:
$(VARIABLE_NAME{key})
To access a variable's substructure, append the variable name with braces containing the key which is being accessed. For example:
$(HTTP_COOKIE{username})
The key is case sensitive and optional. If a key is not specified, the environment variable returns the whole content of the environment fragment. Oracle advises specifying an environment variable without a key only for testing whether the environment is empty. In the following ESI markup, $(logindata)
is a variable that is evaluated against a null
value:
<esi:environment src="/getlogindata" name="logindata"/> <esi:include src="/login/$(logindata{account})"/"> <esi:choose> <esi:when test="$(logindata) != null"> <esi:include src="/login/$(logindata{account})"/> </esi:when> <esi:otherwise> <esi:include src="/login/guest.html"/> <esi:otherwise> </esi:choose>
You can use the logical OR (|
) operator to specify a default value in the following form:
$(VARIABLE|default)
A variable takes the default value only when the variable or its key does not exist. If it evaluates to an empty string, the empty string is returned, not the default value.
The following example results in Oracle Web Cache fetching http://example.com/default.html
if the cookie id
is not in the request:
<esi:include src="http://example.com/$(HTTP_COOKIE{id}|default).html"/>
As with other literals, if whitespace must be specified, the default value must be single-quoted. For example:
$(HTTP_COOKIE{first_name}|'new user')
Note:
HTTP_HOST
and HTTP_REFERER
do not support default values.Table 11-3 lists the HTTP request variables supported by ESI. Note the following:
Except for QUERY_STRING
, the values for the variables are taken from HTTP request-header fields. In the case of QUERY_STRING
, the value is taken from either the HTTP request body or the URL.
Variables are only interpreted when enclosed within ESI tags.
Variables with a substructure type of List or Dictionary are accessed by a key.
Variables identified with a substructure type of Dictionary make access to strings available through their appropriate keys.
Dictionary keys are case sensitive.
Variables identified with a substructure type of List return a Boolean value depending on whether the requested value is present.
Table 11-3 HTTP Request Variables Supported by ESI
Variable Name | HTTP Header Field | Substructure Type/Variable Type | Description | Example |
---|---|---|---|---|
Specifies the set of languages that are preferred as a response. The language is used as the key. |
List/Boolean |
Specifies the language to use as the key and evaluates to the language specified in the HTTP request header |
Variable Setting:
HTTP Request Header Contains:
Result: Returns |
|
Specifies cookie name and value pairs. A cookie name is used as the key. If the |
Dictionary/String |
Specifies the cookie name to use as the key and returns that cookie's value |
Variable Setting:
HTTP Request Header Contains:
Result: Returns |
|
Any HTTP request header |
Dictionary/String |
Specifies an HTTP request header name to use as the key and returns that header's value |
Variable Setting:
HTTP Request Header Contains:
Result: Returns
|
|
Specifies the host name and port number of the resource. Port 80 is the default port number. |
Not Applicable/String |
Returns the value of the |
Variable Setting:
HTTP Request Header Contains:
Result: Returns
|
|
Specifies the URL of the reference resource |
Not Applicable/String |
Returns the value of the |
Variable Setting:
HTTP Request Header Contains:
Result: Returns
|
|
|
Specifies the Web browser type, browser version, or operating system that initiated the request. |
Dictionary/String |
Specifies one of three keys: |
Variable Setting:
HTTP Request Header Contains:
Result: Returns
Result: Returns
Result: Returns |
|
Not Applicable |
Dictionary/String |
Given a parameter name in a query string, returns the value of the parameter without URL encoding. The query string can be in an URL or a request body. See Also: |
Variable Setting:
Query Request Contains:
Result: Returns the value of |
|
Not Applicable |
Not Applicable/String |
Specifies to return the entire query string encoded |
Variable Setting:
Query Request Contains:
Result: Returns the entire query string encoded:
|
|
Not Applicable |
Dictionary/String |
Given a parameter name in a query string, returns the value of the parameter with URL encoding. The query string can be in an URL or a request body. |
Variable Setting:
Query Request Contains:
Result: Returns the value of
|
|
Not Applicable |
Not Applicable/String |
The same as |
Variable Setting:
Query Request Contains:
Result: Returns the entire query string encoded:
|
Not Applicable |
Dictionary/String |
The same as |
Variable Setting:
Query Request Contains:
Result: Returns the value of |
ESI uses several mechanisms to handle exceptions encountered during an ESI fragment request. In a given situation, you can make use of all mechanisms simultaneously, or use one at a time, depending on the business logic you are developing.
The first mechanism is found in the ESI language, which provides three specific elements for fine-grain control over content assembly in error scenarios:
The alt
attribute of the <esi:include>
tag
The onerror
attribute of the <esi:include>
tag
The try
|attempt
|except
block
When the fragment specified for the src
attribute of the <esi:include>
tag cannot be fetched, the fragment specified with the alt
attribute is used as an alternative. If the alt
attribute is not used or the fragment cannot be fetched, the onerror
attribute is used. The onerror
attribute is used before the try
|attempt
|except
block. If the try
|attempt
|except
block does not exist, the exception handling is propagated to the parent or template page. If all the ESI language controls fail, Oracle Web Cache displays a default page for the fragment.
See the following sections:
The <esi:inline>
and <esi:include>
tags enable applications to adopt ESI page fragmentation and assembly. The following sections describe the tags and explain when the tags are appropriate to use.
Section 11.1.8.1, "Using Inline for Non-Fetchable Fragmentation"
Section 11.1.8.2, "Using Inline for Fetchable Fragmentation"
Section 11.1.8.4, "Selecting the Fragmentation Mechanism for Your Application"
Most existing applications are only designed to output an entire Web page to HTTP requests. These fragments and templates are non-fetchable, meaning they are not to be fetched independently from the origin server. If a cache needs any of these fragments or templates, the corresponding full Web page must be requested. To use ESI page assembly for non-fetchable fragments, an application can output the full page response just as it does normally, with the exception that at the beginning and the end of each fragment, an <esi:inline>
tag is inserted with a fragment name to demarcate the fragment. Oracle Web Cache stores the enclosed portions as separate fragments and the original page as a page template without the enclosed fragments. Fragments are shared among templates if their names are identical and they are from the same site.
Example 11-4 shows a simple <esi:inline>
example. The HTML table enclosed by the <esi:inline>
tag is the fragment content. The area preceding <esi:inline name="/news101">
and the area following </esi:inline>
form the page template. If another page contains an <esi:inline>
tag with the same name "/news101"
, the two fragments logically share the same content.
Example 11-4 Inline Non-Fetchable Example
<HTML> ... <esi:inline name="/news101"> <TABLE> ... </TABLE> </esi:inline> ... </HTML>
When an application uses non-fetchable <esi:inline>
fragments, the full page must be requested for every cache miss. At first, it can appear that there is no apparent cache benefit for cache misses. However, non-fetchable <esi:inline>
fragments improves overall caching by:
Increasing the cache hit ratio
Because shared fragments can be extracted into separate fragments, the size of the dynamic portion is reduced. A reduced space requirement results in a higher cache hit ratio than full page caching.
Reducing cache update frequency
Dynamic shared fragments require only one update. For example, a shared stock market fragment may expire much more frequently than any other parts of the page. With <esi:inline>
fragmentation, only one cache update of any full page containing this fragment is enough to bring all full pages sharing this fragment current. Therefore, even non-fetchable <esi:inline>
fragments can significantly reduce cache update frequency. The cost reduction is proportional to the degree of sharing.
To invalidate non-fetchable fragments, you must invalidate both the template object and the non-fetchable fragments to ensure the fragments are invalidated.
<esi:inline>
fragments are by default non-fetchable. If an application supports independently fetchable fragments, it is possible to use the <esi:inline>
for fetchable fragments by setting the fetchable
attribute to yes
.
Example 11-5 shows an <esi:inline>
example with a fetchable fragment named /news101
. A request for the page returns the template page and the fetchable fragment.
Example 11-5 Inline Fetchable Example
<HTML> ... <esi:inline name="/news101" fetchable="yes"> <TABLE> ... </TABLE> </esi:inline> ... </HTML>
See Section 11.1.8.2 for further information about the fetchable
attribute.
The <esi:include>
tag is another way to define fragments and templates in an HTTP output for dynamic content caching and assembly. It is in many ways similar to the <esi:inline>
tag. It defines a name for the defined fragment. The page including an <esi:include>
tag is a template that references the defined fragment. However, it also has some key differences which make its applicable scenarios very different from those of <esi:inline>
:
An <esi:include>
tag in a template only defines the reference to a fragment.
It does not enclose an embedded fragment directly in the template. As a result, a template with <esi:include>
tags can be applied to multiple users. In contrast, a template with embedded <esi:inline>
tags must be unique to each user.
A fragment referenced by an <esi:include>
tag must always be independently fetchable by HTTP or HTTPS.
The requested URL equals the fragment name. In contrast, an <esi:inline>
tag's name only identifies the uniqueness of the fragment and is not used to fetch the actual content. The attribute defining the fragment name in <esi:include>
fragment is src
instead of name
.
There are at least two scenarios where using <esi:include>
tags is beneficial:
Some applications, such as a Web portal, naturally assemble content from external sources. The application only provides a template that is used to fetch various fragments from third-party sources. In this case, the <esi:include>
tags fetch and assemble directly, reducing one layer of redundancy.
Some applications offer faster responses for template-only requests than full-page requests that use <esi:inline>
tags. If <esi:include>
is used for page fragmentation and assembly, Oracle Web Cache can miss only on the templates when most or all fragments are already cached, saving effective cache miss cost. In many cases, it is also valuable to cache the personalized templates because these seldom change.
Example 11-1 shows ESI markup with <esi:include>
tags.
Although both <esi:include>
and <esi:inline>
enable Oracle Web Cache to fetch fragments for the client browser, <esi:include>
is more robust for performing this task and provides an easy way in which to manage fragments. Because <esi:include>
affects the application flow, it is best to incorporate <esi:include>
early in the design phase of an application. For an existing application, <esi:inline>
is better mechanism because it requires minimal change to your application.
When Oracle Web Cache receives a client request for a template page with a Referer
request-header field, it forwards the request with the Referer
request header to the origin server. In turn, the origin server returns fragments to Oracle Web Cache with the URL of the template as the value for the Referer
header. This functionality associates the fragment request with the template request.
Session cookie establishment for ESI templates and fragments works much the same way as typical Oracle Web Cache objects with the following additional features:
Cookie
request-header field inheritance
When a client requests an ESI template page that includes fragments, requests for fragment pages are generated in Oracle Web Cache. A fragment request inherits the Cookie
request-header field from the template request if the value of the Host
request-header field matches the value of Host
request-header field in the template request.
Set-Cookie
response-header field accumulation
When assembly of fragments is complete, Oracle Web Cache includes a Set-Cookie
response-header field in the response with the cookie information from the template. For those fragments with a Host
request-header field that matches the Host
request-header field in the template, Oracle Web Cache also accumulates the Set-Cookie
response-header fields with that of the template. For those fragments with a Host
request-header field that does not match the Host
request-header field in the template, Oracle Web Cache does not accumulate the Set-Cookie
response-header field with that of the template and other matching fragments.
See Section 11.1.6 for a description of how you can use the HTTP_COOKIE
variable in ESI markup.
For an overview of partial page caching, see Section 11.1.
This section describes how to enable dynamic assembly of Web pages with fragments and how to create rules for the cacheable and non-cacheable page fragments. It contains the following topics:
To enable partial page caching:
Configure the template page as follows:
Use ESI markup tags in the template to fetch and include the fragments.
Important:
ESI tags cannot be used on a page that contains<!-- WEBCACHETAG-->
and <!-- WEBCACHEEND-->
tags. If you require simple personalization and are using ESI, see Section 11.2.2, "Using ESI for Simple Personalization".In the template page, configure the HTTP response with the Surrogate-Control
response-header field. For example:
Surrogate-Control: max-age=30+60, content="ORAESI/9.0.4"
If the Surrogate-Control
response-header field does not include all the caching attributes required for the template page, create a caching rule for the page.
Configure the fetchable fragments:
Use a Surrogate-Control
response-header field in the HTTP response message.
If the Surrogate-Control
response-header field does not include all the caching attributes required for the fragment, create a caching rule for the fragment.
For more information, see:
Section 11.4 for further information about ESI markup tags
Section 6.10 for further information about configuring the Surrogate-Control
response-header field
Section 6.8 for further information about configuring caching rules
You can use variable expressions for simple personalization.
For example, the following HTML substitutes a user's name based on the value the client browser passes with username
cookie. In addition, the session information contained within the sessionID
cookie is used to replace session information for one user with another user.
The same effect is achieved with the following ESI markup:
<esi:vars> Welcome $(HTTP_COOKIE{'username'})! Here is a <A HREF="/jsp/myPage.jsp?sessionID=$(QUERY_STRING{'sessionid'})">link</A>. </esi:vars>
The <esi:vars>
tag enables you to use an ESI environment variable outside of an ESI tag. You can also use variables with other ESI tags.
See the following sections:
This section provides examples of ESI usage in the following topics:
Figure 11-2 shows a portal site response page, http:
//www.company.com/servlet/oportal?username=Mark
, for a registered user named Mark.
This page is assembled by Oracle Web Cache. A template page configured with ESI markup tags for a personalized greeting, weather, stocks, promotional advertisement, news, and sports fragments is assembled based on Mark's preferences. For example, because Mark chose San Francisco weather, the application looks up San Francisco weather information and puts it into the final full HTML page output. Because of its dynamic content, this page would not be cacheable. On the other hand, with ESI markup tags, Oracle Web Cache assembles and caches most of the content.
The following sections describe how the template page and its fragments are implemented using <esi:inline>
and <esi:include>
tags:
This section describes how <esi:inline>
tag fragmentation and assembly can drastically increase the value of dynamic content caching for pages that do not contain real-time elements. It shows how to apply the <esi:inline>
tag for an existing application that supports non-fetchable fragments. The <esi:inline>
tag helps reduce space consumption and improves cache hit ratios by isolating the dynamic content.
Note:
If an application supports independently fetchable fragments, it is possible to use the<esi:inline>
for fetchable fragments by setting the fetchable
attribute to yes
. See Section 11.4.5 for further information about the fetchable
attribute.To use the <esi:inline>
tag, the logical fragments in portal.esi
are marked with the <esi:inline>
tags. The personalized greeting, Weather Forecast, My Stocks, Promotion campaign, Latest News, and Latest Sports News naturally become fragments because they have individual caching properties and can be shared. The My Stock fragment is further broken down into five sub-fragments, one for each stock quote. In addition, to achieve the maximum fragment sharing, the common HTML code sections between each two personalized fragments are also enclosed as ESI fragments and are given constant names, so that the varying template contains as little common data as possible.
Example 11-6 shows portal.esi
with <esi:inline>
tags.
Example 11-6 portal.esi with inline Tags
<esi:inline name="/Common_Fragment_1" > <!-- First common fragment --> <HTML> ... <!-- Personalized Greeting With ESI variable --> Welcome, $(QUERY_STRING{username})! </esi:inline> <esi:inline name="/Weathers_San_Francisco" > ... <!-- Personalized Weather Forecast --> Weather Forecast for San Francisco <TABLE> <TR> <TD> Currently: 50F </TD> </TR> </TABLE> </esi:inline> <esi:inline name="/Common_Fragment_2" > <!-- Second common fragment --> ... </esi:inline> <esi:inline name="/Stocks_$(QUERY_STRING{username})" > <!-- Personalized Stock Quote Selections --> <TABLE> <TR> <TD> <esi:inline name="/ticker_IBM"> IBM 84.99 </esi:inline> <BR> <esi:inline name="/ticker_ORCL"> ORCL 13.379 </esi:inline> <BR> <esi:inline name="/ticker_YHOO"> YHOO 27.15 </esi:inline> <TD> </TR> </TABLE> </esi:inline> <esi:inline name="/Common_Fragment_3"> <!-- Third common fragment --> ... </esi:inline> <esi:inline name="/ExternalAdvertisement"> <!-- External Advertisement --> <TABLE> <TR> <TD> <a href="http://www.companyad.com/advert?promotionID=126532"> <img src="http://www.companyad.com/advert_img?promotionID=126532"> </a> </TD> </TR> </TABLE> </esi:inline> <esi:inline name="/Common_Fragment_4"> <!-- Fourth common fragment --> ... </esi:inline> <esi:inline name="/Top_News_Finance"> <!-- Personalized Top News --> Latest News for finance <TABLE> <TR> Tech Spending Growth Indexes Little Changes Home Sales Hit Record High Gas Prices Dip Again </TR> </TABLE> </esi:inline> <esi:inline name="/Sports_News_Soccer" > <!-- Personalized Sports News --> Latest Sports News for Soccer <TABLE> <TR> Preparation for World Cup Youth Cup game on a Sunday Latest Scores </TR> </TABLE> </esi:inline> <esi:inline name="/Common_Fragment_5" > ... </esi:inline>
Example 11-7 shows the markup for the personalized greeting. The fragment is common to all personalized pages belonging to different users. Because the <esi:inline>
tag assigns this fragment a constant name, a different user, such as John, would have the same fragment in his template with the same fragment name. Two fragments are shared if and only if their names are identical. This way, the same shared fragment in all templates only need a single update when it expires or is invalidated. $(QUERY_STRING{username})
is an ESI environment variable that provide access to value of the username
. This variable is used here because this application uses the username
query string parameter to pass along the user's name. By using this variable, the first fragment becomes common to all users.
Example 11-7 portal.esi Example with inline Tags: Personalized Greeting
<esi:inline name="/Common_Fragment_1" > <!-- First common fragment --> <HTML> ... <!-- Personalized Greeting With ESI variable --> Welcome, $(QUERY_STRING{username})! </esi:inline>
Example 11-8 shows the markup for Weather Forecast. The fragment is unique to each city. Every template selecting the same city would share this fragment with Mark's page due to the fragment naming.
Example 11-8 portal.esi Example with inline Tags: Weather Forecast
<esi:inline name="/Weathers_San_Francisco" > <!-- Personalized Weather Forecast --> Weather Forecast for San Francisco <TABLE> <TR> <TD> Currently: 50F </TD> </TR> </TABLE> </esi:inline>
Example 11-9 shows the markup for My Stocks. The stock quotes fragment encloses all stock picks in Mark's page. It is further divided into five sub-fragments, one for each stock pick, using nested <esi:inline>
tags. Thus, Mark's ESI template references his stock selection fragment, which in turn references five particular stock pick fragments. While the stock picks are shared by many user's stock selection fragment, the stock selection fragment itself is also a template uniquely owned by Mark. This markup separates the unique information from the shared information, maximizing the reduction of cache updates and space consumption of personal stock selection.
Example 11-9 portal.esi Example: My Stocks Fragment
<esi:inline name="/Stocks_$(QUERY_STRING{username})" > <!-- Personalized Stock Quote Selections --> <TABLE> <TR> <TD> <esi:inline name="/ticker_IBM"> IBM 84.99 </esi:inline> <BR> <esi:inline name="/ticker_ORCL"> ORCL 13.379 </esi:inline> <BR> <esi:inline name="/ticker_YHOO"> YHOO 27.15 </esi:inline> <TD> </TR> </TABLE> </esi:inline>
Example 11-10 shows the markup for referencing an advertisement in the Promotion section. promotionID
is the based on the user's identification.
Example 11-10 portal.esi Example with inline Tags: Promotion
<esi:inline name="/ExternalAdvertisement"> <!-- External Advertisement --> <TABLE> <TR> <TD> <a href="http://www.companyad.com/advert?promotionID=126532"> <img src="http://www.companyad.com/advert_img?promotionID=126532"> </a> </TD> </TR> </TABLE> </esi:inline>
Rotating advertisements that change in every response is an example of real- time content that renders little value in non-fetchable ESI <esi:inline>
caching. Even the smallest portion of real-time content embedded as a non-fetchable ESI inline fragment would require the entire response to be regenerated and fetched, effectively creating cache misses all the time. To use ESI and dynamic content caching for these real-time fragments, use the <esi:include>
tag.
See Section 11.2.3.1.2 for an example of using <esi:include>
tag for real-time advertisements
The Latest News and Latest Sports News fragments are similar to the weather fragment. All the common areas are also defined as fragments. Although it is possible to leave them as part of the template, that would consume unnecessary storage space. Example 11-11 shows the markup.
Example 11-11 portal.esi Example with inline Tags: Latest News and Latest Sports News
<esi:inline name="/Top_News_Finance"> <!-- Personalized Top News --> Latest News for finance <TABLE> <TR> Tech Spending Growth Indexes Little Changes Home Sales Hit Record High Gas Prices Dip Again </TR> </TABLE> </esi:inline> <esi:inline name="/Sports_News_Soccer" > <!-- Personalized Sports News --> Latest Sports News for Soccer <TABLE> <TR> Preparation for World Cup Youth Cup game on a Sunday Latest Scores </TR> </TABLE> </esi:inline>
This section shows how the <esi:include>
tag can be used for fragmentation and assembly of fetchable fragments whose content are not embedded in the template.
Example 11-12 shows portal.esi
with <esi:include>
tags.
Example 11-12 portal.esi with include Tags
<HTML> ... <!-- Personal Profile --> <esi:comment text="Profile refers to environment variables stored in /servlet/GetProfile. GetProfile servlet enables access to a set of environment variables with personal profile information."/> <esi:environment src="/servlet/GetProfile?username=$(QUERY_STRING{username})" name="Profile"/> ... <!-- Personalized Greeting With ESI variable --> <esi:vars>Welcome, $(QUERY_STRING{username})!</esi:vars> ... <!-- Personalized Weather Forecast --> <TABLE> <TR> <TD> <esi:include src="/servlet/Weather?city=$(Profile{city})&state=$(Profile{state})"/> </TD> </TR> </TABLE> ... <!-- Personalized Stock Quote Selections --> <TABLE> <TR> <TD> <esi:include src="/servlet/PersonalizedStockSelection?username=$(QUERY_STRING{username})"/> </TD> </TR> </TABLE> ... <!-- External Advertisement --> <TABLE> <TR> <TD> <esi:try> <esi:attempt> <esi:comment text="Include an ad"/> <esi:include src="/servlet/Advert"/> </esi:attempt> <esi:except> <esi:comment text="Just write an HTML link instead"/> <A HREF="http://www.oracle.com">http://www.oracle.com</a> </esi:except> </esi:try> </TD> </TR> </TABLE> ... <!-- Personalized Top News --> Latest News for <esi:vars>$(Profile{news})</esi:vars> <TABLE> <TR> <TD> <esi:choose> <esi:when test="$(Profile{news}) == 'Internet'"> <esi:include src="/servlet/News?type=Top&topic=internet"/> </esi:when> <esi:when test="$(Profile{news}) == 'finance'"> <esi:include src="/servlet/News?type=Top&topic=business"/> </esi:when> <esi:otherwise> <esi:include src="/servlet/News?type=Top&topic=technology"/> </esi:otherwise> </esi:choose> </TD> </TR> </TABLE> ... <!-- Personalized Sports News --> Latest Sports News for <esi:vars>$(Profile{sport})</esi:vars> <TABLE> <TR> <TD> <esi:choose> <esi:when test="$(Profile{sport}) == 'golf'"> <esi:include src="/servlet/News?type=Sports&topic=golf"/> </esi:when> <esi:when test="$(Profile{sport}) == 'soccer'"> <esi:include src="/servlet/News?type=Sports&topic=soccer"/> </esi:when> <esi:when test="$(Profile{sport}) == 'basketball'"> <esi:include src="/servlet/News?type=Sports&topic=basketball"/> </esi:when> <esi:when test="$(Profile{sport}) == 'baseball'"> <esi:include src="/servlet/News?type=Sports&topic=baseball"/> </esi:when> <esi:otherwise> <esi:include src="/servlet/News?type=Sports&topic=soccer"/> </esi:otherwise> </esi:choose> </TD> </TR> </TABLE>
Example 11-13 specifies Profile
to refer to the environment variables stored in GetProfile
. GetProfile
enables access to user profile variables, which are used as parameters in the included fragments:
Example 11-13 portal.esi Example: Custom Profile Environment Variable Setting
<!-- Personal Profile --> <esi:comment text="Profile refers to environment variables stored in /servlet/GetProfile. GetProfile servlet enables access to a set of environment variables with personal profile information."/> <esi:environment src="/servlet/GetProfile?username=$(QUERY_STRING{username})" name="Profile"/>
Example 11-14 shows GetProfile
, which provides access to the city
, state
, news
, and sports
environment variables.
Example 11-14 portal.esi Example: GetProfile File with Environment Variables
<?xml version="1.0"?> <esi-environment esiversion="ORAESI/9.0.4"> <city>San_Francisco</city> <state>CA</state> <news>finance</news> <sports>soccer</sports> </esi-environment>
Example 11-15 shows the markup for the personalized greeting Welcome, Mark!
. The personalized greeting is achieved by the <esi:vars>
tag, which bases the greeting on the username
parameter embedded in the URL. The parameter username
is the registered user's name. This markup enables the personalized greeting to be included in the cacheable template page.
Example 11-15 portal.esi Example with vars tag: Personalized Greeting
<esi:vars>Welcome, $(QUERY_STRING{username})!</esi:vars>
Example 11-16 shows the markup for Weather Forecast. Weather Forecast includes a servlet fragment name Weather
, which uses the value of the user's city
and state
environment variables in GetProfile
to display the correct weather forecast for the user. Because GetProfile
has a value of San Francisco
for the city
environment variable and California
for the state
environment variable, the weather forecast is for San Francisco, California.
Example 11-16 portal.esi Example with include Tags: Weather Forecast
<TABLE> <TR> <TD> <esi:include src="/servlet/Weather?city=$(Profile{city})&state=$(Profile{state})"/> </TD> </TR> </TABLE>
The markup for My Stocks is depicted in Example 11-17. My Stocks includes a servlet fragment named PersonalizedStockSelection
. The displayed stocks are based on the userID
parameter encoded in the URL. userID
is the registered user's unique ID.
Example 11-17 portal.esi Example with include Tags: My Stocks Fragment
<TABLE> <TR> <TD> <esi:include src="/servlet/PersonalizedStockSelection?username=$(QUERY_STRING{username})"/> </TD> </TR> </TABLE>
The markup for the included fragment PersonalizedStockSelection
is depicted in Example 11-18. It includes fragments for three stock quotes: IBM, ORCL, and YHOO.
Example 11-18 portal.esi Example: PersonalizedStockSelection Fragment for Mark
<TABLE> <TR> <TD> <BR> <esi:include src="Quote?symbol=IBM"/> <BR> <esi:include src="Quote?symbol=ORCL"/> <BR> <esi:include src="Quote?symbol=YHOO"/> <BR> </TD> </TR> </TABLE>
Because the output is different for each user, the PersonalizedStockSelection
fragment is not cacheable. However, the response to each of the included quotes is cacheable, enabling stock quotes to be shared by multiple users. Even when many users share quotes, only one browser reload is needed when the quotes are updated. For example, the PersonalizedStockSelection
fragment for another user named Scott is depicted in Example 11-19. It includes fragments for three stock quotes: IBM, ORCL, and SCO. As described, IBM and ORCL are also shared by Mark. If Mark reloads the page first and caches the quotes, then the IBM and ORCL quotes for Scott are automatically refreshed.
Example 11-19 portal.esi Example: PersonalizedStockSelection Fragment for Scott
<TABLE> <TR> <TD> <BR> <esi:include src="Quote?symbol=IBM"/> <BR> <esi:include src="Quote?symbol=ORCL"/> <BR> <esi:include src="Quote?symbol=SCO"/> <BR> </TD> </TR> </TABLE>
Example 11-20 shows the markup for rotating advertisements in the Promotion section. The advertisements rotates in the sense that the advertisement changes for each response. By separating the generation of the included image fragment response from the template page, Oracle Web Cache can cache the template and integrate the dynamic advertisement into the template.
Example 11-20 portal.esi Example with include Tags: Promotion
<TABLE> <TR> <TD> <esi:try> <esi:attempt> <esi:comment text="Include an ad"/> <esi:include src="/servlet/Advert"/> </esi:attempt> <esi:except> <esi:comment text="Just write an HTML link instead"/> <A HREF="www.oracle.com">www.oracle.com</a> </esi:except> </esi:try> </TD> </TR> </TABLE>
As shown in Example 11-21, the response to the included image fragment for the banner is not cacheable. When a user requests this page, Oracle Web Cache sends the request to the application Web server to generate the banner. From the application Web server, Advert
generates the banner for the request.
Example 11-21 portal.esi Example: Rotating Banner Output
<TABLE> <TR> <TD> <A HREF="http://www.companyad.com/redirect?refID=11934502"> <IMG src="http://www.companyad.com/advert_img?refID=11934502"></A> </TD> </TR> </TABLE>
As shown in Example 11-22, the next time the user reloads the page, Advert
generates another banner for the request.
Example 11-22 portal.esi Example: Rotating Banner Reload
<TABLE> <TR> <TD> <A HREF="http://www.companyad.com/redirect?refID=123456602"> <IMG src="http://www.companyad.com/advert_img?refID=123456602"></A> </TD> </TR> </TABLE>
The banner relies on alternate processing with the <esi:try>
tag. If the servlet cannot run Advert
, a link to www.oracle.com
appears in the banner's place.
Example 11-23 shows the markup for Latest News and Latest Sports News:
Latest News displays the news headlines based on the user's news
category, internet
, finance
, or technology
, by using conditional processing with the <esi:choose>
tag. Because GetProfile
has a value of finance
for the news
environment variable, the headlines displayed relate to finance, /servlet/News?type=Top&topic=business
.
Similarly, Latest Sports News displays the sports headlines based on the user's sports
category, golf
, soccer
, basketball
, baseball
, or soccer
, by using conditional processing. Because GetProfile
has a value of soccer
for the sports
environment variable, the output includes headlines relating to soccer, /servlet/News?type=Sports&topic=soccer
.
Example 11-23 portal.esi Example with include Tags: Latest News and Sports Sections
Latest News for <esi:vars>$(Profile{news})</esi:vars> <TABLE> <TR> <TD> <esi:choose> <esi:when test="$(Profile{news}) == 'internet'"> <esi:include src="/servlet/News?type=Top&topic=internet"/> </esi:when> <esi:when test="$(Profile{news}) == 'finance'"> <esi:include src="/servlet/News?type=Top&topic=business"/> </esi:when> <esi:otherwise> <esi:include src="/servlet/News?type=Top&topic=technology"/> </esi:otherwise> </esi:choose> </TD> </TR> </TABLE> ... <!-- Personalized Sports News --> Latest Sports News for <esi:vars>$(Profile{sport})</esi:vars> <TABLE> <TR> <TD> <esi:choose> <esi:when test="$(Profile{sport}) == 'golf'"> <esi:include src="/servlet/News?type=Sports&topic=golf"/> </esi:when> <esi:when test="$(Profile{sport}) == 'soccer'"> <esi:include src="/servlet/News?type=Sports&topic=soccer"/> </esi:when> <esi:when test="$(Profile{sport}) == 'basketball'"> <esi:include src="/servlet/News?type=Sports&topic=basketball"/> </esi:when> <esi:when test="$(Profile{sport}) == 'baseball'"> <esi:include src="/servlet/News?type=Sports&topic=baseball"/> </esi:when> <esi:otherwise> <esi:include src="/servlet/News?type=Sports&topic=soccer"/> </esi:otherwise> </esi:choose> </TD> </TR> </TABLE>
ESI variables can be used within an HTML tag. For example, consider Example 11-24. Its HTML code uses PL/SQL for an HTML form with a text box in it.
Example 11-24 PL/SQL Code without Personalization
htp.p('<form action="test" method="GET">'); htp.p('<table border="0" > <tr> <td><input type="text" name="p_name" size="8" value="'||p_name||'"></td> </tr> <tr> <td><input type="submit" value="Search"></td> </tr> </table>');
Example 11-25 shows how the $HTTP_COOKIE
variable is used with the <esi:vars>
tag to replace the value of p_name
with the user's name.
Example 11-25 PL/SQL Code with Personalization through ESI
htp.p('<form action="test" method="GET">'); htp.p('<table border="0" > <tr><esi:vars> <td><input type="text" name="p_name" size="8" value="$(HTTP_COOKIE{'p_name'}"></td> </tr></esi:vars> <tr> <td><input type="submit" value="Search"></td> </tr> </table>');
Inline invalidation is implemented as part of Edge Side Includes (ESI) and provides a useful way for origin servers to "piggyback" invalidation messages on transactional responses sent to Web Cache. For instance, when a customer purchases a vegetarian cookbook on an e-commerce site, the confirmation response could contain instructions for invalidating all catalog pages related to the book, its author and vegetables. The ability to send invalidation message inline reduces the connection overhead associated with sending out-of-band invalidations and is a useful tool for ESI developers.
To configure inline invalidation:
In the template page, configure the HTTP response with the Surrogate-Control
response-header field that includes content="ESI-INV/1.0"
:
Surrogate-Control: content="ESI-INV/1.0"
In the body of the same response, use the <esi:invalidate>
tag to insert either a basic or advanced inline invalidation request.
You can insert an inline invalidation request anywhere in the ESI template. You can insert multiple requests, but only the first one processes. The execution of the inline invalidation is blocking. That is, if the ESI template contains other ESI features, inline invalidation is executed first.
Basic invalidation syntax:
<esi:invalidate [output="yes"]> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <SYSTEM> <SYSTEMINFO NAME="name" VALUE="value"/> </SYSTEM> <OBJECT> <BASICSELECTOR URI="URL"/> <ACTION REMOVALTTL="TTL"/> <INFO VALUE="value"/> </OBJECT> </INVALIDATION> </esi:invalidate>
Advanced invalidation syntax:
<esi:invalidate [output="yes"]> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <SYSTEM> <SYSTEMINFO NAME="name" VALUE="value"/> </SYSTEM> <OBJECT> <ADVANCEDSELECTOR URIPREFIX="prefix" URIEXP="URL_expression" HOST="host_name:port" METHOD="HTTP_request_method" BODYEXP="HTTP_body"/> <COOKIE NAME="cookie_name" VALUE="value"/> <HEADER NAME="HTTP_request_header" VALUE="value"/> <OTHER name="URI" TYPE="SUBSTRING|REGEX" VALUE="value"/> </ADVANCEDSELECTOR> </OBJECT> </INVALIDATION> </esi:invalidate>
For more information, see:
Section 7.5.1 for invalidation request syntax
Section 11.4.6 for a description of the <esi:invalidate>
tag
Following is an example about an online bike shop using inline invalidation in their simple Web application. It has two CGI scripts written in Perl. show_bike.pl
displays how many bikes of a certain model are in stock. Since it involves database query and its result remains the same until a purchase occurs, show_bike.pl
is cached. buy_bike.pl
is used by customers to buy a bike. When this page is requested, show_bike.pl
is no longer valid—an invalidation is needed.
Example 11-26 shows the code for show_bike.pl
.
Example 11-26 show_bike.pl Code
#!/usr/local/bin/perl # first, retrieve how many bikes are in stock # and assign it to $nBikes (omitted!) print <<END; Content-Type: text/html Cache-Control: private Surrogate-Control: max-age=3600 <html> <body> <h1>Bike: model 2005</h1> <p>There are $nBikes bike(s) in stock for purchase!</p> <p>Click <a href="/cgi/buy_bike.pl">here</a> to purchase a bike.</p> </body> </html> END
Note that max-age=3600
informs Oracle Web Cache to only cache this page for up to an hour.
Example 11-27 shows the code for buy_bike.pl
with an inline invalidation request.
Example 11-27 buy_bike.pl Code with an Inline Invalidation Request
#!/usr/local/bin/perl print <<END; Content-Type: text/html Cache-Control: private Surrogate-Control: content="ESI/1.0 ESI-INV/1.0" <html> <body> <h1>Thank you for purchasing bike model 2000.</h1> <p>Click <a href="/cgi/show_bike.pl">here</a> to read more about this model.</p> <esi:invalidate> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <OBJECT> <BASICSELECTOR URI="/cgi/show_bike.pl"/> <ACTION REMOVALTTL="0"/> </OBJECT> </INVALIDATION> </esi:invalidate> <p>Thanks again!</p> </body> </html> END
The ESI-INV/1.0
token in Surrogate-Control
instructs Oracle Web Cache to process the <esi:invalidate>
tag.
Example 11-28 shows the browser response for buy_bike.pl
. Because Oracle Web Cache has already processed the inline invalidation request, the inline invalidation is not present in the response.
Example 11-28 Browser Response of buy_bike.pl
Content-Type: text/html Cache-Control: private Surrogate-Control: content="ESI/1.0 ESI-INV/1.0" <html> <body> <h1>Thank you for purchasing bike model 2000.</h1> <p>Click <a href="/cgi/show_bike.pl">here</a> to read more about this model.</p> <p>Thanks again!</p> </body> </html>
To facilitate debugging, the application developer can perform the following:
Add the Surrogate-Capability
request header that includes "ESI-INV/1.0"
:
Surrogate-Capability: content="ESI-INV/1.0"
When the Surrogate-Capability
request header is added for inline invalidation, Oracle Web Cache includes the invalidation request in the response.
Enable the output
attribute of the <esi:invalidate>
tag.
When the output
attribute is enabled, Oracle Web Cache includes the invalidation result in the response enclosed within comments <!--
result
-->
.
Example 11-29 shows the browser response of buy_bike.pl
when both the Surrogate-Capability
request header is enabled for the inline invalidation and the output
attribute of the <esi:invalidate>
tag is enabled.
Example 11-29 Browser Response of show_bike.pl with Diagnostic Inline Invalidation Information
Content-Type: text/html Cache-Control: private Surrogate-Control: content="ESI/1.0 ESI-INV/1.0" <html> <body> <h1>Thank you for purchasing bike model 2000.</h1> <p>Click <a href="/cgi/show_bike.pl">here</a> to read more about this model.</p> <esi:invalidate output="yes"> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <OBJECT> <BASICSELECTOR URI="/cgi/show_bike.pl"/> <ACTION REMOVALTTL="0"/> </OBJECT> </INVALIDATION> </esi:invalidate> <!-- <?xml version="1.0"?> <!DOCTYPE INVALIDATIONRESULT SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATIONRESULT VERSION="WCS-1.1"> <OBJECTRESULT> <BASICSELECTOR URI="/cgi/show_bike.pl/> <RESULT ID="1" STATUS="SUCCESS" NUMINV="1"/> </OBJECTRESULT> </INVALIDATIONRESULT> --> <p>Thanks again!</p> </body> </html>
This section describes the following ESI tags, which are used for partial page caching operations:
The <esi:choose>
, <esi:when>
, and <esi:otherwise>
conditional tags provide the ability to perform logic based on Boolean expressions.
<esi:choose> <esi:when test="BOOLEAN_expression"> Perform this action </esi:when> <esi:when test="BOOLEAN_expression"> Perform this action </esi:when> <esi:otherwise> Perform this other action </esi:otherwise> </esi:choose>
Each <esi:choose>
tag must have a least one <esi:when>
tag, and may optionally contain exactly one <esi:otherwise>
tag.
Oracle Web Cache executes the first <esi:when>
tag whose test attribute evaluates truthfully, and then exit the <esi:choose>
tag. If no <esi:when>
tag evaluates to true and an <esi:otherwise>
tag is present, that element's content executes.
Other HTML or ESI element can be included inside <esi:when>
or <esi:otherwise>
elements.
The test
attribute uses Boolean expressions to determine how to evaluate true or false logic. ESI supports the following Boolean operators:
==
(equal to)
!=
(not equal to)
>
(greater than)
<
(less than)
>=
(greater than or equal to)
<=
(less than or equal to)
&
(and)
|
(or)
!
(not)
Note the following about the use of Boolean expressions:
Operands associate from left to right.
Sub-expressions can be grouped with parentheses to explicitly specify association.
If both operands are numeric, then the expression is evaluated numerically.
If either operand is non-numeric, then both operands are evaluated as strings. For example, '
a
'
==3
evaluates to '
a
'
==
'
3
'
, where 3
is evaluated as a string.
The comparison of two Boolean expressions results in an undefined operation.
If an operand is empty or undefined, then the expression always evaluates to false.
The logical operators (&
, !
, and|
) are used to qualify expressions, but cannot be used to make comparisons.
Use single quotes ('
) for constant strings. For example, the following string is a valid construction:
$(HTTP_COOKIE{name})=='typical'
Escaped single quotes (\
'
) are not permitted. For example, the following is not supported:
$(HTTP_COOKIE{'user\'s name'})=='typical'
Arithmetic operations and assignments are not permitted.
A null value evaluates whether a variable is empty.
When a number is compared with null, that number is converted into an equivalent string and compared against an empty string. In the following ESI markup, $(logindata{name})
is a variable that provides access to the value of the name
. If name
is empty and evaluates to null, then the expression evaluates to true; if name
is not empty and does not evaluate to null, then the expression evaluates to false.
Note:
If a variable exists but evaluates to an empty string, then the value is not considered null.<esi:choose> <esi:when test="$(logindata{name}) == null"> <esi:include src=/login/$(logindata{name})"/> </esi:when> <esi:otherwise> <esi:include src=/login/guest.html"/> <esi:otherwise> </esi:choose>
The following expressions show correct usage of Boolean operators:
!(1==1) !('a'<='c') (1==1)|('abc'=='def') (4!=5)&(4==5)
The following expressions show incorrect usage of Boolean operators:
(1 & 4) ("abc" | "edf")
Statements must be placed inside a <esi:when>
or <esi:otherwise>
subtag. Statements outside the subtags cannot be evaluated as conditions. Example 11-30 shows invalid placement of statements.
Example 11-30 Statement Placement
<esi:choose> This markup is invalid because any characters other than whitespace are not allowed in this area. <esi:when test="$(HTTP_HOST) == 'www.company.com'"> <esi:include src="/company.html" /> </esi:when> This markup is invalid because any characters other than whitespace are not allowed in this area. <esi:when test="$(HTTP_COOKIE{fragment) == 'First Fragment'"> <img src="/img/TheImage.gif"> </esi:when> This markup is invalid because any characters other than whitespace are not allowed in this area. <esi:otherwise> The default selection. </esi:otherwise> This markup is invalid because any characters other than whitespace are not allowed in this area. </esi:choose>
The following ESI markup includes advanced.html
for requests that use the cookie Advanced
and basic.html
for requests that use the cookie Basic
:
<esi:choose> <esi:when test="$(HTTP_COOKIE{group})=='Advanced'"> <esi:include src="http://www.company.com/advanced.html"/> </esi:when> <esi:when test="$(HTTP_COOKIE{group})=='Basic User'"> <esi:include src="http://www.company.com/basic.html"/> </esi:when> <esi:otherwise> <esi:include src="http://www.company.com/new_user.html"/> </esi:otherwise> </esi:choose>
The <esi:comment>
tag enables you to comment ESI instructions, without making the comments available in the output.
<esi:comment text="text commentary"/>
<esi:comment>
is an empty element, and does not have an end tag.
The <esi:comment>
tag is not evaluated by Oracle Web Cache. If comments must be visible in the HTML output, use standard XML/HTML comment tags.
The <esi:environment>
tag enables you to include custom environment variables from included fragments. When included, these variables can then be used with the other ESI tags.
There are two forms of this tag. In the first form, <esi:environment>
does not have a closing </esi:environment>
tag:
<esi:environment src="environment_URL" name="environment_name" [max-age="expiration_time [+ removal_time]]" [method="GET|POST"] [onerror="continue"] [timeout="fetch_time"]/>
In the second form with elements, <esi:environment>
has a closing </esi:environment>
tag:
<esi:environment src="environment_URL" name="environment_name" [max-age="expiration_time [+ removal_time]"] [method="GET|POST"] [onerror="continue"] [timeout="fetch_time"]> [<esi:request_header name="request_header" value="value"/>] [<esi:request_body value="value"/>] [<esi:log>log_message</esi:log>] </esi:environment>
src
—Specifies the URL from which to obtain environment variables and their values.
The URL can be either an absolute or relative URL. When specifying an absolute URL, use the following formats:
"http://
host_name
:
port
/
path
/
filename
"
"https://
host_name
:
port
/
path
/
filename
"
If you specify the host name for an absolute URL, you must prefix it with http://
or https://
. An HTML parser treats the host:80
in the following URL as a folder name rather than a host name:
src="host:80/index.htm"
To make this URL valid, you specify the following:
src="http://host:80/index.htm"
Relative URLs are resolved relative to the template page. The result sets the ESI environment for the current template.
The source code of the URL requires the following XML format:
<?xml version="1.0"?> <esi:environment esiversion="ORAESI/9.0.4"> <variable_name>variable_value</variable_name> <variable_name>variable_value</variable_name> </esi:environment>
name
—Specifies the name to use to refer to the environment variable.
method
—Specifies the HTTP request method of the environment fragment. Valid values are GET
or POST
.
max-age
—Specifies the time, in seconds, to expire the XML file, and optionally, specifies the time, in seconds, to remove the XML file after the expiration time.
timeout
—Specifies the time, in seconds, for the fragment to be fetched. If the fragment has not been fetched within the time interval, the fetch is aborted.
onerror
—Specifies that if the fetch failed on the src
object, to ignore the ESI tag and serve the page.
request_body
—Specifies the HTTP request body of the fragment.
request_header
—Specifies an HTTP request header field and value for Oracle Web Cache to use.
log
—Specifies a log message of the fragment to be included in the access_log_file
.fragment
file when the x-esi-info
log field is set. You can provide a descriptive text string that identifies the fragment and the application that generated the fragment. By providing descriptive text, you can easily identify the fragment in the log file, enabling you to determine how often the fragment is requested.
See Table 9-5 for further information about the x-esi-info
log field.
Specify only one <esi:environment>
tag for each template page, before other ESI tags.
The attributes do not have to be in a particular order.
Do not specify multiple request_body
elements.
You can have zero or more request_header
elements.
Use multiple request_header
elements to specify multiple HTTP request header fields:
<esi:environment src="environment_URL" [max-age="expiration_time [+ removal_time]"][method="GET|POST"] [onerror="continue"] [timeout="fetch_time"]> <esi:request_header name="request_header" value="value"/> <esi:request_header name="request_header" value="value"/> </esi:environment>
If no request_header
elements are specified, Oracle Web Cache uses other request headers from the parent page.
Do not specify multiple log
elements.
For more information, see:
Section 11.1.6 for usage instructions for variables
Section 11.4.4 for usage notes on max-age
, method
, onerror
, request_body
, and request_header
Section 11.1.7 for usage notes on onerror
The following ESI output specifies logindata
to refer to the environment variables stored in catalog.xml
. The file catalog.xml
enables access to the value of the vendorID
environment variable, which is used as a parameter in the included URL:
<esi:environment src="/catalog.xml" name="logindata"/> <esi:include src="http://provider.com/intranetprovider?vendorID=$(logindata{vendorID})"/>
The file catalog.xml
has the following content:
<?xml version="1.0"?> <esi:environment esiversion="ORAESI/9.0.4"> <product_description>stereo</product_description> <vendorID>3278</vendorID> <partner1>E-Electronics</partner1> <partner2>E-City</partner2> </esi:environment>
The following ESI output specifies logindata
to refer to the environment variables stored in env.dat
. The file env.dat
enables access to the value of the env
environment variable, which is used as a parameter in the included log message for dir1.txt
. The log messages for dir1.txt
and esi-log2.html
are written to the access_log
.fragment
file when the x-esi-info
log field is set and the fragments are requested.
<esi:environment src="/esi/env.dat" name="env"> <esi:log>Used environment /esi/env.dat</esi:log> </esi:environment> <esi:include src="/cached/dir1.txt"> <esi:log>Fragment:/cache/dir1.txt is included, by $(env{xl_name})</esi:log> </esi:include> <font color="red">Including /cgi-bin/esi-fetch.sh?/esi/esi-log2.html in esi-log1.html </font> <esi:include src="/cgi-bin/esi-fetch.sh?/esi/esi-log2.html"> <esi:log>Fragment: /cgi-bin/esi-fetch.sh?/esi/esi-log2.html is included </esi:log>
The <esi:include>
tag provides syntax for including fragments.
See Section 11.1.8 for a comparison of <esi:inline>
and <esi:include>
usage.
There are two forms of this tag. In the first form, <esi:include>
does not have a closing </esi:include>
tag:
<esi:include src="URL_fragment" [alt="URL_fragment"] [max-age="expiration_time [+removal_time]]" [method="GET|POST"] [onerror="continue"] [redirect=yes|no] [timeout="fetch_time"]/>
In the second form, with elements, <esi:include>
has a closing </esi:include>
tag:
<esi:include src="URL_fragment" [alt="URL_fragment"] [max-age="expiration_time[+removal_time]"] [method="GET|POST"] [onerror="continue"] [redirect=yes|no] [timeout="fetch_time"]> [<esi:request_header name="request_header" value="value"/>] [<esi:request_body value="value"/>] [<esi:log>log_message</esi:log>] </esi:include>
src
—Specifies the URL of the fragment to fetch. The URL can be a literal string or it can include variables.
The URL can either be an absolute or relative URL. When specifying an absolute URL, use the following formats:
"http://
host_name
:
port
/
path
/
filename
"
"https://
host_name
:
port
/
path
/
filename
"
If you specify the host name for an absolute URL, you must prefix it with http://
or https://
. An HTML parser treats the host:80
in the following URL as a folder name rather than a host name:
src="host:80/index.htm"
To make this URL valid, you specify the following:
src="http://host:80/index.htm"
Relative URLs are resolved relative to the template page. The included result replaces the element in the markup served to the browser.
You can specify an XML fragment if the XML file fragment is valid XML. For example, the following specifies that Oracle Web Cache use XSL Transformations (XSLT) to transform the XML into HTML using a style sheet. The style sheet maps XML formats to HTML formats:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?>
Ensure that both the XML fragment and the XSL style sheet response pages are configured with a Content-Type
response-header field that includes text and XML media types. For example:
Content-Type: text/xml
For more information about XSLT, see http://www.w3.org/TR/xslt
.
alt
—Specifies an alternative resource if the src
is not found. The requirements for the value are the same as those for src
.
max-age
—Specifies the time, in seconds, to expire the fragment, and optionally, specifies the time, in seconds, to remove the fragment after expiration time. Use this attribute if the template page has a higher tolerance for stale fragments than specified by the time-to-live parameters in fragment responses.
method
—Specifies the HTTP request method of the fragment. Valid values are GET
or POST
.
onerror
—Specifies that if the fetch failed on the src
object to ignore the ESI tag and serve the page.
redirect
—Specifies how to serve the fragment when the src
fragment resides temporarily under a different URL. yes
specifies that the URL be redirected and displayed; no
specifies that the fragment URL not be redirected and an HTTP 302 Found
status code be served for the fragment. yes
is the default.
timeout
—Specifies the time, in seconds, for the fragment to be fetched. If the fragment has not been fetched within the time interval, the fetch is aborted.
See Section 11.1.7 for usage notes on alt
and onerror
.
request_body
—Specifies the HTTP request body of the fragment.
request_header
—Specifies an HTTP request header field and value for Oracle Web Cache to use. You can specify multiple HTTP request headers. When this attribute is specified, all request headers from the parent fragment or template page are ignored.
log
—Specifies a log message of the fragment to be included in the access_log
.fragment
file when the x-esi-info
log field is set. You can provide a descriptive text string that identifies the fragment and the application that generated the fragment. By providing descriptive text, you can easily identify the fragment in the log file, enabling you to determine how often the fragment is requested.
See Table 9-5 for further information about the x-esi-info
log field.
<esi:include>
supports up to three levels of nesting.
<esi:include>
does not support escaped double quotes (\"
). For example, the following is not supported:
<esi:include src="file\"user.htm"/>
The attributes do not have to be in a particular order.
The src
attribute supports both HTTP and HTTPS. Oracle Web Cache permits the template and fragments to use different protocols. Note the following:
If the src
attribute specifies a fragment's relative path, such as src="/PersonalizedGreeting"
, the template's protocol is used.
If the protocol used in the src
attribute does not match the protocol specified in the Site-to-Server Mapping page (Origin Servers, Sites, and Load Balancing > Site-to-Server Mapping) of Oracle Web Cache Manager, then Oracle Web Cache uses the protocol configured for the origin server in the Site-to-Server Mapping page. Oracle Web Cache also reports the following warning message to the event log:
[Date] [warning 11250] [ecid: request_id, serial_number] ESI include fragment protocol does not match origin server protocol: Origin Server Protocol=protocol URL=URL
For example, if the template page is configured with <esi:include> src="https://www.company.com:80/gifs/frag1.gif"/>
and the site-to-server mapping specifies HTTP for the origin server, then http://www.company.com:80/gifs/frag1.gif
is used and the following message appears in the event log:
[03/Feb/2005:23:16:46 +0000] [warning 11250] [ecid: 90125204378,0] ESI include fragment protocol does not match origin server protocol: Origin Server Protocol=http URL=https://www.company.com:80/gifs/frag1.gif
Do not specify multiple request_body
elements.
You can have zero or more request_header
elements.
Use multiple request_header
elements to specify multiple HTTP request header fields:
<esi:include src="URL_fragment" [max-age="expiration_time[+removal_time]"] [method="GET|POST"] [onerror="continue"] [timeout="fetch_time"]> <esi:request_header name="request_header" value="value"/> <esi:request_header name="request_header" value="value"/> </esi:include>
Do not specify multiple log
elements.
The <esi:include>
tag instructs Oracle Web Cache to fetch the fragment specified by the src
attribute.
If the include is successful, the contents of the fetched src
URL are displayed. The included object is included exactly at the point of the include tag. For example, if the include tag is in a table cell, the fetched object is displayed in the table cell.
The max-age
control directive in the Surrogate-Control
response-header field applies to the response; the max-age
attribute applies only to that particular usage of the fragment response through the <esi:include>
tag. If both the max-age
control directive in the Surrogate-Control
response-header field and the max-age
attribute are set, then the effective expiration and removal time-to-live for this particular inclusion are the longest maximum age of the expiration and the removal time-to-live, respectively. If a particular page has a greater tolerance for staleness of a fragment, then set the max-age
attribute to a longer time than the max-age
control directive. Use the max-age
attribute to increase cache hits by serving fragments stale until the removal time. max-age=infinity
specifies that the object never expires.
If method
is not set, then GET
is assumed. However, if the request_body
element is set, then POST
is assumed.
Oracle Web Cache generates the following HTTP request headers for all fragment requests:
Host
Content-Length
Surrogate-Capability
Connection
The request_header
element enables you to control HTTP headers other than these. Do not specify these HTTP request headers as request_header
attributes, as a conflict can affect the operation of Oracle Web Cache.
If no request_header
elements are specified, Oracle Web Cache uses other request headers from the parent page.
See Section 11.1.8 for a comparison of <esi:inline>
and <esi:include>
usage.
The following ESI markup includes a file named frag1.htm
. The fragment must be fetched within 60 seconds. If the fetch fails, Oracle Web Cache ignores the includes and serves the page. If the fetch succeeds, Oracle Web Cache includes the fragment. Oracle Web Cache expires the fragment after five minutes, and removes it after another eight minutes.
<esi:include src="/frag1.htm" timeout="60" maxage="300+480" onerror="continue"/>
The following ESI output includes the result of a dynamic query:
<esi:include src="/search?query=$QUERY_STRING(query)"/>
The following ESI output includes a personalized greeting, a Cookie
HTTP request header, and an HTTP request body that includes the date. Log message "Fragment: /Personalized Greeting is included"
writes to the access_log
.fragment
file when the x-esi-info
log field is set and the fragment is requested.
<esi:include src="/PersonalGreeting"> <esi:request_header name="Cookie" value="pname=Scott Tiger"/> <esi:request_body value="day=05, month=10, year=2001"/> <esi:log>Fragment: /Personalized Greeting is included</esi:log> </esi:include>
For more information, see Section 11.2.3.1 for an extended example of <esi:include>
usage.
The <esi:inline>
tag marks a fragment as a separately cacheable fragment, embedded in the HTTP response of another object. Oracle Web Cache stores and assembles these fragments independently as <esi:include>
fragments.
See Section 11.1.8 for a comparison of <esi:inline>
and <esi:include>
usage.
<esi:inline name="URL" fetchable="yes|no" [max-age="expiration_time [+ removal_time]"] [timeout="fetch_time"] Embedded HTML code </esi:inline>
name
—Specifies a unique name for the fragment in URL format.
fetchable
—yes
instructs Oracle Web Cache to fetch a fragment from the origin server when it expires. The template for the fragment is not included during this fetching process. no
instructs Oracle Web Cache to fetch the entire template from the origin server when there is a cache miss, and then try to extract all the fragments from the template.
max-age
—Specifies the time, in seconds, to expire the fragment, and optionally, specifies the time, in seconds, to remove the fragment after the expiration time. Use this attribute if the template page has a higher tolerance for stale fragments than specified by the time-to-live parameters in fragment responses.
timeout
—Specifies the time, in seconds, for the fragment to be fetched. If the fragment has not been fetched within the time interval, the fetch is aborted.
Some inline fragments are only delivered as part of an HTTP response for another object. These are not independently fetchable by Oracle Web Cache the way <esi:include>
fragments are. When a non-fetchable fragment is needed by Oracle Web Cache, it must request the object from which the inline fragment was extracted.
When a non-fetchable <esi:inline>
fragment is not found in the cache, Oracle Web Cache re-fetches the fragment's parent template. This behavior implies that the parent cannot be another non-fetchable <esi:inline>
fragment. If the parent is an <esi:inline>
non-fetchable fragment, the response returned to the browser is undefined.
For more information, see:
The following ESI output embeds financial headlines:
<esi:inline name="/Top_News_Finance"> Latest News for Finance <TABLE> <TR> Blue-Chip Stocks Cut Losses; Nasdaq Up MO French rig factory with explosives New York Times Volkswagen faces Brazil strike CNN Europe Airbuss reliability record BBC </TR> </TABLE> </esi:inline>
See Section 11.2.3.1 for an extended example of <esi:inline>
usage.
The <esi:invalidate>
tag enables you to configure an invalidation request within the response of a browser page.
Basic invalidation syntax:
<esi:invalidate [output="yes"]> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <SYSTEM> <SYSTEMINFO NAME="name" VALUE="value"/> </SYSTEM> <OBJECT> <BASICSELECTOR URI="URL"/> <ACTION REMOVALTTL="TTL"/> <INFO VALUE="value"/> </OBJECT> </INVALIDATION> </esi:invalidate>
Advanced invalidation syntax:
<esi:invalidate [output="yes"]> <?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <SYSTEM> <SYSTEMINFO NAME="name" VALUE="value"/> </SYSTEM> <OBJECT> <ADVANCEDSELECTOR URIPREFIX="prefix" URIEXP="URL_expression" HOST="host_name:port" METHOD="HTTP_request_method" BODYEXP="HTTP_body"/> <COOKIE NAME="cookie_name" VALUE="value"/> <HEADER NAME="HTTP_request_header" VALUE="value"/> <OTHER name="URI" TYPE="SUBSTRING|REGEX" VALUE="value"/> </ADVANCEDSELECTOR> <ACTION REMOVALTTL="TTL"/> <INFO VALUE="value"/> </OBJECT> </INVALIDATION> </esi:invalidate>
output
—yes
specifies that the invalidation result be included in the browser response, enclosed within comments <!--
result
-->
. no
specifies that the invalidation result not be displayed in the output. Specify a value of yes
for a test environment; specify a value of no
for a production environment.
The <esi:remove>
tag allows for specification of non-ESI markup output if ESI processing is not enabled with the Surrogate-Control
header or there is not an ESI-enabled cache.
Any HTML or ESI elements can be included within this tag, except other <esi:remove>
tags. Note that nested ESI tags are not processed.
The following ESI markup includes http://www.company.com
if the <esi:include>
content cannot be included:
<esi:include src="http://www.company.com/ad.html"/> <esi:remove> <A HREF="http://www.company.com">www.company.com</A> </esi:remove>
Normally, when Oracle Web Cache processes this example block, it fetches the ad.html
file and includes it into the template page while silently discarding the <esi:remove>
tag and its contents. If ESI processing is not enabled, all of the elements are passed through to the browser, which ignores ESI markup. However, the browser displays the <A HREF=...
> HTML link.
The <esi:try>
tag provides for exception handling. The <esi:try>
tag must contain exactly one instance of an <esi:attempt>
tag and one or more <esi:except>
tags. See Section 11.1.7 for usage notes on alt
and onerror
.
In the following form, only one <esi:except>
tag is supported:
<esi:try> <esi:attempt> Try this... </esi:attempt> <esi:except> If the attempt fails, then perform this action... </esi:except> </esi:try>
In the following form, multiple <esi:except>
tags with different types are supported:
<esi:try> <esi:attempt> Try this... </esi:attempt> <esi:except [type="type"]> If the attempt fails, then perform this action... </esi:except> <esi:except [type="type"]> Perform this action... </esi:except> <esi:except> If the attempt fails, then perform this action... </esi:except> </esi:try>
Oracle Web Cache first processes the contents of <esi:attempt>
. A failed <esi:attempt>
triggers an error and causes Oracle Web Cache to process the contents of the <esi:except>
tag.
Specify an <esi:except>
tag without a type for general errors; specify an <esi:except>
tag with a type for specific errors. The <esi:except>
tag accepts the following case-insensitive types:
nestingtoodeep
: An error occurs because the fragment include depth has exceeded the maximum include depth.
originserverbusy
: An error occurs because the origin server for this fragment is busy and cannot accept new requests now. This is caused by Oracle Web Cache-to-origin server request queue limit being reached.
noconnection
: An error occurs because the cache cannot connect to the origin server serving this fragment.
networktimeout
: An error occurs because a fragment request to the origin server has timed out in the network connection.
httpclienterror
: An error occurs because the origin server returns an HTTP 4xx status code, a client error, such as a malformed HTTP request or an unauthorized access.
httpservererror
: An error occurs because the origin server returns an HTTP 5xx status code, a server error.
incompatiblefragmentversio
n: An error occurs because a fragment's processing requirement is not supported or not compatible with the template. <!-- WEBCACHETAG-->
and <!-- WEBCACHEEND-->
processing in an ESI fragment is not compatible with ESI processing. A fragment may be plain data that does not need any processing in the cache, or it may be an ESI template itself that requires processing of ESI features supported in this release. The ESI features in use are specified by the Surrogate-Control
content
control directive.
incorrectresponseheader
: An error occurs because the response headers for a fragment causes the error.
incorrectesifragment
: An error occurs when Oracle Web Cache tries to parse or process the ESI fragment response body due to errors in the body.
incorrectxmlfragment
: An error occurs because there is an error in XSLT retrieval, parsing, or processing by Oracle Web Cache.
The following ESI markup attempts to fetch an advertisement. If the advertisement cannot be included, Oracle Web Cache includes a static link instead.
<esi:try> <esi:attempt> <esi:comment text="Include an ad"/> <esi:include src="http://www.company.com/ad1.htm"/> </esi:attempt> <esi:except> <esi:comment text="Just write some HTML instead"/> <a href=www.company.com>www.company.com</a> </esi:except> </esi:try>
The following ESI markup attempts to fetch a fragment. If the fragment cannot be included because of httpclienterror
, then Oracle Web Cache includes /cgi-bin/esi-fetch?/esi/tryNestL1.html
instead.
<esi:try> <esi:attempt> <esi:include src="/frag.html"/> </esi:attempt> <esi:except type="httpclienterror"> <esi:include src="/cgi-bin/esi-fetch?/esi/tryNestL1.html"/> </esi:except> </esi:try>
The following <esi:try>
attempts to include the fragment http://server.portal.com/pls/ppcdemo/!PCDEMO.wwpro_app_provider.execute_portlet/513104940/26
containing several HTTP request headers. If the fragment cannot be included because of various type
errors, Oracle Web Cache returns an Unknown ESI Exception
error.
<esi:try> <esi:attempt> <esi:include src="http://server.portal.com/pls/ppcdemo/!PCDEMO.wwpro_app_provider.execute_portlet/513104940/26" timeout="15000" > <esi:request_header name="X-Oracle-Device.MaxDocSize" value="0"/> <esi:request_header name="Accept" value="text/html,text/xml,text/vnd.oracle.mobilexml"/> <esi:request_header name="User-Agent" value="Mozilla/4.0 (compatible; MSIE 5.5; Windows; YComp 5.0.0.0) RPT-HTTPClient/0.3-3"/> <esi:request_header name="Device.Orientation" value="landscape"/> <esi:request_header name="Device.Class" value="pcbrowser"/> <esi:request_header name="PORTAL-SUBSCRIBER" value="us"/> <esi:request_header name="Device.Secure" value="false"/> <esi:request_header name="PORTAL-SUBSCRIBER-DN" value="dc=us,dc=oracle,dc=com"/> <esi:request_header name="PORTAL-SUBSCRIBER-GUID" value="A5EE385440E6252BE0340800208A8B00"/> <esi:request_header name="Accept-Language" value="en-us"/> <esi:request_header name="PORTAL-USER-DN" value="cn=public,cn=users,dc=us,dc=oracle,dc=com"/> <esi:request_header name="PORTAL-USER-GUID" value="A5EE55B396E22651E0340800208A8B00"/> <esi:request_header name="Content-Type" value="application/x-www-form-urlencoded"/> </esi:include> </esi:attempt> <esi:except type="incompatiblefragmentversion" > This happens when a fragment's processing requirement is not supported or not compatible with the template. </esi:except> <esi:except type="noconnection" > The cache is unable to connect to the origin server serving this fragment. </esi:except> <esi:except type="nestingtoodeep" > The fragment include depth has exceeded the maximum include depth. The default value defined in Web Cache is 3. </esi:except> <esi:except type="httpservererror" > The origin server returns an HTTP 5xx status code, a server error. </esi:except> <esi:except type="httpclienterror" > The origin server returns an HTTP 4xx status code, a client error, such as a malformed HTTP request or an unauthorized access. </esi:except> <esi:except type="incorrectresponseheader" > This happens when the response headers for a fragment cause the error. </esi:except> <esi:except type="incorrectxmlfragment" > This happens when there is any kind of error in Oracle Web Cache XSLT retrieval, parsing, or processing. </esi:except> <esi:except type="originserverbusy" > The origin server for this fragment is busy and cannot accept new requests now. This is caused by Oracle Web Cache-to-origin server request queue limit. </esi:except> <esi:except type="networktimeout" > This is thrown by a fragment whose request to the origin server has timed out in the network connection. </esi:except> <esi:except type="incorrectesifragment" > An error is encountered when Oracle Web Cache tries to parse or process the ESI fragment response body due to errors in the body. </esi:except> <esi:except> Unknown ESI Exception </esi:except> </esi:try>
The <esi:vars>
tag enables you to use variables outside of ESI tags. For example, instead of specifying a variable inside a <esi:include>
or <esi:choose>
block, you can use the <esi:vars>
tag to specify a variable inside HTML code.
If the variable does not use the complete $(
VARIABLE_NAME
{
key
})
format, Oracle Web Cache reports the following error message to the event log:
[Date] [error 12086] [ecid: request_id, serial_number]ESI syntax error. Unrecognized keyword keyword is at line line.
Do not nest the <esi:vars>
tag within an HTML code line. The following is an example of incorrect syntax:
HTML code <esi:vars>$(VARIABLE_NAME{key})</esi:vars>HTML code
For example, the following is invalid:
<IMG SRC="http://www.example.com/<esi:vars>$(HTTP_COOKIE{type})</esi:vars>/hello.gif"/>
Section 11.1.6 and Section 11.4.3 for usage of HTTP request variables and custom variables
The following ESI markup includes the cookie type
and its value as part of the included URL:
<esi:vars> <IMG SRC="http://www.example.com/$(HTTP_COOKIE{type})/hello.gif"/> </esi:vars>
The following ESI output refers to logindata
as part of the <A HREF=...>
link for the Welcome page. logindata
refers to an XML file that contains custom environment variables. The output also includes the user's sessionID
and category type
cookie values as part of the other <A HREF=...>
links.
<esi:vars> <A HREF="welcome.jsp?name=$(logindata{name})"> <A HREF="/shopping.jsp?sessionID=$(QUERY_STRING{sessionID})&type=$(QUERY_STRING{type})"> <IMG SRC="/img/shopping.gif"> </A> <A HREF="/news.jsp?sessionID=$(QUERY_STRING{sessionID})&type=$(QUERY_STRING{type})"> <IMG SRC="/img/news.gif"> </A> <A HREF="/sports.jsp?sessionID=$(QUERY_STRING{sessionID})&type=$(QUERY_STRING{type})"> <IMG SRC="/img/sports.gif"> </A> <A HREF="/fun.jsp?sessionID=$(QUERY_STRING{sessionID})&type=$(QUERY_STRING{type})"> <IMG SRC="/img/fun.gif"> </A> <A HREF="/about.jsp?sessionID=$(QUERY_STRING{sessionID})&type=$(QUERY_STRING{type})"> <IMG SRC="/img/about.gif"> </A> </esi:vars>
The <!--esi...--->
tag enables HTML marked up with ESI tags to display to the browser without processing the ESI tags. When a page is processed with this tag, Oracle Web Cache removes the starting <!--esi
and ending -->
elements, while still processing the contents of the page. When the markup cannot be processed, this tag assures that the ESI markup does not interfere with the final HTML output.
Any ESI or HTML elements can be included within this tag, except other <!--esi...-->
tags.
In the following ESI markup, the <!--esi and --> are removed in the final output. The output displays the content generated by <p><esi:vars>Hello, $(HTTP_COOKIE{name})!</esi:vars></p>, plus any surrounding text. <!--esi <p><esi:vars>Hello, $(HTTP_COOKIE{name})!</esi:vars></p> -->
If the ESI markup cannot be processed, then the <p><esi:vars>Hello, $(HTTP_COOKIE{name})!</esi:vars></p>
is displayed in the HTML output.