자바 웹 프로그래밍 Next Step [Chapter 3]

Wonkyun Jung·2023년 5월 8일
0

자바웹프로그래밍

목록 보기
2/2
post-thumbnail

요구사항 1. Request Handler 수정을 통해 webapp의 index.html로 접속


HelloWorld 만 출력하는 페이지에서 index.html파일을 읽어와서 화면에 출력하도록 수정

RequestHandler 수정전.java

    public void run() {
        log.debug("New Client Connect! Connected IP : {}, Port : {}", 
        connection.getInetAddress(), connection.getPort());

        try (InputStream in = connection.getInputStream(); 
        			OutputStream out = connection.getOutputStream()) {
            // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
            DataOutputStream dos = new DataOutputStream(out);
            byte[] body = "Hello World".getBytes();
            response200Header(dos, body.length);
            responseBody(dos, body);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }


RequestHandler 수정후.java

public void run() {
        log.debug("New Client Connect! Connected IP : {}, Port : {}", 
        connection.getInetAddress(),connection.getPort());

        try (InputStream in = connection.getInputStream(); 
        							OutputStream out = connection.getOutputStream()) {
            
            // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
            
            //1.사용자가 입력한 URL를 'UTF-8' 방식으로 받는다
        	BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
        	String line = br.readLine();
        	
        	//log.debug("request line : {}",line);
        	
        	//2. 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서 
        	if(line == null)return;
        	
            //3.들어온 라인을 공백기준으로 파싱해준다
        	String [] tokens = line.split(" ");
        	
            //4.URL로 부터 들어온 토큰들 확인 
        	while(!"".equals(line)) {
        		line = br.readLine();
                log.debug(tokens[i]);
        	}
        	
            
            DataOutputStream dos = new DataOutputStream(out);
            
            //5. file을 읽을 수 있게 Byte로 webapp + /index.html를 읽게 한다
            byte[] body = Files.readAllBytes(new File("./webapp"+tokens[1]).toPath());
            response200Header(dos, body.length);
            responseBody(dos, body);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
  • 4번에서 들어온 url 토큰 목록

우리가 사용할 것은 token[1]에 있는 /index.html



요구사항 2. Get 방식으로 회원가입하기



수정전에는 URL이 들어와도 아무런 매핑을 해주지 않는데 GET 방식으로 들어온 회원가입 URL을 파싱해서 User 객체에 저장해보자

RequestHandler 수정전.java

public void run() {
        log.debug("New Client Connect! Connected IP : {}, Port : {}", 
        connection.getInetAddress(),connection.getPort());

        try (InputStream in = connection.getInputStream(); 
        							OutputStream out = connection.getOutputStream()) {
            
            // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
        	BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
        	String line = br.readLine();
        	
        	if(line == null)return;
        	
            //3.들어온 라인을 공백기준으로 파싱해준다
        	String [] tokens = line.split(" ");
            
            DataOutputStream dos = new DataOutputStream(out);
            
            byte[] body = Files.readAllBytes(new File("./webapp"+tokens[1]).toPath());
            response200Header(dos, body.length);
            responseBody(dos, body);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }


RequestHandler 수정후.java

public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", 
        connection.getInetAddress(),connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = 
        											connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();

			// log.debug("request line : {}",line);

			// 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서
			if (line == null)
				return;
			
			String[] tokens = line.split(" ");
			
			String url = tokens[1];
			
			///1. user/create로 시작하는 URL이 들어올 때 처리해줌 
			if (url.startsWith("/user/create")) {
				//2. create?~~ 에서 ?의 위치를 저장
				int index = url.indexOf("?");
				
				//3. ?이후의 url을 핵심 url로 자른다
				String pointUrl = url.substring(index+1);
				
				//4. ?이후에 userId=admin&password=1234...로 들어왔을 때 
                //= 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(pointUrl);
				
				//5. User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),
                										datas.get("name"),datas.get("email"));
				log.debug("user info: {}",user);
			}
			
			else {
				DataOutputStream dos = new DataOutputStream(out);
				byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
				response200Header(dos, body.length);
				responseBody(dos, body);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}


  • 객체 생성 완료



요구사항 3 POST 방식으로 회원가입하기


요구사항 2번에서 form으로 Get 방식으로 받아서 url parsing을 통해 객체를 생성했다. 이번엔 Post 방식을 이용해서 Http 본문을 parsing 해서 객체를 생성해본다.

RequestHandler 수정전.java


public void run() {
        log.debug("New Client Connect! Connected IP : {}, Port : {}", 
        connection.getInetAddress(),connection.getPort());

        try (InputStream in = connection.getInputStream(); 
        							OutputStream out = connection.getOutputStream()) {
            
            // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
        	
            BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
        	String line = br.readLine();
        	
        	if(line == null)return;
        	
        	String [] tokens = line.split(" ");
            
            DataOutputStream dos = new DataOutputStream(out);
            
            byte[] body = Files.readAllBytes(new File("./webapp"+tokens[1]).toPath());
            response200Header(dos, body.length);
            responseBody(dos, body);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }


RequestHandler 수정후.java

public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
				connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();
			String[] tokens = line.split(" ");
			
           	//1. form을 통해 받은 회원가입 정보가 들어있는 http 본문 길이
			int contentLength = 0;
			
            System.out.println("출력 시작");
			System.out.println("-----------------------------------");
			
            while(!line.equals("")) {
				line = br.readLine();
				System.out.println(line);
				
                2. 길이에 대한 정보는 Content-Length: 90 이런식으로 나옴
                if(line.contains("Content-Length")){
					contentLength = getContentLength(line);
				}
			}
			
            System.out.println("-----------------------------------");
			System.out.println("출력 종료");
			
			// 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서
			if (line == null)
				return;

			String url = tokens[1];
			
			//4. user/create로 들어올 때 처리해줌 (post방식은 url이 달라지지 않음)
			if ("/user/create".equals(url)) {
				String body = IOUtils.readData(br, contentLength);

				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
				//User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),datas.get("name"),
           								datas.get("email"));
				log.debug("user info: {}",user);
			}
			
			else {
				DataOutputStream dos = new DataOutputStream(out);
				byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
				response200Header(dos, body.length);
				responseBody(dos, body);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    
    //3. http 메세지 parsing, message : information 으로 들어오는 것을 파싱해준다 
    private int getContentLength(String line) {
		String[] headerTokens = line.split(":");
		return Integer.parseInt(headerTokens[1].trim());
	}
  • 요청시 들어오는 HTTP 본문은 다음과 같고 우리는 여기서 요청의 본문 길이인 90에 대해서 읽어주면 된다

  • 객체 생성완료


요구사항 4 302 status code 적용

"회원가입"을 완료하면 /index.html 페이지로 이동 현재 /user/create로 유지되는 상태이기 때문에 응답으로 전달할 파일이 없음. 회원가입을 완료한 후 /index.html 페이지로 이동하게 한다.

RequestHandler 수정전.java


public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
				connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();
			String[] tokens = line.split(" ");
            
			int contentLength = 0;
			
            System.out.println("출력 시작");
			System.out.println("-----------------------------------");
			
            while(!line.equals("")) {
				line = br.readLine();
				System.out.println(line);
				
                if(line.contains("Content-Length")){
					contentLength = getContentLength(line);
				}
			}
			
            System.out.println("-----------------------------------");
			System.out.println("출력 종료");
			
			if (line == null)
				return;

			String url = tokens[1];
			
			if ("/user/create".equals(url)) {
				String body = IOUtils.readData(br, contentLength);

				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
				//User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),datas.get("name"),
           								datas.get("email"));
				log.debug("user info: {}",user);
			}
			
			else {
				DataOutputStream dos = new DataOutputStream(out);
				byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
				response200Header(dos, body.length);
				responseBody(dos, body);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    
    private int getContentLength(String line) {
		String[] headerTokens = line.split(":");
		return Integer.parseInt(headerTokens[1].trim());
	}


RequestHandler 수정후.java

public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
				connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();
			String[] tokens = line.split(" ");
			
			int contentLength = 0;
			

			while(!line.equals("")) {
				line = br.readLine();
				if(line.contains("Content-Length")){
					contentLength = getContentLength(line);
				}
			}
			
			// 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서
			if (line == null)
				return;

			String url = tokens[1];
			
			if ("/user/create".equals(url)) {
				String body = IOUtils.readData(br, contentLength);

				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
				//User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),datas.get("name"),datas.get("email"));
				log.debug("user info: {}",user);
				
				//1. response 헤더를 만들기 위해 output 객체를 만들고 이동할 url로 바꿔준다
				DataOutputStream dos = new DataOutputStream(out);
				url = "/index.html";
				response302Header(dos, url);
			}
			
			else {
				DataOutputStream dos = new DataOutputStream(out);
				byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
				response200Header(dos, body.length);
				responseBody(dos, body);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    
//2. 200 Header에서 302 Header로 변경후 요청 url로 redirect 시켜준다 
private void response302Header(DataOutputStream dos, String url) {
		try {
			dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
			dos.writeBytes("Location: " + url + "\r\n");
			dos.writeBytes("\r\n");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    


로그인이 성공하면 /index.html로 이동하고, 로그인이 실패하면 /user/login_failed.html로 이동한다 -> 여기서 앞에서 회원가입한 사용자로 로그인 할 수 있어야 하며 로그인이 성공할 경우 요청 헤더의 Cookie 헤더 값이 logined=true, 로그인이 실패하면 Cookie 헤더 값이 logined=false로 전달한다.


RequestHandler 수정전.java

public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
				connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();
			String[] tokens = line.split(" ");
			
			int contentLength = 0;
			

			while(!line.equals("")) {
				line = br.readLine();
				if(line.contains("Content-Length")){
					contentLength = getContentLength(line);
				}
			}
			
			// 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서
			if (line == null)
				return;

			String url = tokens[1];
			
			if ("/user/create".equals(url)) {
				String body = IOUtils.readData(br, contentLength);

				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
				//User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),datas.get("name"),datas.get("email"));
				log.debug("user info: {}",user);
				
				DataOutputStream dos = new DataOutputStream(out);
				url = "/index.html";
				response302Header(dos, url);
			}
			
			else {
				DataOutputStream dos = new DataOutputStream(out);
				byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
				response200Header(dos, body.length);
				responseBody(dos, body);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    
private void response302Header(DataOutputStream dos, String url) {
		try {
			dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
			dos.writeBytes("Location: " + url + "\r\n");
			dos.writeBytes("\r\n");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
    


RequestHandler 수정후.java


public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
				connection.getPort());

		try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
			// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = br.readLine();
			String[] tokens = line.split(" ");
			
			int contentLength = 0;
			

			while(!line.equals("")) {
				line = br.readLine();
				if(line.contains("Content-Length")){
					contentLength = getContentLength(line);
				}
			}
			
			// 만약에 들어온 url이 없으면 리턴해준다 -> 무한루프 막기 위해서
			if (line == null)
				return;

			String url = tokens[1];
			
			if ("/user/create".equals(url)) {
				String body = IOUtils.readData(br, contentLength);

				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
				//User 객체 생성 
				User user = new User(datas.get("userId"),datas.get("password"),datas.get("name"),datas.get("email"));
				log.debug("user info: {}",user);
				
				//Database에 유저 추가하기 
				DataBase.addUser(user);
				
				//response 헤더를 만들기 위해 output 객체를 만들고 이동할 url로 바꿔준다
				DataOutputStream dos = new DataOutputStream(out);
				url = "/index.html";
				response302Header(dos, url);
			}
			
			
            //1. login form 요청이 들어올 때 
			else if ("/user/login".equals(url)) {
				
				String body = IOUtils.readData(br, contentLength);
				
				//userId=admin&password=1234...로 들어왔을 때 = 을 기준으로 key:value parsing
				Map<String, String> datas = HttpRequestUtils.parseQueryString(body);
				
                //2. data의 userId값을 받아 DB안에 해당 id를 가진 객체가 있는지 확인
				User user = DataBase.findUserById(datas.get("userId"));
				
				//3. 해당하는 id로 회원가입한 이력이 없을 경우 loginFail로 보내준다 
				if(user == null) {
					responseResource(out, "/user/login_failed.html");
					return ;
				}
				
				//4. id와 password가 모두 일치하는 경우
				if(user.getPassword().equals(datas.get("password"))) {
					DataOutputStream dos = new DataOutputStream(out);
					response302LoginSuccessHeader(dos);
				}else {
					//5. id는 일치하나 password는 일치하지 않는 경우
					responseResource(out, "/user/login_failed.html");
				}
				
				DataOutputStream dos = new DataOutputStream(out);
				response302LoginSuccessHeader(dos);
			}
			else {
				responseResource(out, url);
			}
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
	
	private int getContentLength(String line) {
		String[] headerTokens = line.split(":");
		return Integer.parseInt(headerTokens[1].trim());
	}
	
	
	//6. Code refactoring
	private void responseResource(OutputStream out, String url) throws IOException{
		DataOutputStream dos = new DataOutputStream(out);
		byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
		response200Header(dos, body.length);
		responseBody(dos, body);
	}
	

	private void response200Header(DataOutputStream dos, int lengthOfBodyContent) {
		try {
			dos.writeBytes("HTTP/1.1 200 OK \r\n");
			dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n");
			dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
			dos.writeBytes("\r\n");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
	
	private void response302Header(DataOutputStream dos, String url) {
		try {
			dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
			dos.writeBytes("Location: " + url + "\r\n");
			dos.writeBytes("\r\n");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
	
    7. 로그인이 성공했을 때 Cookie를 설정하고 redirect할 경로를 설정
	private void response302LoginSuccessHeader(DataOutputStream dos) {
		try {
			dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
			dos.writeBytes("Set-Cookie: logined=true \r\n");
			dos.writeBytes("Location: " + "../index.html" + "\r\n");
			dos.writeBytes("\r\n");
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}
	

	private void responseBody(DataOutputStream dos, byte[] body) {
		try {
			dos.write(body, 0, body.length);
			dos.flush();
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}


  • 로그인 실패 시 다음과 같은 login_Failed.html로 보내준다

  • 로그인 성공 시 index.html로 이동한다

최종 코드

public class RequestHandler extends Thread {
    private static final Logger log = LoggerFactory.getLogger(RequestHandler.class);

    private Socket connection;

    public RequestHandler(Socket connectionSocket) {
        this.connection = connectionSocket;
    }

    public void run() {
        log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
                connection.getPort());

        try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
            BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            // url을 가져와서 line으로 받는다 
            String line = br.readLine();
            if (line == null) {
                return;
            }
            
            //request line : GET /fonts/glyphicons-halflings-regular.woff HTTP/1.1
            log.debug("request line : {}", line);
            String[] tokens = line.split(" ");

            int contentLength = 0;
            //기본적으로 로그인을 하지 않으면 false
            boolean logined = false;
            
            //Http Header에 있는 정보들을 한줄 한줄 파싱해준다 
            while (!line.equals("")) {
                line = br.readLine();
                log.debug("header : {}", line);
                //header : Host: localhost:8080로 들어온다면 Host: localhost:8080의 길이를 리턴 
                //Content-Length: 90 form으로 받으면 Content-Length가 존재
                if (line.contains("Content-Length")) {
                    contentLength = getContentLength(line);
                }
                //로그인이 되어있다면 header : Cookie: logined=true가 헤더에 포함
                if (line.contains("Cookie")) {
                    logined = isLogin(line);
                }
            }

            String url = getDefaultUrl(tokens);
            
            //form tag에서 회원가입을 하면 user.create로 보낸다  
            //<form name="question" method="post" action="/user/create">
            if ("/user/create".equals(url)) {
                //이런식으로 받은 쿼리스트링을 파싱해서 맵으로 바꿔준다 
            	String body = IOUtils.readData(br, contentLength);
                Map<String, String> params = HttpRequestUtils.parseQueryString(body);
                //User 객체 만들어주기
                User user = new User(params.get("userId"), params.get("password"), params.get("name"),
                        params.get("email"));
                log.debug("user : {}", user);
                //DB추가 
                DataBase.addUser(user);
                DataOutputStream dos = new DataOutputStream(out);
                response302Header(dos);
            } 
            //로그인 요청이 들어왔을 떄 로직처리
            else if ("/user/login".equals(url)) {
                String body = IOUtils.readData(br, contentLength);
                Map<String, String> params = HttpRequestUtils.parseQueryString(body);
                User user = DataBase.findUserById(params.get("userId"));
                //만약에 해당 id의 유저가 DB에 있고
                if (user != null) {
                	//패스워드 역시 같다면 302 response
                    if (user.login(params.get("password"))) {
                        DataOutputStream dos = new DataOutputStream(out);
                        response302LoginSuccessHeader(dos);
                    } else {
                    	//패스워드가 다르다면 fail로
                        responseResource(out, "/user/login_failed.html");
                    }
                } else {
                	//id가 DB에 없는 경우 
                    responseResource(out, "/user/login_failed.html");
                }
            } 
            
            //가입한 유저 리스트 
            else if ("/user/list".equals(url)) {
                //로그인 상태가 아니면
            	if (!logined) {
            		//로그인 하도록
                    responseResource(out, "/user/login.html");
                    return;
                }
            	
            	//DB에서 user들을 다 꺼내서 테이블 만들고 출력해준다
                Collection<User> users = DataBase.findAll();
                StringBuilder sb = new StringBuilder();
                sb.append("<table border='1'>");
                for (User user : users) {
                    sb.append("<tr>");
                    sb.append("<td>" + user.getUserId() + "</td>");
                    sb.append("<td>" + user.getName() + "</td>");
                    sb.append("<td>" + user.getEmail() + "</td>");
                    sb.append("</tr>");
                }
                sb.append("</table>");
                byte[] body = sb.toString().getBytes();
                DataOutputStream dos = new DataOutputStream(out);
                response200Header(dos, body.length);
                responseBody(dos, body);
            } else if (url.endsWith(".css")) {
                //css적용
            	responseCssResource(out, url);
            } else {
                responseResource(out, url);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
    
    //Http Header를 파싱하면서 cookie여부에 따라서 로그인이 되었는지 확인 
    private boolean isLogin(String line) {
        String[] headerTokens = line.split(":");
        Map<String, String> cookies = HttpRequestUtils.parseCookies(headerTokens[1].trim());
        String value = cookies.get("logined");
        if (value == null) {
            return false;
        }
        return Boolean.parseBoolean(value);
    }

    private void responseResource(OutputStream out, String url) throws IOException {
        DataOutputStream dos = new DataOutputStream(out);
        byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
        response200Header(dos, body.length);
        responseBody(dos, body);
    }

    private void responseCssResource(OutputStream out, String url) throws IOException {
        DataOutputStream dos = new DataOutputStream(out);
        byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
        response200CssHeader(dos, body.length);
        responseBody(dos, body);
    }

    private int getContentLength(String line) {
        String[] headerTokens = line.split(":");
        return Integer.parseInt(headerTokens[1].trim());
    }

    private String getDefaultUrl(String[] tokens) {
        String url = tokens[1];
        if (url.equals("/")) {
            url = "/index.html";
        }
        return url;
    }

    private void response200Header(DataOutputStream dos, int lengthOfBodyContent) {
        try {
            dos.writeBytes("HTTP/1.1 200 OK \r\n");
            dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n");
            dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
            dos.writeBytes("\r\n");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private void response200CssHeader(DataOutputStream dos, int lengthOfBodyContent) {
        try {
            dos.writeBytes("HTTP/1.1 200 OK \r\n");
            dos.writeBytes("Content-Type: text/css;charset=utf-8\r\n");
            dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
            dos.writeBytes("\r\n");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private void response302Header(DataOutputStream dos) {
        try {
            dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
            dos.writeBytes("Location: /index.html \r\n");
            dos.writeBytes("\r\n");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private void response302LoginSuccessHeader(DataOutputStream dos) {
        try {
            dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
            dos.writeBytes("Set-Cookie: logined=true \r\n");
            dos.writeBytes("Location: /index.html \r\n");
            dos.writeBytes("\r\n");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private void responseBody(DataOutputStream dos, byte[] body) {
        try {
            dos.write(body, 0, body.length);
            dos.writeBytes("\r\n");
            dos.flush();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
}

0개의 댓글