package org.deftserver.web.handler;
import java.io.File;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import org.deftserver.web.http.HttpException;
import org.deftserver.web.http.HttpRequest;
import org.deftserver.web.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A RequestHandler that serves static content (files) from a predefined directory.
*
* "Cache-Control: public" indicates that the response MAY be cached by any cache, even if it would normally be
* non-cacheable or cacheable only within a non- shared cache.
*
*/
public class StaticContentHandler extends RequestHandler {
private final static Logger logger = LoggerFactory.getLogger(StaticContentHandler.class);
private final static StaticContentHandler instance = new StaticContentHandler();
private final FileTypeMap mimeTypeMap = MimetypesFileTypeMap.getDefaultFileTypeMap();
public static StaticContentHandler getInstance() {
return instance;
}
/** {inheritDoc} */
@Override
public void get(HttpRequest request, HttpResponse response) {
this.perform(request, response, true);
}
/** {inheritDoc} */
@Override
public void head(final HttpRequest request, final HttpResponse response) {
this.perform(request, response, false);
}
/**
* @param request the <code>HttpRequest</code>
* @param response the <code>HttpResponse</code>
* @param hasBody <code>true</code> to write the message body; <code>false</code> otherwise.
*/
private void perform(final HttpRequest request, final HttpResponse response, boolean hasBody) {
final String path = request.getRequestedPath();
final File file = new File(path.substring(1)); // remove the leading '/'
if (!file.exists()) {
throw new HttpException(404);
} else if (!file.isFile()) {
throw new HttpException(403, path + "is not a file");
}
final long lastModified = file.lastModified();
response.setHeader("Last-Modified", String.valueOf(lastModified));
response.setHeader("Cache-Control", "public");
String mimeType = mimeTypeMap.getContentType(file);
if ("text/plain".equals(mimeType)) {
mimeType += "; charset=utf-8";
}
response.setHeader("Content-Type", mimeType);
final String ifModifiedSince = request.getHeader("If-Modified-Since");
if (ifModifiedSince != null) {
long ims = Long.parseLong(ifModifiedSince);
if (lastModified <= ims) {
response.setStatusCode(304); //Not Modified
logger.debug("not modified");
return;
}
}
if(hasBody) {
response.write(file);
}
}
}