You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2014/07/30 19:11:20 UTC
svn commit: r1614716 -
/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java
Author: sobryan
Date: Wed Jul 30 17:11:19 2014
New Revision: 1614716
URL: http://svn.apache.org/r1614716
Log:
TRINIDAD-2498: ResourceServlet does not preserve outgoing headers from URLConnection
* Added code to preserve the headers if needed.
Modified:
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java?rev=1614716&r1=1614715&r2=1614716&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java Wed Jul 30 17:11:19 2014
@@ -34,6 +34,9 @@ import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -759,26 +762,59 @@ public class ResourceServlet extends Htt
}
catch (IOException exception)
{
- lastModified = -1;
+ lastModified = 0;
}
- if (lastModified >= 0)
+ if (lastModified == 0)
response.setDateHeader("Last-Modified", lastModified);
- // If we're not in debug mode, set cache headers
- if (!_debug)
+ //Handle cache controls. So this is a bit complex and confusing. If
+ //either of the cache headers are provide AND we are not in debug mode
+ //then we should set the cache to a default value. This is to maintain
+ //backward compatibility. If, however, the expiration or cache control
+ //headers are provided, we should just use those.
+ String cacheControl = connection.getHeaderField("cache-control");
+ Long expires = connection.getExpiration();
+
+ if (!_debug && null == cacheControl && 0 == expires)
{
// We set two headers: Cache-Control and Expires.
// This combination lets browsers know that it is
// okay to cache the resource indefinitely.
// Set Cache-Control to "Public".
- response.setHeader("Cache-Control", "Public");
-
- // Set Expires to current time + one year.
- long currentTime = System.currentTimeMillis();
-
- response.setDateHeader("Expires", currentTime + ONE_YEAR_MILLIS);
+ cacheControl = "Public";
+ expires = System.currentTimeMillis() + ONE_YEAR_MILLIS;
+ }
+
+ if(null != cacheControl)
+ {
+ response.setHeader("Cache-Control", cacheControl);
+ }
+
+ if(0 != expires)
+ {
+ response.setDateHeader("Expires", expires);
+ }
+
+ Map<String, List<String>> headerMap = connection.getHeaderFields();
+ if(null != headerMap) //There are some wonkey impl's out there, best to guard against null
+ {
+ //put additional headers
+ for(Map.Entry<String, List<String>> entry: connection.getHeaderFields().entrySet())
+ {
+ //We handled a number of headers above and there are others we might want
+ //to exclude. We test for those headers here.
+ String key = entry.getKey();
+ if(Arrays.binarySearch(_INCLUDED_HEADERS, key.toLowerCase()) >= 0 && null != entry.getValue())
+ {
+ //Header is not excluded, add all the entries
+ for(String value:entry.getValue())
+ {
+ response.addHeader(key, value);
+ }
+ }
+ }
}
}
@@ -939,11 +975,58 @@ public class ResourceServlet extends Htt
// Size of buffer used to read in resource contents
private static final int _BUFFER_SIZE = 2048;
-
+
private volatile boolean _debug;
private volatile ConcurrentMap<String, ResourceLoader> _loaders;
private volatile ConcurrentMap<String, Class<?>> _loaderErrors;
private volatile FacesContextFactory _facesContextFactory;
private volatile Lifecycle _lifecycle;
private volatile ProjectStage _projectStage;
+
+ //There are only a handful of headers that this servlet supports being propigated
+ //to the server. Headers must be included in this white-list in order to be sent
+ //over. The reason we provide a white-list instead of a black-list is primarily
+ //for security.
+ private static final String[] _INCLUDED_HEADERS;
+
+ static
+ {
+ //Here are some notable headers that are missing from the list:
+ // "Content-Type" - Set directly on the response
+ // "Last-Modified" - Sets directly on the response
+ // "Cache-Control" - This is added because the servlet sets its own
+ // "Expires" - This is addded because the servlet sets its own
+ // "Server" - This should reflect THIS server
+ // "Set-Cookie" - Cookies, right now, are not preserved in the client.
+ // We are a proxy, we need better cookie handling.
+ // "Status" - Returned by the servlet container
+ // "Via" - Intentionally mask any proxying behind the firwall
+ // "WWW-Authenticate" - This should be handled by this servlet
+ // "Allow" - Returned by this servlet
+
+ String[] tempArray = new String[]
+ {
+ "age",
+ "content-language",
+ "content-location",
+ "content-md5",
+ "content-disposition",
+ "content-range",
+ "date",
+ "link",
+ "p3p",
+ "refresh",
+ "retry-after",
+ "strict-transport-security",
+ "trailer",
+ "transfer-encoding",
+ "vary",
+ "warning"
+ };
+
+ //Ensure the items are in natural order so they can be binary searched.
+ Arrays.sort(tempArray);
+
+ _INCLUDED_HEADERS = tempArray;
+ }
}