http

sesame·2022년 3월 7일
0

교육

목록 보기
39/46
post-thumbnail

HTTP는 최상위 계층인 application 계층에 동작
개념적으로만 봤을 때 HTTP는 TCP/IP 계층 위에 동작하는 거라고 볼 수 있다.

  • 데이터 형태
    tcp: byte Array(패킷)로 정보를 통신
    http: String(메시지)으로 정보를 통신

예를 들어서 클라이언트로부터 특정 URL로 요청이 들어오면 DNS 서버가 도메인에 매핑되는 IP 주소를 받아옵니다. TCP 계층에서 HTTP 메시지를 패킷으로 분해합니다. 그리고 IP 계층에서 전송 위치를 확인하고 네트워크를 통하여 전송합니다. 그리고 받는쪽은 위의 과정을 역순으로 진행하여 처리합니다.

추가로 소켓도 마찬가지로 TCP 기반으로 나온건데 HTTP와의 차이점은 연결지향 / 동기식 통신이 필요할 때는 소켓 통신을 이용하는게 더 유리하다는 점입니다.

HTTP, TCP, IP

HTTP: 웹에서 자주 사용되는 프로토콜

TCP/IP에서 쓰는 주소 : 물리주소(MAC 주소), 논리주소(IP 주소), 포트주소(port)

전송을 담당하는 IP
IP는 계층으로 따지면 네트워크 계층에 해당
IP의 역할은 각 패킷을 상대방에게 전달하는 것
목적지까지 중계를 해주는 도중의 컴퓨터 또는 라우터와 같은 네트워크 장비는 목적지에 도착하기 위한 대략적인 행선지만 알고있다. 이런 구조를 라우팅이라고 한다.

신뢰성을 담당하는 TCP
TCP는 전송계층에 해당하는 프로토콜로 신뢰성을 가진 바이트스트림을 사용
바이트 스트림은 커다란 데이터를 보내기 쉽도록 TCP세그먼트라고 하는 단위의 패킷으로 작게 나누어 전송
이때 각 패킷에는 번호가 붙기 때문에 누락된 패킷이 있는지 검증할 수 있고 신뢰도를 담보할 수 있다.

이름 변환을 담당하는 DNS
네트워크를 이용하는 컴퓨터는 IP주소와는 별개로 호스트 이름 www를 붙일 수 있다. DNS는 HTTP와 같은 응용프로그램 계층 시스템으로 주로 호스트 이름이나 도메인 이름 IP주소의 이름 변환을 제공한다. 이름 변환이란 사람이 쉽게 외우기 힘든 IP주소를 사람이 좀 더 외우기 쉬운 도메인 이름으로 변경하거나 반대로 도메인 이름을 IP주소로 변경하는 작업을 말한다.

TCP/IP 4계층을 통해서 네트워크 통신의 예시를 들면
1. 클라이언트 -> 서버, 특정 주소로 요청
2. DNS 상에서 IP 주소를 받아옴
3. HTTP 계층 -> HTTP 메시지 작성
4. TCP 계층 -> HTTP 메시지를 패킷으로 분해
5. IP 계층 -> 전송 위치를 확인
6. Ethernet 계층 -> 네트워크를 통해서 전송
7. 수신은 위의 과정의 역순으로 진행함.

HTTP header

HTTP 메시지를 전송할 때

다음과 같은 메시지가 client, server 사이에서 전송된다.

HTTP 메시지는 보통 header + body로 이루어지는데

이런 구조로 이루어져있다.

이 헤더에는

이렇게 Request와 Response로 나뉘어진다.

header 분류

General Header(공통 헤더)

공통 헤더는 요청 및 응답의 메시지 모두에서 사용되지만 컨텐츠에는 적용되지 않는 헤더

  • Date
    일반적인 HTTP 헤더는 만들어진 날짜와 시간을 포함
General-Header: Data: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT

// Date: Wed, 21 Oct 2015 07:28:00 GMT
  • Connection
    Connection 헤더는 현재의 전송이 완료된 후 네트워크 접속을 유지할지 말지를제어
