javaで超簡易HTTPサーバを作ってみた。

JDK6からcom.sun.net.httpserverパッケージに含まれるHttpServerクラスを使って
超簡易HTTPサーバを作ってみた。

ソースをgistに上げてみた。
HttpBackdoor · GitHub


使用例(windows)

javac HttpBackdoor.java
java -cp C:\;.\ HttpBackdoor 8080

使い方は、引数にポート番号を指定して起動するとそのポートでサーバが起動して、
引数無しの場合は80番でサーバが起動。
どこをドキュメントルートにするかはクラスパス指定で行う。
javaのオプションで"-cp <なんかのパス>;.\"と指定すればOK。カレントディレクトリを"最後"につける。
デフォルトだとカレントディレクトリにクラスパスが通ってるはずなので、
ドキュメントルートにしたいディレクトリでjavaコマンドを実行すればいいはず。
なので、ただ単に"java HttpBackdoor"で起動して、ブラウザでhttp://ホスト名/にアクセスすれば見れる。
javaが入ってるwindows環境でちょっと他のマシンからブラウザ経由で何かをダウンロードさせたい場合に使える・・・気がしなくもないツールw
名前にBackdoorとつけたようにセキュリティに関して何も考えてないですw
親切にも指定ディレクトリのファイル一覧が見れるようになってますよ!

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.List;
import java.util.Map.Entry;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

/**
 * usage:<br>
 *  java HttpBackdoor<br>
 *  java HttpBackdoor 8080<br>
 *  java HttpBackdoor -cp &lt;docRoot&gt;.\ 8080
 *
 * @author maji_KY
 *
 */
public class HttpBackdoor implements HttpHandler {

	private static final Class<HttpBackdoor> cls = HttpBackdoor.class;
	private static final byte[] NOT_FOUND = "<html><head><title>404 - Not Found</title></head><body>404 - Not Found</body></html>".getBytes();
	private static final byte[] SERVER_ERROR = "<html><head><title>500 - Error</title></head><body>500 - Error</body></html>".getBytes();


	/**
	 * @param args port
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {

		HttpBackdoor httpBackdoor = new HttpBackdoor();

		int port = (args.length >= 1)?Integer.parseInt(args[0]):80;

		HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);

		server.createContext("/", httpBackdoor);
		server.start();

	}

	@Override
	public void handle(HttpExchange ex)  throws IOException {

		OutputStream out = ex.getResponseBody();

		try {

			printLog(ex);
			URL url = cls.getResource(ex.getRequestURI().toString());

			if(url != null) {

				File file = new File(url.toURI());
				System.err.println(file);

				byte[] buf;
				if(file.isFile()) {
					InputStream is = cls.getResourceAsStream(ex.getRequestURI().toString());
					buf = new byte[(int) file.length()];
					is.read(buf);
					is.close();
				}else {
					StringBuilder sb = new StringBuilder("<html><title></title><body><a href=\"../\">../</a><br>\n");
					for(File f : file.listFiles()) {
						String name = f.isDirectory()?f.getName()+"/" : f.getName();
						sb.append("<a href=\"").append(name).append("\">").append(name).append("</a><br>\n");
					}
					sb.append("</body></html>");
					buf = sb.toString().getBytes();
				}

				ex.sendResponseHeaders(200, buf.length);
				out.write(buf);
				System.err.println("ok\n");
			}else {
				try {
					System.err.println("not found\n");
					ex.sendResponseHeaders(404, NOT_FOUND.length);
					out.write(NOT_FOUND);
				} catch (IOException e) {
					e.printStackTrace();
				}

			}

		} catch (Exception e) {
			System.err.println("error\n");
			ex.sendResponseHeaders(500, SERVER_ERROR.length);
			out.write(SERVER_ERROR);

			e.printStackTrace();
		} finally {
			out.close();
			ex.close();
		}

	}

	private void printLog(HttpExchange ex) {
		Headers headers = ex.getRequestHeaders();

		System.err.println(ex.getRemoteAddress());
		System.err.print(ex.getRequestMethod());
		System.err.print(" ");
		System.err.println(ex.getRequestURI());
		for(Entry<String, List<String>>  h : headers.entrySet()) {
			System.err.print(h.getKey()+":");
			System.err.println(h.getValue());
		}
		System.err.println();
	}

}

ソース見てお分かりの通り、でかいファイルにアクセスすると…