Skip to content

Commit

Permalink
SAK-14142 Allow Portal to serve static content from WAR.
Browse files Browse the repository at this point in the history
The portal previously required that the WARs were all unpacked, this allows it to serve it’s content from a WAR that hasn’t been expanded.
  • Loading branch information
buckett committed Jul 25, 2015
1 parent 3144e06 commit 8e3b150
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Properties;
import java.util.zip.ZipEntry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
Expand All @@ -49,9 +52,10 @@
public abstract class StaticHandler extends BasePortalHandler
{

public static final int MAX_SIZE_KB = 100;
private Properties contentTypes = null;

private static final ThreadLocal<StaticCache[]> staticCacheHolder = new ThreadLocal<StaticCache[]>();
private static final ThreadLocal<StaticCache[]> staticCacheHolder = new ThreadLocal<>();

private static final Log log = LogFactory.getLog(StaticHandler.class);

Expand Down Expand Up @@ -109,21 +113,48 @@ public void doStatic(HttpServletRequest req, HttpServletResponse res, String[] p
res.sendError(404);
return;
}
InputStream inputStream;
String filename = path.substring(path.lastIndexOf("/"));
long lastModified = -1;
long length = -1;
String realPath = servletContext.getRealPath(path);
File f = new File(realPath);
if (f.length() < 100 * 1024)
if (realPath == null) {
// We not uncompressing the webapps.
URL url = servletContext.getResource(path);
inputStream = url.openStream();
if (url != null) {
try {
ZipEntry zipEntry = ((JarURLConnection)url.openConnection()).getJarEntry();
lastModified = zipEntry.getLastModifiedTime().toMillis();
length = zipEntry.getSize();
} catch (ClassCastException cce) {
// Can't get extra data, but should all work.
log.debug("We don't seem to be a JAR either.", cce);
}
} else {
res.sendError(404);
return;
}
} else {
File f = new File(realPath);
inputStream = new FileInputStream(f);
lastModified = f.lastModified();
length = f.length();
}
if (length >= 0 && length < MAX_SIZE_KB * 1024)
{
for (int i = 0; i < staticCache.length; i++)
{
StaticCache sc = staticCache[i];
if (sc != null && path.equals(sc.path))
{
if (f.lastModified() > sc.lastModified)
// If we don't have a good last modified time it's cached forever
if (lastModified > sc.lastModified)
{
sc.buffer = loadFileBuffer(f);
sc.buffer = loadFileBuffer(inputStream, (int)length);
sc.path = path;
sc.lastModified = f.lastModified();
sc.contenttype = getContentType(f);
sc.lastModified = lastModified;
sc.contenttype = getContentType(filename);
sc.added = System.currentTimeMillis();
}
// send the output
Expand Down Expand Up @@ -152,23 +183,22 @@ public void doStatic(HttpServletRequest req, HttpServletResponse res, String[] p
sc = current;
}
}
sc.buffer = loadFileBuffer(f);
sc.buffer = loadFileBuffer(inputStream, (int)length);
sc.path = path;
sc.lastModified = f.lastModified();
sc.contenttype = getContentType(f);
sc.lastModified = lastModified;
sc.contenttype = getContentType(filename);
sc.added = System.currentTimeMillis();
sendContent(res, sc);
return;

}
else
{
res.setContentType(getContentType(f));
res.addDateHeader("Last-Modified", f.lastModified());
res.setContentLength((int) f.length());
sendContent(res, f);
res.setContentType(getContentType(filename));
res.addDateHeader("Last-Modified", lastModified);
res.setContentLength((int) length);
sendContent(res, inputStream);
return;

}

}
Expand Down Expand Up @@ -206,36 +236,30 @@ protected class StaticCache
/**
* send the static content from the file
*
* @param res
* @param f
* @param res The ServletResponse to write the content to.
* @param inputStream The InputStream to read from
* @throws IOException
*/
private void sendContent(HttpServletResponse res, File f) throws IOException
private void sendContent(HttpServletResponse res, InputStream inputStream) throws IOException
{
FileInputStream fin = null;
try
{
fin = new FileInputStream(f);
res.setContentType(getContentType(f));
res.addDateHeader("Last-Modified", f.lastModified());
res.setContentLength((int) f.length());
byte[] buffer = new byte[4096];
int pos = 0;
int bsize = buffer.length;
int nr = fin.read(buffer, 0, bsize);
int nr = inputStream.read(buffer, 0, bsize);
OutputStream out = res.getOutputStream();
while (nr > 0)
{
out.write(buffer, 0, nr);
nr = fin.read(buffer, 0, bsize);
nr = inputStream.read(buffer, 0, bsize);
}

}
finally
{
try
{
fin.close();
inputStream.close();
}
catch (Exception ex)
{
Expand All @@ -247,33 +271,32 @@ private void sendContent(HttpServletResponse res, File f) throws IOException
/**
* load a file into a byte[]
*
* @param f
* @return
* @param inputStream The InputStream to read from.
* @param length The length of the input.
* @return The loaded bytes
* @throws IOException
*/
private byte[] loadFileBuffer(File f) throws IOException
private byte[] loadFileBuffer(InputStream inputStream, int length) throws IOException
{
FileInputStream fin = null;
try
{
fin = new FileInputStream(f);
byte[] buffer = new byte[(int) f.length()];
byte[] buffer = new byte[length];
int pos = 0;
int remaining = buffer.length;
int nr = fin.read(buffer, pos, remaining);
int nr = inputStream.read(buffer, pos, remaining);
while (nr > 0)
{
pos = pos + nr;
remaining = remaining - nr;
nr = fin.read(buffer, pos, remaining);
nr = inputStream.read(buffer, pos, remaining);
}
return buffer;
}
finally
{
try
{
fin.close();
inputStream.close();
}
catch (Exception ex)
{
Expand All @@ -284,12 +307,11 @@ private byte[] loadFileBuffer(File f) throws IOException
/**
* get the content type of the file
*
* @param f
* @return
* @param name The file name.
* @return The content type.
*/
String getContentType(File f)
String getContentType(String name)
{
String name = f.getName();
int dot = name.lastIndexOf(".");
String contentType = null;
if (dot >= 0 && dot < name.length())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ public int doGet(String[] parts, HttpServletRequest req,
}
};
// Check we get this correct.
assertEquals("text/javascript", handler.getContentType(new File("myfile.js")));
assertEquals("text/javascript", handler.getContentType(new File("/somepath/to/myfile.js")));
assertEquals("text/javascript", handler.getContentType(new File("another/path/myfile.js")));
assertEquals("text/javascript", handler.getContentType(new File("myfile.js").getName()));
assertEquals("text/javascript", handler.getContentType(new File("/somepath/to/myfile.js").getName()));
assertEquals("text/javascript", handler.getContentType(new File("another/path/myfile.js").getName()));
// Check trailing don't don't break things.
assertEquals("application/octet-stream", handler.getContentType(new File("file.that.ends.with.dot.")));
assertEquals("application/octet-stream", handler.getContentType(new File("file.that.ends.with.dot.").getName()));
}

@Override
Expand Down

0 comments on commit 8e3b150

Please sign in to comment.