Skip to main content
Version: 8.2405.x.x RR

Server Push Support

The HTTP/2 protocol allows the server to PUSH responses to a client, even without a request from the client. The client can disable this feature, in which case the server may only PUSH on a request that came from the client.

The intention with the feature is to allow the server to send resources that the client that will likely need. This can be a css or javascript resource that belongs to a html page the client requested, or a set of images that is referenced by a css, etc.

The advantage for the client is that it saves the time to send the request, which may range from a few milliseconds to half a second, depending on the location of the server. The disadvantage is that the client may receive data that it already has in its cache. HTTP/2 allows for the early cancellation of such requests, but the process still may lead to inefficient use of resources.

In nevisProxy, you can configure server push support using Apache httpd as explained in the following sections.

Link </xxx.css>;rel=preload, </xxx.js>; rel=preload

If the connection supports PUSH, these two resources will be sent to the client. Depending on the configuration of the Servlet (Http(s)ConnectorServlet or BackendConnectorServlet), you may have to add a LuaFilter to rewrite this header.

info

The LuaFilters are only needed if the 'Link'-value of the AutoRewrite Parameter of the HttpConnectorServlet is disabled.

Http(s)ConnectorServlet with mappingType 'requestURI' and no URLPrefix configured

no LuaFilter needed

Http(s)ConnectorServlet with mappingType 'pathInfo' and no URLPrefix configured

        <filter>
<filter-name>AdaptLinkHeaderForPathInfoFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Script.OutputHeaderFunctionName</param-name>
<param-value>outputStream</param-value>
</init-param>
<init-param>
<param-name>Script</param-name>
<param-value>
function outputStream(req, resp)
local linkHeader = resp:getHeader("Link")
if linkHeader then
newLinkHeadr = string.gsub(linkHeader, '&lt;/([^&gt;]*)', function(url)
return '&lt;' .. tostring(req:getContextPath()) .. tostring(req:getServletPath()) .. url
end)
resp:setHeader("Link", newLinkHeadr)
end
end
</param-value>
</init-param>
</filter>

Http(s)ConnectorServlet with mappingType 'requestURI' and a URLPrefix configured

  <filter>
<filter-name>AdaptLinkHeaderForURIPrefixFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Script.OutputHeaderFunctionName</param-name>
<param-value>outputStream</param-value>
</init-param>
<init-param>
<param-name>Script</param-name>
<param-value>
function outputStream(req, resp)
local linkHeader = resp:getHeader("Link")
if linkHeader then
newLinkHeadr = string.gsub(linkHeader, '<@URIPREFIX@/([^>]*)', function(url)
return '</' .. url
end)
resp:setHeader("Link", newLinkHeadr)
end
end
</param-value>
</init-param>
</filter>

→ replace '@URIPREFIX@' with the configured URIPrefix in the Http(s)ConnectorServlet

Http(s)ConnectorServlet with mappingType 'pathInfo' and a URLPrefix configured

  <filter>
<filter-name>AdaptLinkHeaderForURIPrefixAndPathInfoFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Script.OutputHeaderFunctionName</param-name>
<param-value>outputStream</param-value>
</init-param>
<init-param>
<param-name>Script</param-name>
<param-value>
function outputStream(req, resp)
local linkHeader = resp:getHeader("Link")
if linkHeader then
newLinkHeadr = string.gsub(linkHeader, '<@URIPREFIX@/([^>]*)', function(url)
return '<' .. tostring(req:getContextPath()) .. tostring(req:getServletPath()) .. url
end)
resp:setHeader("Link", newLinkHeadr)
end
end
</param-value>
</init-param>
</filter>

→ replace '@URIPREFIX@' with the configured URIPrefix in the Http(s)ConnectorServlet

BackendConnectorServlet

no LuaFilter needed

If the backend doesn't send a Link-header, you can configure a HeaderDelegationFilter like this:

    <filter>
<filter-name>H2PushFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::delegation::HeaderDelegationFilter</filter-class>
<init-param>
<param-name>DelegateToFrontend</param-name>
<param-value>
Link:&lt;/server_push/style.css&gt;;rel=preload, &lt;/server_push/helloWorld.png&gt;; rel=preload
</param-value>
</init-param>
</filter>

The path (in the example '/server_push/style.css' and '/server_push/helloWorld.png') must be the same as if the request came directly from the frontend. If you use the same urls that are expected by the backend, then you have to map same LuaFilter as described above, depending on the configuration of the Http(s)ConnectorServlet or BackendConnectorServlet.

For more information on server push support, see the apache reference guide.