Rust코드

<!-- HTML generated using hilite.me -->
use std::io::{Read,Write}; #[derive(Debug)] enum Method{ Get, Post, Put, Delete } struct HttpRequest{ method:Method, path:String } fn decode_url(url:&str)->String{ let mut res = Vec::<u8>::new(); let mut iter = url.bytes(); /* TODO: 귀찮으니 포기 */ return String::from( url); } use std::net::TcpStream; impl HttpRequest{ fn parse(stream:&mut TcpStream)->Option<HttpRequest>{ let req_line = Self::read_header_line(stream).unwrap(); //println!("{}",req_line); let req = match Self::parse_req_line(&req_line){ Some(v)=>v, None=>return None }; //println!("{:?}",req); return Some(HttpRequest{ method:req.0, path:decode_url(req.1) }); } fn read_header_line(stream:&mut TcpStream)->Option<String>{ let mut s = Vec::<u8>::new(); let mut byte = [0u8;1]; loop{ let res = stream.read(&mut byte); if let Err(e) = res{ //eprintln!("{}:{} {:?}",file!(), line!(), e); return None; } //let l = res.unwrap(); //println!("{}",l); s.push(byte[0]); if byte[0] != b'\n'{ continue; } return match String::from_utf8(s){ Ok(v)=>Some(v), Err( _ )=>None }; } } fn parse_req_line(line:&str)->Option<(Method, &str)>{ let mut spliter = line.split(' '); let it = spliter.next(); if let None = it{ return None; } let it = it.unwrap(); let method = match it{ "GET"=>Method::Get, "POST"=>Method::Post, "PUT"=>Method::Put, "DELETE"=>Method::Delete, _=>{return None;} }; let it = spliter.next(); if let None = it{ return None; } let path = it.unwrap(); return Some((method, path)); } } struct Response{ } impl Response{ fn not_found(mut stream:TcpStream){ stream.write_all(b"HTTP/1.1 404 NOT FOUND\\r\\nConnection: Clouse;\\r\\n\\r\\n").unwrap(); stream.flush(); } fn send_file(mut stream:TcpStream, path:&str){ let path = format!(".{}",path); let path = path.replace("../",""); let mut file = match std::fs::File::open(path){ Ok(v)=>v, Err(e)=>{ Self::not_found(stream); return; } }; stream.write_all(b"HTTP/1.1 200 OK\\r\\nConnection: Clouse;\\r\\n").unwrap(); let meta = file.metadata().unwrap(); let content_length = format!("Content-Type: application/octet-stream\\r\\nContent-Length: {}\\r\\n\\r\\n",meta.len()); stream.write_all(content_length.as_bytes()).unwrap(); let mut buffer = [0u8;4096]; loop{ let read_size = file.read(&mut buffer).unwrap(); if read_size == 0{ break; } stream.write_all(&buffer[..read_size]).unwrap(); stream.flush(); } stream.flush(); } } fn main() { let server = std::net::TcpListener::bind("0.0.0.0:2017").expect("Tcp 소켓 초기화 실패"); for it in server.incoming(){ if let Err(e) = it{ eprintln!("{:?}",e); continue; } let stream = it.unwrap(); std::thread::spawn(move||{ let mut stream = stream; stream.nodelay(); let request = HttpRequest::parse(&mut stream); if let None = request{ Response::not_found(stream); return; } let request = request.unwrap(); match request.method{ Method::Get=>Response::send_file(stream, &request.path), _=>Response::not_found(stream) }; }); } }

Java

<!-- HTML generated using hilite.me -->
import java.io.*; import java.net.*; import java.util.StringTokenizer; public class Webserver { public static void main(String[] args){ ServerSocket listener = null; try{ listener = new ServerSocket(6789); } catch (Exception e){ e.printStackTrace(); return; } while(true){ Socket stream = null; try{ stream = listener.accept(); } catch(Exception e){ e.printStackTrace(); continue; } Thread worker = null; try { worker = new Thread(new HttpRequest(stream)); } catch(Exception e){ e.printStackTrace(); continue; } //System.out.println("worker start!"); worker.start(); } } } final class HttpRequest implements Runnable { final static String CRLF = "\\r\\n"; Socket socket; // Constructor public HttpRequest(Socket socket) throws Exception { this.socket = socket; } // Implement the run() method of the Runnable interface. public void run() { try { processRequest(); } catch (Exception e) { System.out.println(e); } } private void processRequest() throws Exception { System.out.printf("worker start! %s\\n",socket.getLocalAddress().toString()); // Get a reference to the socket's input and output streams. InputStream is = socket.getInputStream(); DataOutputStream os = new DataOutputStream(socket.getOutputStream()); // Set up input stream filters. BufferedReader br = new BufferedReader(new InputStreamReader(is)); // Get the request line of the HTTP request message. String requestLine = br.readLine(); // Extract the filename from the request line. StringTokenizer tokens = new StringTokenizer(requestLine); tokens.nextToken(); // skip over the method, which should be "GET" String fileName = tokens.nextToken(); // Prepend a "." so that file request is within the current directory. fileName = "." + fileName ; // Open the requested file. FileInputStream fis = null ; boolean fileExists = true ; try { fis = new FileInputStream(fileName); } catch (FileNotFoundException e) { fileExists = false ; } // Debug info for private use System.out.println("Incoming!!!"); System.out.println(requestLine); String headerLine = null; while ((headerLine = br.readLine()).length() != 0) { System.out.println(headerLine); } // Construct the response message. String statusLine = null; String contentTypeLine = null; String entityBody = null; if (fileExists) { statusLine = "HTTP/1.0 200 OK" + CRLF; contentTypeLine = "Content-Type: " + contentType(fileName) + CRLF; } else { statusLine = "HTTP/1.0 404 Not Found" + CRLF; contentTypeLine = "Content-Type: text/html" + CRLF; entityBody = "<HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>" + "<BODY>Not Found</BODY></HTML>"; } // Send the status line. os.writeBytes(statusLine); // Send the content type line. os.writeBytes(contentTypeLine); // Send a blank line to indicate the end of the header lines. os.writeBytes(CRLF); // Send the entity body. if (fileExists) { sendBytes(fis, os); fis.close(); } else { os.writeBytes(entityBody) ; } // Close streams and socket. os.close(); br.close(); System.out.printf("worker end! %s\n",socket.getLocalAddress().toString()); socket.close(); } private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception { // Construct a 1K buffer to hold bytes on their way to the socket. byte[] buffer = new byte[1024]; int bytes = 0; // Copy requested file into the socket's output stream. while ((bytes = fis.read(buffer)) != -1) { os.write(buffer, 0, bytes); } } private static String contentType(String fileName) { if(fileName.endsWith(".htm") || fileName.endsWith(".html")) { return "text/html"; } if(fileName.endsWith(".ram") || fileName.endsWith(".ra")) { return "audio/x-pn-realaudio"; } return "application/octet-stream" ; } }

하는 일은 거의 비슷함