학습 목표
- HTTP 모듈을 이용해서 서버를 작성할 수 있습니다.
- HTTP 요청을 분석하는 코드를 작성할 수 있습니다.
- HTTP 응답 메시지를 작성하는 코드를 작성할 수 있습니다.
- 정적 파일 요청과 서비스 제공하는 서버를 작성할 수 있습니다.
1. HTTP 서버
◎ HTTP 서버 구동 코드
var http = require('http');
var server = http.createServer(function(req, res) {
res.end('Hello World');
}).listen(3000);
2. HTTP 요청
◎ HTTP 요청
- 클라이언트 요청 분석
- request 이벤트 리스너의 파라미터
- req : IncomingMessage
var server = http.createServer(function(req, res) {} )
▷ 클라이언트 요청 분석
▷ IncomingMessage
- message.url : 요청 url, 경로와 쿼리 문자열
- message.method : 요청 메소드
- message.headers : 요청 메소드의 헤더
- message(streamable) : 요청 메시지 바디
▷ 요청 URL 경로와 쿼리 문자열 분석
▷ URL 분석하기 : URL 모듈
var url = require('url');
url.parse(req.url, true);
▷ 요청 메시지 헤더 분석
▷ 헤더 정보 : request.header
var headers = request.headers;
headers.host;
headers.content-type;
headers.user-agent;
. . .
▷ 요청 메시지 바디 분석
- IncomingMessage의 data 이벤트 사용
- POST 요청을 다루는 장에서 다룬다.
◎ HTTP 요청 출력
▷ 요청 내용 콘솔에 출력하기
var server = http.createServer(function(req, res) { console.log('HTTP Method : ' + req.method); console.log('HTTP URL : ' + req.url); console.log('== HEADERS =='); console.log(req.headers); res.end('Hello Node.js'); });
3. HTTP 응답
◎ 응답 메시지- 응답 메시지 : http.ServerResponse
- 상태 코드와 상태 메시지
- 응답 메시지 헤더
- 응답 메시지 바디
▷ 메시지 상태
response.statusCode
response.statusMessage
▷ 메시지 헤더
response.writeHead(statusCode[, statusMessage][, headers])
response.removeHeader(name)
response.getHeader(name)
response.setHeader(name, value)
▷ 메시지 바디
response.end([data][, endcoding][, callback])
response.write(chunk[, encoding][, callback])
▷ HTTP 상태 코드와 메시지
// 200 OK
response.statusCode = 200;
response.statusMessage = 'OK';
// 404 Error
response.statusCode = 404;
response.statusMessage = 'Not found';
▷ 응답 메시지 헤더
▷ 응답 코드, 메시지 헤더 작성 함수 : writeHead
res.writeHead(200, {'Content-Length': body.length,
'Content-Type': 'text/plain'});
▷ 헤더 작성하기 : setHeader
res.setHeader("Content-Type", "text/html");
res.setHeader("Content-Length", body.length);
// 200 OK
response.statusCode = 200;
response.statusMessage = 'OK';
// 404 Error
response.statusCode = 404;
response.statusMessage = 'Not found';
▷ 응답 메시지 헤더
▷ 응답 코드, 메시지 헤더 작성 함수 : writeHead
res.writeHead(200, {'Content-Length': body.length,
'Content-Type': 'text/plain'});
▷ 헤더 작성하기 : setHeader
res.setHeader("Content-Type", "text/html");
res.setHeader("Content-Length", body.length);
▷ 응답 메시지 바디
▷ 응답 메시지 종료
response.write(chunk[, endcoding][, callback])
response.end()
▷ 응답 메시지 작성 시 주의
▷ 응답 메시지 종료 - 클라이언트 대기 - timeout
http.createServer(function(req, res) {
res.write('Hello Node.js');
res.end(); // 응답 메시지를 완료시켜주어야 한다.
});
▷ 메시지 헤더는 메시지 바디 작성 전에
res.write('Hello World');
// 바디를 작성한 이후에 헤더를 작성하면 에러가 발생한다.
res.setHeader('Conent-Type', 'text/plain');
▷ 응답 메시지 종료
response.write(chunk[, endcoding][, callback])
response.end()
▷ 응답 메시지 작성 시 주의
▷ 응답 메시지 종료 - 클라이언트 대기 - timeout
http.createServer(function(req, res) {
res.write('Hello Node.js');
res.end(); // 응답 메시지를 완료시켜주어야 한다.
});
▷ 메시지 헤더는 메시지 바디 작성 전에
res.write('Hello World');
// 바디를 작성한 이후에 헤더를 작성하면 에러가 발생한다.
res.setHeader('Conent-Type', 'text/plain');
4. HTTP 서버 작성
◎ 정적 파일 요청
▷ 정적인 컨텐츠(이미지, html, 음악 등) 요청
- 미리 작성된 파일로 응답
▷ 요청 예
- http://myServer.com/image/cat.jpg
- http://myservice.net/music/sing.mp3
▷ 요청 경로
- req.url
▷ 요청 경로 분석
- path 모듈
▷ 정적 파일 요청 : 응답
- 정적 파일 찾기
- 파일 로딩, 응답
▷ fs 모듈
- fs.readFile(FILEPATH, CALLBACK);
▷ 응답 메시지에 파일 내용 쓰기
- res.write();
- res.end();
▷ 정적 파일 요청에 대한 응답
fs.access(path, fs.F_OK, function(exist) {
fs.readFile(path, function(err, data) {
res.end(data);
});
});
◎ 정적 파일 요청
- 정적 파일 요청에 대한 응답
- 정적 파일 체크
- 상태 코드
- 컨텐츠 타입
▷ 파일이 없으면?
▷ 404 에러 처리 코드
fs.access(path, fs.R_OK, function(err) {
// 접근 불가능 시 404 에러
if( err ) {
res.statusCode = 404;
res.end('Not Found');
return;
}
}
▷ 정적 파일 응답
fs.access(path, fs.F_OK, function(err) {
if( err ) {
res.statusCode = 404;
res.end('Not found');
return;
}
fs.readFile(path, function(err, data) {
res.statusCode = 200;
res.setHeader('Content-type', 'image/jpg'); // 이미지라면
res.end(data);
});
});
▷ 스트림 파이프
- 입력 스트림 : fs.createReadStream()
- 출력 스트림 : res
fs.createReadStream(path).pipe(res);
▷ 파미콘 : 웹 사이트의 아이콘 이미지
▷ 파비콘 요청
- GET /favicon.ico
▷ 파비콘 응답 코드
if( request.url == '/favicon.ico' ) {
// 파비콘 처리
return;
}
▷ 컨텐츠 타입
var server = http.createServer(function(req, res) {
if(req.url == '/favicon.ico') {}
else if(req.url == '/image.png' ) {
res.writeHeader(200, {'Content-Type':'image/png'});
fs.read...
}
else if(req.url == '/music.mp3') {
res.writeHeader(200, {'Content-Type':'audio/mp3'});
fs.createReadStrea...
}
else if(req.url == '/movie.mp4') {
res.writeHead(200, {'Content-Type':'video/mp4'});
fs.createReadStream...
}
});
◎ 정적 파일 서비스
▷ 요청 URL의 경로를 실제 파일 경로 매핑
- myServier.com/resource/image.png -> ./resources/image.png
- myServier.com/resource/audio.mp3 -> ./resources/audio.mp3
▷ 요청 url에서 경로 생성
URL로부터 파일의 패스 정보를 가져와서 바로 파일에 대한 경로를 만들어 줄 수 있다.
파일을 찾고 파일에 대한 읽기위한 경로를 만드는 과정이 단순해짐.
var pathUtil = require('path');
var path= __dirname + pathUtil.sep + 'resources' + req.url;
◎ 웹 페이지 서비스
▷ 요청
- 인덱스 요청
- 파비콘 요청
- JS와 css요청
- 이미지 요청 : <img>
▷ 서비스 용 html
<html>
<link rel="stylesheet" type="text/css" href='public/style.css'>
<body>
<h1>Hello Kitty</h1>
<img src='image/cat.jpg'>
</body>
</html>
html요청
css 요청
image 요청
파비콘 요청 에 대한 응답 처리를 모두 해주저야 한다.
▷ 서버 코드
var server = http.createServer(function(req, res) {
if(req.url == '/favicon.ico') {
// 파비콘 응답
}
else if(req.url == '/') {
// 기본 페이지 : index.html
fs.createReadStream('./public/index.html').pipe(res);
}
else {
var path = __dirname + req.url;
}
})
◎ 서비스
▷ 서비스
▷ URL 쿼리 문자열 : 합계 구하기
http://127.0.0.1:3000/count?start=1&end=10
▷ 서버 코드
// URL 분석 : 쿼리 문자열
var parsed = url.parse(request.url, true);
var query = parsed.query;
// start와 end
var start = parseInt(query.start);
var end = parseInt(query.end);
if(입력값 오류) {
response.statusCode = 404;
response.end('Wrong Parameter');
}
else {
// 합계 구하기
response.statusCode = 200;
response.end('Result : ' + result);
}
학습 정리
◎ 지금까지 'HTTP 서버'에 대해 살펴보았습니다.
- HTTP 요청
클라이언트의 HTTP 요청을 분석했습니다. - HTTP 응답
클라이언트에게 HTTP 응답 메시지를 작성하고 전송하는 방법을 알아봤습니다. - HTTP 서버
다양한 형태의 HTTP 서버 작성 방법을 알아봤습니다.