Skip to content

Instantly share code, notes, and snippets.

@bakyeono
Last active June 11, 2018 16:45
Show Gist options
  • Save bakyeono/3ea0a3f8b7e3212bc8c3cf68a66cf1c5 to your computer and use it in GitHub Desktop.
Save bakyeono/3ea0a3f8b7e3212bc8c3cf68a66cf1c5 to your computer and use it in GitHub Desktop.

그림으로 배우는 HTTP & Network Basic 학습: 2018-06-12

오늘 할 것

  • 저녁 식사
  • 참여자 자기소개
  • 학습 목표 공유
  • 교재 목차 살펴보기
  • 학습 진행 방법 정하기
  • 1장 훑어보기

참여자들 자기소개

각자의 학습 목표 공유하기

교재 목차 살펴보기

  • 1장 웹과 네트워크의 기본에 대해 알아보자
  • 2장 간단한 프로토콜 HTTP
  • 3장 HTTP 정보는 HTTP 메시지에 있다
  • 4장 결과를 전달하는 HTTP 상태 코드
  • 5장 HTTP와 연계하는 웹 서버
  • 6장 HTTP 헤더
  • 7장 웹을 안전하게 하는 HTTPS
  • 8장 누가 액세스하고 있는지를 확인하는 인증
  • 9장 HTTP에 기능을 추가한 프로토콜
  • 10장 웹 콘텐츠에서 사용하는 기술
  • 11장 웹 공격 기술

학습 진행 방법 정하기

회차별 학습 범위

다음은 제가 임의로 나누어 본 것입니다.

  • 1주: (HTTP 소개) 1장
  • 2주: (HTTP 메시지 소개) 2장, 3장
  • 3주: (HTTP 메시지 자세히) 4장, 5장, 6장
  • 4주: (식별 및 보안) 7장, 8장, 11장
  • 5주: (관련 기술들) 9장, 10장

학습 방식 제안

  • 한 주마다 당번을 2 명 정도 정한다. 당번은 책 내용을 간단히 요약해서 소개한다. 그리고 사람들이 책을 잘 읽었는지 확인할 수 있는 퀴즈를 낸다. 퀴즈는 책에서 찾아 답변할 수 있는 쉬운 것으로 낸다. 당번이 아닌 사람들은 퀴즈를 맞추며 토론한다.
  • 각자 책을 읽으며 모르겠거나 더 궁금한 것을 질문하고 토론한다.

(심화 학습을 원하는 분을 위해) 도전과제 및 실습

  • 웹 브라우저가 작성하는 HTTP 요청 메시지 읽고 해석해보기
  • 웹 서버가 되돌려주는 HTTP 응답 메시지 읽고 해석해보기
  • RFC 2616 읽어보기
  • (텔넷, Python, C 등 원하는 방식으로) HTTP 요청 메시지를 작성해 발신해보자
  • HTTP 요청 메시지를 수신하고 HTTP 응답 메시지를 회신해보기
  • 클라이언트에 쿠키를 제공하고, 세션을 관리해 보기

1장 훑어보기

1장 요약

1.1 웹은 HTTP로 나타낸다

  • 웹 브라우저는 URL을 이용해 웹 서버에서 리소스를 받아 온다.
  • HTTP는 웹 서버와 웹 클라이언트 사이에서 이루어지는 통신의 약속을 정한 것이다.

1.2 HTTP는 이렇게 태어났고 성장했다

  • 팀 버너스 리 박사가 멀리 떨어져 있는 연구자들과 지식을 공유하기 위한 시스템으로 WWW를 고안했다.
  • WWW(월드 와이드 웹)을 구성하는 기술로 HTML, HTTP, URL 등이 제안되었다.
  • HTTP에는 몇 가지 버전이 있으며, 현재는 HTTP/1.1(RFC2616)이 가장 많이 사용되고 있다.

1.3 네트워크의 기본은 TCP/IP

  • TCP/IP는 응용 계층, 전송 계층, 네트워크 계층, 링크 계층으로 이루어진 프로토콜 집합이다.
  • 각 계층마다 고유한 역할을 담당하며, 다른 수준의 계층에서 하는 일을 서로 모르더라도 통신을 원활하게 수행할 수 있도록 한다. 덕분에 응용 프로그래머가 TCP, IP, 네트워크 인터페이스 등을 잘 모르더라도 HTTP 통신을 수행할 수 있다. (마찬가지로 네트워크 하드웨어를 프로그래밍하는 개발자도 웹 프로그래밍을 신경쓰지 않아도 된다. 관심의 분리.)

1.4 HTTP와 관계가 깊은 프로토콜은 IP/TCP/DNS

  • IP는 IP 주소와 MAC 주소를 이용해 데이터를 목적지로 연결한다.
  • TCP는 데이터를 패킷으로 분할하고 신뢰성 있게 전송한다.

1.5 이름 해결을 담당하는 DNS

  • DNS는 도메인 이름과 IP 주소를 교환한다.

