-------------------------------------------------------------
# 3ì¥: ê°ë° íê²½ êµ¬ì¶ ë° ì¹ ìë² ììµ ì구ì¬í
## 3-0. ìë¡
- 3ì¥ì ì ë°ì ì¸ êµ¬ì± ë´ì©
1. ì§ë¬¸/ëµë³ ê²ìíì ëí ìë¹ì¤ ì구ì¬íê³¼ ì¤ìµ ì구ì¬í ì ì
2. Web Clientì ìë²ê°ì ë°ì´í° íµì ì ìí HTTP Web Application Server 구ì¶
3. Localìì Web Application ê°ë°
4. ë²ì ê´ë¦¬ ìì¤í
ìì ìì¤ ì½ë ê´ë¦¬
5. ê°ë°í Applicationì ì격 ìë²ì ë°°í¬
## 3-1. ìë¹ì¤ ì구 ì¬í
- ì§ë¬¸/ëµë³ ê²ìíì ì구ì¬íì ì¬ì©ìì íë¦ ìì¼ë¡ ì´í´ë³´ì
1. ì§ë¬¸/ëµë³ ê²ìí
1. Headerìì íìê°ì
, ë¡ê·¸ì¸, ë¡ê·¸ìì, ê°ì¸ì ë³´ ìì ì´ ê°ë¥
2. íìê°ì
í´ë¦ ì íì ê°ì
íì´ì§ë¡ ì´ë
3. ë¡ê·¸ì¸ ë²í¼ì ë르면 ë¡ê·¸ì¸ íì´ì§ë¡ ì´ë ë° ë¡ê·¸ì¸ ê°ë¥
4. ì§ë¬¸ ëª©ë¡ íë©´ìì ì§ë¬¸ í´ë¦ ì ê° ì§ë¬¸ì ìì¸ë³´ê¸° íë©´ì¼ë¡ ì´ë
1. ëµë³ ì¶ê° ë° ìì /ìì ê°ë¥
## 3-2. ë¡ì»¬ ê°ë° íê²½ 구ì¶
- 기본ì ì¼ë¡ Java 8 Versionê³¼ ì´í´ë¦½ì¤ë¥¼ ì´ì©íì¬ êµ¬ì±ëë¤. (ë¬¼ë¡ ë³ê²½ë ê°ë¥)
- ì´í´ë¦½ì¤ì Git Perspective를 ì´ì©í ë°©ë²
1. https://github.com/slipp/web-application-server ìì Project를 ìì ì Repositoryì Forkíë¤.
2. ì´í´ë¦½ì¤ì Git Perspectiveìì Forkí Repository를 Git clone íë¤.
3. cloneí íë¡ì í¸ë¥¼ ë¡ì»¬ í´ëì Importíë¤.
4. Importí íë¡ì í¸ìì **WebServer.java**를 Java Applicationì¼ë¡ ì¤ííë¤.
5. âHello worldâê° ì ì¶ë ¥ëëì§ íì¸
- í°ë¯¸ëìì Git Cloneí í Import íë ë°©ë²
- [https://www.youtube.com/watch?v=5hjYe_PggJI](https://www.youtube.com/watch?v=5hjYe_PggJI)
## 3-3. ì격 ìë²ì ë°°í¬
- ì°¸ê³ ì íë¸ ìì
1. íê¸ ì¸ì½ë© ì¤ì , ìë° 8 ì¤ì¹ ë° ì¤ì , Maven ì¤ì¹ ë° ê³¼ì
1. [https://www.youtube.com/watch?v=dWGzApCuF9M](https://www.youtube.com/watch?v=dWGzApCuF9M)
2. Git ì¤ì¹, Github ì ì¥ì Clone, ë©ì´ë¸ì íì©í ë¹ë, HTTP ì¹ ìë² ìì, ìì¤ ì½ë ìì ì ì¬ë°°í¬ ê³¼ì
1. [https://www.youtube.com/watch?v=N8iLAuAo-Qw](https://www.youtube.com/watch?v=N8iLAuAo-Qw)
### 3-3-0. AWS EC2 ì¤ì
- EC2
- EC2ë AWSìì ì ê³µíë **í´ë¼ì°ë ì»´í¨í
ìë¹ì¤**ë¡ ìë§ì¡´ì´ ê° ì¸ê³ì 구ì¶í ë°ì´í° ì¼í°ì ìë²ì© ì»´í¨í°ë¤ì ììì ì격ì¼ë¡ ì¬ì©í ì ìë ìë¹ì¤ì´ë¤. (ì¦ í ëì ì»´í¨í°ë¥¼ ìë íë ê²!!)
- EC2 ì¤ì
1. ìë§ì¡´ ì¹ ìë¹ì¤(AWS)ì ì ìíì¬ ë¡ê·¸ì¸ì íë©´ ë¤ìê³¼ ê°ì íë©´ì ë³¼ ì ìëë° ì¬ê¸°ì EC2를 ì ííì¬ âì¸ì¤í´ì¤ ììâì í´ë¦ íë¤.


2. ì¸ì¤í´ì¤ ììì ë르면 Amazon Machine Image(AMI) ë° ì¸ì¤í´ì¤ ì íì ì íí ì ìë íì´ì§ë¡ ëì´ê°ë¤. ì´ ë¶ë¶ìì í리 í°ì´ì Ubuntu 22.04 LTS ë²ì ì ì ííë¤.
í리 í°ì´ë¥¼ ì¬ì©íë¤ë©´ ì¸ì¤í´ì¤ì ì íì **t2.mircro**ë¡ ê³ ì ì´ë¤.



3. í¤ íì´ë EC2 ìë²ì SSH ì ìì ìí´ íìì ì¸ ë¶ë¶ì´ë¤.
**ì í¤íì´ ìì±**âì íµí´ í¤ íì´ë¥¼ ìì± íë©´ `[keyì´ë¦].pem` íì¼ì´ ë¤ì´ë¡ë ëëë° ì´ íì¼ì ìì¹ì ê°ì ssh ëª
ë ¹ì ìííë©´ ëë¤. ë¨!! í ë² ë¤ì´ë°ì íìë ì¬ ë¤ì´ë¡ëê° ë¶ê°ë¥í기 ë문ì ë°±ì
ì´ íìíë¤.

4. ë¤í¸ìí¬ë ë³´ì 그룹ì ë°ë¡ ìì±íëë¡ íìì¼ë©° SSH í¸ëí½ì ê²½ì° **ìì¹ ë¬´ê´**ì¼ë¡ ì´ì´ëìë¤. ë³´ì ì í¹ì ipìì ì ìíëë¡ ì¤ì í´ì¼ íì§ë§ íì¬ë ì¤í°ë를 ìí ê²ì´ë¯ë¡ ì´ë IPììë ì ìì´ ê°ë¥íëë¡ íìë¤. ì¤í ë¦¬ì§ êµ¬ì±ì ê²½ì° í리 í°ì´ë ìµë 30GB ë²ì© SSD를 ì¬ì©í ì ìì´ì 29GB를 í ë¹íìë¤.

5. ì¤ì ì´ ëë í ì¸ì¤í´ì¤ ììì ë르면 ì¸ì¤í´ì¤ ìì± ìë£ ë©ìì§ê° ëì¤ë©°, ì¸ì¤í´ì¤ íì¼ë¡ ê° ë³´ë©´ ìì±í ì¸ì¤í´ì¤ë¥¼ ë³¼ ì ìë¤.

6. AWS EC2 ì¸ì¤í´ì¤ë ìë²ë¥¼ ì¤ì§íê³ ë¤ì ì¤ííë©´ Public IPê° ë³ê²½ë기 ë문ì Rebootì í´ë ì¬ì©í ì ìë IPê° íìíë¤.
íë ¥ì IPë ë§ë¤ì´ëê³ ì¬ì©íì§ ìëë¼ë ê³¼ê¸ì´ ë기 ë문ì íìí ë§í¼ë§ ìì±íì!
ë©ë´ì âíë ¥ì IPâ를 í´ë¦íì¬ âíë ¥ì IP 주ì í ë¹âì ì ííë¤.

7. 기본 Defaultë¡ í ë¹ì í´ì£¼ë©´ ëë¤.

8. ê·¸ í ìì±í íë ¥ì IPì ìì±í EC2 ì¸ì¤í´ì¤ë¥¼ ì°ê²°íë©´ ì¸ì¤í´ì¤ì IPê° íë ¥ì IPë¡ ê³ ì ë¨ì ì ì ìë¤.

9. ì´ì ì¸ì¤í´ì¤ë¥¼ ì°ê²°í´ë³´ì.
ì íí ì¸ì¤í´ì¤ìì ì¤ë¥¸ìª½ ë§ì°ì¤ í´ë¦ ì ì¸ì¤í´ì¤ ì°ê²° ì 보를 ìë ¤ì£¼ê¸´ íì§ë§ ë§¤ë² ì´ë°ìì¼ë¡ ì°ê²°íë©´ ë§¤ì° ë¶í¸íë¤. ì´ë **í¸ì¤í¸ë¥¼ ë±ë¡íë ë°©ë²**ì ì¬ì©íë©´ ê°ë¨íê² ì ìí ì ìë¤.
- ì°ì í¤ íì¼ì´ ìë í´ëì ê°ì í°ë¯¸ë ì¤í í í¤ íì¼ì´ ê¶íì ë³ê²½íë¤.
```bash
$ chmod 400 "본ì¸ì í¤ íì¼ ì´ë¦".pem
```
- ê·¸ í í¤ íì´ íì¼ì `~/.ssh/`ë¡ ë³µì¬íê³ (ë°±ì
) ë³µì¬í í¤ íì¼ ê¶íì ë³ê²½íë¤.
```bash
$ cp "본ì¸ì í¤ íì¼ ì´ë¦".pem ~/.ssh/
$ cd ~/.ssh
$ chmod 600 "본ì¸ì í¤ íì¼ ì´ë¦".pem
```
- ê·¸ í `~/.ssh/` ëë í°ë¦¬ì `config` íì¼ì ìì±í´ì ë¤ìì ì½ë를 ì
ë ¥íë¤.
ìì±ìë ì´ë¯¸ ë§ë¤ì´ëì ì¤ì ì ë³´ê° ì¡´ì¬íì¬ ë°ì ì¶ê°ë¥¼ í´ì£¼ìë¤.
```
$ vi ~/.ssh/config
# ìëë íì¼ ë´ì©
# ssh -i {í¤ íì´ íì¼} {ì ì ì´ë¦}@{íë ¥ì IP}
Host {ìíë í¸ì¤í¸ ì´ë¦}
User {ì ì ì´ë¦}
HostName {íë ¥ì IP}
IdentityFile {í¤ íì´ íì¼ ìì¹}
```
- ì´ì í¤ íì´ íì¼ì´ ìë ê³³ììë SSH ì ìì´ ê°ë¥íë¤.
```bash
$ ssh "ì¤ì í í¸ì¤í¸ì´ë¦"
```
10. ë§ì§ë§ì¼ë¡ ë³´ì그룹ì ì¤ì í´ì£¼ì. ì°ì AWSìì ì¸ ì ìë ë³´ì 그룹ì ë ê°ì§ ì¢
ë¥ê° ìë¤.
- ì¸ë°ì´ë (Inbound): ì¸ë¶ -> EC2 ì¸ì¤í´ì¤ ë´ë¶ íì©
- ììë°ì´ë (Outbound): EC2 ì¸ì¤í´ì¤ ë´ë¶ -> ì¸ë¶ íì©
ë³´ì 그룹ì **ì¸ì¤í´ì¤ì ë³´ì Tab**ìì ë³¼ ì ìë¤.
- ì¸ë°ì´ë ê·ì¹ììë ì¸ë¶ìì EC2ë¡ ìì²í ë íì©í IP ëìì ì¤ì í ì ìë¤.
EC2를 ìì±í ë ë³´ì ê·¸ë£¹ì´ Defaultë¡ ë§ë¤ì´ì¡ì§ë§, ìë¡ ìì±í ê·ì¹ì íµí´ ì ì©í ê²ì´ë¤.
ì íì 먼ì ì ííë©´ ê·¸ì ë§ê² íë¡í ì½ê³¼ í¬í¸ì ë²ìê° ê³ ì ëë©°, í¹ì IPë ëìì ë£ì¼ë ¤ë©´ âì¬ì©ì ì§ì âì¼ë¡ ì¶ê°í ì ìë¤.
ì°ì ê°ì¥ ë§ì´ ì¬ì©íë âSSHâ, âHTTPâ, âHTTPSâ를 ì¶ê°íë¤. **0.0.0.0/0**ì 모ë IPì ì ìì íì©íë¤ë ì기ì´ë¤.

- ê·ì¹ì ë¤ ì¤ì íê³ ì ì¥íë¤ë©´ ì¸ì¤í´ì¤ë¡ ìì ìì±í ë³´ì그룹ì¼ë¡ ë³ê²½íë©´ ì ìì ì¼ë¡ ì ì©ëë¤.

### 3-3-1. ê³ì ì¶ê° ë° sudo ê¶í í ë¹
- AWS EC2ë¡ ì¤ìµì ì§íí ê²½ì° ë¤ì ë¨ê³ë¶í° ì§ííë©´ ëë¤.
- [AWS EC2ê° ìë ë¤ë¥¸ ubuntu ìë²ë¥¼ ì´ì©í ê²½ì°](https://kyungsnim.net/176)
### 3-3-2. ê° ê³ì ë³ UTF-8 ì¸ì½ë©ì ì¤ì íì¬ íê¸ ì´ì í´ê²°
- ë¤ì ëª
ë ¹ì ì¤ííì¬ ìì¤í
ì ì²´ ê³ì ìì íê¸ê³¼ ê´ë ¨í ì¸ì½ë©ì ì¬ì©í ì ìëë¡ ì¤ì íë¤.
```bash
sudo locale-gen ko_KR.EUC-KR ko_KR.UTF-8
sudo dpkg-reconfigure locales
```
- ê° ê³ì ì ëë í 리ì .bash_profileì ë¤ìê³¼ ê°ì ì¤ì ì ì¶ê°íë¤.
- ë§ì½ .bash_profile íì¼ì´ ìë¤ë©´ vi ëª
ë ¹ì íµí´ ë§ë¤ì´ì¤ë¤.
```bash
(ë§ì½ .bash_profile íì¼ì´ ìë¤ë©´)
vi .bash_profile
(.bash_profile íì¼)
LANG="ko_KR.UTF-8"
LANGUAGE="ko_KR:ko:en_US:en"
(ì ì¥ í ìë²ë¥¼ ì¬ììí´ì¼ ë°ìíì§ë§ source ëª
ë ¹ì ì´ì©íì¬ Reboot ìì´ ë°ë¡ ìë²ì ë°ìí ì ìë¤.)
source .bash_profile
(env ëª
ë ¹ì íµí´ ë°ì 결과를 íì¸í ì ìë¤.)
(env: íì¬ ì§ì ëì´ ìë íê²½ ë³ìë¤ì ì¶ë ¥íê±°ë, ìë¡ì´ íê²½ ë³ì를 ì¤ì íê³ ì ì©ë ë´ì©ì ì¶ë ¥íë ëª
ë ¹ì´)
env
```

### 3-3-3. JDK, Maven ì¤ì¹
- JDK 8 ì¤ì¹
```xml
wget --no-cookies --no-check-certificate --header "Cookie: oraclelicense=accept-securebackup-cookie" https://javadl.oracle.com/webapps/download/GetFile/1.8.0_301-b09/d3c52aa6bfa54d3ca74e617f18309292/linux-i586/jdk-8u301-linux-x64.tar.gz
```
- EC2 ì¸ì¤í´ì¤ìì wget ëª
ë ¹ì íµí´ ubuntu ë²ì jdk를 ë¤ì´ë¡ë ë°ê³ ìì¶ì íì´ì¤ë¤.
```bash
wget [ë¤ì´ë¡ë 주ì]
tar -xvf [ìì¶ì í´ì í íì¼ ì´ë¦]
```
- ê³ì Home ëë í 리ì .bash_profile íì¼ì JAVA_HOME/bin ëë í 리를 PATHë¡ ë±ë¡íë¤.
```bash
(ì¬ë³¼ë¦ ë§í¬ë¥¼ ì°ê²°)
ln -s [ìë° ëë í 리 ì´ë¦]/ java
vi .bash_profile
(.bahs_profile ììì)
export JAVA_HOME=~/java
export PATH=$PATH:$JAVA_HOME/bin
```
- PATH ì¤ì ì ìë£ í java -version ëª
ë ¹ì ì¤íí´ ì¤ì¹í ìë° ë²ì ì íì¸íë¤.
```bash
java -version
```
- Maven ì¤ì¹
- [https://maven.apache.org/](https://maven.apache.org/)
- ì ë§í¬ìì mavenì ë¤ì´ë¡ë íë¤. (tar.gz íì¼)
- ìì¶ì í´ì íë©´ ì¤ì¹ê° ìë£ëë¤.
```bash
wget [ë¤ì´ë¡ë 주ì]
tar -xvf [ìì¶ì í´ì í íì¼ ì´ë¦]
```
- .bash_profileì MAVEN_HOME/bin ëë í 리를 PATHë¡ ì¤ì íë¤.
```bash
(ì¬ë³¼ë¦ ë§í¬ë¥¼ ì°ê²°)
ln -s [ë©ì´ë¸ ëë í 리 ì´ë¦]/ maven
vi .bash_profile
(.bahs_profile ììì)
export JAVA_HOME=~/maven
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
```
- PATH ì¤ì ìë£ í mvn -version ëª
ë ¹ì íµí´ ì¤ì¹í Maven ë²ì ì íì¸íë¤.
```bash
mvn -version
```
- ìë² ì¤í
```bash
java -cp target/classes/:target/dependency/* webserver.WebServer 8080
// 백그ë¼ì´ë ì¤í
java -cp target/classes/:target/dependency/* webserver.WebServer 8080 &
```
### 3-3-4. Git ì¤ì¹. clone ë° ë¹ë
- git ì¤ì¹
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git
```
- git clone
```bash
git clone [cloneí url]
```
## 3-4. ì¹ ìë² ì¤ìµ
- 3ì¥ììì ì¤ìµ ì구 ì¬íì ë¤ìê³¼ ê°ì 구ì±ì¼ë¡ ëì´ìë¤.
- index.html ìëµí기
- GET ë°©ìì¼ë¡ íìê°ì
í기
- POST ë°©ìì¼ë¡ íìê°ì
í기
- 302 status code ì ì©
- ë¡ê·¸ì¸í기
- ë¡ê·¸ì¸ ì¬ë¶ì ë°ë¥¸ ì¬ì©ì ëª©ë¡ ì¶ë ¥
- CSS ì§ìí기
- ìì¤ ì½ë ë¶ì
1. WebServer.java
1. ì¹ ìë²ë¥¼ ììíê³ , ì¬ì©ìì ìì²ì´ ìì ëê¹ì§ ë기 ìíì ìë¤ê° ì¬ì©ì ìì²ì´ ìì ê²½ì° ì¬ì©ìì ìì²ì RequestHandler í´ëì¤ì ìì
2. RequestHandler.java
1. ì¬ì©ìì ìì²ì ëí ì²ë¦¬ì ìëµì ëí ì²ë¦¬ë¥¼ ë´ë¹íë í´ëì¤
### 3-4-1. ì구ì¬í (1) - index.html ìëµí기
- WebServer.java를 ì¤ííê³ ë¸ë¼ì°ì ìì [localhost:8080/index.html](http://localhost:8080/index.htmlì) ë¡ ì ìí´ë³´ì
- ì ìíê³ ê°ë°ì ë구 â Network â localhostì Header를 ë³´ë©´ ë¤ìê³¼ ê°ì Request Header ë©ìì§ë¥¼ ë³¼ ì ìë¤.

- ì´ ìì² ê°ì InputStreamì íµí´ ë¤ì´ì¤ê³ ì´ë¥¼ BufferdReader를 íµí´ ê°ì ì¶ë ¥í ì ìë¤.
```java
// ìì² ë¼ì¸ ì¶ì¶í기 -> HTTP Header : GET /index.html HTTP 1.1
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String headerMessage = br.readLine();
log.debug("HTTP Request Header : {}", headerMessage);
// ì ì²´ ê° ì¶ì¶í기
if (headerMessage == null) return;
while (!headerMessage.equals("")) {
headerMessage = br.readLine();
log.debug(" : {}", headerMessage);
}
```
- ìì² ë¼ì¸ ê°ìì /index.htmlì ì¶ì¶í기 ìí´ì 공백ì 구ë¶ìë¡ split í¨ì를 ì´ì©íë¤
```java
String tokens[] = headerMessage.split(" ");
```
- ì¶ì¶í /index.htmlì ì´ì©íì¬ ì¹ ìë²ì ìì²ì ë³´ë´ë©´ index.htmlì ë´ì©ì ìëµë°ì ì ìë¤.
```java
byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath());
DataOutputStream dos = new DataOutputStream(out);
response200Header(dos, body.length);
responseBody(dos, body);
```
### 3-4-2. ì구ì¬í (2) - GET ë°©ìì¼ë¡ íì ê°ì
í기
- ì§ê¸ ìíìì ì¹ ìë²ë¥¼ ëì´ ìíìì íì ê°ì
ì ë르면 ìëì ê°ì HTTP Header ìì²ì ë³¼ ì ìë¤.

- ì´ ìì²ìì ì ì ìëê±´ **GET ë°©ìì¼ë¡ ìì²ì´ ì¨ë¤ë ì **ê³¼ ê²½ë¡ê° **/user/create?** ë¡ ììíë¤ë ì ì´ë¤.
- ì´ URL ì 보를 íµí´ ì°ë¦¬ë íìê°ì
ì ì§íí ì ìë íí¸ë¥¼ ì»ì ì ìë¤.
```java
// ì구ì¬í 2. GET ë°©ìì¼ë¡ íì ê°ì
í기
// http header ìì² ë©ì¸ì§
String url = tokens[1];
// startWith([String]) -> String 문ìì´ë¡ ììíë©´ True를, ìëë¼ë©´ false를 ë°ííë í¨ì
if (url.startsWith("/user/create")) {
// urlìì ?ì ìì¹ë¥¼ ë°í
int index = url.indexOf("?");
String queryString = url.substring(index + 1);
// parseQueryString()
// &를 기ì¤ì¼ë¡ ëëë©°, =를 기ì¤ì¼ë¡ key : valueë¡ ëëì´ Mapì ì ì¥íë¤.
Map

- GET ë°©ìì ì¬ì©ìê° ì
ë ¥í ë°ì´í°ê° URLì íì ë기 ë문ì ë³´ìì ì¸ ì¸¡ë©´ìì ì·¨ì½íë¤.
- ë ë¸ë¼ì°ì ì ì ì±
ë§ë¤ ë¤ë¥´ì§ë§ í¬ë¡¬ ë¸ë¼ì°ì ì ê²½ì° 2MBì 길ì´ë¡ ì í(주ìì°½ íìë 32KB)ì ëë¤ê³ íë¤.

<ì¶ì² : [Chromium Docs](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length) >
### 3-4-3. ì구ì¬í (3) - POST ë°©ìì¼ë¡ íì ê°ì
í기
- GET ë°©ìì POST ë°©ìì¼ë¡ ë³ê²½í기 ìí´ form.htmlì form íê·¸ method ìì±ì getìì postë¡ ìì íë¤.
```html