Connection: keep-alive  //지속 연결
Connection: close		//연결 종료
  • Cache-Control
    캐싱을 허용할지 허용하지 않을지를 정하기 위해 사용

  • Content-Encoding

Request Header(요청 헤더)

HTTP 요청에서 사용되지만 메시지의 컨텐츠와 관련이 없는 HTTP 헤더
보통 Fetch될 리소스나 클라이언트 자체에 대한 정보를 포함하여 서버로 보내진다.

  • Host
    서버의 도메인 네임과 서버가 현재 Listening 중인 TCP 포트를 지정
    만약 포트가 지정되지 않는다면 요청된 서버의 기본 포트를 의미한다. (HTTP URL은 80)
    Host 헤더는 반드시 하나가 존재해야 한다.
    만약 한 개가 아니라 없거나 여러개면 400(Bad Request) 상태 코드가 전송된다.
Host: <host>:<port_Optional>

// Host: blog.naver.com
  • User-Agent
    현재 사용자가 어떤 클라이언트(운영체제와 브라우저를 포함한)를 이용해 요청을 보냈는지 확인할 수 있다.
User-Agent: <product> / <product-version> <comment>

// Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
  • Accept
    Accept는 요청을 보낼 때 서버에게 어떤 터입으로 응답을 보내줬으면 좋겠다고 명시
Accept: text/html

Accept-Charset : 원하는 Character Set
Accept-Language : 원하는 Lang
Accept-Encoding : 원하는 Encoding 방식

  • Authorization
    사용자가 서버에 인가된 사용자임을 증명할 때 사용
Authorization: <type> <credentials>

// Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

type : 인증 타입으로 보통 Basic과 Bearer을 사용한다.
credentials : 사용자명과 비밀번호, 다른 페이로드가 합처져 base64로 인코딩된 값

보통 JWT나 Bearer 토큰을 서버로 보낼 때 사용하며 자격이 증명되지 않을 경우 401 Unauthorized 상태를 알려준다.

  • Origin
    POST와 같은 요청을 보낼 때, 요청이 어느 주소에서 시작되었는지를 나타낸다.
Origin: null
Origin: <scheme> "://" <hostname> [ ":" <port> ]

// Origin: https://developer.mozilla.org

scheme : 사용하는 프로토콜
hostname : 서버의 이름 또는 ip
port : 서버에 열린 tcp 포트

  • Referer
    이 페이지 이전에 대한 주소가 담겨있다.

Response Header(응답 헤더)

위치 또는 서버 자체에 대한 정보(이름, 버전)과 같이 응답에 대한 부가적인 정보를 갖는 헤더

  • Access-Control-Allow-Origin
    요청을 보내는 클라이언트의 주소와 요청을 받는 백엔드 주소가 다르면 CORS 에러가 발생
    이 때 Access-Control-Allow-Origin 헤더에 클라이언트의 주소를 적어야 에러가 발생하지 않는다.

만약 프로토콜, 서브도메인, 도메인, 포트 중 하나라도 다르면 CORS 에러가 발생

Access-Control-Allow-Origin: *
//주소를 일일지 지정하기 싫다면 *로 모든 주소에 CORS 요청을 허용가능
//그러나 보안이 취약해지는 점이 있기 때문에 해당 헤더를 사용해야한다.

Access-Control-Allow-Origin:
Access-Control-Allow-Origin: null

// Access-Control-Allow-Origin: https://developer.mozilla.org


