Mercurial Hosting > nabble
view src/cachingfilter/FileHandler.java @ 66:3fbe9cb2e325 default tip
security
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 18 Sep 2024 03:51:47 -0600 |
parents | 7ecd1a4ef557 |
children |
line wrap: on
line source
package cachingfilter; import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import javax.servlet.ServletOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.jetty.io.nio.DirectNIOBuffer; import org.eclipse.jetty.server.AbstractHttpConnection; public abstract class FileHandler { abstract void close(); abstract InputStream getInputStream(); abstract void writeTo(ServletOutputStream out) throws IOException; public interface Factory { public FileHandler newInstance(File file) throws IOException; } private static final Logger logger = LoggerFactory.getLogger(FileHandler.class); private static abstract class BufferedFactory implements Factory { abstract DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException; public FileHandler newInstance(File file) throws IOException { final DirectNIOBuffer fileBuffer = getDirectNIOBuffer(file); return new FileHandler() { void close() {} InputStream getInputStream() { return new BufferInputStream(fileBuffer); } void writeTo(ServletOutputStream out) throws IOException { if (out instanceof AbstractHttpConnection.Output) { logger.trace("sendFileContent using AbstractHttpConnection.Output"); ((AbstractHttpConnection.Output)out).sendContent(fileBuffer); } else { fileBuffer.writeTo(out); } } }; } } public static final Factory mappedFile = new BufferedFactory() { private MappedByteBuffer map(File file) throws IOException { FileInputStream fis = new FileInputStream(file); try { return fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); } finally { fis.close(); } } DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException { return new DirectNIOBuffer(map(file),true); } }; public static final Factory memFile = new BufferedFactory() { DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException { int len = (int)file.length(); DirectNIOBuffer buffer = new DirectNIOBuffer(len); InputStream is = new FileInputStream(file); buffer.readFrom(is,len); is.close(); return buffer; } }; public static final Factory ioFile = new Factory() { public FileHandler newInstance(File file) throws IOException { final InputStream in = new BufferedInputStream(new FileInputStream(file)); return new FileHandler() { void close() { try { in.close(); } catch(IOException e) { logger.error("",e); } } InputStream getInputStream() { return in; } void writeTo(ServletOutputStream out) throws IOException { byte[] a = new byte[8192]; while(true) { int n; try { n = in.read(a); } catch(IOException e) { throw new RuntimeException(e); } if( n == -1 ) break; out.write(a,0,n); } } }; } }; public static final Factory mappedOrIoFile = new Factory() { public FileHandler newInstance(File file) throws IOException { try { return mappedFile.newInstance(file); } catch(IOException e) { if( !"Operation not permitted".equals(e.getMessage()) ) throw e; logger.warn("couldn't map "+file+" length="+file.length(),e); return ioFile.newInstance(file); } } }; public static Factory factory = mappedFile; // change for other implementations }