java로 web server 만드는 과제중인데요..
조회수 280회
안녕하세요. 회사에서 java로 web server만드는 과제중인데요..
네트웍프로그래밍, http, 자바 소켓 프로그래밍에 대해서 검색도 해보고 책도 빌려봐서 개념은 알것 같은데 java 코드로 옮기려니 어떻게 해야할지 감이 안옵니다. 검색해도 문제에 나온 host 헤더에 관한 코드는 안나와서 막막합니다..
이번 주에 중간리뷰를 한다고 하는데 진전이 없습니다..
코드로 구현할 방법이 있을까요?
그리고 개발자 분들은 검색해서 나온 개념을 코드로 어떻게 옮기고 활용하시나요?
검색해서 맞는 코드가 나오지 않으면 어떻게 해야할지 모르겠습니다.
문제는..
- HTTP/1.1의 Host 헤더를 해석가능 해야한다.
예를 들어, a.com 과 b.com의 요청을 구현된 웹서버에서 도메인에 따라 다른 데이터를 제공할 수 있어야 한다.
아래는 문제 내실때 같이 주신 예제 코드입니다.
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by cybaek on 15. 5. 22..
*/
public class HttpServer {
private static final Logger logger = Logger.getLogger(HttpServer.class.getCanonicalName());
private static final int NUM_THREADS = 50;
private static final String INDEX_FILE = "index.html";
private final File rootDirectory;
private final int port;
public HttpServer(File rootDirectory, int port) throws IOException {
if (!rootDirectory.isDirectory()) {
throw new IOException(rootDirectory
+ " does not exist as a directory");
}
this.rootDirectory = rootDirectory;
this.port = port;
}
public void start() throws IOException {
ExecutorService pool = Executors.newFixedThreadPool(NUM_THREADS);
try (ServerSocket server = new ServerSocket(port)) {
logger.info("Accepting connections on port : " + server.getLocalPort());
logger.info("Document Root: " + rootDirectory);
while (true) {
try {
logger.info("Runnable Start ");
Socket request = server.accept();
Runnable r = new RequestProcessor(rootDirectory, INDEX_FILE, request);
logger.info("Runnable r1 : " + r);
pool.submit(r);
logger.info("Runnable r2 : " + r);
} catch (IOException ex) {
logger.log(Level.WARNING, "Error accepting connection", ex);
}
}
}
}
public static void main(String[] args) {
// get the Document root
File docroot;
try {
docroot = new File(args[0]);
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("Usage: java JHTTP docroot port : " + ex);
return;
}
// set the port to listen on
int port;
try {
port = Integer.parseInt(args[1]);
if (port < 0 || port > 65535) port = 80;
} catch (RuntimeException ex) {
port = 80;
}
try {
HttpServer webserver = new HttpServer(docroot, port);
webserver.start();
} catch (IOException ex) {
logger.log(Level.SEVERE, "Server could not start", ex);
}
}
}
import java.io.*;
import java.net.Socket;
import java.net.URLConnection;
import java.nio.file.Files;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RequestProcessor implements Runnable {
private final static Logger logger = Logger.getLogger(RequestProcessor.class.getCanonicalName());
private File rootDirectory;
private String indexFileName = "index.html";
private Socket connection;
public RequestProcessor(File rootDirectory, String indexFileName, Socket connection) {
if (rootDirectory.isFile()) {
throw new IllegalArgumentException(
"rootDirectory must be a directory, not a file");
}
try {
rootDirectory = rootDirectory.getCanonicalFile();
} catch (IOException ex) {
}
this.rootDirectory = rootDirectory;
if (indexFileName != null)
this.indexFileName = indexFileName;
this.connection = connection;
}
@Override
public void run() {
// for security checks
String root = rootDirectory.getPath();
logger.info("RequestProcessor Start!!!!!!!");
logger.info( "root : " + root);
try {
OutputStream raw = new BufferedOutputStream(connection.getOutputStream());
Writer out = new OutputStreamWriter(raw);
Reader in = new InputStreamReader(new BufferedInputStream(connection.getInputStream()), "UTF-8");
StringBuilder requestLine = new StringBuilder();
while (true) {
int c = in.read();
if (c == '\r' || c == '\n')
break;
requestLine.append((char) c);
}
String get = requestLine.toString();
logger.info("connection.getRemoteSocketAddress" + connection.getRemoteSocketAddress() + " " + get);
String[] tokens = get.split("\\s+");
String method = tokens[0];
String version = "";
if (method.equals("GET")) {
String fileName = tokens[1];
if (fileName.endsWith("/")) fileName += indexFileName;
String contentType =
URLConnection.getFileNameMap().getContentTypeFor(fileName);
if (tokens.length > 2) {
version = tokens[2];
}
File theFile = new File(rootDirectory, fileName.substring(1, fileName.length()));
if (theFile.canRead()
// Don't let clients outside the document root
&& theFile.getCanonicalPath().startsWith(root)) {
byte[] theData = Files.readAllBytes(theFile.toPath());
if (version.startsWith("HTTP/")) { // send a MIME header
sendHeader(out, "HTTP/1.0 200 OK", contentType, theData.length);
}
// send the file; it may be an image or other binary data
// so use the underlying output stream
// instead of the writer
raw.write(theData);
raw.flush();
} else {
// can't find the file
String body = new StringBuilder("<HTML>\r\n")
.append("<HEAD><TITLE>File Not Found</TITLE>\r\n")
.append("</HEAD>\r\n")
.append("<BODY>")
.append("<H1>HTTP Error 404: File Not Found</H1>\r\n")
.append("</BODY></HTML>\r\n")
.toString();
if (version.startsWith("HTTP/")) { // send a MIME header
sendHeader(out, "HTTP/1.0 404 File Not Found", "text/html; charset=utf-8", body.length());
}
out.write(body);
out.flush();
}
} else {
// method does not equal "GET"
String body = new StringBuilder("<HTML>\r\n").append("<HEAD><TITLE>Not Implemented</TITLE>\r\n").append("</HEAD>\r\n")
.append("<BODY>")
.append("<H1>HTTP Error 501: Not Implemented</H1>\r\n")
.append("</BODY></HTML>\r\n").toString();
if (version.startsWith("HTTP/")) { // send a MIME header
sendHeader(out, "HTTP/1.0 501 Not Implemented",
"text/html; charset=utf-8", body.length());
}
out.write(body);
out.flush();
}
} catch (IOException ex) {
logger.log(Level.WARNING, "Error talking to " + connection.getRemoteSocketAddress(), ex);
} finally {
try {
connection.close();
} catch (IOException ex) {
}
}
}
private void sendHeader(Writer out, String responseCode, String contentType, int length)
throws IOException {
out.write(responseCode + "\r\n");
Date now = new Date();
out.write("Date: " + now + "\r\n");
out.write("Server: JHTTP 2.0\r\n");
out.write("Content-length: " + length + "\r\n");
out.write("Content-type: " + contentType + "\r\n\r\n");
out.flush();
}
}
댓글 입력