개발공부일지
NodeJS - 요청, 응답 본문
목차
1. Response 클래스로 만들기
2. server 만들기
3. Request class 만들기
4. header와 body나눠주고 sendFile보내기
1. Response 클래스로 만들기
- lib 디렉토리 안에 response.js 파일 만들기
const fs = require("fs");
const path = require("path");
const TEMPLATE_DIR = "views";
const STATUS_MESSAGE = {
200: "OK",
404: "NOT FOUND",
};
class Response {
version = "HTTP/1.1";
statusCode;
headers = {};
body;
socket;
constructor(socket) {
this.socket = socket;
this.intialHeaders();
}
setStatus(_code) {
this.statusCode = _code;
return this;
}
setHeaders(key, value) {
this.headers[key] = value;
return this;
}
setContentLength() {
if (!this.body) return null;
const buffer = Buffer.from(this.body);
this.setHeaders("Content-Length", buffer.length);
}
setBody(_body) {
this.body = _body;
this.setContentLength();
return this;
}
intialHeaders() {
this.headers = {};
this.headers["Connection"] = "Close";
this.headers["Content-Type"] = "text/html; charset=UTF-8";
}
convertToHttpStartLine() {
const statusCode = this.statusCode || 200;
const startLine = [
this.version,
statusCode,
STATUS_MESSAGE[statusCode],
].join(" ");
return startLine;
}
convertToHtpHeaders() {
const headers = [];
for (const key in this.headers) {
const message = `${key}: ${this.headers[key]}`;
headers.push(message);
}
return headers.join("\r\n");
}
sendFile(filename) {
const filepath = path.join(__dirname, "..", TEMPLATE_DIR, filename);
const buffer = fs.readFileSync(filepath);
const body = buffer.toString();
return this.send(body);
}
send(data) {
this.setBody(data);
return this.end();
}
end() {
const startLine = this.convertToHttpStartLine();
const headers = this.convertToHtpHeaders();
this.statusCode = null;
const message = [startLine, headers, "", this.body].join("\r\n");
return message;
}
}
const res = new Response();
module.exports = Response;
- class response 객체를 스트링화 해주는 역할을 한다.
2. server 만들기
require("dotenv").config();
// console.log(process.env.SEVER_PORT);
const { SEVER_PORT } = process.env;
const PORT = SEVER_PORT || 3000;
const net = require("net");
const server = net.createServer();
server.on("connection", (socket) => {
console.log("ESTABLISHED");
socket.on("data", (chunk) => {
console.log(chunk.toString());
});
});
server.listen(PORT, () => {
console.log(`Server Listening on Port ${PORT}`);
});
- NPM dotenv를 써서 SERVER PORT 3000 으로 설정해준다.
3. Request class 만들기
- lib 디렉토리안에 request.js 파일 만들기
- 버퍼를 가져와서 객체로 만들어주기
const NEW_LINE = "\r\n";
const LINE = NEW_LINE + NEW_LINE;
class Request {
headers;
rawHeaders = [];
rawStartLine = "";
constructor(buffer) {
console.log("request....");
const [headerString, bodyString] = this.getRequestMessage(buffer);
this.setRawHeader(headerString);
console.log(this.rawHeaders);
console.log(this.rawStartLine);
}
setRawHeader(header) {
const headerArr = header.split(NEW_LINE);
this.rawStartLine = headerArr.shift();
this.rawHeaders = headerArr;
}
getRequestMessage(buffer) {
const [header, ...rest] = buffer.toString().split(LINE);
const body = rest.join(LINE);
// console.log(header, body);
return [header, body];
}
}
module.exports = Request;
// server.js 파일에서
const Request = require("./lib/request");
server.on("connection", (socket) => {
console.log("ESTABLISHED");
socket.on("data", (chunk) => {
const req = new Request(chunk);
console.log(chunk.toString());
console.log(req);
});
});
- header split 해서 배열안에 넣어주기
const SPACE = " ";
const START_LINE_NAMES = ["method", "uri", "version"];
constructor(buffer) {
console.log("request....");
const [headerString, bodyString] = this.getRequestMessage(buffer);
this.setRawHeader(headerString);
const startLine = this.parseStartLine();
console.log(startLine);
}
parseStartLine() {
const startLine = this.rawStartLine.split(SPACE);
console.log(startLine);
const mappingName = startLine.map((value, index) => [
START_LINE_NAMES[index],
value,
]);
console.log(mappingName);
const obj = mappingName.reduce((acc, line) => {
const [key, value] = line;
acc[key] = value;
return acc;
}, {});
console.log(obj);
}
- startLine 파싱해주기
constructor(buffer) {
const [headerString, bodyString] = this.getRequestMessage(buffer);
this.setRawHeader(headerString);
const startLine = this.parseStartLine();
this.headers = { ...startLine };
const headers = this.parseHeaders();
this.headers = { ...this.headers, ...headers };
console.log(this.headers);
}
parseHeaders() {
// console.log(this.rawHeaders);
const headers = this.rawHeaders.reduce((acc, raw) => {
const [key, valule] = raw.split(": ");
acc[key] = valule;
return acc;
}, {});
// console.log(headers);
return headers;
}
- header 파싱해주기
4. header와 body나눠주고 sendFile보내기
- server.js 파일에서
require("dotenv").config();
const { SERVER_PORT } = process.env;
const PORT = SERVER_PORT || 3001;
const net = require("net");
const Request = require("./lib/request");
const Response = require("./lib/response");
const server = net.createServer();
server.on("connection", (socket) => {
console.log("ESTABLISHED");
socket.on("data", (chunk) => {
const req = new Request(chunk);
const res = new Response(socket);
res.sendFile("index.html");
});
});
server.listen(PORT, () => {
console.log(`Server Listening on Port ${PORT}`);
});
※ class Response → 객체를 스트링화하는 역할
※ class Request → 버퍼를 가져와서 객체로 만들어주는 역할
※ 게시판 만들고 이동시키기
// server.js 파일에서
const uri = req.headers.uri;
// console.log(uri);
if (uri === "/") {
res.sendFile("index.html");
} else if (uri === "/board/list") {
res.sendFile("board/list.html");
} else if (uri === "/board/write") {
res.sendFile("board/write.html");
} else if (uri === "/board/view") {
res.sendFile("board/view.html");
}
'NodeJS' 카테고리의 다른 글
NodeJS - express 사용하기 (0) | 2023.09.12 |
---|---|
NodeJS - RESTful, URL, URI, Request method (GET, POST) (0) | 2023.09.11 |
NodeJS - Response Message class문법으로 만들기 (0) | 2023.09.07 |
NodeJS - net 모듈을 사용해서 TCP 구현 (0) | 2023.08.31 |
NodeJS - network, OSI 7계층, host, 프로토콜, port (0) | 2023.08.30 |