diff --git a/assignment/network/http/simple_webserver/beomsu/Main.java b/assignment/network/http/simple_webserver/beomsu/Main.java new file mode 100644 index 0000000..d950599 --- /dev/null +++ b/assignment/network/http/simple_webserver/beomsu/Main.java @@ -0,0 +1,11 @@ +import java.io.IOException; +import java.net.ServerSocket; + +public class Main { + + public static void main(String[] args) throws IOException { + Server server = new Server(); + + server.run(); + } +} \ No newline at end of file diff --git a/assignment/network/http/simple_webserver/beomsu/Server.java b/assignment/network/http/simple_webserver/beomsu/Server.java new file mode 100644 index 0000000..08d82bd --- /dev/null +++ b/assignment/network/http/simple_webserver/beomsu/Server.java @@ -0,0 +1,129 @@ +import java.io.*; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.*; + +public class Server { + private static final int BUFFER_SIZE = 1024; + private static final int PORT = 80; + + private Selector selector; + private ByteBuffer buffer; + + public Server() throws IOException { + selector = Selector.open(); + buffer = ByteBuffer.allocate(BUFFER_SIZE); + } + + public void run() throws IOException { + ServerSocketChannel serverChannel = ServerSocketChannel.open(); + serverChannel.socket().bind(new InetSocketAddress(PORT)); + serverChannel.configureBlocking(false); + System.out.println(PORT + "포트에 서버 소켓이 할당되었습니다."); + + serverChannel.register(selector, SelectionKey.OP_ACCEPT); + + while (true) { + int readyChannels = selector.select(); + if (readyChannels == 0) { + continue; + } + + Set selectedKeys = selector.selectedKeys(); + Iterator keyIterator = selectedKeys.iterator(); + + while (keyIterator.hasNext()) { + SelectionKey key = keyIterator.next(); + + if (key.isAcceptable()) { + handleAccept(serverChannel); + } else if (key.isReadable()) { + handleRead(key); + } + + keyIterator.remove(); + } + } + } + + private void handleAccept(ServerSocketChannel serverChannel) throws IOException { + SocketChannel clientChannel = serverChannel.accept(); + clientChannel.configureBlocking(false); + clientChannel.register(selector, SelectionKey.OP_READ); + } + + private void handleRead(SelectionKey key) throws IOException { + SocketChannel clientChannel = (SocketChannel) key.channel(); + + buffer.clear(); + int bytesRead = clientChannel.read(buffer); + + if (bytesRead == -1) { + clientChannel.close(); + key.cancel(); + return; + } + + buffer.flip(); + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + + String request = new String(data); + String[] requestLines = request.split("\n"); + String[] tokenizedStartLine = requestLines[0].split(" "); + + if (tokenizedStartLine[1].equals("/favicon.ico")) { + return; + } + + String response = sendResponse(tokenizedStartLine[1]); + clientChannel.write(ByteBuffer.wrap(response.getBytes())); + clientChannel.close(); + } + + private String sendResponse(String endpoint) throws IOException { + + StringBuilder fileContent = new StringBuilder(); + addResponseHeader(fileContent); + + if (endpoint.equals("/")) { + return generateResponse(fileContent, "/article1"); + } + + if ( + endpoint.equals("/article2") || + endpoint.equals("/article3") + ) { + return generateResponse(fileContent, endpoint); + } + + throw new IllegalArgumentException("요청받은 리소스는 존재하지 않습니다."); + } + + private void addResponseHeader(StringBuilder fileContent) { + fileContent.append(""" + HTTP/1.1 200 OK\r + Content-Type: text/html\r + \r + """); + } + + private String generateResponse(StringBuilder fileContent, String endpoint) throws IOException { + BufferedReader reader = new BufferedReader( + new FileReader(String.format("src/resource%s.html", endpoint)) + ); + + String line; + while ((line = reader.readLine()) != null) { + fileContent.append(line); + } + + reader.close(); + + return fileContent.toString(); + } +} diff --git a/assignment/network/http/simple_webserver/beomsu/resource/article1.html b/assignment/network/http/simple_webserver/beomsu/resource/article1.html new file mode 100644 index 0000000..ce2470d --- /dev/null +++ b/assignment/network/http/simple_webserver/beomsu/resource/article1.html @@ -0,0 +1,19 @@ + + + + + + 안녕하세요 나는 범수 + + +

안녕하세요 누구냐고 묻는다면 나는 범수

+
+ +
+github 프로필. 이것은 내 것. 게시글 말고 내 프로필을 보세요. +
+article2 +
+article3 + + \ No newline at end of file diff --git a/assignment/network/http/simple_webserver/beomsu/resource/article2.html b/assignment/network/http/simple_webserver/beomsu/resource/article2.html new file mode 100644 index 0000000..b34c4d2 --- /dev/null +++ b/assignment/network/http/simple_webserver/beomsu/resource/article2.html @@ -0,0 +1,15 @@ + + + + + + 안녕하세요 나는 범수 + + +

안녕하세요 누구냐고 묻는다면 나는 범수

+
+ +
+여기는 아티클 2!! github 프로필. 이것은 내 것. 게시글 말고 내 프로필을 보세요. + + \ No newline at end of file diff --git a/assignment/network/http/simple_webserver/beomsu/resource/article3.html b/assignment/network/http/simple_webserver/beomsu/resource/article3.html new file mode 100644 index 0000000..840978a --- /dev/null +++ b/assignment/network/http/simple_webserver/beomsu/resource/article3.html @@ -0,0 +1,15 @@ + + + + + + 안녕하세요 나는 범수 + + +

안녕하세요 누구냐고 묻는다면 나는 범수

+
+ +
+여기는 아티클 3!! github 프로필. 이것은 내 것. 게시글 말고 내 프로필을 보세요. + + \ No newline at end of file