- Allow
특정 메서드만 허용하겠다라는 것을 지정하는 헤더이다.
```c
Allow: <http-methods>

// Allow: GET, POST, HEAD
  • Content-Disposition
    응답 본문을 브라우저가 어떻게 표시해야 할지 알려주는 헤더
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"

// ex)
POST /test.html HTTP/1.1
Host: example.org
Content-Disposition: form-data; name="field2"; filename="example.txt"
  • Location
    redirect 헤더
    300번대 응답이나 201 Created 응답일 때 어느 페이지로 이동할지를 알려준다.
Location: <url>

// ex)
HTTP/1.1 302 Found
Location: /
  • Content-Security-Policy
    외부 파일들을 불러올 경우, 차단할 소스와 불러올 소스를 명시가능
Content-Security-Policy: <policy-directive>; <policy-directive>

// Content-Security-Policy: default-src https:

만얀 이 값을 self라고 지정한다면 자신과 같은 도메인의 파일만 가져 올 수 있다.

Entity Header(엔티티 헤더)

컨텐츠 길이나 MIME 타입과 같이 Entity Body에 대한 자세한 정보를 포함하는 헤더

MIME 타입이란 클라이언트에게 전송된 문서의 다양성을 알려주기 위한 메커니즘
MIME 종류 참고

Content-Language: ko-kr
Content-Length: 25907
Content-Type: text/html;charset=UTF-8
//Content-Type: multipart/form-data; boundary=something
  • Content-Length
    메시지 본문의 길이(바이트).
    HTTP 요청에서 Content-Length는 선택사항입니다.
    GET 또는 DELETE의 경우 길이가 0이어야 합니다. POST의 경우, Content-Length가 지정되고 메시지 행의 길이와 일치하지 않으면 메시지는 잘리거나 지정된 길이까지 널로 채워집니다.
    Content-Length는 컨텐츠가 없는 경우(값이 0인 경우)에도 항상 HTTP 응답에서 리턴됩니다.
  • Content-Type
    개체의 미디어 타입(MIME)과 문자열 인코딩(UTF-8)을 지정하기 위해 사용

  • Content-Language
    사용 언어

  • Content-Encoding
    미디어 타입을 압축하기 위해서 사용
    이 헤더가 존재한다면 그 값은어떤 방식으로 인코딩 되는지 알 수 있다.
    우리가 gzip등의 알고리즘을 통해 encoding 해서 보낸다면 브라우저가 알아서 해제해서 사용한다.

Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: identity
Content-Encoding: br

REST API 관점에서 보는 HTTP 상태 코드

1xx : 전송 프로토콜 수준의 정보 교환
2xx : 클라어인트 요청이 성공적으로 수행됨
3xx : 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함
4xx : 클라이언트의 잘못된 요청
5xx : 서버쪽 오류로 인한 상태코드

2XX Success

2xx 번대의 상태 코드들은 서버가 클라이언트의 요청을 성공적으로 처리했다는 의미

200 OK

클라이언트의 요청을 서버가 정상적으로 처리했다.
클라이언트에게 더 정확하고 자세한 정보를 제공하기 위해선 적절한 상태 코드를 보내는 것이 좋다.(2xx 상태 코드들은 각각 세분화된 목적을 갖는다.)

HTTP/1.1 200 OK
{
"result" : true
"status" : 200
}

201 Created

클라이언트의 요청을 서버가 정상적으로 처리했고 새로운 리소스가 생겼다.

HTTP/1.1 201 Created
{
"id" : 1,
"name" : "hak"
}

HTTP 헤더의 Content-Location를 이용하여 만들어진 리소스 생성된 위치를 알려주면 좋다.

HTTP/1.1 201 Created
Content-Location: /users/1
{
    "id" : 1,
    "name" : "hak"
}

202 Accepted

클라이언트의 요청은 정상적이나, 서버가 아직 요청을 완료하지 못했다.

202 상태 코드에서 중요한 것은 작업의 확인
비동기 작업은 해당 요청이 언제 완료되는지 알 수 없다.
클라이언트가 요청의 완료 여부를 확인할 수 있는 방법을 제공해야 한다.

  1. Callback
    콜백은 서버가 작업이 완료되면 클라이언트에게 알려주는 것

  2. Polling
    폴링은 클라이언트가 주기적으로 해당 작업의 상태를 조회하는 것

결론은 비동기 요청(202 상태 코드)은 콜백이든 폴링이든 클라이언트가 요청의 완료 여부를 확인할 수 있는 방법을 제공해야 한다는 것

204 No Content

클라이언트의 요청은 정상적이다. 하지만 컨텐츠를 제공하지 않는다.

PUT
자원 수정 요청의 결과가 기존의 자원 내용과 동일하여 변경된 내용이 없을 때 204로 응답할 수 있다.
만약 수정 요청으로 자원의 내용이 변경된다면 201로 응답할 것이다.


DELETE
삭제 요청으로 자원을 삭제하여 더 이상 존재하지 않고 그 자원을 참조하는 모든 자원도 삭제되어 더 이상 HTTP body를 응답하는 것이 무의미해졌을 때 사용한다.

4XX Client errors

400 Bad Request

클라이언트의 요청이 유효하지 않아 더 이상 작업을 진행하지 않는 경우

그러나, 400 상태 코드로 응답하는 것만으로는 부족하다.
오류 발생 시 파라미터의 위치(path, query, body), 사용자 입력 값, 에러 이유를 꼭 명시하는 것이 좋다.

HTTP/1.1 400 Bad Request
{
	"errors": {
		"message": "'name'(body) must be String, input 'name': 123",
		"detail": [
			{
			"location": "body",
			"param": "name",
			"value": 123,
			"error": "TypeError",
			"msg": "must be String"
			}
		]
	}
}

401 Unauthorized

클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우

401은 비인증

  • 비인증: Not
    비인증은 아니다의 뜻이 강하다. 즉, 인증이 안된 상태다.
  • 미인증: Not enough
    미인증은 부족하다의 뜻이 강하다. 즉, 권한이 부족한 상태다

403 Forbidden

클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우

404 Not Found

클라이언트가 요청한 자원이 존재하지 않다.

REST API에선 크게 두 가지 경우
1. 경로가 존재하지 않음
대부분 API 프레임워크에선 경로(라우팅)에 대한 에러 처리를 해주기 때문에 존재하지 않는 경로는 쉽게 404로 응답할 수 있다.
ex)GET /users/abc/def/wow 경우 아예 존재하지 않는 경로

  1. 자원이 존재하지 않음
    자원의 경우는 개발자가 처리해줘야 한다.
    PUT /users/1 경우 /users/:id로 존재하는 경로다. 또한 :id엔 숫자 값이 오고 요청도 숫자기 때문에 400 Bad Request도 아니다. 이때 서버는 ID 1을 갖는 사용자가 있는지 먼저 확인을 해야 한다.
    이것이 자원에 대한 존재 여부를 파악하는 것이다.
    만약, 존재 여부를 파악하지 않고 그대로 진행을 하면 후속 작업에서 오류가 발생할 가능성이 있고 이것은 5XX 오류로 이어질 수 있다.
    즉, 존재하는 경로에 대한 요청이라도 자원이 존재하는지 파악 후, 존재하지 않는다면 404 상태 코드로 응답해야 한다.

-- 404 오류의 경우 두 가지 모두 확인을 해야 한다는 설명을 위한 표현이다.

405 Method Not Allowed

클라이언트의 요청이 허용되지 않는 메소드인 경우

메소드란 POST, GET, PUT, DELTE 등 HTTP Method를 말한다.
즉, 자원(URI)은 존재하지만 해당 자원이 지원하지 않는 메소드일 때 응답하는 상태 코드다.

409 Conflict

클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우

429 Too Many Requests

클라이언트가 일정 시간 동안 너무 많은 요청을 보낸 경우

ex)

DELETE /users/1 HTTP/1.1
X-TOKEN: password
  • 자원(URI) /users/1에 존재하는 메소드고 Not 405
  • /users/:id에서 :id가 유효한 형식이고 Not 400
  • 1 사용자도 존재하고 Not 404
  • 헤더의 인증(X-TOKEN)도 정확하고 Not 401
  • 삭제 권한도 있는 경우 Not 403


    클라이언트의 삭제 요청은 받아들여져서 200 혹은 204로 응답해야 하지만,
    사용자의 게시물이 존재하는 경우 사용자를 삭제할 수 없다는 비지니스 로직이 있을 수 있다


    이렇게 API 사용에 있어 비지니스 로직상 모순이 발생하여 처리가 불가능한 경우 응답하는 상태 코드다.

5XX Server errors

API 서버의 응답에서 5XX오류가 발생해서는 안된다.
보통 개발 과정에서 유효하지 않은 요청을 사전에 처리하지 않은 경우(400)에 많이 발생한다.

ex)요청에 대해 4XX 오류를 발생시킬 가능성이 있는데 사전에 확인 작업을 하지 않은 경우



HTTP Request, Response

메시지는 세 부분(공백 제외) 으로 구성되어 있습니다.

HTTP Request 메시지 구조

1) Start Line

Start Line에는 HTTP 메소드, Request target, HTTP version이 있습니다.

  • HTTP 메소드는 요청의 의도를 담고 있는 GET, POST, PUT, DELETE 등이 있습니다. GET은 존재하는 자원에 대한 요청, POST는 새로운 자원을 생성, PUT은 존재하는 자원에 대한 변경, DELETE는 존재하는 자원에 대한 삭제와 같은 기능을 가지고 있습니다.

  • Request target은 HTTP Request가 전송되는 목표 주소입니다.

  • HTTP version은 version에 따라 Request 메시지 구조나 데이터가 다를 수 있어서 version을 명시합니다.

2) Header

Header에는 HTTP Request 그 자체에 대한 정보를 담고 있습니다. key : value 형태로 이루어져 있습니다.
이 Header에 경우 Request, Response에만 있는 Header 외에 공통 Header도 있기에 여기선 우선 Request Header에 있는 정보만 알려드리겠습니다.

Host : 요청하려는 서버 호스트 이름과 포트번호
User-agent : 클라이언트 프로그램 정보. 이 정보를 통해 서버는 클라이언트 프로그램(브라우저)에 맞는 최적의 데이터를 보내줄 수 있다.
Referer : 바로 직전에 머물렀던 웹 링크 주소
Accept : 클라이언트가 처리 가능한 미디어 타입 종류 나열
If-Modified-Since : 여기에 쓰여진 시간 이후로 변경된 리소스 취득. 페이지가 수정되었으면 최신 페이지로 교체한다.
Authorization : 인증 토큰을 서버로 보낼 때 쓰이는 Header
Origin : 서버로 Post 요청을 보낼 때 요청이 어느 주소에 시작되었는지 나타내는 값. 이 값으로 요청을 보낸 주소와 받는 주소가 다르면 CORS(Cross-Origin Resource Sharing) 에러가 발생한다.
Cookie : 쿠키 값이 key-value로 표현된다.

3) Body

HTTP Request가 전송하는 데이터를 담고 있는 부분입니다. 전송하는 데이터가 없다면 Body 부분은 비어있습니다.
보통 POST 요청일 경우, HTML 폼 데이터가 포함되어 있습니다.

HTTP Response 메시지 구조

1) Start Line

Response의 Start Line에는 HTTP version, Status Code, Status Text가 있습니다.

-0 Staus Code는 Response 상태를 나타내는 코드입니다. 요청 정상 처리를 나타내는 200이나 페이지가 이동되거나 없어졌을 때를 나타내는 404와 같은 코드로 이 부분은 추후에 정리 하겠습니다.

  • Status Text는 Response 상태를 간략하게 글로 설명해 줍니다.

2) Header

Location : 301, 302 상태코드일 때만 볼 수 있는 Header로 서버의 응답이 다른 곳에 있다고 알려주면서 해당 위치(URI)를 지정합니다.
Server : 웹 서버의 종류
Age : max-age 시간내에서 얼마나 흘렀는지 초 단위로 알려주는 값
Referrer-policy : 서버 referrer 정책을 알려주는 값 ex) origin, no-referrer, unsafe-url
WWW-Authenticate : 사용자 인증이 필요한 자원을 요구할 시 , 서버가 제공하는 인증 방식
Proxy-Authenticate : 요청한 서버가 프록시 서버인 경우 유저 인증을 위한 값

3) Body

HTTP Request 메시지의 Body와 동일합니다. 마찬가지로 전송하는 데이터가 없으면 비어있습니다.



참고
https://sanghaklee.tistory.com/61
https://livlikwav.github.io/study/rest,http,tcp,udp/
https://code-examples.net/ko/q/150e16a

[node.js REST API 서버 만들기] 3. 만들기
링크텍스트
Ulfius HTTP Framework
소켓 프로그래밍
HTTP Request / Response 메시지 구조

0개의 댓글