net 모듈을 배우고 구현해본 서버입니다.
브라우저에서 요청하는 파일을 파싱해서 템플릿 모듈에 있는 키값과 일치하면 해당 키의 값으로 저장되어 있는 텍스트 파일을 브라우저에게 전달 할 수 있도록 구현해 보았습니다.
server.js
const net = require("net");
const template = require("./template");
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || "127.0.0.1";
const response = (buffer, type) => `HTTP/1.1 200 ok
Connection: keep-alive
Keep-Alive: timeout=5
Content-type: text/${type}
Content-length: ${buffer.length}
${buffer.toString()}`;
const fileType = {
html: "html",
css: "css",
js: "javascript",
};
const server = net.createServer((c) => {
c.setEncoding("utf-8");
c.on("data", (data) => {
let page = data.split("\n")[0].split(" ")[1];
let type;
if (page === "/favicon.ico") {
page = "/";
}
if (page === "/index.html") {
page = "/";
}
if (page.length > 1) {
type = fileType[page.split(".")[1]];
} else {
type = "html";
}
const text = Buffer.from(template[page]);
c.write(response(text, type));
c.end();
});
});
server.listen(PORT, HOST, () => {
console.log(`Server Listening Port : ${PORT}`);
server.on("connection", () => {
console.log("접속 성공");
});
});
template.js
const template = {
"/": `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<header>
<div class="header-wrap">
<h1>
<img src="http://www.kiweb.or.kr/images/main_new/logo_new_2018.png" alt="" />
</h1>
<div class="nav-container">
<nav>
<ul class="dep1">
<li>
<a href="./introduction.html">학교소개</a>
<div class="dep2">
<ul>
<li>
<a href="#">인사말</a>
</li>
<li>
<a href="#">연혁</a>
</li>
<li>
<a href="#">교직원소개</a>
</li>
<li>
<a href="#">시설소개</a>
</li>
<li>
<a href="#">오시는 길</a>
</li>
</ul>
</div>
</li>
<li>
<a href="#">교육과정</a>
<div class="dep2">
<ul>
<li>
<a href="#">과정안내</a>
</li>
</ul>
</div>
</li>
<li>
<a href="#">취업정보</a>
<div class="dep2">
<ul>
<li>
<a href="#">취업자인터뷰</a>
</li>
<li>
<a href="#">취업현황</a>
</li>
<li>
<a href="#">포트폴리오</a>
</li>
</ul>
</div>
</li>
<li>
<a href="#">커뮤니티</a>
<div class="dep2">
<ul>
<li>
<a href="#">공지사항</a>
</li>
<li>
<a href="#">수강후기</a>
</li>
<li>
<a href="#">KI이야기</a>
</li>
<li><a href="#">KI기자단</a></li>
<li><a href="#">교수칼럼</a></li>
</ul>
</div>
</li>
<li>
<a href="#">상담신청</a>
<div class="dep2">
<ul>
<li><a href="#">상담게시판</a></li>
<li><a href="#">상담게시판</a></li>
<li><a href="#">자주묻는질문</a></li>
</ul>
</div>
</li>
</ul>
</nav>
</div>
<h2>
<img src="http://www.kiweb.or.kr/images/common/snb_img.png" alt="" />
</h2>
</div>
</header>
<script src="./index.js"></script>
</body>
</html>
`,
"/index.css": `
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
color: #666;
}
body {
font-family: "NanumBarunGothic";
background-color: #777;
}
header {
width: 100%;
background-color: #fff;
position: relative;
}
header::after {
content: "";
/* base header */
position: absolute;
z-index: -1;
width: 100%;
height: 0;
background: rgba(50, 50, 50, 0.9);
visibility: hidden;
transition: all 0.3s ease;
}
header.active::after {
height: 190px;
visibility: visible;
}
header > .header-wrap {
width: 1200px;
height: 102px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
flex-wrap: wrap;
}
header > .header-wrap > h1 {
width: 176px;
}
header > .header-wrap > .nav-container {
width: 900px;
}
header > .header-wrap > h2 {
margin: 42px 42px 0 42px;
visibility: hidden;
transition: all 0.5s ease;
}
header > .header-wrap > .nav-container > nav > .dep1 {
display: flex;
justify-content: space-between;
}
header > .header-wrap > .nav-container > nav > .dep1 > li {
display: flex;
align-items: center;
flex-direction: column;
}
header > .header-wrap > .nav-container > nav > .dep1 > li > a {
width: 180px;
height: 102px;
padding: 40px 0;
text-align: center;
font-size: 19px;
font-weight: bold;
color: #004385;
}
.dep2 {
/* base .header-wrap */
position: absolute;
visibility: hidden;
top: 102px;
padding-top: 8px;
opacity: 0;
transition: all 0.5s ease;
}
.dep2 > ul > li {
width: 180px;
text-align: center;
}
.dep2 > ul > li > a {
display: inline-block;
width: 100%;
height: 35px;
padding: 10px 0;
font-size: 13px;
font-weight: bold;
color: #afafaf;
}
.dep2 > ul > li > a:hover {
color: #ebebeb;
}
`,
"/introduction.html": `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>학교소개</div>
</body>
</html>
`,
"/index.js": `const header = document.querySelector("header");
const logo = document.querySelector("header > .header-wrap > h2");
const dep1 = document.querySelector(".dep1");
const dep2 = document.querySelectorAll(".dep2");
const dep1Over = (e) => {
console.log(e.target);
for (let i = 0; i < dep2.length; i++) {
dep2[i].style = "visibility: visible; opacity: 1";
}
logo.style = "visibility: visible";
header.classList.add("active");
};
const dep1Leave = (e) => {
console.log(e.target);
for (let i = 0; i < dep2.length; i++) {
dep2[i].style = "visibility: hidden; opacity: 0; transition: none";
}
logo.style = "visibility: hidden; transition: none";
header.classList.remove("active");
};
dep1.addEventListener("mouseover", dep1Over);
dep1.addEventListener("mouseleave", dep1Leave);
`,
};
module.exports = template;