이 글은 [파이썬 웹 프로그래밍](저자 김석훈, 출판사 한빛미디어) 교재를 보고 공부하며 정리한 글임.
웹 프로그램은 클라이언트 + 서버 로 구성됨.
1.1 웹 프로그래밍이란?
웹 프로그래밍 : HTTP(S) 프로토콜로 통신하는, 클라이언트와 서버를 개발하는 것
웹 클라이언트와 서버를 같이 개발할 수도 있고 둘 중 하나만 개발할 수도 있다.
장고는 서버를 개발할때 쓰는 웹 프레임워크!
ex)
네이버에 접속할때
웹 브라우저 = 웹 클라이언트
네이버 서버 = 웹 서버
즉,
웹 클라이언트 = 요청 <------(http/https 프로토콜)------>웹 서버 = 응답
-> 동작!
웹 클라이언트는 다양하게 만들 수있다(아래 4가지).
- 웹 브라우저를 사용
- 리눅스 curl 명령 사용해 요청
- Telnet을 사용하여 요청
- 직접 만든 클라이언트로 요청
1.2 다양한 웹 클라이언트
1.2.1 웹 브라우저를 사용하여 요청
www.example.com 도메인에 있는 웹 서버를 대상으로 HTTP 요청을 보내고 응답을 확인해보자
웹 브라우저는 주소창에 입력된 문장을 해석 -> 웹 서버에게 HTTP 요청을 보냄(웹 클라이언트의 역할)
요청 받은 www.example.com 도메인의 웹 서버는 결과를 웹 브라우저로 전송함.
그러면 웹 브라우저는 그 전송받은 결과를 사용자가 볼 수 있도록 화면에 보여줌
1.2.2 리눅스 curl 명령을 사용하여 요청
명령 프롬프트에 curl 명령 입력하면 인자로 넘어온 URL로 HTTP 요청을 보냄
요청받은 www.example.com 도메인 웹서버는 결과를 응답해줌
C:\Users\da692>curl http://www.example.com
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
1.2.3 Telnet을 사용하여 요청
리눅스의 telnet 프로그램을 사용하여 HTTP 요청 보내는 방법
1.2.4 직접 만든 클라이언트로 요청
파이선 프로그램으로 간단한 웹 클라이언트 만들기
C:\Users\da692\Django>python example.py
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
1.3 HTTP 프로토콜
HTTP : 웹 서버와 웹 클라이언트 사이에서 데이터를 주고받기 위해 사용하는 통신 방식, TCP/IP 프로토콜 위에서 동작
-> 서버와 클라이언트는 각각 TCP/IP 동작에 필수적인 IP 주소 가져야함
1.3.1 HTTP 메시지의 구조
HTTP 메세지
- 요청메세지
- 응답메세지
HTTP의 구조
- 스타트라인 : 요청라인 / 상태라인
- 헤더 : 생략 가능 (각 행의 끝에 줄바꿈 문자인 CRLF 있음)
- 빈 줄 : 헤더의 끝을 빈 줄로 식별
- 바디 : 생략 가능
ex)
요청메세지 예
GET /book.shakespeare HTTP/1.1
Host: www.example.com:8080
->요청라인: 요청방식, 요청 URL, 프로토콜 버전
헤더: 이름:값
ex)
응답메세지 예
HTTP/1.1 200 OK
Content-Type: application/xhtml+xml; charset=utf-8
<html>
...
<html>
->상태라인: 프로토콜 버전, 상태 코드, 상태 텍스트
헤더:
바디: HTML 텍스트
1.3.2 HTTP 처리 방식
HTTP 메소드를 통해 클라이언트가 원하는 처리 방식을 서버에 알려줌
- GET : 리소스 취득, Read
- POST : 리소스 생성, 리소스 데이터 추가, Cretae
- PUT : 리소스 변경, Update
- DELETE : 리소스 삭제, Delete
- HEAD : 리소스의 헤더 취득
- OPTIONS : 리소스가 서포트하는 메소드 취득
- TRACE : 루프백 시험에 사용
- CONNECT : 프록시 동작의 터널 접속으로 변경
1.3.3 GET 메소드와 POST 메소드
GET은 URL 부분의 ? 뒤에 이름=값 쌍으로 이어붙임
ex)
GET http://docs.djangoproject.com/search/?q=forms&release=1 HTTP/1.1
POST는 GET에서 URL에 포함시켰던 파라미터들을 요청 메세지의 바디에 넣음
ex)
POST http://docs.djangoproject.com/search/ HTTP/1.1
Content-Type: application/x-www-from-urlencoded
q=forms&release=1
GET 방식은 URL 길이 제한 -> 많은 양의 데이터 보내기 어려움 & 웹브라우저 주소창에 그대로 노출돼서 보안 취약
파이썬 장고 프레임 워크에서도 폼의 데이터는 POST 방식만을 사용
1.3.4 상태 코드
응답메세지의 상태라인에 있는 상태코드(3자리) -> 서버에서의 처리결과 확인
ex)
1xx : Information
2xx : Success
200 : OK
201 : Created
202 : Accepted
3xx : Redirection
4xx : Client Error
404 : Not Found
5xx : Server Error
등등...
1.4 URL 설계
처음에 웹 어플리케이션 개발할 때 디자인이 화면 UI 설계하듯
프로그램 로직 측면에서 URL 설계
구성
- URL 스킴 : URL에 사용된 프로토콜
- 호스트명 : 웹 서버의 호스트명(도메인, IP)
- 포트번호 : 웹 서버내의 서비스 포트번호. 생략시 디폴트 포트번호(http는 80, https는 443)
- 경로 : 파일 경로
- 쿼리스트링 : 질의 문자열(이름 = 값 쌍)
- 프라그먼트 : 문서 내의 앵커 등 조각 지정
ex)
http://www.example.com:80/services?category=2&kind=patents#n10
URL스킴
호스트명
포트번호
경로
쿼리스트링
프라그먼트
1.4.1 URL을 바라보는 측면
API의 명명 규칙
- URL을 RPC로 바라보는 방식
- URL을 REST로 바라보는 방식
RPC : 클라이언트가 네트워크 상에서 원격에 있는 서버가 제공하는 API 함수 호출하는 방식
ex)
http://blog.example.com/search?q=test&debug=true
-> 웹 클라이언트에서 URL을 전송하는 것이 웹 서버의 API 함수를 호출한다고 인식
REST : 웹 서버에 존재하는 요소들 모두 리소스라고 정의, URL을 통해 웹 서버의 특정 리소스를 포현한다는 개념
리소스에 대한 조작을 GET, POST, PUT, DELETE 등의 HTTP 메소드로 구분
ex)
http://blog.example.com/search/test GET 메소드 사용
-> 웹 클라이언트에서 URL을 전송하는 것이 웹 서버에 있는 리소스 상태에 대한 데이터를 주고받는 것으로 인식
1.4.2 간편 URL
최근엔 REST 방식을 기반으로 사용자에게 친숙하도록 간편URL 사용.
1.4.3 파이썬의 우아한 URL
파이썬 프레임워크에서는 처음부터 간편 URL 체계 도입.
+ 정규표현식 추가적으로 사용 가능
1.5 웹 애플리케이션 서버
웹 클라이언트(ex: 웹 브라우저)의 요청을 받아 처리하는 것 == 웹 서버
웹 서버를 세분화하면 다음과 같이 나눌 수 있음.
- 웹 서버 : 주로 정적 페이지인 파일을 웹 클라이언트에게 제공할 때 사용
- 웹 애플리케이션 서버 : 동적 페이지 요청을 받아서 요청 처리 -> 결과를 웹 서버로 반환
1.5.1 정적 페이지 vs 동적 페이지
- 정적 페이지 : 항상 같은 내용 표시. 웹 서비스 제공자가 사전에 준비하여 서버 측에 배치.
- 동적 페이지 : 누가 언제 어떻게 요구했는지따라 다른 내용이 반환됨.(ex : 현재 시각 페이지, 온라인 쇼핑 장바구니)
CGI 규격 : 웹 서버와는 별도의 프로그램과 웹 서버 사이에 정보를 주고받는 규칙을 정의한 것
1.5.2 CGI 방식의 단점
CGI : 웹 서버와 독립적인 프로그램 사이에 정보를 주고받는 규격
-> 이 규격 준수하면 어떤 언어 사용해도 CGI 프로그램 개발 가능
전통적인 CGI 방식 : 웹 서버가 (Python, C 등으로 만들어진) CGI 프로그램을 직접 호출하여 개별 프로세스를 생성
-> 각각 클라이언트 요청에 따라 별도의 프로세스가 생성되는 바람에 메모리 요구량 큼
-> 현재는 거의 사용 X
1.5.3 CGI 방식의 대안 기술
- 별도의 애플리케이션(CGI 프로그램과 같은 역할 하는 프로그램)을 스크립트 언어로 작성, 스크립트 처리하는 스크립트 엔진을 웹 서버에 내장시키기
- 애플리케이션 처리하는 프로세스를 미리 데몬으로 가동시키고, 웹 서버의 요청을 데몬에서 처리
1.5.4 애플리케이션 서버 방식
웹 서버가 직접 프로그램 호출 X
웹 애플리케이션 서버를 통해 간접적으로 웹 애플리케이션 프로그램 실행
-> 웹 애플리케이션 서버는 결과를 웹 서버에 전달
-> 웹 서버는 결과를 웹 클라이언트에게 전송
웹 서버랑 웹 애플리케이션 서버의 역할은 구분짓는게 좋다. -> 메모리의 문제
1.5.5 웹 서버와의 역할 구분
웹 서버와 웹 애플리케이션 서버를 한 HW(Hardware)박스에서 기동시키는 것도 가능하고
HW박스를 분리하여 구성할 수도 있음 -> 이 경우에는 메모리 효율을 더 높일 수 있음