org.xsocket.connection.http.server.FileServiceHandler Maven / Gradle / Ivy
/*
* Copyright (c) xsocket.org, 2006 - 2008. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
* The latest copy of this software may be found on http://www.xsocket.org/
*/
package org.xsocket.connection.http.server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xsocket.DataConverter;
import org.xsocket.Execution;
import org.xsocket.connection.http.BodyDataSink;
import org.xsocket.connection.http.HttpResponse;
import org.xsocket.connection.http.HttpResponseHeader;
import org.xsocket.connection.http.InvokeOn;
import org.xsocket.connection.http.HttpRequest;
/**
* File service handler which returns the requested file
*
* @author [email protected]
*/
public final class FileServiceHandler implements IHttpRequestHandler {
private static final Logger LOG = Logger.getLogger(FileServiceHandler.class.getName());
public static final boolean SHOW_DIRECTORY_TREE_DEFAULT = false;
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
private static final Map MIME_TYPE_MAPPING = ServerUtils.getMimeTypeMapping();
private String fileBasepath = null;
private boolean isShowDirectoryTree = false;
/**
* constructor
*
* @param fileBasepath the base path
*
* @throws FileNotFoundException if the base path not exists
*/
public FileServiceHandler(String fileBasepath) throws FileNotFoundException {
this(fileBasepath, SHOW_DIRECTORY_TREE_DEFAULT);
}
/**
* constructor
*
* @param fileBasepath the base path
* @param isShowDirectoryTree true, if the directory tree will been shown, if the requests file is a directory
*
* @throws FileNotFoundException if the base path not exists
*/
public FileServiceHandler(String fileBasepath, boolean isShowDirectoryTree) throws FileNotFoundException {
this.fileBasepath = fileBasepath;
this.isShowDirectoryTree = isShowDirectoryTree;
if (!new File(fileBasepath).exists()) {
throw new FileNotFoundException("base path "+ fileBasepath + "does not exits");
}
}
/**
* {@inheritDoc}
*/
@Execution(Execution.MULTITHREADED)
@InvokeOn(InvokeOn.MESSAGE_RECEIVED)
public void onRequest(HttpRequest request, HttpResponseContext responseContext) throws IOException {
// only GET or POST is supported by this handler
if (request.getMethod().equalsIgnoreCase("GET") || request.getMethod().equalsIgnoreCase("POST")) {
String requestURI = URLDecoder.decode(request.getRequestURI(), "UTF-8");
int ctxLength = request.getContextPath().length() + request.getRequestHandlerPath().length();
if (requestURI.length() > ctxLength) {
String filepath = requestURI.substring(ctxLength, requestURI.length());
if (filepath.length() > 0) {
String path = fileBasepath + filepath;
path = path.replace("/", "\\");
if (path.endsWith("\\")) {
path = path.substring(0, path.length() - 1);
}
File file = new File(path);
if (file.exists()) {
if (file.isFile()) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine(filepath + " requested. returning data");
}
HttpResponseHeader responseHeader = new HttpResponseHeader(200);
int pos = filepath.lastIndexOf(".");
if (pos != -1) {
String extension = filepath.substring(pos + 1, filepath.length());
String mimeType = MIME_TYPE_MAPPING.get(extension);
if (mimeType != null) {
responseHeader.setContentType(mimeType);
}
}
FileChannel fc = new RandomAccessFile(file, "r").getChannel();
BodyDataSink outChannel = responseContext.send(responseHeader, (int) fc.size());
outChannel.transferFrom(fc);
outChannel.close();
fc.close();
return;
} else {
if (isShowDirectoryTree) {
if (file.isDirectory()) {
String body = printDirectoryTree(request, file);
responseContext.send(new HttpResponse(200, "text/html", body));
return;
}
}
}
} else {
if (isShowDirectoryTree) {
if (file.isDirectory()) {
String body = printDirectoryTree(request, file);
responseContext.send(new HttpResponse(200, "text/html", body));
return;
}
}
}
}
} else {
responseContext.sendError(404, request.getRequestURI() + " not found");
}
}
if (isShowDirectoryTree) {
String body = printDirectoryTree(request, new File(fileBasepath));
responseContext.send(new HttpResponse(200, "text/html", body));
return;
}
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("unsupported method " + request.getMethod() + " returning 404");
}
responseContext.sendError(404, request.getRequestURI() + " not found");
}
private String printDirectoryTree(HttpRequest request, File directory) throws IOException {
StringBuilder sb = new StringBuilder();
String dir = URLDecoder.decode(request.getRequestURI(), "UTF-8");
sb.append("\r\n");
sb.append(" \r\n");
sb.append(" Index of " + dir + " \r\n");
sb.append(" \r\n");
sb.append(" \r\n");
sb.append(" Index of " + dir + "
\r\n");
sb.append(" \r\n");
sb.append("
\r\n");
for (File file : directory.listFiles()) {
sb.append(" ");
sb.append(" ");
if (file.isDirectory()) {
sb.append("[DIR]");
} else {
sb.append("[TXT]");
}
sb.append(" \r\n");
sb.append(" ");
String path = request.getRequestURI().substring(request.getRequestHandlerPath().length() + 1, request.getRequestURI().length());
if (path.length() > 0) {
String[] parts = path.split("/");
path = parts[parts.length -1];
sb.append(" " + file.getName() + "");
sb.append(" \r\n");
sb.append(" ");
sb.append(DataConverter.toFormatedDate(file.lastModified()));
sb.append(" \r\n");
sb.append(" ");
if (!file.isDirectory()) {
sb.append(DataConverter.toFormatedBytesSize(file.length()));
} else {
sb.append("-");
}
sb.append(" \r\n");
sb.append(" ");
}
sb.append("
\r\n");
sb.append(" \r\n");
sb.append(" " + DATE_FORMAT.format(new Date()) + " xSocket-http (" +
ServerUtils.getVersionInfo() + ") at " + request.getServerName() +
" Port " + request.getServerPort() + "
\r\n");
sb.append(" \r\n");
sb.append("\r\n");
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy