%@
page session="false"%><%@
page errorPage="error.jsp"%><%@
page import="java.net.URL"%><%@
page import="java.net.URLConnection"%><%@
page import="java.net.MalformedURLException"%><%@
page import="java.io.ByteArrayOutputStream"%><%@
page import="java.io.BufferedInputStream"%><%@
page import="java.io.BufferedReader"%><%@
page import="java.io.InputStream"%><%@
page import="java.io.PipedInputStream"%><%@
page import="java.io.PipedOutputStream"%><%@
page import="java.io.Reader"%><%@
page import="java.util.zip.GZIPOutputStream "%><%@
page import="java.io.IOException"%><%!
// ~~~~
// Design Note:
// Use redirects to prevent proxy caches to mix up
// responses for various clients.
// ~~~~
// ~~~~~~~~~~~~~
public class JavascriptResource extends Object
{
private String mURL;
private String mContentType = "text/html";
private long mLastModified;
private long mExpires;
private String mGzipString;
private byte[] mCharArray;
// list of browsers that are supported, sort with most
// common on top:
private final String[] mAcceptedAgents = {
"Mozilla/4.0 (compatible; MSIE 5.5;",
"Mozilla/4.0 (compatible; MSIE 5.01;",
"Mozilla/5.0",
};
public JavascriptResource(String url)
throws MalformedURLException, IOException
{
if (url == null)
throw new IllegalArgumentException("JavascriptResource(): no URL");
mURL = url;
initResource();
}
/**
* Returns true if the User-Agent header from the request
* is found in the mAcceptedAgents array.
* Uses String.indexOf to match against mAcceptedAgents.
*/
private boolean acceptGzip(HttpServletRequest request)
{
if (request == null) {
throw new IllegalArgumentException("acceptGzip: no request");
}
final String agent = request.getHeader("User-Agent");
if (agent == null) {
return false;
}
for (int i = 0; i < mAcceptedAgents.length; i++) {
if (agent.indexOf(mAcceptedAgents[i]) >= 0) {
return true;
}
}
return false;
}
/**
* Retrieve the contents of the file at mURL and
* compress it.
*/
private void initResource()
throws MalformedURLException, IOException
{
final URL httpresource = new URL(mURL);
final URLConnection conn = httpresource.openConnection();
mContentType = conn.getContentType();
mLastModified = conn.getLastModified();
mExpires = conn.getExpiration();
final Object obj = conn.getContent();
if (!(obj instanceof InputStream)) {
throw new RuntimeException(
"initResource(): Not a valid resource, of type " +
obj.getClass().getName());
}
mCharArray = new byte[conn.getContentLength()];
BufferedInputStream in = new BufferedInputStream((InputStream)obj);
int c;
for (int i = 0;(c = in.read()) != -1; i++) {
mCharArray[i] = (byte)c;
}
mGzipString = compress(mCharArray);
}
// Gzip compress the given array and return the
// compressed String.
// This seems to work best with JspWriter...
private String compress(byte[] chararray)
throws IOException
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(os);
gzos.write(chararray, 0, chararray.length);
gzos.close();
os.close();
return os.toString();
}
/**
* Send the response to the client and close
* the JspWriter connection stream.
*/
public void write(
JspWriter out,
HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
if (!acceptGzip(request)) {
response.sendRedirect(response.encodeURL(mURL));
}
response.setStatus(200);
response.setContentType(mContentType);
response.addHeader("Content-Encoding", "gzip");
if (mLastModified > 0l) {
response.addDateHeader("Last-Modified", mLastModified);
}
if (mExpires > 0l) {
response.addDateHeader("Expires", mExpires);
}
out.write(mGzipString);
out.close();
}
} // ~~~~~~ end JavascriptResource class ~~~~~~
%><%
// Get resource with the r argument:
JavascriptResource h =
new JavascriptResource(request.getParameter("r"));
// Return the resource, gzipped if possible
h.write(out, request, response);
%>