Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발공부일지

NodeJS - 요청, 응답 본문

NodeJS

NodeJS - 요청, 응답

보람- 2023. 9. 9. 16:42

목차

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");
    }