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
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" ;
}
}
하는 일은 거의 비슷함
네. 잘 보 았 으 ㅂ 니 다.
우왕굳~
ㅈㄴ 길다;;;