/*
* ###
* Phresco File Server
*
* Copyright (C) 1999 - 2012 Photon Infotech Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ###
*/
package com.photon.phresco.fileserver;
import java.net.*;
import java.io.*;
import java.util.*;
public class PhrescoFileServer
{
public static void main(String[] args) {
// read arguments
if (args.length != 2) {
System.out.println("Usage: java FileServer <port> <wwwhome>");
System.exit(-1);
}
int port = Integer.parseInt(args[0]);
String wwwhome = args[1];
// open server socket
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
} catch (IOException e) {
System.err.println("Could not start server: " + e);
System.exit(-1);
}
System.out.println("FileServer accepting connections on port " + port);
// request handler loop
while (true) {
Socket connection = null;
try {
// wait for request
connection = socket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
OutputStream out = new BufferedOutputStream(
connection.getOutputStream());
PrintStream pout = new PrintStream(out);
// read first line of request (ignore the rest)
String request = in.readLine();
if (request == null)
continue;
log(connection, request);
while (true) {
String misc = in.readLine();
if (misc == null || misc.length() == 0)
break;
}
// parse the line
if (!request.startsWith("GET")
|| request.length() < 14
|| !(request.endsWith("HTTP/1.0") || request
.endsWith("HTTP/1.1"))) {
// bad request
errorReport(pout, connection, "400", "Bad Request",
"Your browser sent a request that "
+ "this server could not understand.");
} else {
String req = request.substring(4, request.length() - 9)
.trim();
if (req.indexOf("..") != -1 || req.indexOf("/.ht") != -1
|| req.endsWith("~")) {
// evil hacker trying to read non-wwwhome or secret file
errorReport(pout, connection, "403", "Forbidden",
"You don't have permission to access the requested URL.");
} else {
String path = wwwhome + "/" + req;
File f = new File(path);
if (f.isDirectory() && !path.endsWith("/")) {
// redirect browser if referring to directory
// without final '/'
pout.print("HTTP/1.0 301 Moved Permanently\r\n"
+ "Location: http://"
+ connection.getLocalAddress()
.getHostAddress() + ":"
+ connection.getLocalPort() + "/" + req
+ "/\r\n\r\n");
log(connection, "301 Moved Permanently");
} else {
if (f.isDirectory()) {
// if directory, implicitly add 'index.html'
path = path + "index.html";
f = new File(path);
}
try {
// send file
InputStream file = new FileInputStream(f);
pout.print("HTTP/1.0 200 OK\r\n"
+ "Content-Type: "
+ guessContentType(path) + "\r\n"
+ "Date: " + new Date() + "\r\n"
+ "Server: FileServer 1.0\r\n\r\n");
sendFile(file, out); // send raw file
log(connection, "200 OK");
} catch (FileNotFoundException e) {
// file not found
errorReport(pout, connection, "404",
"Not Found",
"The requested URL was not found on this server.");
}
}
}
}
out.flush();
} catch (IOException e) {
System.err.println(e);
}
try {
if (connection != null)
connection.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
private static void log(Socket connection, String msg) {
//System.err.println(new Date() + " ["
// + connection.getInetAddress().getHostAddress() + ":"
// + connection.getPort() + "] " + msg);
}
private static void errorReport(PrintStream pout, Socket connection,
String code, String title, String msg) {
pout.print("HTTP/1.0 " + code + " " + title + "\r\n" + "\r\n"
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+ "<TITLE>" + code + " " + title + "</TITLE>\r\n"
+ "</HEAD><BODY>\r\n" + "<H1>" + title + "</H1>\r\n" + msg
+ "<P>\r\n" + "<HR><ADDRESS>FileServer 1.0 at "
+ connection.getLocalAddress().getHostName() + " Port "
+ connection.getLocalPort() + "</ADDRESS>\r\n"
+ "</BODY></HTML>\r\n");
log(connection, code + " " + title);
}
private static String guessContentType(String path) {
if (path.endsWith(".html") || path.endsWith(".htm"))
return "text/html";
else if (path.endsWith(".txt") || path.endsWith(".java"))
return "text/plain";
else if (path.endsWith(".gif"))
return "image/gif";
else if (path.endsWith(".class"))
return "application/octet-stream";
else if (path.endsWith(".jpg") || path.endsWith(".jpeg"))
return "image/jpeg";
else
return "text/plain";
}
private static void sendFile(InputStream file, OutputStream out) {
try {
byte[] buffer = new byte[1000];
while (file.available() > 0)
out.write(buffer, 0, file.read(buffer));
} catch (IOException e) {
System.err.println(e);
}
}
}