1.6 각각과 HTTP와의 관계

  • 웹 브라우저가 웹 사이트를 표시하기까지의 과정
  1. (사용자가) 웹 브라우저에 URL을 입력한다.
  2. (웹 브라우저가) DNS에 도메인 이름을 질의하여 IP 주소를 구한다.
  3. (웹 브라우저가) 웹 서버의 IP 주소로 HTTP 메시지를 발송한다.
  4. (OS는) TCP 계층에서 데이터를 여러 개의 패킷으로 나누어 발송한다.
  5. (인터넷을 구성하는 각 노드는) IP에 따라 데이터를 목적지로 중계하여 보낸다.
  6. (웹 서버의 OS는) TCP 계층에서 데이터 패킷을 전달받아 다시 합친다. 유실되었거나 손상된 패킷이 있으면 다시 요청한다.
  7. (웹 서버는) HTTP 요청 메시지를 해석하여 적절한 처리를 하고, HTTP 응답 메시지를 회신한다.
  8. 위와 동일한 통신 과정을 거친다.
  9. (웹 브라우저가) 전달받은 HTTP 응답 메시지를 해석하여 리소스를 사용자에게 제공한다.

1.7 URI와 URL

  • URI: Uniform Resource Identifiers

  • URL: ~ Location

  • URN: ~ Name

  • Uniform: 여러 가지 리소스를 지시할 수 있고, 여러 가지 스키마를 사용할 수 있다.

  • Resource: 리소스란 식별 가능한 모든 것이다. 파일, 일기예보, 부작용을 수반하는 오퍼레이션 지시 등

  • Identifier: 식별자

  • URL 양식

스키마://사용자:패스워드@호스트:포트번호/하위경로?질의문#프래그먼트

1장 퀴즈

  1. 웹 브라우저가 하는 일과 웹 서버가 하는 일은 각각 무엇인가요?
  2. 웹 서버가 웹 클라이언트에 먼저 정보를 보낼 수 있나요?
  3. HTTP, URL, HTML은 어떻게 함께 사용되나요?
  4. TCP/IP는 무엇이고 어떻게 구성되어 있나요? 통신 프로토콜을 여러 계층으로 나누는 이유는 무엇인가요?
  5. HTTP, TCP, IP가 담당하는 역할은 각각 무엇인가요?
  6. DNS는 무엇이고 왜 필요한가요?
  7. 전체 인터넷을 파악할 수 있을까요?
  8. 웹 브라우저가 웹 리소스를 다운로드할 때 일어나는 통신 과정을 설명해 보세요.
  9. URI, URL, URN은 무엇이고 서로 어떻게 다른가요?

참고: HTTP 메시지 직접 보내 보기

  • urllib.request, requests 등의 고수준 API로는 메시지를 직접 작성해서 발송할 수가 없다. 파이썬 3에서 HTTP 메시지를 직접 작성해서 발신해보고 싶다면 소켓을 이용해햐 한다. 아래와 같은 코드를 작성하면 된다.
#! /usr/bin/env python3
import socket

def request(host, port, message):
    """HTTP 요청 메시지를 발신한다.

    Args:
        host (string): 메시지를 보낼 호스트
        port (int): 메시지를 보낼 포트 번호
        message (string): HTTP 요청 메시지

    Returns:
        (string) 응답 메시지

    """
    # 1. 소켓을 준비한다.
    # 주소 설정 방식을 IPv4로 지정, 소켓 유형을 스트림으로 지정한다.
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2초 동안 응답이 없으면 접속을 끊도록 설정한다.
    sock.settimeout(2)

    # 2. 지정한 호스트와 포트에 접속한다.
    sock.connect((host, port))

    # 3. 요청 메시지를 발신한다.
    sock.sendall(message.encode('utf-8'))

    # 4. 응답 메시지를 수신한다.
    # 올바르게 하려면,
    # 헤더를 파싱하여 본문의 길이를 확인한 후 그 길이만큼 수신해야 한다.
    # 하지만 귀찮으니 timeout으로 처리하자.
    response = b''
    while True:
        try:
            response += sock.recv(4096)
        except socket.timeout:
            break

    # 5. 소켓의 읽기/쓰기를 연결을 끊고 소켓을 닫는다.
    sock.shutdown(socket.SHUT_RDWR)
    sock.close()

    return response.decode('utf-8')



request_message = """GET / HTTP/1.1\r
Host: google.com\r
\r
"""

response_message = request('google.com', 80, request_message)

print('REQUEST MESSAGE:')
print('=' * 60)
print(request_message)

print('RESPONSE MESSAGE:')
print('=' * 60)
print(response_message)

위 코드를 request.py로 저장하고, 커맨드라인에서 실행하면 된다.

./request.py
REQUEST MESSAGE:
============================================================
GET / HTTP/1.1
Host: google.com


RESPONSE MESSAGE:
============================================================
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Mon, 11 Jun 2018 15:18:02 GMT
Expires: Wed, 11 Jul 2018 15:18:02 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

텔넷 클라이언트를 이용해 테스트할 수도 있으나 메시지를 timeout 이전에 단번에 정확하게 입력해야 해서 좀 불편하다.

$ telnet google.com 80
Trying 172.217.161.78...
Connected to google.com.
Escape character is '^]'.
GET / HTTP/1.1
Host: google.com

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Mon, 11 Jun 2018 15:16:00 GMT
Expires: Wed, 11 Jul 2018 15:16:00 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment