<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>syn.log</title>
        <link>https://velog.io/</link>
        <description>틈틈이 두 페이지씩 원서 읽기</description>
        <lastBuildDate>Sat, 16 May 2026 07:37:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>syn.log</title>
            <url>https://velog.velcdn.com/images/dvlp-sy/profile/543ada6f-e712-4758-9e0e-ec234334b54d/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. syn.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dvlp-sy" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p483 ~ p495" 完]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p483-p495-%E5%AE%8C</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p483-p495-%E5%AE%8C</guid>
            <pubDate>Sat, 16 May 2026 07:37:45 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-21-logging-and-usage-tracking">Chapter 21. Logging and Usage Tracking</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="what-to-log">What to Log?</h3>
<ul>
<li><strong>[목적1]</strong> 서버나 프록시의 문제를 발견하기 위함</li>
<li><strong>[목적2]</strong> 웹 사이트 접근에 관한 통계를 생성하기 위함<ul>
<li>통계 -&gt; 마케팅, 청구서, 서버나 대역폭 증설을 위한 자료 등으로 활용</li>
</ul>
</li>
<li><strong>일반적으로 로깅되는 항목</strong><ul>
<li>서버와 클라이언트 사이의 의도치않은 상호작용 디버깅<ul>
<li>클라이언트나 서버의 HTTP 버전</li>
</ul>
</li>
<li>무엇을 위한 요청인가<ul>
<li>HTTP 메서드</li>
<li>요청 리소스 URL</li>
</ul>
</li>
<li>요청으로 인해 어떤 일이 발생했는가<ul>
<li>HTTP 응답 코드</li>
</ul>
</li>
<li>특정 시점에 얼마나 많은 바이트가 오고 가는가<ul>
<li>요청 및 응답메시지의 크기</li>
<li>트랜잭션이 발생한 시점 (타임스탬프)</li>
</ul>
</li>
<li>User-Agent 헤더와 Referer 헤더 값</li>
</ul>
</li>
</ul>
<hr>
<h3 id="common-log-format">Common Log Format</h3>
<blockquote>
<p>NCSA에 의해 정의 -&gt; 대부분의 상업용 &amp; 오픈소스 서버에서 디폴트로 사용하는 로그 포맷</p>
</blockquote>
<pre><code>209.1.32.44 - - [03/Oct/1999:14:16:00 -0400] &quot;GET / HTTP/1.0&quot; 200 1024
http-guide.com - dg [03/Oct/1999:14:16:32 -0400] &quot;GET / HTTP/1.0&quot; 200 477
http-guide.com - dg [03/Oct/1999:14:16:32 -0400] &quot;GET /foo HTTP/1.0&quot; 404 0</code></pre><ul>
<li><code>remotehost</code> : 요청자 컴퓨터의 호스트명 or IP 주소</li>
<li><code>username</code> : 애플리케이션 로직 내부 레벨에서의 사용자 이름 (OAuth2, JWT 등)</li>
<li><code>auth-username</code> : 인증이 수행된 후 요청자가 인증한 사용자 이름 (Basic Auth, Digest Auth 등)</li>
<li><code>timestamp</code> : 요청 날짜와 시각</li>
<li><code>request-line</code> : HTTP 요청 라인</li>
<li><code>response-code</code> : HTTP 응답 코드</li>
<li><code>response-size</code> : Content-Length 값</li>
</ul>
<hr>
<h3 id="combined-log-format">Combined Log Format</h3>
<blockquote>
<p>Common Log Format에 두 가지 필드가 추가된 형식</p>
</blockquote>
<pre><code>209.1.32.44 - - [03/Oct/1999:14:16:00 -0400] &quot;GET / HTTP/1.0&quot; 200 1024 &quot;http://www.joes-hardware.com/&quot; &quot;5.0: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)&quot;</code></pre><ul>
<li><code>Referer</code> : HTTP 헤더의 Referer 값 -&gt; 유입 링크</li>
<li><code>User-Agent</code> : HTTP 헤더의 User-Agent 값 -&gt; 유입 도구(기기, 브라우저 등) </li>
</ul>
<hr>
<h3 id="netscape-extended-log-format">Netscape Extended Log Format</h3>
<blockquote>
<p>Common Log Format에 프록시나 캐시 등 HTTP 응용 프로그램과 연관된 필드까지 통합한 형식</p>
</blockquote>
<pre><code>209.1.32.44 - - [03/Oct/1999:14:16:00-0400] &quot;GET / HTTP/1.0&quot; 200 1024 200 1024 0 0 215 260 279 254 3</code></pre><ul>
<li><code>proxy-response-code</code> : 서버에서 프록시로 전달된 HTTP 응답 코드</li>
<li><code>proxy-response-size</code> : 서버에서 프록시로 전달된 Content-Length 값</li>
<li><code>client-request-size</code> : 클라이언트에서 프록시로 전달된 Content-Length 값</li>
<li><code>proxy-request-size</code> : 프록시에서 서버로 전달된 Content-Length 값</li>
<li><code>client-request-hdr-size</code> : 클라이언트의 요청 헤더 바이트 크기</li>
<li><code>proxy-response-hdr-size</code> : 요청자에게 전달된 프록시의 응답 헤더 바이트 크기</li>
<li><code>proxy-request-hdr-size</code> : 서버에 전달된 프록시의 응답 헤더 바이트 크기</li>
<li><code>server-response-hdr-size</code> : 서버의 응답 헤더 바이트 크기</li>
<li><code>proxy-timestamp</code> : 요청이나 응답이 프록시를 통과하는 데 소요된 시간</li>
</ul>
<hr>
<h3 id="netscape-extended-2-log-format">Netscape Extended 2 Log Format</h3>
<blockquote>
<p>Netscape Extended Log Format에 몇 가지 필드가 추가된 형식</p>
</blockquote>
<pre><code>209.1.32.44 - - [03/Oct/1999:14:16:00-0400] &quot;GET / HTTP/1.0&quot; 200 1024 200 1024 0 0 215 260 279 254 3 DIRECT FIN FIN WRITTEN</code></pre><ul>
<li><code>route</code> : 클라이언트 요청에 응답하기 위해 프록시가 사용한 경로<ul>
<li><code>DIRECT</code> : 원본 서버에서 리소스 조회</li>
<li><code>PROXY(host:port)</code> : host:port에 해당하는 프록시에서 리소스 조회</li>
<li><code>SOCKS(socks:port)</code> : SOCKS 서버를 통해 리소스 조회</li>
</ul>
</li>
<li><code>client-finish-status-code</code> : 클라이언트 -&gt; 프록시 요청이 성공적으로 이루어졌는지 확인하기 위한 상태 코드 (성공 FIN, 실패 INTR, 타임아웃 TIMEOUT)</li>
<li><code>proxy-finish-status-code</code> : 프록시 -&gt; 서버 요청이 성공적으로 이루어졌는지 확인하기 위한 상태 코드 (성공 FIN, 실패 INTR, 타임아웃 TIMEOUT)</li>
<li><code>cache-result-code</code> : 캐시 상태 코드 -&gt; 캐시가 요청에 어떻게 대응하였는지 확인</li>
</ul>
<hr>
<h3 id="squid-proxy-log-format">Squid Proxy Log Format</h3>
<blockquote>
<p>오픈소스 프로젝트 Squid에서 고안한 로그 형식</p>
</blockquote>
<pre><code>99823414 3001 209.1.32.44 TCP_MISS/200 4087 GET http://www.joes-hardware.com - DIRECT/proxy.com text/html</code></pre><ul>
<li>Timestamp, time-elapsed, host-ip, action-code, status, size, method, URL, RFC 931 ident, hierarchy, from, content-type 필드로 구성</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/19e1c10b-31a9-4789-b9f6-0bd3337a198f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/817e4561-429d-4d5d-bef9-7df8ca6cb1b6/image.png" alt=""></p>
<hr>
<h3 id="hit-metering">Hit Metering</h3>
<blockquote>
<p>Cache Busting을 방지하기 위해, 프록시 캐시에서 집계된 콘텐츠 제공횟수를 정기적으로 원본 서버에 보고하는 프로토콜 (RFC 2227)</p>
</blockquote>
<ul>
<li>현재는 거의 사용되지 않는 기술</li>
<li>HTTP extension의 형태<ul>
<li>캐시와 서버의 접근 정보 공유</li>
<li>캐싱된 리소스의 사용 빈도 조절</li>
</ul>
</li>
<li>동작 방식
<img src="https://velog.velcdn.com/images/dvlp-sy/post/aa7d3a45-6880-448d-9f0f-7783f37b55f1/image.png" alt=""><ul>
<li>클라이언트 -&gt; 프록시 : 일반적인 HTTP 트랜잭션 수행</li>
<li>프록시 -&gt; 서버 : <code>Meter</code> 헤더에 자신이 Hit Metering을 제공함을 전달</li>
<li>서버 -&gt; 프록시 : <code>Meter</code> 헤더를 통해 프록시에게 usage reports를 전송할 것을 요청</li>
<li>이후 요청에서 프록시 -&gt; 서버 : <code>Meter</code> 헤더를 통해 reports 전달</li>
</ul>
</li>
</ul>
<h4 id="the-meter-header">The Meter Header</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/1264a305-a99d-4ad0-8656-b6aadddd7653/image.png" alt=""></p>
<hr>
<h3 id="a-word-on-privacy">A Word on Privacy</h3>
<ul>
<li>로그에는 사용자의 정보가 남을 수 있으므로 privacy에 항상 유의해야 한다</li>
<li>서버 관리자는 고객의 트랜잭션 정보가 모니터링 되고 있음을 사전에 고지해야 한다</li>
</ul>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>예전에 클라이언트 요청 IP를 확인해야 할 일이 있어서 Nginx 로그를 열어본 적이 있었다. Nginx 위에 WAS를 올리는 방식이 익숙하지 않았던 나는.. 난생 처음 보는 Nginx 구성 파일과 로그에 완전히 정신이 나가버렸다. 사실 좀만 집중해서 보면 그렇게 어려울 것도 없었는데 처음이라 쫄았다.</p>
<p>여타 서버와 마찬가지로 Nginx도 NCSA 표준 포맷으로 로깅이 되어 있었는데, 각각의 필드가 뭘 의미하는지 정확히 알지 못해서 많이 헤맸던 기억이 난다. 로그에 IP 주소가 여러 개 찍혀 있었기 때문이다. 하나는 NCSA 포맷의 remote_addr 값이고, 다른 IP는 Nginx에서 제공하는 http_x_forwarded_for 값이었다. 요청이 로드밸런서나 앞단의 프록시를 거쳐서 들어오는 경우에는 remote_addr 값이 클라이언트의 IP가 아닐 수 있어서 XFF 헤더를 함께 사용하는 상황이었다. 이제는 표준 포맷을 알고 있으니 무엇이 remote_addr고 무엇이 커스텀 헤더인지 쉽게 구분할 수 있을 것 같다.</p>
<hr>
<h2 id="✏️-완독-후기">✏️ 완독 후기</h2>
<hr>
<p>처음 HTTP 책을 읽기 시작한 게 2024년 1월 18일, 오늘 날짜가 2026년 5월 16일이다. 당최 얼마나 게으른 건지 모르겠다. 2년이 넘는 시간 동안 책 한 권을 붙잡고 있었던 것도 여러모로 대단하다. 하루에 두 페이지 읽는 것조차 귀찮아서 미루고 미룬 내 자신도 대단하고, 그런 와중에 또 포기는 안 해서 꾸역꾸역 어떻게든 493페이지를 다 읽어낸 것도 대단하다. 확실히 나도 정상은 아니라고 생각한다.</p>
<p>이 책을 읽는 동안 계절이 두 사이클을 돌았고, 그 사이에 인턴도 하고 졸업도 했다. 요즘 같은 AI 시대에 개발자들 입에 풀칠하고 살기 힘들다지만 다람쥐 책 읽듯 묵묵히 내가 할 수 있는 일을 해나가는 사람이 되겠다. 포기하고 싶은 순간이 와도 포기하지 않고, 작심삼일을 백 번 하더라도 무언가를 반드시 이루고야 마는, 그런 사람이 되겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p475 ~ p482"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p475-p482</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p475-p482</guid>
            <pubDate>Fri, 15 May 2026 08:37:38 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-20-redirection-and-load-balancing">Chapter 20. Redirection and Load Balancing</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="carp-cache-array-routing-protocol">CARP (Cache Array Routing Protocol)</h3>
<ul>
<li><p>Microsoft와 Netscape Communication이 제안한 표준</p>
</li>
<li><p>프록시 서버 묶음을 하나의 논리적인 캐시로 표현하기 위한 방식</p>
</li>
<li><p><strong>CARP vs ICP</strong>
<img src="https://velog.velcdn.com/images/dvlp-sy/post/b80b94e1-bda2-4899-aca6-994599399a94/image.png" alt=""></p>
<ul>
<li><strong>ICP (Internet Cache Protocol)</strong> : 한 캐시가 동일한 계층의 캐시 집합에서 콘텐츠를 찾을 수 있도록 하는 프로토콜 (MISS가 발생하면 부모 프록시로 전달)<ul>
<li>여러 캐시에 콘텐츠 미러링 -&gt; 웹 오브젝트에 접근할 수 있는 통로가 여러 개</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/2114ff54-2cdc-4f47-8b3f-7b7e43faa700/image.png" alt=""></p>
<ul>
<li><strong>CARP</strong> : 문서가 여러 서버에 분산되어 있고 그 중 하나의 서버와 상호작용할 수 있게 하는 프로토콜<ul>
<li>URL에 해시함수 적용 -&gt; 특정 서버에만 콘텐츠 저장</li>
<li>각 프록시 서버에 폴링하지 않고 한 번의 lookup으로 객체 조회 가능</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>장점</strong></p>
<ul>
<li>모든 Sibling Caches에 쿼리 X -&gt; 효율적</li>
</ul>
</li>
<li><p><strong>단점</strong></p>
<ul>
<li>한 프록시 서버가 다운되면 해시함수가 수정되어야 한다</li>
<li>한 프록시 서버가 다운되면 해당 서버의 콘텐츠가 다른 프록시 서버로 다시 분산되어야 한다</li>
<li>따라서, 프록시 서버가 자주 다운되는 경우 비용이 증가한다</li>
</ul>
</li>
</ul>
<h4 id="carp-redirection-method">CARP Redirection Method</h4>
<ul>
<li>참여 중인 프록시 서버 테이블 구성<ul>
<li>주기적으로 프록시 서버 간 heartbeat를 확인할 수 있다</li>
<li>Load(CPU speed, HDD 용량 등), TTL countdown, 기타 전역변수 정보 등을 엔트리에 포함할 수 있다</li>
<li>테이블은 RPC 인터페이스에 의해 원격으로 관리된다</li>
</ul>
</li>
<li>참여 중인 프록시 서버에 대해 해시함수 계산<ul>
<li>해시함수 반환값은 프록시가 처리할 수 있는 부하의 양을 고려한다</li>
</ul>
</li>
<li>URL에 기반해 숫자를 반환하는 독립적인 해시함수 정의</li>
<li>URL 해시함수 적용 결과 + 프록시 서버 해시함수 적용 결과 = 배열 번호<ul>
<li>배열 번호의 최댓값이 프록시 서버를 결정</li>
<li>Deterministic -&gt; 이후에 발생하는 요청도 동일한 프록시 서버로 포워딩</li>
</ul>
</li>
</ul>
<hr>
<h3 id="htcp-hyper-text-caching-protocol">HTCP (Hyper Text Caching Protocol)</h3>
<ul>
<li>ICP vs HTCP<ul>
<li>ICP : HTTP/0.9 기반의 프로토콜 -&gt; URL만으로 문서 존재 여부 확인</li>
<li>HTCP : HTTP/1.0과 HTTP/1.1의 새로운 헤더를 반영한 프로토콜 -&gt; URL + 요청/응답 헤더를 통해 문서 존재 여부 확인</li>
</ul>
</li>
<li>HTCP Redirection Method<ul>
<li>ICP와 동일, 요청과 응답만 조금 다르다</li>
</ul>
</li>
</ul>
<h4 id="htcp-message-format">HTCP Message Format</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/f169b664-41c0-49a5-9815-c3985596817f/image.png" alt=""></p>
<ul>
<li>Header : 32비트 메시지 길이, 8비트 major 버전, 8비트 minor 버전으로 구성<ul>
<li>메시지 길이는 모든 header, data, authentication의 크기 포함</li>
</ul>
</li>
<li>Data : HTCP 메시지와 기타 데이터 포함<ul>
<li><code>Data length</code> : 16비트 데이터 길이</li>
<li><code>Opcode</code> :  4비트 HTCP 트랜잭션 opcode</li>
<li><code>Response code</code> : 4비트 트랜잭션 상태 -&gt; 0(인증 필요), 1(안전하지 않은 인증), 2(미구현), 3(지원되지 않는 major 버전), 4(지원되지 않는 minor 버전), 5(허용되지 않는 opcode)</li>
<li><code>F1</code> : 요청자에 의해 지정되는 1비트 플래그 -&gt; 요청의 경우 응답이 필요한지 여부 지정, 응답의 경우 전체 메시지에 대한 응답인지 opcode에 대한 응답인지 여부 지정</li>
<li><code>RR</code> : 메시지가 요청인지 응답인지 나타내는 1비트 플래그</li>
<li><code>Transaction ID</code> : 요청자의 네트워크 주소와 HTCP 트랜잭션 식별자가 결합된 32비트 값</li>
<li><code>Opcode data</code> : opcode별로 다른 값</li>
</ul>
</li>
</ul>
<h4 id="htcp-opcodes">HTCP opcodes</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/52b7018f-fd37-45e2-a445-34be8a296306/image.png" alt=""></p>
<h4 id="htcp-authentication">HTCP Authentication</h4>
<ul>
<li><code>Auth length</code> : Length 필드의 길이를 포함한 Authentication 섹션의 길이 (16비트)</li>
<li><code>Sig time</code> : 00:00:00 Jan 1, 1970 GMT부터 서명 생성 시점까지의 시간 (32비트)</li>
<li><code>Sig expire</code> : 00:00:00 Jan 1, 1970 GMT부터 서명 만료 시점까지의 시간 (32비트)</li>
<li><code>Key name</code> : 공유된 비밀키의 이름 지정</li>
<li><code>Signature</code> : HMAC-MD5 다이제스트 값 (버전, Sig time, Sig expire, HTCP 데이터, 키)</li>
</ul>
<h4 id="setting-caching-policies">Setting Caching Policies</h4>
<ul>
<li>SET 메시지를 통해 캐싱 정책 지정 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/c8a1db3a-4dcb-4da9-b9fc-0a24f337bc10/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p469 ~ p474"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p469-p474</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p469-p474</guid>
            <pubDate>Wed, 13 May 2026 08:17:16 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-20-redirection-and-load-balancing">Chapter 20. Redirection and Load Balancing</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="cache-redirection-methods">Cache Redirection Methods</h3>
<blockquote>
<p>캐싱 프록시 서버에서 사용되는 정교한 리디렉션 기술</p>
</blockquote>
<ul>
<li>Reliable &amp; High-performance &amp; Content-aware</li>
<li>특정 콘텐츠가 있을 확률이 높은 위치에 요청 전송</li>
</ul>
<h3 id="wccp-redirection">WCCP Redirection</h3>
<ul>
<li>라우터가 프록시 캐시로 웹 트래픽을 리디렉션하기 위한 프로톸콜<ul>
<li>[기능1] 캐시 식별 (이용 가능한가? 현재 동작 중인가?)</li>
<li>[기능2] 캐시 간 로드밸런싱</li>
<li>[기능3] 특정 유형의 트래픽을 특정 서버로 전달</li>
</ul>
</li>
</ul>
<h4 id="wccp2의-동작-방식">WCCP2의 동작 방식</h4>
<ul>
<li>WCCP-enabled 라우터와 캐시가 포함된 네트워크에서의 통신 상황 가정</li>
<li>WCCP 서비스 그룹 생성<ul>
<li>서비스 그룹 구성 : 트래픽 유형, 트래픽 전송 방식, 부하 분산 방식 정의</li>
</ul>
</li>
<li>서비스 그룹에 포함된 라우터가 HTTP 트래픽을 캐시로 리디렉션<ul>
<li>라우터는 서비스 그룹에 포함된 캐시 중 하나를 선택해서 요청 전달</li>
<li>캐시의 IP 주소를 캡슐화하거나 IP MAC 주소를 포워딩</li>
</ul>
</li>
<li>캐시가 요청을 제공할 수 없는 경우<ul>
<li>패킷이 라우터로 반환되어 일반적인 포워딩 수행</li>
</ul>
</li>
<li>서비스 그룹에 포함된 요소 간 heartbeat 메시지를 주고받을 수 있다</li>
</ul>
<h4 id="wccp2-메시지의-유형">WCCP2 메시지의 유형</h4>
<ol>
<li><code>WCCP2_HERE_I_AM</code> : 캐시 -&gt; 라우터<pre><code>WCCP Message Header
Security Info Component
Service Info Component
Web-cache Identity Info Component
Web-cache View Info Component
Capability Info Component (optional)
Command Extension Component (optional)</code></pre><ul>
<li>캐시가 트래픽을 수용할 수 있음을 라우터에 전달</li>
</ul>
</li>
<li><code>WCCP2_I_SEE_YOU</code> : 라우터 -&gt; 캐시<pre><code>WCCP Message Header
Security Info Component
Service Info Component
Router Identity Info Component
Router View Info Component
Capability Info Component (optional)
Command Extension Component (optional)</code></pre><ul>
<li>WCCP2_HERE_I_AM의 응답</li>
<li>패킷 포워딩 방식, 할당 방식, 패킷 반환 방식, 보안 방식 등을 협의하는 데 사용</li>
</ul>
</li>
<li><code>WCCP2_REDIRECT_ASSIGN</code> : 지정된 캐시 -&gt; 라우터<pre><code>WCCP Message Header
Security Info Component
Service Info Component
Assignment Info Component, or Alternate Assignment Component</code></pre><ul>
<li>로드 밸런싱을 위한 할당 정보 전달</li>
</ul>
</li>
<li><code>WCCP2_REMOVAL_QUERY</code> : 라우터 -&gt; 캐시<pre><code>WCCP Message Header
Security Info Component
Service Info Component
Router Query Info Component</code></pre><ul>
<li>정해진 기간 동안 WCCP2_HERE_IAM을 전송하지 않은 캐시를 서비스 그룹에서 삭제</li>
</ul>
</li>
</ol>
<h4 id="wccp2-메시지의-구성-요소">WCCP2 메시지의 구성 요소</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/9fdfb46e-7877-45ca-80a1-c146512ca83e/image.png" alt=""></p>
<h4 id="gre-packet-encapsulation">GRE packet encapsulation</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/ab0081dc-740a-42f9-8cf0-db8830569be2/image.png" alt=""></p>
<ul>
<li>GRE(Generic Router Encapsulation) : 패킷을 리디렉션할 때 클라이언트와 서버의 IP 주소를 캡슐화하는 것</li>
<li>IP 헤더 프로토 필드 보유<ul>
<li>패킷을 받는 프록시에 패킷이 캡슐화되어 있음을 알릴 수 있다</li>
<li>캡슐화로 인해 클라이언트 IP 주소가 손실되지 않는다</li>
</ul>
</li>
</ul>
<h4 id="wccp-load-balancing">WCCP load balancing</h4>
<ul>
<li>Heartbeat messages : 서비스 그룹 내 요소 간 동작(running) 여부를 확인하기 위해 사용</li>
<li>Heartbeat message가 없는 경우 WCCP 라우터는 트래픽을 바로 인터넷으로 전송한다</li>
</ul>
<hr>
<h3 id="internet-cache-protocol">Internet Cache Protocol</h3>
<blockquote>
<p>한 캐시가 Sibling Caches에서 콘텐츠를 찾을 수 있게 하는 프로토콜</p>
</blockquote>
<ul>
<li><p>Sigling Caches : 동일한 계층에 위치한 캐시들 (not downstream, upstream)</p>
</li>
<li><p>캐시가 HTTP 메시지로부터 요청받은 콘텐츠를 보유하고 있지 않은 경우</p>
<ul>
<li>근처의 Sibling Cache에서 콘텐츠 탐색</li>
<li>Sibling Cache에서 콘텐츠를 발견한 경우 원본 서버로 요청 전송 X -&gt; 비용 감소</li>
</ul>
</li>
<li><p>Cache Clustering Protocol</p>
<ul>
<li>일련의 ICP 쿼리를 통해 HTTP 요청의 최종 도착지가 달라진다</li>
</ul>
</li>
<li><p>Object Discovery Protocol</p>
<ul>
<li>특정 URL에 대해 HIT 응답과 MISS 응답을 보낸다</li>
<li>캐시는 인근 캐시와 자유롭게 HTTP 연결을 열고 오브젝트가 존재하는지 확인 가능</li>
</ul>
</li>
<li><p>Simple and Lightweight</p>
<ul>
<li>32비트의 ICP 메시지, 간단한 파싱</li>
<li>UDP 데이터그램을 통한 전달 -&gt; 높은 전송 효율 but 손실 가능<ul>
<li>ICP를 사용하는 프로그램은 타임아웃 기능과 손실된 데이터그램을 감지할 수 있는 기능을 가져야 한다</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="icp-메시지의-구성요소">ICP 메시지의 구성요소</h4>
<ul>
<li><code>Opcode</code> : ICP 메시지의 의미를 나타내는 8비트 값, ICP_OP_QUERY 요청 메시지, ICP_OP_HIT, ICP_OP_MISS 로 구성</li>
<li><code>Version</code> : ICP 프로토콜의 버전 번호 (RFC 2186)</li>
<li><code>Message length</code> : ICP 메시지의 전체 바이트 크기를 나타내는 16비트 값 -&gt; ICP 메시지 크기는 16383 바이트를 초과할 수 없고 URL의 길이는 16KB보다 짧아야 한다</li>
<li><code>Request number</code> : 요청 번호 -&gt; 1번 요청에 대한 응답에도 동일한 번호가 포함되어야 한다</li>
<li><code>Options</code> : ICP의 동작을 제어하기 위한 32비트 bit vector<ul>
<li>ICP_FLAG_HIT_OBJ : ICP 응답에 문서 데이터를 포함할 것인지 여부</li>
<li>ICP_FLAG_SRC_RTT : Sibling Cache에 의해 측정된 원본 서버까지의 왕복 시간 추정치를 포함할 것인지 여부</li>
</ul>
</li>
<li><code>Option data</code> : 부가적인 기능을 위해 사용되는 32비트 데이터<ul>
<li>ICPv2는 16비트를 Sibling Cache에서 원본 서버까지의 왕복 시간 추정치를 담는 데 사용</li>
</ul>
</li>
<li><code>Sender host address</code> : 메시지 송신자의 32비트 IP 주소 (실제로는 사용되지 않는다)</li>
<li><code>Payload</code> : 메시지 유형에 따라 서로 다른 내용 보유<ul>
<li>ICP_OP_QUERY : 요청자의 호스트 주소(4바이트)와 NUL-terminated URL</li>
<li>ICP_OP_HIT_OBJ : NUL-terminated URL과 16비트의 오브젝트 크기</li>
</ul>
</li>
</ul>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>무지성으로 개발을 하다 보면 아무래도 HTTP 자체에만 집중하게 되는 것 같다. 클라이언트와 서버 사이에 존재하는 수많은 라우터들이 어떻게 패킷을 주고받는지는 딱히 관심도 없고 흐린 눈으로 봐왔다. 근데 원리를 알고 보니 좀 재밌다.</p>
<p>네트워크 내에서 라우터와 캐시 풀을 구성하고 WCCP라는 프로토콜을 통해 성능을 개선하고 있다는 것을 알게 됐다. 같은 계층의 Cache간 탐색이 필요할 때는 ICP를 사용한다는 것, 캐시간 빠른 통신을 위해 UDP 위에 구현된다는 것도 알게 됐다.</p>
<p>이 세상에는 참 신기한 프로토콜이 많은 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p461 ~ p469"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p461-p</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p461-p</guid>
            <pubDate>Wed, 11 Mar 2026 07:02:16 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-20-redirection-and-load-balancing">Chapter 20. Redirection and Load Balancing</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="network-element-control-protocol">Network Element Control Protocol</h3>
<ul>
<li><strong>NECP</strong><ul>
<li>Network Element가 Server Element와 소통하기 위한 프로토콜</li>
<li><code>Network Elements</code> : IP 패킷을 포워딩하는 라우터나 스위처 등의 장치</li>
<li><code>Server Elements</code> : 응용 계층에서 콘텐츠를 제공하는 웹 서버나 프록시 등의 장치</li>
</ul>
</li>
<li>로드밸런싱을 명시적으로 지원하지 않는다<ul>
<li>대신, SE가 NE에 로드밸런싱 정보를 제공할 수 있는 수단 제공 -&gt;. NE가 적절히 부하를 분산하도록 한다</li>
</ul>
</li>
<li>MAC forwarding, GRE 캡슐화, NAT 등의 패킷 포워딩 수단 제공</li>
</ul>
<h4 id="messages">Messages</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/be9c1086-a291-4718-b09e-316775831e53/image.png" alt=""></p>
<hr>
<h3 id="proxy-redirection-methods">Proxy Redirection Methods</h3>
<h4 id="explicit-browser-configuration">Explicit Browser Configuration</h4>
<ul>
<li>사용자가 직접 프록시의 이름이나 IP/port를 입력할 수 있는 메뉴 제공<ul>
<li>사용자가 브라우저를 정확히 구성하기 어려우니 사전에 구성되어 있는 브라우저를 다운로드 받게 유도하는 편</li>
</ul>
</li>
<li>브라우저가 특정 프록시에 모든 요청을 전송하도록 구성 -&gt; 브라우저가 어떤 프록시에 접속해야 하는지 알고 있다</li>
<li>단점<ul>
<li>프록시를 사용하도록 구성된 브라우저는 원본 서버에 접속할 수 없다</li>
<li>프록시에 문제가 발생하는 경우 응답을 받을 수 없다</li>
<li>네트워크 구조를 변경하거나, 변경된 사항을 엔드 유저한테 전파하기 어렵다 (서비스 제공자가 더 많은 프록시를 제공하길 원하는 경우 사용자가 직접 설정을 바꿔야 한다)</li>
</ul>
</li>
</ul>
<h4 id="proxy-auto-configuration">Proxy Auto-configuration</h4>
<ul>
<li>브라우저가 동적으로 올바른 프록시 서버를 구성하도록 한다</li>
<li><code>PAC</code> : Proxy Auto-Configuration Protocol<ul>
<li>브라우저는 각각의 URL이 접속해야 할 프록시가 구성된 PAC 파일을 받는다</li>
<li>브라우저는 재시작할 때마다 새로운 PAC 파일 을 받아 구성된다</li>
<li>JavaScript로 작성되며, FindProxyForURL 메서드를 정의해야 한다<pre><code class="language-javascript">function FindProxyForURL(url, host)</code></pre>
</li>
<li>브라우저는 모든 요청 URL에 대해 FindProxyForURL 메서드를 호출해야 한다 (Return value는 여러 개의 프록시일 수 있다)<pre><code class="language-javascript">return_value = FindProxyForURL(url_of_request, host_in_url);</code></pre>
</li>
<li>PAC 파일에는 로드밸런싱, 요청 라우팅, 실패 처리 등 부가적인 기능 또한 포함된다</li>
</ul>
</li>
<li><strong>동작 방식</strong>
  <img src="https://velog.velcdn.com/images/dvlp-sy/post/fc0307d1-74b5-43ab-a953-7f9ea6991f26/image.png" alt=""><ul>
<li>&quot;netscape.com&quot; 도메인으로 요청이 오는 경우 원본 서버로 접속</li>
<li>그 밖의 다른 요청에 대해서는 “Proxy1.joes-cache.com&quot;로 접속</li>
</ul>
</li>
<li><strong>장점</strong><ul>
<li>브라우저가 호스트명과 관련된 다양한 파라미터(DNS 주소, 서브넷 등)를 바탕으로 프록시를 선택할 수 있다</li>
<li>네트워크 구조 변화에 맞춰 동적으로 적합한 프록시에 적합할 수 있다</li>
</ul>
</li>
<li><strong>단점</strong><ul>
<li>PAC 파일을 어느 서버에서 받아올지 사전에 구성되어 있어야 한다 (즉 완벽히 자동화된 구성 시스템이 아니다)</li>
<li>위의 단점을 해결하기 위해 <code>WPAD</code>가 등장했다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="web-proxy-autodiscovery-protocol-wpad">Web Proxy Autodiscovery Protocol (WPAD)</h3>
<ul>
<li>웹 브라우저가 가장 인접한 프록시를 찾아 사용할 수 있게 하는 프로토콜</li>
<li>WPAD를 정의하는 가장 일반적인 어려움은 수많은 탐색 프로토콜 중 어떤 것을 선택할 것인지, 브라우저마다 어떻게 서로 다르게 프록시를 구성할 것인지다</li>
</ul>
<h4 id="pac-file-autodidscovery">PAC file Autodidscovery</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/d94d99e8-5015-49fb-8241-4a95af5c2bc9/image.png" alt=""></p>
<ul>
<li>WPAD는 인터넷 상에 PAC 파일을 두고 적합한 프록시 서버를 결정하기 위해 PAC 파일을 사용한다</li>
<li>WPAD는 프록시 서버의 이름을 명시적으로 결정하지 않는다</li>
<li>WPAD는 PAC 파일 URL(CURL)을 발견하면, 해당 PAC 파일을 불러와 JavaScript 프로그램을 실행하여 프록시 서버를 결정한다</li>
</ul>
<h4 id="wpad-algorithm">WPAD algorithm</h4>
<ul>
<li><p>적합한 PAC 파일 CURL을 가져오기 위해 다양한 탐색 기술이 사용된다</p>
<ul>
<li>DHCP(Dynamic Host Discovery Protocol)</li>
<li>SLP(Service Location Protocol)</li>
<li>DNS well-known hostnames</li>
<li>DNS SRV records</li>
<li>DNS service URLs in TXT records</li>
</ul>
</li>
<li><p>WPAD 클라이언트가 리소스 탐색 요청을 전송하면 DHCP, SLP, DNS well-known hostnames, DNS SRV records, DNS service URLs in TXT recors를 순차적으로 확인한다</p>
</li>
<li><p>모든 탐색 매커니즘을 시도했음에도 PAC 파일이 발견되지 않으면 WPAD 프로토콜은 실패 처리되며 클라이언트는 프록시 서버를 사용하지 않도록 구성된다</p>
</li>
<li><p>DNS 탐색은 몇 바퀴에 거쳐 이루어질 수 있다</p>
</li>
</ul>
<h4 id="curl-discovery-using-dhcp">CURL discovery using DHCP</h4>
<ul>
<li>CURL은 DHCP 옵션 코드 252에 포함된다</li>
</ul>
<h4 id="dns-a-record-lookup">DNS A record lookup</h4>
<pre><code>QNAME=wpad.TGTDOM., QCLASS=IN, QTYPE=A</code></pre><ul>
<li>DNS alias “wpad”를 사용해서 프록시를 자동 탐색한다</li>
</ul>
<h4 id="retrieving-the-pac-file">Retrieving the PAC file</h4>
<pre><code>Accept: application/x-ns-proxy-autoconfig</code></pre><ul>
<li>PAC 파일에 대해 GET 요청을 전송할 때 Accept 헤더에 적절한 CFILE 포맷 정보를 포함해야 한다</li>
<li>CURL의 결과로 리디렉션 응답이 오는 경우 클라이언트는 최종 destination까지 리디렉션해야 한다</li>
</ul>
<h4 id="when-to-execute-wpad">When to execute WPAD</h4>
<ul>
<li>웹 클라이언트를 시작할 때 : 최초로 인스턴스를 시작할 때 WPAD가 사용되며 이후에 생성되는 인스턴스는 설정을 상속 받는다.</li>
<li>클라이언트 호스트의 IP 주소가 바뀔 때마다</li>
<li>기존에 다운로드 했던 PAC 파일이 만료되었을 때</li>
<li>현재 구성된 PAC 파일을 따르면 실패가 발생할 때</li>
</ul>
<h4 id="wpad-spoofing">WPAD Spoofing</h4>
<ul>
<li>악성 사용자가 third-level domain을 선점하고 wpad 프록시 서버를 만들면 수많은 브라우저가 악성 프록시 서버에 도달하게 된다</li>
<li>IE 5.01 이후로는 third-level domain까지 탐색하지 않도록 막음</li>
</ul>
<h4 id="timeouts">Timeouts</h4>
<ul>
<li>각각의 탐색 단계를 10초로 제한하는 것이 합리적 (타임아웃은 구현마다 상이할 수 있음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p452 ~ p 461"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p452-p-461</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p452-p-461</guid>
            <pubDate>Tue, 03 Mar 2026 08:18:12 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-20-redirection-and-load-balancing">Chapter 20. Redirection and Load Balancing</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="http-redirection">HTTP Redirection</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/c889ba7f-c510-4ed5-a79e-5d6d5ffad450/image.png" alt=""></p>
<ul>
<li>장점<ul>
<li>리디렉트 하는 서버가 클라이언트의 IP 주소를 알고 있다 -&gt; 더 많은 정보를 보유한 채로 destination을 선택할 수 있다</li>
</ul>
</li>
<li>단점<ul>
<li>어느 서버로 리디렉트할지 결정하는 과정에서 많은 프로세싱 파워 소모</li>
<li>요청을 두 번 보내야 하므로 사용자 지연 증가<ul>
<li>리디렉트 하는 서버에 장애가 발생하면 사이트 전체가 마비된다</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="dns-redirection">DNS Redirection</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/739e6857-6cb2-44b2-a6d0-d9289f607036/image.png" alt=""></p>
<ul>
<li>DNS는 하나의 도메인에 여러 개의 IP를 바인딩할 수 있다</li>
<li>DNS가 반환하는 IP는 Round Robin 방식이나 부하가 적은 서버를 선택하는 등 다양한 방식으로 결정될 수 있다</li>
</ul>
<h4 id="dns-round-robin">DNS round robin</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/556c20f8-c5e4-43c4-af50-d010e9a6aaf6/image.png" alt=""></p>
<ul>
<li>여러 개의 웹 서버 팜 가운데 하나에 순차적으로 로드 밸런싱하는 방식</li>
<li>대부분의 DNS 클라이언트는 첫 번째 주소를 사용 -&gt; DNS 서버가 <code>nslookup</code>이 완료될 때마다 IP 주소를 로테이션 하여 부하를 분산한다</li>
</ul>
<h4 id="the-impact-of-dns-caching">The impact of DNS caching</h4>
<ul>
<li>DNS lookup의 결과가 응용 프로그램이나 OS, 하위의 DNS 서버에 저장되고 재사용될 수 있다 -&gt; 동일한 주소를 반복적으로 사용하는 문제 발생</li>
<li>대부분의 운영체제가 DNS lookup을 자동으로 수행하고 결과를 저장하므로 IP 주소의 로테이션이 원활하게 이루어지지 않을 수 있다</li>
<li>하나의 클라이언트가 계속해서 동일한 IP로 접속하게 되지만 여러 클라이언트에 대해서는 여전히 로드 밸런싱의 효과가 있다</li>
</ul>
<h4 id="other-dns-based-redirection-algorithms">Other DNS-based redirection algorithms</h4>
<ul>
<li><code>Load-balancing algorithms</code> : 웹 서버의 부하를 추적해서 가장 부하가 적은 서버로 리디렉트 하는 기술</li>
<li><code>Proximity-routing algorithms</code> : 사용자를 가장 가까운 웹 서버로 리디렉트 하는 기술</li>
<li><code>Fault-masking algorithms</code> : 네트워크 상태를 모니터링하고 중간에 결함이 발생하지 않도록 요청을 라우팅하는 기술</li>
</ul>
<hr>
<h3 id="anycast-addressing">Anycast Addressing</h3>
<ul>
<li>동일한 IP를 가진 웹 서버가 여러 위치에 분산되어 있을 때 최단 경로로 라우팅하기 위한 기술</li>
<li>각각의 웹 서버가 인근의 backbone 라우터에게 자신이 라우터라고 전파 -&gt; backbone 라우터가 특정 anycast 주소에 대한 패킷을 받으면 가장 가까운 라우터로 이동시킨다</li>
<li>요구사항<ul>
<li>서버가 라우터 프로토콜을 이해하고 사용할 수 있어야 한다</li>
<li>라우터가 IP 주소 충돌 문제를 해결할 수 있어야 한다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="ip-mac-forwarding">IP MAC Forwarding</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/79bf941e-803f-4e35-93a4-a35d6340ba6b/image.png" alt=""></p>
<ul>
<li>Layer 4-aware Switch : IP, 포트번호에 대한 정보를 갖고 라우팅</li>
</ul>
<hr>
<h3 id="ip-address-forwarding">IP Address Forwarding</h3>
<ul>
<li>들어오는 패킷의 TCP/IP 주소를 확인하고 Destination IP 주소에 따라 라우팅한다</li>
<li>Destination의 MAC Address가 아닌 IP 주소에 기반하는 것이 특징 -&gt; 여러 hop을 거친 곳에 destination이 위치하더라도 포워딩이 가능하다</li>
<li><code>Full NAT</code> : 스위치가 서버로 요청을 넘길 때 클라이언트 IP를 스위치의 IP로 교체하는 방식<ul>
<li>장점 : 네트워크 구성이 복잡해도 반드시 스위치로 돌아올 수 있다</li>
<li>단점 : 서버가 진짜 클라이언트의 IP 주소를 알 수 없다</li>
</ul>
</li>
<li><code>Half NAT</code> : 스위치가 서버로 요청을 넘길 때 클라이언트 IP를 그대로 유지하는 방식<ul>
<li>장점 : 서버가 진짜 클라이언트의 IP 주소를 알 수 있다</li>
<li>단점 : 서버와 클라이언트 사이의 모든 네트워크 경로를 통제해야 한다</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p448 ~ p452"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p448-p452</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p448-p452</guid>
            <pubDate>Mon, 02 Mar 2026 12:00:56 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-20-redirection-and-load-balancing">Chapter 20. Redirection and Load Balancing</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="why-redirect">Why Redirect?</h3>
<ul>
<li>웹 콘텐츠가 다양한 위치에 분배되어 있는 이유는 다음과 같다<ul>
<li>안정성 있는 HTTP 트랜잭션을 위해서 (한 서버가 다운되면 가용성에 문제 발생)</li>
<li>지연을 최소화하기 위해서 (더 가까운 위치에서 리소스를 가져오면 빠르다)</li>
<li>네트워크 대역폭을 절약하기 위해서 (네트워크 혼잡 회피)</li>
</ul>
</li>
<li><code>Redirect</code>의 의의<ul>
<li>가장 적절한 위치의 콘텐츠를 찾을 수 있다</li>
<li>네트워크 혼잡을 피할 수 있으며 로드 밸런싱(부하 분산)이 가능하다</li>
</ul>
</li>
</ul>
<h3 id="where-to-redirect">Where to Redirect</h3>
<ul>
<li>웹 서버 리디렉션 : IP에 기반하여 요청 처리 -&gt; 어떤 destination이 가장 최적인가</li>
<li>프록시 리디렉션 : 프로토콜에 기반하여 요청 처리 -&gt; destination과 무관하게 효율적인 경로가 무엇인가</li>
</ul>
<hr>
<h3 id="overview-of-redirection-protocols">Overview of Redirection Protocols</h3>
<ul>
<li>인터넷을 통해 전달되는 HTTP 메시지는 HTTP 응용 프로그램과 라우팅 장치의 영향을 받는다<ul>
<li><code>Browser Apps</code> : 어떤 프록시 서버에 전달할 것인지 구성</li>
<li><code>DNS Resolvers</code> : 메시지를 전달할 IP 주소 선택</li>
<li><code>Routers</code> : TCP/IP 기반의 패킷 라우팅 수행</li>
<li><code>Web Servers</code> : 웹 서버에 도달한 후의 부가적인 리디렉션</li>
</ul>
</li>
</ul>
<h4 id="general-redirection-methods">General Redirection Methods</h4>
<ul>
<li><code>HTTP Redirection</code> : 콘텐츠를 제공할 최적의 웹 서버를 선택한다 (Round-robin일 수도 있고 지연을 최소화하는 방식일 수도 있고 최단 경로를 찾는 방식일 수도 있다)</li>
<li><code>DNS Redirection</code> : 여러 개의 IP 중 하나의 IP를 선택한다 (Round-robin일 수도 있고 지연을 최소화하는 방식일 수도 있고 최단 경로를 찾는 방식일 수도 있다)</li>
<li><code>Anycast Addressing</code> : 여러 서버가 동일한 IP를 사용하는 경우, 각각의 서버가 라우터를 구성하여 가까운 라우터로 패킷을 전달하게 한다 (119에 비유해보자 -&gt; 서울 소방서와 부산 소방서는 같은 소방서지만 서울에서 신고하면 서울 소방서로 라우팅된다)</li>
<li><code>IP MAC for Forwarding</code> : 패킷의 destination address로 포워딩한다</li>
<li><code>IP Address Forwarding</code> : Layer-4 스위치가 패킷의 destination port를 확인한 후 리디렉션 패킷의 IP 주소를 프록시 서버의 IP 주소로 변환한다</li>
</ul>
<h4 id="proxy-and-cache-redirection-techniques">Proxy and Cache Redirection Techniques</h4>
<ul>
<li><code>PAC(Proxy Auto-Configuration)</code> : 구성 서버로부터 PAC 파일을 받아 각각의 URL이 어떤 프록시를 사용해야 하는지 전달하기 위한 프로토콜.</li>
<li><code>WPAD(Web Proxy Autodiscovery Protocol)</code> : 브라우저가 구성 서버에 PAC 파일의 URL을 요청하기 위한 프로토콜. PAC 방식과 달리 브라우저를 특별히 구성하지 않아도 된다.</li>
<li><code>WCCP(Web Cache Coordination Protocol)</code> : 라우터가 패킷의 destination address를 확인한 후 프록시 서버의 IP 주소로 패킷을 리디렉션하는 프로토콜.</li>
<li><code>ICP(Internet Cache Protocol)</code> : 여러 캐시에 요청받은 콘텐츠를 질의하기 위한 프로토콜.</li>
<li><code>CARP(Cache Array Routing Procol)</code> : 캐시가 상위 캐시로 요청을 포워딩하는 데 사용되는 프로토콜. ICP 방식과 달리 캐시의 콘텐츠가 교집합이 없으며 여러 개의 캐시가 하나의 거대한 캐시처럼 동작할 때 사용한다.</li>
<li><code>HTCP(Hyper Text Caching Protocol)</code> : 참여 중인 여러 프록시가 여러 캐시에 요청받은 콘텐츠를 질의하기 위한 프로토콜. ICP와 달리 헤더까지 질의한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p439 ~ p447"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p439-p447</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p439-p447</guid>
            <pubDate>Fri, 27 Feb 2026 06:04:36 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-19-publishing-systems">Chapter 19. Publishing Systems</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="collections-and-namespace-management">Collections and Namespace Management</h3>
<ul>
<li>WebDAV는 XML 네임스페이스 파티션을 통해 충돌 없이 정확한 리소스/컬렉션 제어가 가능하다</li>
<li><code>DELETE</code>, <code>MKCOL</code>, <code>COPY</code>, <code>MOVE</code>, <code>PROPFIND</code> 5가지 네임스페이스를 사용한다</li>
</ul>
<h4 id="the-mkcol-method">The MKCOL Method</h4>
<ul>
<li>클라이언트가 서버의 특정 URL에 컬렉션을 생성하기 위한 메서드</li>
<li><code>PUT</code>, <code>POST</code> 메서드를 오버라이딩하는 경우 요청에 추가적인 데이터나 프로토콜이 필요할 수 있음 + 접근 제어가 어려움 -&gt; MKCOL 메서드를 추가하기로 결정</li>
<li>Request<pre><code>MKCOL /publishing HTTP/1.1
Host: minstar
Content-Length: 0
Connection: Keep-Alive</code></pre></li>
<li>Response<pre><code>HTTP/1.1 201 Created
Server: Microsoft-IIS/5.0
Date: Fri, 10 May 2002 23:20:36 GMT
Location: http://minstar/publishing/
Content-Length: 0</code></pre><ul>
<li><code>201 Created</code> : 컬렉션이 성공적으로 생성됨</li>
<li><code>405 Method Not Allowed</code> : 동일한 컬렉션이 이미 존재함</li>
<li><code>403 Forbidden</code> : 쓰기 권한(컬렉션 생성 권한)이 없음</li>
<li><code>409 Conflict</code> : 컬렉션을 생성할 상위 컬렉션이 존재하지 않음</li>
</ul>
</li>
</ul>
<h4 id="the-delete-method">The DELETE Method</h4>
<ul>
<li>컬렉션을 삭제하기 위한 메서드 -&gt; 기존의 DELETE 메서드를 의미적으로 확장하여 사용</li>
<li>주요 요청/응답 헤더<ul>
<li><code>Depth</code>  :  삭제할 컬렉션의 깊이 (설정되지 않으면 무한으로 간주)</li>
<li><code>Content-Location</code> : 삭제된 컬렉션의 URL</li>
</ul>
</li>
<li>Request<pre><code>DELETE /publishing HTTP/1.0
Host: minstar</code></pre></li>
<li>Response<pre><code>HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Tue, 14 May 2002 16:41:44 GMT
Content-Location: http://minstar/publishing/
Content-Type: text/xml
Content-Length: 0</code></pre></li>
</ul>
<h4 id="the-copy-and-move-methods">The COPY and MOVE Methods</h4>
<ul>
<li>요청 URL를 Source URL, <code>Destination</code> 헤더 값을 타겟 URL로 사용</li>
<li>주요 요청/응답 헤더<ul>
<li><code>Depth</code> : 컬렉션의 깊이 (Depth가 0인 경우 지정된 리소스 하나에만 COPY, MOVE 메서드가 적용되며 infinity가 허용됨)</li>
<li><code>Overwrite</code> : Overwrite가 F인 경우 동일한 리소스가 destination에 존재하면 연산에 실패함</li>
</ul>
</li>
<li><code>COPY</code> : 원본을 destination에 복사<ul>
<li>일반적으로는 원본 리소스의 속성도 그대로 복사된다</li>
<li>만약 속성을 그대로 복사하고 싶지 않다면 XML body에 명시할 수 있다</li>
</ul>
</li>
<li><code>MOVE</code> : 원본을 destination에 복사 -&gt; 새로 생성된 URI의 무결성 확인 -&gt; 원본 삭제</li>
<li>Request<pre><code>{COPY,MOVE} /publishing HTTP/1.1
Destination: http://minstar/pub-new
Depth: infinity
Overwrite: T
Host: minstar</code></pre></li>
<li>Response<pre><code>HTTP/1.1 201 Created
Server: Microsoft-IIS/5.0
Date: Wed, 15 May 2002 18:29:53 GMT
Location: http://minstar.inktomi.com/pub-new/
Content-Type: text/xml
Content-Length: 0</code></pre></li>
</ul>
<hr>
<h3 id="enhanced-http11-methods">Enhanced HTTP/1.1 Methods</h3>
<ul>
<li>WebDAV는 <code>DELETE</code>, <code>PUT</code>, <code>OPTIONS</code> 메서드를 일부 수정함</li>
</ul>
<h4 id="the-put-method">The PUT Method</h4>
<ul>
<li>저자가 자신의 콘텐츠를 공유된 사이트로 전송하기 위한 메서드</li>
<li>WebDAV는 PUT Method가 locking을 지원하도록 수정</li>
<li>Request<pre><code>PUT /ch-publish.fm HTTP/1.1
Accept: */*
If:&lt;http://minstar/index.htm&gt;(&lt;opaquelocktoken:********&gt;)
User-Agent: DAV Client (C)
Host: minstar.inktomi.com
Connection: Keep-Alive
Cache-Control: no-cache
Content-Length: 1155</code></pre><ul>
<li><code>If</code> : 리소스에 걸린 락과 일치하는 락 토큰이 명시된 경우 PUT 연산 수행</li>
</ul>
</li>
</ul>
<h4 id="the-options-method">The OPTIONS Method</h4>
<ul>
<li>WebDAV 서버의 수용력을 확인하기 위한 메서드</li>
<li>WebDAV 클라이언트가 최초로 전송하는 요청에 주로 사용</li>
<li>Request<pre><code>OPTIONS /ch-publish.fm HTTP/1.1
Accept: */*
Host: minstar.inktomi.com</code></pre></li>
<li>Response<pre><code>HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
MS-Author-Via: DAV
DASL: &lt;DAV:sql&gt;
DAV: 1, 2
Public: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL,PROPFIND,
PROPPATCH, LOCK, UNLOCK, SEARCH
Allow: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, COPY, MOVE, PROPFIND,PROPPATCH,
SEARCH, LOCK, UNLOCK</code></pre></li>
<li><code>DAV</code> 헤더 : DAV 호환 클래스에 대한 정보를 제공한다<ul>
<li>Class 1 compliance : RFC 2518에 명시된 모든 요구사항을 준수하는 서버 -&gt; 만약 리소스가 Class 1을 준수한다면 1을 반환한다</li>
<li>Class 2 compliance : Class 1을 준수하면서 LOCK 메서드를 지원하는 서버 (Timeout, Lock-Token 헤더와 그에 상응하는 XML 요소 제공) -&gt; 만약 리소스가 Class 2를 준수한다면 2를 반환한다</li>
</ul>
</li>
<li><code>Public</code> 헤더 : 서버에서 지원하는 모든 메서드를 나열한 헤더</li>
<li><code>Allow</code> 헤더 : Public 헤더의 부분집합, 특정 리소스에 대해 지원하는 모든 메서드를 나열한 헤더</li>
<li><code>DASL</code> 헤더 : SEARCH 메서드에서 사용되는 쿼리문의 유형을 제공하는 헤더</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP: The Definitive Guide "p432 ~ p439"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p432-p439</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p432-p439</guid>
            <pubDate>Mon, 23 Feb 2026 07:31:48 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-19-publishing-systems">Chapter 19. Publishing Systems</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="webdav-locking-and-overwrite-prevention">WebDAV Locking and Overwrite Prevention</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/225e7e35-410c-4ae4-9bd6-28602d60f04a/image.png" alt=""></p>
<ul>
<li>Lost Update Problem : A가 수정한 문서를 B가 덮어씀으로 인해 A의 수정사항이 반영되지 않는 문제</li>
<li><strong><em>WebDAV Locking</em></strong><ul>
<li><code>Exclusive Write Locking</code> : Lock을 가진 owner가 쓰기 권한 독점 -&gt; 충돌이 발생할 만한 잠재적인 위험 제거</li>
<li><code>Shared Write Locking</code> : 그룹 단위로 리소스의 쓰기 권한 소유 -&gt; 각각의 author가 교집합 없이 서로 다른 역할을 가지고 있는 경우 적합한 방식</li>
</ul>
</li>
<li><strong><em>PROPFIND</em></strong><ul>
<li>리소스의 Locking 지원 여부, 리소스가 사용 가능한 Lock 타입을 결정하는 속성</li>
</ul>
</li>
<li><strong><em>Locking Process</em></strong><ul>
<li><ol>
<li>Lock 부여 -&gt; 서버가 opaquelocktoken 발급</li>
</ol>
</li>
<li><ol start="2">
<li>Digest authentication 수행</li>
</ol>
</li>
<li><ol start="3">
<li>WebDAV 클라이언트가 토큰과 함께 PUT 요청 수행</li>
</ol>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="the-lock-method">The LOCK Method</h3>
<ul>
<li>WebDAV Locking<ul>
<li>클라이언트가 서버와 연결을 유지하지 않아도 된다</li>
<li>하나의 LOCK 요청으로 여러 개의 리소스를 락할 수 있다</li>
</ul>
</li>
<li>XML elements<ul>
<li><code>&lt;locktype&gt;</code> : lock 유형 (write)</li>
<li><code>&lt;lockscope&gt;</code> : exclusive or shared 명시</li>
<li><code>&lt;owner&gt;</code> : 현재 락을 소유한 사용자가 누구인지 지정</li>
<li><code>&lt;locktoken&gt;</code> : URI scheme에서 락을 식별하기 위한 토큰</li>
<li><code>&lt;depth&gt;</code> : 클라이언트 요청에 포함된 Depth 헤더의 값 (디렉토리 depth)</li>
<li><code>&lt;timeout&gt;</code> : 락의 유효시간</li>
</ul>
</li>
<li>Request<pre><code>LOCK /ch-publish.fm HTTP/1.1
Host: minstar
Content-Type: text/xml
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
Content-Length: 201
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;a:lockinfo xmlns:a=&quot;DAV:&quot;&gt;
&lt;a:lockscope&gt;&lt;a:exclusive/&gt;&lt;/a:lockscope&gt;
&lt;a:locktype&gt;&lt;a:write/&gt;&lt;/a:locktype&gt;
&lt;a:owner&gt;&lt;a:href&gt;AuthorA&lt;/a:href&gt;&lt;/a:owner&gt;
&lt;/a:lockinfo&gt;</code></pre></li>
<li>Response<pre><code>HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Fri, 10 May 2002 20:56:18 GMT
Content-Type: text/xml
Content-Length: 419
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;a:prop xmlns:a=&quot;DAV:&quot;&gt;
&lt;a:lockdiscovery&gt;&lt;a:activelock&gt;
&lt;a:locktype&gt;&lt;a:write/&gt;&lt;/a:locktype&gt;
&lt;a:lockscope&gt;&lt;a:exclusive/&gt;&lt;/a:lockscope&gt;
&lt;a:owner xmlns:a=&quot;DAV:&quot;&gt;&lt;a:href&gt;AutherA&lt;/a:href&gt;&lt;/a:owner&gt;
&lt;a:locktoken&gt;&lt;a:href&gt;opaquelocktoken:*****&lt;/a:href&gt;&lt;/a:locktoken&gt;
&lt;a:depth&gt;0&lt;/a:depth&gt;
&lt;a:timeout&gt;Second-180&lt;/a:timeout&gt;
&lt;/a:activelock&gt;&lt;/a:lockdiscovery&gt;
&lt;/a:prop&gt;</code></pre></li>
<li>HTTP 상태코드
  <img src="https://velog.velcdn.com/images/dvlp-sy/post/3da902a5-1b03-4702-bc53-21a4187f1047/image.png" alt=""></li>
</ul>
<h4 id="the-opaquelocktoken-scheme">The opaquelocktoken scheme</h4>
<ul>
<li>모든 리소스에 대해 고유하게 발급</li>
<li>WebDAV 명세에서는 ISO-11578의 UUID 매커니즘을 사용할 것을 권장함</li>
</ul>
<h4 id="the-lockdiscovery-xml-element">The &lt;lockdiscovery&gt; XML element</h4>
<ul>
<li>락 리프레시 방법<ul>
<li>요청 : 락 토큰을 If 헤더에 포함하여 전송</li>
<li>응답 : 허용되는 타임아웃 값을 포함하여 반환 (콤마로 구분된 리스트)</li>
</ul>
</li>
<li>Lock timeout은 가이드라인일 뿐 서버와 반드시 연동되는 것은 아니다 (관리자가 수동으로 리셋하거나 예기치못한 사건으로 락이 리셋될 수도 있다)</li>
<li>Lost Update Problem을 완전히 해결하지 못한다</li>
</ul>
<h4 id="the-unlock-method">The UNLOCK Method</h4>
<ul>
<li>Digest authentication이 성공적으로 이루어지고 토큰이 일치할 때 언락 가능</li>
<li>언락에 성공할 경우 <code>204 No Content</code> 상태코드 반환</li>
<li>언락에 실패할 경우 <code>424 Failed Dependency</code> 상태코드 반환</li>
</ul>
<hr>
<h3 id="properties-and-meta-data">Properties and META Data</h3>
<ul>
<li><code>live properties</code> : 동적으로 수정 가능한 속성</li>
<li><code>dead properties</code> : 정적인 속성</li>
<li>WebDAV는 live properties를 지원하기 위해 HTTP에 <code>PROPFIND</code>와 <code>PROPPATCH</code> 메서드를 추가함</li>
</ul>
<h4 id="the-propfind-method">The PROPFIND Method</h4>
<ul>
<li>주어진 리소스나 컬렉션의 속성을 얻기 위한 메서드</li>
<li>한 번의 호출로 컬렉션의 모든 계층에 대한 속성과 값을 획득할 수 있는 표현력을 가진다</li>
<li>유형<ul>
<li><ol>
<li>모든 속성과 그 속성의 값 요청</li>
</ol>
</li>
<li><ol start="2">
<li>주어진 속성과 그 속성의 값 요청</li>
</ol>
</li>
<li><ol start="3">
<li>모든 속성의 이름 요청</li>
</ol>
</li>
</ul>
</li>
<li>XML elements<ul>
<li><code>&lt;allprop&gt;</code> : 반환할 모든 속성의 이름 -&gt; 모든 속성과 그 속성의 값을 얻기 위해 &lt;propfind&gt; element에 &lt;alldrop&gt;을 포함하거나 본문 없이 요청을 전송해야 한다</li>
<li><code>&lt;propname&gt;</code> : 반환할 일부 속성의 이름 집합</li>
<li><code>&lt;prop&gt;</code> : &lt;propfind&gt;의 서브 요소 -&gt; 구체적인 속성과 값을 명시하는 요소</li>
<li><code>&lt;multistatus&gt;</code> : 여러 개의 응답을 포함하기 위한 컨테이너</li>
<li><code>&lt;href&gt;</code> : 리소스의 URI를 식별하기 위한 요소</li>
<li><code>&lt;status&gt;</code> : 특정 요청의 HTTP 상태 코드를 포함하는 요소</li>
<li><code>&lt;propstat&gt;</code> : 한 &lt;status&gt; 요소와 &lt;prop&gt; 요소를 그룹핑하는 요소</li>
</ul>
</li>
<li>Request<pre><code>PROPFIND /ch-publish.fm HTTP/1.1
Host: minstar.inktomi.com
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
Depth: 0
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 0</code></pre></li>
<li>Response<pre><code>HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
...........
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;a:multistatusxmlns:b=&quot;urn:uuid:********/&quot; xmlns:c=&quot;xml:&quot; xmlns:a=&quot;DAV:&quot;&gt;
&lt;a:response&gt;
    &lt;a:href&gt;http://minstar/ch-publish.fm &lt;/a:href&gt;
    &lt;a:propstat&gt;
        &lt;a:status&gt;HTTP/1.1 200OK&lt;/a:status&gt;
        &lt;a:prop&gt;
            &lt;a:getcontentlength b:dt=&quot;int&quot;&gt;1155&lt;/a:getcontentlength&gt;
      ......................
      ......................
            &lt;a:ishidden b:dt=&quot;boolean&quot;&gt;0&lt;/a:ishidden&gt;
            &lt;a:iscollection b:dt=&quot;boolean&quot;&gt;0&lt;/a:iscollection&gt;
        &lt;/a:prop&gt;
    &lt;/a:propstat&gt;
&lt;/a:response&gt;&lt;/a:multistatus&gt;</code></pre></li>
</ul>
<h4 id="the-proppatch-method">The PROPPATCH Method</h4>
<ul>
<li>주어진 리소스에 대해 여러 개의 속성을 지정 혹은 삭제할 수 있는 원자적 매커니즘</li>
<li>원자성 -&gt; 모든 요청이 성공하거나 완전히 실패함이 보장된다</li>
<li>XML elements<ul>
<li><code>propertyupdate</code> : 수정할 모든 속성을 담는 컨테이너</li>
<li><code>set</code> : 설정할 속성값을 명시하는 요소, 한 개 이상의 &lt;prop&gt; 서브 요소를 포함 (이미 속성값이 존재하는 경우 덮어쓴다)</li>
<li><code>remove</code> : 삭제할 속성값을 명시하는 요소, &lt;prop&gt; 서브 요소에 속성명만 포함</li>
</ul>
</li>
<li>Request<pre><code>&lt;d:propertyupdate xmlns:d=&quot;DAV:&quot; xmlns:o=&quot;http://name-space/scheme/&quot;&gt;
&lt;d:set&gt;
&lt;d:prop&gt;
&lt;/d:prop&gt;
&lt;/d:set&gt;
&lt;o:owner&gt;Author A&lt;/o:owner&gt;
&lt;d:remove&gt;
&lt;d:prop&gt;
&lt;o:owner/&gt;
&lt;/d:prop&gt;
&lt;/d:remove&gt;
&lt;/d:propertyupdate&gt;</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP: The Definitive Guide "p424 ~ p432"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p424-p432</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p424-p432</guid>
            <pubDate>Fri, 20 Feb 2026 09:07:50 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-19-publishing-systems">Chapter 19. Publishing Systems</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="frontpage-server-extensions-for-publishing-support">FrontPage Server Extensions for Publishing Support</h3>
<ul>
<li>FrontPage(FP) : 마이크로소프트에서 제공하는 다목적 웹 저작 및 게시 도구<ul>
<li>웹 사이트 생성과 관리를 하나로 결합하려는 시도</li>
</ul>
</li>
<li>FrontPage Server Extensions(FPSE) : 서버 사이드의 FP 확장 프로그램<ul>
<li>FP를 구동하는 클라이언트와 웹 사이트 사이에서 필요한 번역 처리 담당</li>
<li>HTTP의 POST 요청 상위의 RPC 레이어에서 구현된 프로토콜 사용</li>
</ul>
</li>
<li>FrontPage Publishing Architecture<ul>
<li><ol>
<li>FP 클라이언트가 본문에 FP 명령이 포함된 요청 메시지 전송<ul>
<li>FP 명령에는 서버에서 파일을 저장/조회하는 내용이 포함됨</li>
</ul>
</li>
</ol>
</li>
<li><ol start="2">
<li>서버가 일반적인 HTML이 아님을 판단 -&gt; CGI나 ISAPI로 구현된 FPSE에 명령 전달</li>
</ol>
</li>
<li><ol start="3">
<li>FPSE 실행 -&gt; 파일 저장/조회</li>
</ol>
</li>
<li><ol start="4">
<li>처리 결과를 응답 메시지로 전송</li>
</ol>
</li>
</ul>
</li>
</ul>
<hr>
<h4 id="frontpage-vocabulary">FrontPage Vocabulary</h4>
<ul>
<li><code>Virtual server</code> : 동일 서버에서 동작하며 각각 고유한 도메인과 IP를 가진 중복된 웹 사이트 중 하나를 칭하는 용어 -&gt; 한 서버에 여러 웹 사이트를 호스팅 할 수 있으므로 multi-hosting 웹 서버라고도 부른다</li>
<li><code>Root web</code> : 웹 서버의 top-level 콘텐츠 디렉토리, multi-hosting 환경에서는 virtual server의 top-level 콘텐츠 디렉토리를 칭하는 용어 -&gt; 즉 서버 하나당 root web은 한 개</li>
<li><code>Subweb</code> : root web 혹은 다른 subweb으로부터 파생된 서브 디렉토리 -&gt; FPSE 확장 웹</li>
</ul>
<hr>
<h4 id="the-frontpage-rpc-protocol">The FrontPage RPC Protocol</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/a173afe7-cb07-48df-ade0-467d228b07b6/image.png" alt=""></p>
<ul>
<li><ol>
<li><p>FP 클라이언트가 본문에 FP 명령이 포함된 요청 메시지 전송</p>
<pre><code>POST /_vti_bin/_vti_aut/author.dll HTTP/1.1
Date: Sat, 12 Aug 2000 20:32:54 GMT
User-Agent: MSFrontPage/4.0
..........................................
&lt;BODY&gt;
method=list+documents%3a4%2e0%2e2%2e3717&amp;service%5fname=&amp;listHiddenDocs=false&amp;listExp
lorerDocs=false&amp;listRecurse=false&amp;listFiles=true&amp;listFolders=true&amp;listLinkInfo=true&amp;l
istIncludeParent=true&amp;listDerived=false
&amp;listBorders=false&amp;listChildWebs=true&amp;initialUrl=&amp;folderList=%5b%3bTW%7c12+Aug+2000+2
0%3a33%3a04+%2d0000%5d</code></pre><ul>
<li><strong>URL</strong> : _vti_inf.html 와 같이 생김</li>
<li><strong>본문</strong> : &lt;BODY&gt; 내부에 <code>method=&lt;command&gt;</code> 형식으로 작성 (&lt;command&gt;에는 서버에서 파일을 저장/조회하는 명령이 포함됨)</li>
<li><strong>명령</strong> : 서버에서 파일을 저장/조회하기 위한 내용<ul>
<li><code>service_name</code> : 메서드가 실행해야 하는 웹 사이트의 URL</li>
<li><code>listHiddenDocs</code> : 숨겨진 문서를 보이게 할 것인지 true/false로 설정 가능</li>
<li><code>listExploreDocs</code> : 태스크 목록을 나열할지 true/false로 설정 가능</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol start="2">
<li>서버가 일반적인 HTML이 아님을 판단 -&gt; CGI나 ISAPI로 구현된 FPSE에 명령 전달</li>
</ol>
</li>
<li><ol start="3">
<li>FPSE 실행 -&gt; 파일 저장/조회</li>
</ol>
</li>
<li><ol start="4">
<li>처리 결과를 응답 메시지로 전송<pre><code>HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Sat, 12 Aug 2000 22:49:50 GMT
Content-type: application/x-vermeer-rpc
X-FrontPage-User-Name: IUSER_MINSTAR
&lt;html&gt;&lt;head&gt;&lt;title&gt;RPC packet&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;method=list documents: 4.0.2.3717
&lt;p&gt;document_list=
&lt;ul&gt;
&lt;li&gt;document_name=help.gif
&lt;\ul&gt;</code></pre></li>
</ol>
</li>
</ul>
<hr>
<h4 id="frontpage-security-model">FrontPage Security Model</h4>
<ul>
<li>사용자를 administrators, authors, browsers 3가지 유형으로 정의</li>
<li>admin : 모든 권한 / authors : author + browser / browsers : browser</li>
<li>웹 서버마다 디폴트 실행 권한은 다르게 설정될 수 있다</li>
<li>모든 Subweb은 Root Web의 권한을 상속받거나 더 작은 범위에서 권한을 선택할 수 있다</li>
</ul>
<hr>
<h3 id="webdav-and-collaborative-authoring">WebDAV and Collaborative Authoring</h3>
<ul>
<li>Web Distributed Authoring and Versioning(WebDAV) : 웹 저작과 협업을 위한 추가 기능 제공</li>
<li>RFC 2518에 정의 -&gt; 적절한 협업 플랫폼을 구축하기 위해 HTTP를 확장하는 데 초점을 맞춤</li>
<li>HTTP 헤더만으로 특정 앱의 정보나 상태를 전달하는 데 어려움이 있어 XML을 주로 사용함<ul>
<li>XML(Extensible Markup Language) : 구조화된 데이터의 표현 방식을 포맷팅하는 언어</li>
<li>구조화된 데이터 : 요청과 응답의 데이터를 트리 구조로 정합성 있게 전달</li>
<li>확장성 : 새로운 기능을 추가할 때 HTTP 규격을 해치지 않고 XML 요소만 추가할 수 있음</li>
</ul>
</li>
</ul>
<hr>
<h4 id="webdav-methods">WebDAV Methods</h4>
<ul>
<li><code>PROPFIND</code> : 리소스의 속성을 받는다</li>
<li><code>PROPPATCH</code> : 한 개 이상의 리소스의 속성을 한 개 이상 지정한다</li>
<li><code>MKCOL</code> : 컬렉션을 생성한다</li>
<li><code>COPY</code> : 리소스 혹은 컬렉션을 주어진 source로부터 destination으로 복사한다 (source와 destination이 같은 기기가 아니어도 된다)</li>
<li><code>MOVE</code> : 리소스 혹은 컬렉션을 주어진 source로부터 destination으로 이동한다 (source와 destination이 같은 기기가 아니어도 된다)</li>
<li><code>LOCK</code> : 한 개 이상의 리소스를 lock 한다</li>
<li><code>UNLOCK</code> : 이전에 lock 되어있던 리소스를 unlock 한다</li>
</ul>
<hr>
<h4 id="webdav-and-xml">WebDAV and XML</h4>
<pre><code>&lt;D:propfind xmlns:D=&quot;DAV:&quot;&gt;</code></pre><ul>
<li>RFC 2518에 WebDAV의 XML 스키마가 정의되어 있다</li>
<li>XML 네임스페이스 <code>DAV:</code> 사용 -&gt; 다양한 요소와 속성이 포함되어 있음</li>
</ul>
<hr>
<h4 id="webdav-headers">WebDAV Headers</h4>
<ul>
<li>RFC 2518에 WebDAV의 새로운 메서드 기능을 강화하기 위한 몇 가지 HTTP 헤더가 정의되어 있다</li>
<li><code>DAV</code> : 서버의 WebDAV 기능을 포함한 헤더 (WebDAV가 지원되는 모든 리소스는 OPTIONS 요청에 대한 응답으로 이 헤더를 포함해야 한다)<pre><code>DAV = &quot;DAV&quot; &quot;:&quot; &quot;1&quot; [&quot;,&quot; &quot;2&quot;] [&quot;,&quot; 1#extend]</code></pre></li>
<li><code>Depth</code> : 트리 구조로 그룹핑된 리소스에 대해 WebDAV를 확장하기 위해 필요한 헤더<pre><code>Depth = &quot;Depth&quot; &quot;:&quot; (&quot;0&quot; | &quot;1&quot; | &quot;infinity&quot;)</code></pre></li>
<li><code>Destination</code> : COPY와 MOVE 메서드에서 destination을 지정하는 헤더<pre><code>Destination = &quot;Destination&quot; &quot;:&quot; absoluteURI</code></pre></li>
<li><code>If</code> : 조건을 명시하고 모든 조건이 false면 요청을 실패 처리, COPY와 PUT과 같은 메서드에서 사전 조건을 확인하기 위해 사용하기도 하지만 주로 lock 점유 여부를 확인하기 위해 사용한다<pre><code>If = &quot;If&quot; &quot;:&quot; (1*No-tag-list | 1*Tagged-list)
No-tag-list = List
Tagged-list = Resource 1*List
Resource = Coded-URL
List = &quot;(&quot; 1*([&quot;Not&quot;](State-token | &quot;[&quot; entity-tag &quot;]&quot;)) &quot;)&quot;
State-token = Coded-URL
Coded-URL = &quot;&lt;&quot; absoluteURI &quot;&gt;&quot;</code></pre></li>
<li><code>Lock-Token</code> : Lock에 대한 정보를 명시하는 헤더 (UNLOCK 요청 메서드에서 Lock을 해제할 때 사용하거나 LOCK 메서드에 대한 응답에 정보를 담기 위해 사용)<pre><code>Lock-Token = &quot;Lock-Token&quot; &quot;:&quot; Coded-URL</code></pre></li>
<li><code>Overwrite</code> : COPY나 MOVE 메서드에서 destination에 이미 파일이 존재하는 경우 덮어쓰기 여부를 지정하는 헤더<pre><code>Overwrite = &quot;Overwrite&quot; &quot;:&quot; (&quot;T&quot; | &quot;F&quot;)</code></pre></li>
<li><code>Timeout</code> : 클라이언트 측에서 Lock의 타임아웃 값을 지정하기 위한 헤더<pre><code>TimeOut = &quot;Timeout&quot; &quot;:&quot; 1#TimeType
TimeType = (&quot;Second-&quot; DAVTimeOutVal | &quot;Infinite&quot; | Other)
DAVTimeOutVal = 1*digit
Other = &quot;Extend&quot; field-value</code></pre></li>
</ul>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>ㅋㅋㅋㅋ 여행 갔다 와서 다시 읽었더니 또 앞의 내용이 잘 기억이 안 난다. 다행히 챕터 18은 끝내고 다녀와서 이해하는 데 크게 무리는 없었지만.. 책을 읽었는데 머릿속에 남는 게 없다면 별무소용이지 않을까. 완독 후에 중요한 내용들은 한 번 싹 정리하는 시간을 가져보는 게 좋겠다.</p>
<p>오늘 읽은 내용은 REST API가 보편화되기 전, 1990년대에서 2000년대 사이에 유행하던 FPSE 아키텍처에 대한 내용이었다. FPSE는 웹 서버 안에 호스팅 작업을 처리하기 위한 인터페이스를 두고 RPC를 통해 웹 사이트를 저장하고 조회하는 방식을 채택한다. HTTP 자체는 무상태 프로토콜이지만 리소스에 대해 Lock과 Unlock을 걸어주는 방식으로 인해 어쩔 수 없이 세션 중심으로 이루어져야 했다고 한다. 조금 부자연스러운 감이 있는 것 같다. 더 난감한 점은 서버에서 세션을 관리할 때 생기는 각종 문제들이다. 세션 관리에 소모되는 메모리나 scale-out의 어려움, redis와 같은 추가적인 캐시 서버의 도입을 고려하지 않을 수 없다. 나아가 캐시 서버의 Lock은 또 어떻게 처리해야 하는가.</p>
<p>한편 REST API는 HTTP 고유의 메서드를 활용하여 무상태로 리소스를 관리한다. 메서드 자체가 동사의 역할을 하기 때문에 URL은 리소스 그 자체를 나타내는 명사형으로 표현한다. 이쯤에서 나는 Lock과 Unlock이 없으면 REST API에서는 어떻게 리소스 동기화가 이루어지는지가 궁금해졌다. 데이터베이스 서버와의 통신이라면 DBMS에서 자체적으로 락 처리를 해주겠지만 단순히 서버의 문서를 가져오는 요청이라면 어떨까. 사실 이 부분은 이전 챕터에서 몇 번 다루었던 내용이다. 리소스마다 버전과 수정일시에 관한 메타데이터가 관리되기 때문에 If-None-Match나 If-Modified-Since와 같은 조건부 헤더를 통해 리소스를 동기화할 수 있다.</p>
<p>두 아키텍처의 동기화 방식 차이는 DB에서 이야기하는 Pessimistic Lock과 Optimistic Lock의 차이와 비슷한 느낌이지 않을까 싶다. FPSE 아키텍처가 데이터에 접근하기 전부터 락을 걸어버리는 Pessimistic Lock이라면, REST API는 충돌이 발생했을 때에만 실패 처리해버리는 Optimistic Lock을 사용하는 셈이다. 네트워크 성능 측면에서 REST가 훨씬 낫기 때문에 오늘날 REST API를 더 많이 사용하게 된 게 아닐까. 물론 REST를 사용하면 정합성이 중요한 데이터의 경우 애플리케이션 단에서 락을 걸어주어야 하지만... 필요할 때 구현하고 나머지는 빠르게 처리하는 게 현명하다고 생각한다.</p>
<p>오늘날 많이 사용하지 않는 아키텍처긴 하지만 꽤나 유익하고 재미있는 내용이었다..!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP: The Definitive Guide "p419 ~ p423"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p419-p423</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p419-p423</guid>
            <pubDate>Thu, 29 Jan 2026 06:23:36 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-18-web-hosting">Chapter 18. Web Hosting</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="making-web-sites-reliable">Making Web Sites Reliable</h3>
<ul>
<li>디바이스 다운, 트래픽 스파이크, 네트워크 용량 초과 등 -&gt; 웹 사이트 장애 유발</li>
<li>서버 팜을 통한 안정성 확보 필요</li>
</ul>
<blockquote>
<p><strong>Mirrored Server Farms</strong>
한 서버에서 문제 발생시 미러링된 다른 서버를 통해 콘텐츠를 확보할 수 있다
<img src="https://velog.velcdn.com/images/dvlp-sy/post/ba4d17bc-7b12-4786-93da-985da31620b5/image.png" alt=""></p>
</blockquote>
<ul>
<li><code>master origin server</code> : 원본 콘텐츠를 포함하며 replica 서버에 해당 콘텐츠를 전파하는 서버</li>
<li><code>replica origin server</code> : 복제본을 저장하고 있는 서버</li>
<li><strong>구현 방법</strong><ul>
<li>요청을 분배할 수 있는 네트워크 스위치를 사용한다</li>
<li>서버에 호스팅된 각각의 사이트의 IP는 스위치의 IP 주소다</li>
</ul>
</li>
<li><strong>요청을 특정 서버로 전달하는 방법</strong><ul>
<li>HTTP redirection : 콘텐츠 URL이 master 서버의 IP 주소와 일치할 때는 replica 서버로 리디렉션 할 수 있다</li>
<li>DNS redirection : 콘텐츠 URL을 통해 4개의 IP 주소를 구분할 수 있다면 DNS 서버가 특정 IP를 선택해 요청을 전달할 수 있다</li>
</ul>
</li>
</ul>
<h4 id="content-distribution-networks-cdn">Content Distribution Networks (CDN)</h4>
<ul>
<li>특정 콘텐츠를 배포하는 데 목적을 둔 네트워크</li>
<li>네트워크 내의 각 노드는 서버일 수도 있고 프록시(Surrogates, Proxy caches, …)일 수도 있다</li>
<li><strong>Surrogates as Replica</strong><ul>
<li>리버스 프록시 -&gt; origin 서버를 대신해서 요청을 받는다</li>
<li>Origin 서버의 콘텐츠의 전체 사본을 보유하지 않고 클라이언트가 요청한 콘텐츠를 보관한다</li>
</ul>
</li>
<li><strong>Proxy Caches as Replica</strong><ul>
<li>Surrogate와 달리 임의의 웹 서버에 대한 요청을 받는다</li>
<li>Layer-2 혹은 Layer-3 장치(스위치나 라우터)를 통해 웹 트래픽을 가로채 프록시 캐시에 전달한다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="making-web-sites-fast">Making Web Sites Fast</h3>
<ul>
<li>서버 팜 구축, 프록시 캐시와 리버스 프록시를 통한 네트워크 트래픽 제어를 통해 혼잡 회피</li>
<li>콘텐츠를 가능한 한 end-user에 가깝게 위치시킴으로써 물리적 시간 감소</li>
<li>빠른 전송을 위한 인코딩 (Chapter 15)</li>
</ul>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>CDN이 뭐의 약자였는지 맨날 까먹는다(...) 대충 콘텐츠 망으로 받아들이고 살았다. 요즘에는 AWS에서 CDN 서비스(CloudFront)를 잘 제공해주고 있어서 CDN이 내부적으로 어떻게 구현되어 있는지 굳이 자세히 알아보려 한 적이 없었던 것 같다. 그렇게 얕게 공부하니 인턴하면서 네트워크 얘기 나올 때마다 땀을 삐질삐질 흘렸던 거다. 나는 세상을 좀 궁금해 할 필요가 있다.</p>
<p>CDN은 콘텐츠 배포를 위한 네트워크다. 네트워크라는 건 결국 n개의 노드가 연결되어 있다는 뜻이고, 그 노드 중에는 캐시도 있고 프록시도 있다. 사람들은 안정적으로 신속하게 정확한 콘텐츠를 공급받길 원한다. CDN은 로드밸런싱을 위한 리버스 프록시와 엣지 서버의 네트워크를 제공함으로써 전국, 더 나아가 전세계의 end-user의 니즈를 충족시키는 기술이다. origin에 위치한 콘텐츠는 사용자 요청에 의해서 인근의 엣지 서버에 저장되고, 동일한 요청이 발생하는 경우 해당 엣지 서버에서 콘텐츠를 제공받을 수 있다. CDN을 사용하면 origin 서버로 직접 요청을 보내는 방식에 비해 안정적이고 빠른 것은 물론 보안적인 측면에서도 좋다. TLS는 오버헤드의 끝판왕이기 때문에 인터넷의 모든 프록시와 서버에 보안 연결을 요구하는 것은 현실적으로 불가능하다. 대신 CDN을 사용하면 origin과 replica 사이에서는 HTTPS를 사용하지 않으면서 외부 망으로부터 들어오는 요청에 대해 HTTPS를 요구할 수 있다. 인가되지 않은 사용자에 대해서는 서버의 접근을 차단할 수 있는 것이다. origin의 IP가 노출되지 않는 건 당연하다.</p>
<p>네트워크가 말이 좀 어려워서 진입장벽이 높긴 한데.. 뭔가 공부하면 공부할수록 쓰는 말들이 다 거기서 거기라는 생각이 든다. 익숙해지면 쉽게쉽게 배우는 느낌이다. AWS가 됐든 백엔드 개발이 됐든 기본적인 것만 알면 연결지어 생각하는 게 가능해진다. 그게 또 네트워크 분야의 매력인 것 같기도 하다..✨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p408 ~ p419"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p408-p419</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p408-p419</guid>
            <pubDate>Wed, 28 Jan 2026 09:04:10 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-18-web-hosting">Chapter 18. Web Hosting</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="preface">Preface</h3>
<ul>
<li><strong>Web Hosting</strong><ul>
<li>콘텐츠 리소스를 저장, 중개, 관리하는 공동의 의무</li>
<li>웹 서버의 가장 주요한 기능 중 하나</li>
</ul>
</li>
<li><strong>Hosting Services</strong><ul>
<li>별도의 하드웨어와 소프트웨어를 갖출 필요 없이 웹 사이트 관리 서비스를 사용할 수 있다</li>
<li>보안, 리포트 등 편의 기능을 갖추고 있다</li>
<li>비용, 성능, 안정성 측면에서 이점을 볼 수 있다</li>
</ul>
</li>
<li><strong>챕터에서 다룰 내용</strong><ul>
<li>Virtual Hosting이 HTTP에 미치는 영향<ul>
<li>Virtual Hosting : 동일한 서버에 서로 다른 웹 사이트를 호스팅하는 것</li>
</ul>
</li>
<li>웹 사이트를 안정성 있게 운용하는 방법</li>
<li>웹 사이트 로딩을 빠르게 하는 방법</li>
</ul>
</li>
</ul>
<hr>
<h3 id="hosting-services">Hosting Services</h3>
<ul>
<li>대량의 하드웨어를 통해 적은 비용으로 안정성 있는 서버를 제공하는 서비스</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/ee7b1d88-d4e4-48cb-80fe-e3eb58584b1e/image.png" alt=""></p>
<hr>
<h3 id="virtual-hosting">Virtual Hosting</h3>
<ul>
<li>하나의 컴퓨팅 자원을 여러 고객이 공유하는 호스팅의 형태</li>
<li>유저 관점에서는 일반 호스팅과 가상 호스팅을 구분할 수 없다</li>
<li>장점 : 트래픽 양이 적은 웹 사이트를 위해 웹 서버 하나를 통째로 빌리지 않아도 된다 (비용 및 자원 절약)</li>
</ul>
<h4 id="virtual-server-request-lacks-host-information">Virtual Server Request Lacks Host Information</h4>
<ul>
<li>HTTP/1.0 : 가상 호스팅된 웹 사이트를 식별할 수 있는 수단을 제공하지 않는다<pre><code>GET /index.html HTTP/1.0
User-agent: SuperBrowser v1.3</code></pre></li>
<li><a href="http://www.joes-hardware.com/index.html">http://www.joes-hardware.com/index.html</a> 에 대한 요청인지 <a href="http://www.marys-antiques.com/index.html">http://www.marys-antiques.com/index.html</a> 에 대한 요청인지 구분할 수 없다</li>
<li>Chapter 6에 언급한 것처럼 surrogates와 intercepting proxies에서도 사이트를 식별할 수 있는 추가 정보가 필요하다</li>
</ul>
<h4 id="making-virtual-hosting-work">Making Virtual Hosting Work</h4>
<ul>
<li>HTTP/1.1 : full URL을 통한 요청 라인을 사용할 수 있게 되었지만 레거시 애플리케이션에서는 적용되지 않을 수 있다 -&gt; 4가지 추가적인 수단을 제공</li>
<li><code>URL path</code> : URL에 특수한 path 컴포넌트를 추가하여 구분하는 방법<ul>
<li>prefix를 중복으로 사용하거나 혼동할 위험이 있다</li>
<li>원본 URL(<a href="http://www.joes-hardware.com/index.html)%EC%9D%B4">http://www.joes-hardware.com/index.html)이</a> 정상 동작하지 않는다</li>
<li>거의 사용 X</li>
</ul>
</li>
<li><code>Port number</code> : 각각의 사이트에 서로 다른 포트번호를 부여하는 방법<ul>
<li>URL에 포트번호를 명시하지 않으면 원본 URL이 정상 동작하지 않는다</li>
<li>거의 사용 X</li>
</ul>
</li>
<li><code>IP address</code> : 각각의 사이트에 서로 다른 IP 주소를 부여하는 방법
  <img src="https://velog.velcdn.com/images/dvlp-sy/post/7da0803a-6634-494f-9d6c-93c25b387b70/image.png" alt=""><ul>
<li>컴퓨터 시스템이 부여할 수 있는 Virtual IP의 개수가 제한적이며 IP 자체도 희소 자원이다</li>
<li>로드밸런싱을 위해 복제된 서버가 많을수록 필요한 IP의 개수도 늘어난다</li>
<li>비교적 자주 사용</li>
</ul>
</li>
<li><code>Host header</code> :  HTTP/1.1의 Host 헤더를 사용하여 식별하는 방법
  <img src="https://velog.velcdn.com/images/dvlp-sy/post/4514dff7-8878-48dc-b1ff-74c7f6f47fc2/image.png" alt=""><ul>
<li>IP 문제를 해결하면서 사이트를 식별할 수 있다</li>
<li>HTTP/1.1에서 사용 가능하다<pre><code>GET /index.html HTTP/1.1
Host: www.joes-hardware.com</code></pre></li>
</ul>
</li>
</ul>
<h4 id="http11-host-headers">HTTP/1.1 Host Headers</h4>
<ul>
<li><strong>표준</strong> : RFC 2068</li>
<li><strong>규격</strong> : <code>Host = “Host” “:” host [ “:” port ]</code></li>
<li><strong>상세 규칙</strong><ul>
<li>포트번호가 포함되어 있지 않은 경우<ul>
<li>디폴트 포트번호로 해석한다</li>
</ul>
</li>
<li>URL이 IP 주소를 포함한 경우<ul>
<li>Host에도 동일한 주소가 포함되어야 한다</li>
</ul>
</li>
<li>URL이 호스트명을 포함한 경우<ul>
<li>Host에는 동일한 호스트명이 담겨야 한다</li>
<li>Host에는 호스트명에 대응하는 IP 주소를 포함할 필요가 없다 (가상 호스팅의 경우 IP 주소가 동일할 수 있기 때문)</li>
<li>Host에는 호스트명의 alias를 포함할 수 없다 (가상 호스팅에서 동작하지 않을 수 있기 때문)</li>
</ul>
</li>
<li>클라이언트가 프록시 서버를 사용하는 경우<ul>
<li>Host에 원본 서버의 포트 번호를 반드시 포함해야 한다</li>
</ul>
</li>
<li>웹 클라이언트는 반드시 모든 요청에 Host 헤더를 포함해야 한다</li>
<li>웹 프록시는 반드시 Host 헤더를 포워딩해야 한다</li>
<li>HTTP/1.1 웹 서버는 Host 헤더 필드가 누락된 경우 400 상태 코드를 반환해야 한다</li>
</ul>
</li>
<li><strong>해석 방법</strong><ul>
<li>요청 메시지에 절대 URL이 포함된 경우 Host 헤더는 무시된다</li>
<li>호스트가 URL에 포함되지 않고 Host 헤더에 포함된 경우 헤더의 값을 채택한다</li>
<li>유효한 호스트를 판단할 수 없는 경우 400 응답을 반환한다</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p401 ~ 407"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p401-407</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p401-407</guid>
            <pubDate>Tue, 27 Jan 2026 08:53:16 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-17-content-negotiation-and-transcoding">Chapter 17. Content Negotiation and Transcoding</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="caching-and-alternates">Caching and Alternates</h3>
<ul>
<li>캐시된 응답을 전송할지 결정하기 위해 Accept 헤더 사용</li>
<li>Variants (Alternates)<ul>
<li>캐시에 저장된 동일 URL, 다른 버전의 문서 (ex. 프랑스어 버전, 스페인어 버전)</li>
<li>Content Negotiation을 통해 어느 버전으로 응답할지 결정한다</li>
</ul>
</li>
</ul>
<blockquote>
<p><code>Vary</code></p>
<ul>
<li>서버가 문서나 특정 콘텐츠를 선택하는 데 필요한 클라이언트 요청 헤더의 목록을 담는다<ul>
<li>새로운 요청 도착 -&gt; 캐시가 Content-Negotiation 헤더를 통해 일치하는 문서를 찾는다</li>
<li>이때 서버가 캐싱된 응답에 Vary 헤더를 포함했는지 반드시 확인해야 한다</li>
<li>Vary 헤더가 있다면 새로운 요청의 헤더 값이 캐싱된 요청의 것과 같은지 확인해야 한다</li>
</ul>
</li>
</ul>
</blockquote>
<hr>
<h3 id="transcoding">Transcoding</h3>
<ul>
<li>요청에 완벽히 일치하는 문서가 없을 때, 에러를 발생시키지 않고 존재하는 문서 중 하나를 클라이언트가 사용할 수 있는 형태로 변환하는 것</li>
<li>(Ex) HTML -&gt; WML, 고화질 이미지 -&gt; 저화질 이미지</li>
</ul>
<blockquote>
<ul>
<li><code>장점</code> : 웹 서버에 페이지의 사본을 여러 개 저장하는 경우 발생하는 문제 해결<ul>
<li>(문제1) 페이지가 조금이라도 바뀌면 전부 다 수정되어야 함</li>
<li>(문제2) 더 많은 공간 차지</li>
<li>(문제3) 서버가 올바른 문서를 결정하고 제공하기 어려움</li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code>단점</code> : 콘텐츠 제공에 지연 발생 (단, 다른 장치(프록시나 캐시)에서 연산을 수행하는 경우 서버 부하를 줄일 수 있다)</li>
</ul>
</blockquote>
<hr>
<h3 id="format-conversion">Format Conversion</h3>
<ul>
<li>Content-negotiation 헤더를 통해 클라이언트가 인지할 수 있는 형태로 포맷을 변환하는 것</li>
<li><code>Transcoding</code>이나 <code>Format Conversion</code>은 콘텐츠 인코딩, 전송 인코딩과 다른 개념<ul>
<li>인코딩은 콘텐츠를 효과적으로 안전하게 전달하기 위해 사용</li>
<li>트랜스코딩과 포맷 변환은 사용자 디바이스에서 콘텐츠를 볼 수 있게 하기 위해 사용</li>
</ul>
</li>
</ul>
<hr>
<h3 id="information-synthesis">Information Synthesis</h3>
<ul>
<li>문서를 요약하는 정보의 핵심 요소로 트랜스코딩에서 주로 사용</li>
<li>(Ex) 문서를 바탕으로 섹션 제목 생성, 페이지에서 광고 제거, 키워드 중심으로 카테고리화</li>
</ul>
<hr>
<h3 id="content-injection">Content Injection</h3>
<ul>
<li>기존 콘텐츠에 추가적인 콘텐츠를 덧붙이는 동적 트랜스코딩 기법</li>
<li>트랜스코딩은 일반적으로 콘텐츠의 양을 줄이기 위해 사용되지만 Content-Injection의 경우 콘텐츠의 양이 증가한다.</li>
<li>(Ex) 자동 광고 생성기, 유저 추적 시스템</li>
</ul>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>인턴을 하면서 캐시를 다룰 일이 많이 있었다. 사용자마다 응답이 달라지는 것은 물론이거니와 시간에 따라, 상황에 따라 응답이 바뀌는 경우도 잦아서.. 값을 관리하는 게 여간 어려운 일이 아니었다. 그때는 주로 DB에서 가져온 엔티티를 캐싱하는 작업을 했었지만, 만약 HTTP를 통해 주고받는 JSON 응답을 캐싱해야 하는 상황이 온다면 실제 프록시에서 하는 것처럼 API마다 max-age, max-stale, min-fresh와 같은 옵션을 추가해줄 수도 있겠다는 생각이 들었다. 애플리케이션단에서 헤더 까서 유효기간 계산하고 새로운 응답을 생성할지 말지 결정하는..? 그런 애노테이션이 있으면 단순히 TTL로 관리하는 것보다 체계적으로 캐시 값을 관리할 수 있을 것 같다. 지금 읽은 내용과 크게 연관은 없지만 갑자기 생각나서 적어봤다.</p>
<p>트랜스코딩은 MSA에서 굉장히 중요한 개념일 것 같다. 다른 서버로부터 정상적인 응답을 받을 수 없는 상황이라면 폴백 응답을 통해 서비스 가용성을 보장하는 게 가장 이상적이다. 서킷브레이커의 역할이 사실상 HTTP 책에서 이야기하는 트랜스코딩과 같지 않을까 하는 생각이 들었다.</p>
<p>다람쥐 책이 오래되긴 했어도 바이블처럼 다루어지는 이유가 있는 것 같다. 프로토콜에 대한 지식도 주지만, 다양한 응용 기술들을 어떻게 활용하면 좋을지 인사이트를 주는 게 참 좋다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p395 ~ p400"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p395-p400</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p395-p400</guid>
            <pubDate>Wed, 21 Jan 2026 06:48:19 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-17-content-negotiation-and-transcoding">Chapter 17. Content Negotiation and Transcoding</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="content-negotiation-techniques">Content-Negotiation Techniques</h3>
<ul>
<li>클라이언트에게 적합한 콘텐츠를 선택하는 방법</li>
<li><strong>Client-Driven</strong><ul>
<li>서버가 여러 개의 선택지를 주고 클라이언트가 버전을 결정하는 방식</li>
<li>장점 : 서버 사이드에서의 편리한 구현, 클라이언트가 최선의 선택을 할 수 있다</li>
<li>단점 : 올바른 콘텐츠를 전달받기 위해 최소한 두 개의 요청이 필요하다, 여러 개의 URL이 필요하다 (메인 페이지와 각각의 상세 페이지 /english, /french 등)</li>
</ul>
</li>
<li><strong>Server-Driven</strong><ul>
<li>서버가 클라이언트의 요청 헤더를 확인하여 버전을 결정하는 방식</li>
<li>장점 : Client-Driven보다 낮은 지연, q-value 매커니즘을 활용할 수 있다</li>
<li>단점 : 일치하는 버전이 없는 경우 서버가 추측하거나 폴백 처리해야 한다</li>
</ul>
</li>
<li><strong>Transparent</strong><ul>
<li>중간 디바이스(프록시)가 클라이언트를 대신하여 버전을 결정하는 방식</li>
<li>장점 : 웹 서버의 negotiation 부하 감소, Client-Driven보다 낮은 지연</li>
<li>단점 : 표준 명세가 정의되어 있지 않다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="client-driven-negotiation">Client-Driven Negotiation</h3>
<ul>
<li>서로 다른 버전의 페이지와 연결된 HTML 문서와 각 버전에 대한 설명을 전송하는 방식</li>
<li>HTML/1.1 300 Multiple Choices 응답 코드를 전송하는 방식</li>
<li>두 방식 모두 클라이언트 사이드에서 사용자에 의해 수동으로 버전이 결정된다</li>
</ul>
<hr>
<h3 id="server-driven-negotiation">Server-Driven Negotiation</h3>
<ul>
<li>Accept와 같은 content-negotiation 헤더를 사용하는 방식</li>
<li>User-Agent와 같은 요청 헤더 값에 따라 적절한 버전을 결정하는 방식</li>
</ul>
<h4 id="content-negotiation-headers">Content-Negotiation Headers</h4>
<pre><code>Accept-Language: en;q=0.5, fr;q=0.0, nl;q=1.0, tr;q=0.0</code></pre><ul>
<li><code>Accept</code> : 어떤 미디어 타입을 허용하는지 전달하기 위한 헤더</li>
<li><code>Accept-Language</code> : 어떤 언어를 허용하는지 전달하기 위한 헤더</li>
<li><code>Accept-Charset</code> : 어떤 charset을 허용하는지 전달하기 위한 헤더</li>
<li><code>Accept-Encoding</code> : 어떤 인코딩 방식을 허용하는지 전달하기 위한 헤더</li>
</ul>
<p>** q-value를 사용하여 선호도를 명시할 수 있다</p>
<p>** 엔티티 헤더와의 차이점 -&gt; 엔티티 헤더는 메시지를 전송하는 동안 반드시 필요한 속성을 명시하는 반면 Content-Negotiation 헤더는 버전 선택을 위한 속성 정보를 주고받는 데 사용된다</p>
<h4 id="varing-on-other-headers">Varing on Other Headers</h4>
<pre><code>Vary: User-Agent</code></pre><ul>
<li><code>Accept-Encoding</code> : 브라우저가 압축(gzip, br 등)을 지원하는지에 따라 다른 파일을 보내는 경우 주로 사용</li>
<li><code>User-Agent</code> : 접속 기기(모바일, 데스크탑)에 따라 다른 파일을 보내는 경우 주로 사용</li>
<li><code>Accept-Language</code> : 사용자의 언어 설정에 따라 다른 파일을 보내는 경우 주로 사용</li>
<li><code>*</code> : 모든 요청에 대해 응답이 달라질 수 있으니 캐싱을 권장하지 않음</li>
</ul>
<hr>
<h3 id="transparent-negotiation">Transparent Negotiation</h3>
<ul>
<li>프록시는 클라이언트가 기대하는 값이 무엇인지 알아야 한다</li>
<li>프록시는 클라이언트의 요청에 가장 적절한 콘텐츠를 선택하기 위해 서버가 어떤 요청 헤더를 활용하는지 알아야 한다 (Vary 헤더 활용)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p384 ~ p394"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p384-p394</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p384-p394</guid>
            <pubDate>Sat, 17 Jan 2026 08:02:57 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-16-internationalization">Chapter 16. Internationalization</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="language-tags-and-http">Language Tags and HTTP</h3>
<ul>
<li>Language Tags : 언어를 지칭하는 짧고 표준화된 문자열 (RFC 3066)<ul>
<li>(Ex) 영어(en), 한국어(ko), 독일어(de)</li>
</ul>
</li>
<li>언어 태그는 지역에 따른 변형과 방언을 묘사할 수 있다<ul>
<li>(Ex) Brazilian Portuguese(pt-BR)</li>
</ul>
</li>
<li>Types of Language Tags<ul>
<li>General language classes</li>
<li>Country-specific languages</li>
<li>Dialects of languages</li>
<li>Regional languages</li>
<li>Standardized non variant languages</li>
<li>Nonstandard languages</li>
</ul>
</li>
</ul>
<h4 id="the-content-language-header">The Content-Language Header</h4>
<pre><code>Content-Language: mi, en</code></pre><ul>
<li>엔티티에 대한 타겟 사용자의 언어</li>
<li>텍스트 문서에만 국한되지 않고 오디오, 영화, 응용 프로그램 등 임의의 미디어 타입에 사용 가능</li>
<li>여러 국가의 사용자에게 전달되어야 하는 경우, 엔티티에 여러 언어가 사용된 경우 콤마로 구분한 리스트 전달 가능</li>
</ul>
<h4 id="the-accept-language-header">The Accept-Language Header</h4>
<pre><code>Accept-Language: en, de-CH, de</code></pre><ul>
<li>사용자가 선호하는 언어</li>
<li>웹 서버가 서로 다른 언어로 된 리소스를 보유하고 있을 때 사용 가능</li>
<li>클라이언트가 여러 언어를 호환할 수 있는 경우 콤마로 구분한 리스트 전달 가능</li>
</ul>
<hr>
<h3 id="subtags">Subtags</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/d5582e47-0c33-4024-b51e-7775d643817a/image.png" alt=""></p>
<ul>
<li>하이픈으로 구분된 태그 구분</li>
<li>First Subtag : Primary Subtag -&gt; IANA 표준화<ul>
<li>Primary Subtag는 A-Z 사이의 문자만 사용한다</li>
<li>그 밖의 Subtag는 숫자까지 포함하여 8글자 내로 표현한다</li>
</ul>
</li>
<li>Second Subtag(optional) -&gt; IANA 표준화</li>
<li>Trailing Subtags -&gt; 비표준</li>
<li>대소문자 구분 없음</li>
</ul>
<h4 id="first-subtag-namespace">First Subtag: Namespace</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/cc6b47ef-4e6a-44ac-b8df-8c605e978109/image.png" alt=""></p>
<ul>
<li>ISO 639에서 선택된 표준화된 언어 토큰 사용</li>
<li>IANA에 등록된 이름을 식별하기 위해 ‘i’ 문자와 ‘x’ 문자가 붙기도 한다</li>
<li>문자가 2개면 ISO 639, 3개면 ISO 639-2에 정의된 언어 코드</li>
</ul>
<h4 id="second-subtag-namespace">Second Subtag: Namespace</h4>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/af8d2f1b-ead2-421f-83bc-fca7532568b2/image.png" alt=""></p>
<ul>
<li>ISO 3166에서 선택된 표준화된 국가 토큰 사용</li>
<li>문자가 2개면 ISO 3166에 정의, 3-8개의 문자는 IANA에 등록되었을 것</li>
<li>문자 1개는 허용되지 않는다</li>
</ul>
<hr>
<h3 id="internationalized-uris">Internationalized URIs</h3>
<ul>
<li>URI는 US-ASCII 문자의 부분집합으로 표현된다
<img src="https://velog.velcdn.com/images/dvlp-sy/post/17182233-29be-43a9-8592-ce0d1cb2f88d/image.png" alt=""><ul>
<li>Reserved : URI에서 특별한 의미를 가지고 있어 일반적으로 사용할 수 없는 문자</li>
<li>Unreserved : 임의의 URI 컴포넌트에서 사용 가능한 문자</li>
<li>Escape : 지원되지 않는 문자를 % 기호와 두 자리의 16진수로 표현한 것<ul>
<li>% 기호 뒤의 두 자리는 US-ASCII 문자의 코드</li>
</ul>
</li>
</ul>
</li>
<li>HTTP 응용 프로그램이 URI를 전달할 때는 Escape를 그대로 두고, 데이터가 필요할 때만 디코딩해야 한다</li>
<li>URI를 두 번 디코딩(Unescape)하지 않도록 주의해야 한다</li>
<li>아스키 문자 시퀀스를 다른 문자 집합의 문자로 표현하는 경우 주의가 필요하다 (표준화된 방식 X)</li>
</ul>
<hr>
<h3 id="other-considerations">Other Considerations</h3>
<ul>
<li><p><strong>Headers and Out-of-Spec Data</strong> : 클라이언트와 서버가 적절히 구현되지 않은 경우가 많아 US-ASCII 문자 집합을 벗어난 헤더가 전달될 수 있다. -&gt; 헤더명이 아스키 범위를 벗어나지 않도록 주의</p>
</li>
<li><p><strong>Dates</strong> : HTTP 명세에서는 GMT 포맷을 정의하고 있지만 모든 웹 서버와 클라이언트가 해당 포맷을 따르지 않는다. -&gt; out-of-spec date에 가능한 한 오류가 발생하지 않게 해야 하고, 만약 파싱이 불가능하다면 보수적으로 해석한다</p>
</li>
<li><p><strong>Domain Names</strong> : 도메인 이름으로 국제 문자를 지원하지 않는다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p378 ~ p384"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p378-p384</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p378-p384</guid>
            <pubDate>Fri, 16 Jan 2026 11:51:40 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-16-internationalization">Chapter 16. Internationalization</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="glyphs-ligatures-and-presentation-forms">Glyphs, Ligatures, and Presentation Forms</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/87c44cfe-b88f-454d-9624-3e58d92f7a8d/image.png" alt=""></p>
<ul>
<li>Glyph : 문자를 표현하는 특정 방식<ul>
<li>하나의 문자가 여러 개의 Glyph를 가질 수 있다</li>
<li>문자를 표현 형태와 동일한 곳으로 간주하지 않도록 유의해야 한다</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/b7dd3edf-e770-4a1f-bb87-608f18eb1524/image.png" alt=""></p>
<ul>
<li>Ligature : 인접한 두 문자를 매끄럽게 연결하기 위한 표현 방식<ul>
<li>Glyph가 바뀌었을 때 텍스트의 의미가 바뀐다면 두 Gliph는 서로 다른 문자를 나타냄을 의미한다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="coded-character-sets">Coded Character Sets</h3>
<ul>
<li>RFC 2277, RFC 2130에 정의된 개념</li>
<li>주로 Code로 인덱싱 된 배열로 구현된다</li>
</ul>
<blockquote>
<p><strong>US-ASCII</strong></p>
<ul>
<li>1968 ANSI 표준에 의해 정의된 문자 집합</li>
<li>0-127 사이의 코드 사용 -&gt; 7비트의 Code Space 필요</li>
</ul>
</blockquote>
<blockquote>
<p><strong>Iso-8859</strong></p>
<ul>
<li>US-ASCII를 포함하는 8비트의 superset</li>
<li>128개의 나머지 비트에 모든 유럽의 문자를 담기 부족해서 iso-8859에 여러 가지 버전이 탄생하게 됨 (ex. Iso-8859-1은 서유럽 문자 포함)</li>
</ul>
</blockquote>
<blockquote>
<p><strong>JIS X 0201</strong></p>
<ul>
<li>ASCII + half-width katakana</li>
</ul>
</blockquote>
<blockquote>
<p><strong>JIS X 0208 &amp; JIS X 0212</strong></p>
<ul>
<li>0208 : 최초의 멀티바이트 일본어 문자 집합 -&gt; 6879개의 Coded Character 포함</li>
<li>0212 : 0208에 6067개의 문자가 추가된 버전</li>
</ul>
</blockquote>
<blockquote>
<p><strong>UCS(Universal Character Set)</strong></p>
<ul>
<li>전 세계 문자를 통합하기 위해 ISO 10646에 정의된 표준</li>
<li>유니코드가 UCS 표준을 따른다</li>
<li>수백만 개의 문자를 저장할 수 있는 Coding Space를 보유하고 있다</li>
</ul>
</blockquote>
<hr>
<h3 id="character-encoding-schemes">Character Encoding Schemes</h3>
<ul>
<li>문자 코드를 콘텐츠 비트로 변환하고, 콘텐츠 비트를 문자 코드로 변환하는 알고리즘</li>
</ul>
<blockquote>
<p><strong>Fixed width</strong></p>
<p>고정된 수의 비트로 Coded Character를 표현하는 방식</p>
</blockquote>
<blockquote>
<p><strong>Variable width (nonmodal)</strong></p>
<ul>
<li>서로 다른 문자 코드에 서로 다른 비트 개수를 할당할 수 있다.</li>
<li>일반적인 문자는 비트 개수를 줄일 수 있다.</li>
<li>레거시 8비트 문자 집합이 호환되며 국제 문자에 대해서는 멀티바이트를 사용할 수 있다.</li>
</ul>
</blockquote>
<blockquote>
<p><strong>Variable width (modal)</strong></p>
<ul>
<li>Escape 패턴을 활용해서 서로 다른 모드간 전환을 수행할 수 있다.</li>
<li>텍스트 내에서 여러 개의 중복된 문자 집합을 오가야 할 때 사용된다.</li>
<li>처리가 복잡하지만 쓰기 시스템에서 유용하다.</li>
</ul>
</blockquote>
<h3 id="utf-8">UTF-8</h3>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/cd1cdfe6-3f8e-4a90-af23-2b948533f701/image.png" alt=""></p>
<ul>
<li>Variable width (nonmodal)</li>
<li>첫 바이트는 인코딩된 문자 바이트의 길이를 나타낸다.<ul>
<li>첫 바이트가 0이면 길이가 1바이트임을 의미한다</li>
</ul>
</li>
<li>그 이후의 바이트는 6비트의 코드 값을 포함한다.<ul>
<li>만약 문자 코드가 5073(1001111010001)이면 길이가 13이므로, 11100001 10001111 10010001 의 3바이트로 표현 가능하다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p375 ~ p377"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p375-p377-fooizul8</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p375-p377-fooizul8</guid>
            <pubDate>Thu, 15 Jan 2026 06:21:55 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-16-internationalization">Chapter 16. Internationalization</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-원문-번역">✏️ 원문 번역</h2>
<hr>
<h3 id="content-type-charset-header-and-meta-tags">Content-Type Charset Header and META Tags</h3>
<blockquote>
<p>Web servers send the client the MIME charset tag in the Content-Type header, using the charset parameter:</p>
</blockquote>
<pre><code>Content-Type: text/html; charset=iso-2022-jp</code></pre><ul>
<li>웹 서버는 Content-Type 헤더의 charset 파라미터에 MIME charset 태그를 실어 클라이언트에게 전송합니다.</li>
</ul>
<blockquote>
<p>If no charset is explicitly listed, the receiver may try to infer the character set from the document contents. For HTML content, character sets might be found in <code>&lt;META HTTP-EQUIV=&quot;Content-Type&quot;&gt;</code> tags that describe the charset.</p>
</blockquote>
<ul>
<li><p>charset이 명시되지 않으면 수신자가 문서 콘텐츠로부터 문자 집합을 추론할 수 있습니다.</p>
</li>
<li><p>HTML 콘텐츠의 경우 <code>&lt;META HTTP-EQUIV=&quot;Content-Type&quot;&gt;</code> 태그에서 명시된 문자 집합을 발견할 수 있습니다.</p>
</li>
</ul>
<blockquote>
<p>Example 16-1 shows how HTML META tags set the charset to the Japanese encoding iso-2022-jp. If the document is not HTML, or there is no META Content-Type tag, software may attempt to infer the character encoding by scanning the actual text for common patterns indicative of languages and encodings.</p>
</blockquote>
<ul>
<li><p>Example 16-1은 HTML META 태그가 iso-2022-jp 인코딩된 일본어로 charset을 설정하는 과정을 나타냅니다.</p>
</li>
<li><p>문서가 HTML이 아니거나 META Content-Type 태그가 없다면 소프트웨어는 실제 텍스트를 스캔하여 인코딩 방식을 추론할 수 있습니다.</p>
</li>
<li><p>텍스트를 스캔한다는 것은 언어와 인코딩의 일반적인 패턴을 찾아낸다는 걸 의미합니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/741955ab-9a7d-400d-90ae-a2467f659a6f/image.png" alt=""></p>
<blockquote>
<p>If a client cannot infer a character encoding, it assumes iso-8859-1.</p>
</blockquote>
<ul>
<li>클라이언트가 문자 인코딩을 추론할 수 없는 경우 iso-8859-1로 가정합니다.</li>
</ul>
<hr>
<h3 id="the-accept-charset-header">The Accept-Charset Header</h3>
<blockquote>
<p>There are thousands of defined character encoding and decoding methods, developed over the past several decades. Most clients do not support all the various character coding and mapping systems.</p>
</blockquote>
<ul>
<li><p>지난 몇십 년간 개발된 문자 인코딩 및 디코딩 방식은 수천 가지가 넘습니다.</p>
</li>
<li><p>때문에 대부분의 클라이언트가 모든 종류의 문자 인코딩과 매핑 시스템을 지원하지 않습니다.</p>
</li>
</ul>
<blockquote>
<p>HTTP clients can tell servers precisely which character systems they support, using the Accept-Charset request header. The Accept-Charset header value provides a list of character encoding schemes that the client supports. For example, the following HTTP request header indicates that a client accepts the Western European iso-8859-1 character system as well as the UTF-8 variable-length Unicode compatibility system. A server is free to return content in either of these character encoding schemes.</p>
</blockquote>
<pre><code>Accept-Charset: iso-8859-1, utf-8</code></pre><ul>
<li><p>HTTP 클라이언트는 Accept-Charset 요청 헤더를 사용하여 서버에게 어떤 문자 시스템을 지원하는지 명확히 전달해야 합니다.</p>
</li>
<li><p>Accept-Charset 헤더값은 클라이언트가 지원하는 문자 인코딩 기법을 나열합니다.</p>
</li>
<li><p>예를 들어 다음의 HTTP 요청 헤더는 클라이언트가 서유럽 iso-8859-1 문자 시스템과 UTF-8 가변길이 유니코드 호환 시스템을 사용할 수 있음을 나타냅니다.</p>
<pre><code>Accept-Charset: iso-8859-1, utf-8</code></pre></li>
<li><p>서버는 두 가지 인코딩 기법 중 하나를 선택하여 콘텐츠를 반환하면 됩니다.</p>
</li>
</ul>
<blockquote>
<p>Note that there is no Content-Charset response header to match the Accept-Charset request header. The response character set is carried back from the server by the charset parameter of the Content-Type response header, to be compatible with MIME. It’s too bad this isn’t symmetric, but all the information still is there.</p>
</blockquote>
<ul>
<li><p>Accept-Charset 요청 헤더에 대응하는 Content-Charset 응답 헤더는 존재하지 않습니다.</p>
</li>
<li><p>응답 문자 집합은 Content-Type 응답 헤더의 charset 파라미터로 반환됩니다. 파라미터의 값은 MIME과 호환됩니다.</p>
</li>
<li><p>헤더가 대칭적이지 않은 건 아쉽지만 어쨌든 모든 정보는 주고받고 있습니다.</p>
</li>
</ul>
<hr>
<h3 id="multilingual-character-encoding-primer">Multilingual Character Encoding Primer</h3>
<blockquote>
<p>The previous section described how the HTTP Accept-Charset header and the Content-Type charset parameter carry character-encoding information from the client and server. HTTP programmers who do a lot of work with international applications and content need to have a deeper understanding of multilingual character systems to understand technical specifications and properly implement software.</p>
</blockquote>
<ul>
<li><p>이전 섹션에서는 HTTP Accept-Charset 헤더와 Content-Type charset 파라미터를 통해 클라이언트에서 서버로 문자 인코딩 정보를 전달하는 방법에 대해 알아보았습니다.</p>
</li>
<li><p>전세계적으로 사용되는 애플리케이션과 콘텐츠를 개발하는 HTTP 프로그래머는 다중 문자 시스템에 대한 깊은 이해가 필요합니다.</p>
</li>
<li><p>기술 명세를 이해하고 소프트웨어를 적절히 구현하기 위함입니다.</p>
</li>
</ul>
<blockquote>
<p>It isn’t easy to learn multilingual character systems—the terminology is complex and inconsistent, you often have to pay to read the standards documents, and you may be unfamiliar with the other languages with which you’re working. This section is an overview of character systems and standards. If you are already comfortable with character encodings, or are not interested in this detail, feel free to jump ahead to “Language Tags and HTTP.”</p>
</blockquote>
<ul>
<li><p>다중 문자 시스템을 학습하는 것은 쉬운 일이 아닙니다.</p>
</li>
<li><p>용어는 복잡하고 일관성이 없으며 종종 표준 문서를 구매해서 들여다봐야 하는 일도 생깁니다. 심지어 작업 중인 다른 언어에 익숙하지 않을 수도 있습니다.</p>
</li>
<li><p>이번 섹션에서는 문자 시스템과 표준을 간단히 살펴보겠습니다.</p>
</li>
<li><p>문자 인코딩에 이미 친숙하거나 구체적인 내용에 큰 흥미가 없다면 &quot;Language Tags and HTTP&quot;로 건너뛰어도 좋습니다.</p>
</li>
</ul>
<h3 id="character-set-terminology">Character Set Terminology</h3>
<blockquote>
<p>Here are eight terms about electronic character systems that you should know:</p>
</blockquote>
<ul>
<li>전자 문자 시스템을 이해하기 위해 반드시 알아야 할 여덟 가지 용어가 있습니다.</li>
</ul>
<blockquote>
<p><strong>Character</strong></p>
</blockquote>
<p>An alphabetic letter, numeral, punctuation mark, ideogram(as in Chinese), symbol, or other textual “atom” of writing. The Universal Character Set (UCS) initiative, known informally as Unicode,* has developed a standardized set of textual names for many characters in many languages, which often are used to conveniently and uniquely name characters.</p>
<p><strong>Character</strong></p>
<ul>
<li><p>알파벳, 숫자, 구두점, 표의문자, 기호 또는 기타 텍스트의 기본 단위를 의미합니다.</p>
</li>
<li><p>유니코드로 널리 알려진 UCS(Universal Character Set)는 다양한 언어의 다양한 문자에 대하여 표준화된 텍스트를 명명한 집합을 개발하였습니다.</p>
</li>
<li><p>유니코드는 문자를 고유하게 명명하는 데 편리하게 사용될 수 있습니다.</p>
</li>
</ul>
<blockquote>
<p><strong>Glyph</strong></p>
</blockquote>
<p>A stroke pattern or unique graphical shape that describes a character. A character may have multiple glyphs if it can be written different ways (see Figure 16-3).</p>
<p><strong>Glyph</strong></p>
<ul>
<li><p>문자를 표현하는 스트로크 패턴이나 고유한 그래픽 형태를 의미합니다.</p>
</li>
<li><p>한 문자가 여러 가지 방식으로 쓰일 수 있다면 여러 개의 glyph를 가질 수 있습니다. (Figure 16-3 참조)</p>
</li>
</ul>
<blockquote>
<p><strong>Coded character</strong></p>
</blockquote>
<p>A unique number assigned to a character so that we can work with it.</p>
<p><strong>Coded character</strong></p>
<ul>
<li>문자에 부여된 고유한 번호입니다.</li>
</ul>
<blockquote>
<p><strong>Coding space</strong></p>
</blockquote>
<p>A range of integers that we plan to use as character code values.</p>
<p><strong>Coding space</strong></p>
<ul>
<li>문자 코드의 값이 사용하도록 지정된 정수 범위입니다.</li>
</ul>
<blockquote>
<p><strong>Code width</strong></p>
</blockquote>
<p>The number of bits in each (fixed-size) character code.</p>
<p><strong>Code width</strong></p>
<ul>
<li>각각의 (고정 사이즈) 문자 코드의 비트 개수입니다.</li>
</ul>
<blockquote>
<p><strong>Character repertoire</strong></p>
</blockquote>
<p>A particular working set of characters (a subset of all the characters in the world).</p>
<p><strong>Character repertoire</strong></p>
<ul>
<li>특정 문자 집합(전세계의 모든 문자들의 부분집합)입니다.</li>
</ul>
<blockquote>
<p><strong>Coded character set</strong></p>
</blockquote>
<p>A set of coded characters that takes a character repertoire (a selection of characters from around the world) and assigns each character a code from a coding space. In other words, it maps numeric character codes to real characters.</p>
<p><strong>Coded character set</strong></p>
<ul>
<li><p>Coded Character의 집합으로, Character Repertoire의 모든 문자에 대해 Coding Space 내에서 각각을 할당합니다.</p>
</li>
<li><p>한마디로 숫자로 된 문자 코드를 실제 문자에 매핑한 것입니다.</p>
</li>
</ul>
<blockquote>
<p><strong>Character encoding scheme</strong></p>
</blockquote>
<p>An algorithm to encode numeric character codes into a sequence of content bits(and to decode them back). Character encoding schemes can be used to reduce the amount of data required to identify characters (compression), work around transmission restrictions, and unify overlapping coded character sets.</p>
<p><strong>Character encoding scheme</strong></p>
<ul>
<li><p>숫자로 된 문자 코드를 콘텐츠 비트로 인코딩 및 디코딩하는 알고리즘입니다.</p>
</li>
<li><p>문자를 식별하는 데 사용되는 데이터량을 줄이기 위해(=압축), 전송 제한을 우회하기 위해, 중복된 Coded Character Set을 통합하기 위해 문자 인코딩 기법이 적용될 수 있습니다.</p>
</li>
</ul>
<h3 id="charset-is-poorly-named">Charset Is Poorly Named</h3>
<blockquote>
<p>Technically, the MIME charset tag (used in the Content-Type charset parameter and the Accept-Charset header) doesn’t specify a character set at all. The MIME charset value names a total algorithm for mapping data bits to codes to unique characters. It combines the two separate concepts of character encoding scheme and coded character set (see Figure 16-2).</p>
</blockquote>
<ul>
<li><p>Content-Type charset 파라미터와 Accept-Charset 헤더에서 사용되는 MIME charset 태그는 기술적으로 문자 집합을 전혀 특정하지 않습니다.</p>
</li>
<li><p>MIME charset 값은 데이터 비트를 코드로, 특정 문자로 매핑하기 위한 알고리즘을 명명할 뿐입니다.</p>
</li>
<li><p>즉 MIME charset 태그는 문자 인코딩 기법과 Coded Character Set이라는 서로 다른 개념을 하나로 통합한 개념입니다. (Figure 16-2 참조)</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/aee54a3f-4ad8-4a92-b339-de833387ca1a/image.png" alt=""></p>
<blockquote>
<p>This terminology is sloppy and confusing, because there already are published standards for character encoding schemes and for coded character sets. Here’s what the HTTP/1.1 authors say about their use of terminology (in RFC 2616):</p>
</blockquote>
<ul>
<li><p>문자 인코딩 기법과 Coded Character Set에 대한 표준이 이미 존재하기 때문에 이러한 용어는 부주의하고 혼란스럽습니다.</p>
</li>
<li><p>HTTP/1.1의 개발자는 RFC 2616에서 해당 용어의 사용에 대해 다음과 같이 이야기합니다.</p>
</li>
</ul>
<blockquote>
<p>The term “character set” is used in this document to refer to a method ... to convert a sequence of octets into a sequence of characters... Note: This use of the term “character set” is more commonly referred to as a “character encoding.” However, since HTTP and MIME share the same registry, it’s important that the terminology also be shared.</p>
</blockquote>
<ul>
<li><p>해당 문서에서 &quot;character set&quot;이라는 용어는 옥텟 비트를 문자 시퀀스로 변환하는 방법을 나타내기 위해 사용되었습니다.</p>
</li>
<li><p>&quot;character set&quot;이라는 용어는 일반적으로 &quot;문자 인코딩&quot;을 나타냅니다.</p>
</li>
<li><p>그러나 HTTP와 MIME이 동일한 레지스트리를 공유하기 때문에 용어 역시 공유되어야 합니다.</p>
</li>
</ul>
<blockquote>
<p>The IETF also adopts nonstandard terminology in RFC 2277:</p>
</blockquote>
<ul>
<li>IETF 또한 RFC 2277에서 비표준 용어를 채택하고 있습니다.</li>
</ul>
<blockquote>
<p>This document uses the term “charset” to mean a set of rules for mapping from a sequence of octets to a sequence of characters, such as the combination of a coded character set and a character encoding scheme; this is also what is used as an identifier in MIME “charset=” parameters, and registered in the IANA charset registry. (Note that this is NOT a term used by other standards bodies, such as ISO).</p>
</blockquote>
<ul>
<li><p>이 문서는 Coded Character Set과 문자 인코딩 기법을 결합하는 것과 같이 옥텟 시퀀스를 문자 시퀀스로 매핑하기 위한 규칙 집합으로 &quot;charset&quot;이라는 용어를 사용합니다.</p>
</li>
<li><p>여기서 이야기하는 charset은 MIME의 &quot;charset=&quot; 파라미터에서 식별자로 사용되는 것과 동일합니다. 이 값은 IANA 문자 집합 레지스트리에 등록되어 있습니다.</p>
</li>
<li><p>ISO와 같은 다른 표준에서 사용되는 용어와 일치하지 않음에 유의 바랍니다.</p>
</li>
</ul>
<blockquote>
<p>So, be careful when reading standards documents, so you know exactly what’s being defined. Now that we’ve got the terminology sorted out, let’s look a bit more closely at characters, glyphs, character sets, and character encodings.</p>
</blockquote>
<ul>
<li><p>표준 문서를 읽을 때는 정의된 바를 명확히 이해할 수 있도록 주의하시기 바랍니다.</p>
</li>
<li><p>필요한 용어들을 살펴보았으니 이제 문자와 Glyph, 문자 집합, 문자 인코딩에 대해 더 상세히 들여다봅시다.</p>
</li>
</ul>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="http를-통해-문자-인코딩-정보를-전달하는-방법">HTTP를 통해 문자 인코딩 정보를 전달하는 방법</h3>
<ul>
<li>클라이언트 : Accept-Charset 헤더를 통해 지원되는 charset 명시<pre><code>Accept-Charset: iso-8859-1, utf-8</code></pre></li>
<li>서버 : Content-Type 헤더를 통해 리소스의 charset 명시<pre><code>Content-Type: text/html; charset=utf-8</code></pre><ul>
<li>charset이 명시된 경우 클라이언트는 명시된 charset으로 디코딩</li>
<li>charset이 명시되지 않은 html 문서의 경우 META Content-Type 태그 확인</li>
<li>charset을 알 수 없는 경우 iso-8859-1로 디코딩</li>
</ul>
</li>
</ul>
<hr>
<h3 id="character-set-용어-정리">Character Set 용어 정리</h3>
<ul>
<li>Glyph : 문자를 표현하는 패턴이나 그래픽 형태 -&gt; 문자의 표현 방식이 여러 가지라면 Glyph도 여러 가지</li>
<li>Coded character : 문자에 부여된 고유한 코드</li>
<li>Coding space : 문자 코드가 사용 가능한 정수 범위</li>
<li>Code width : 문자 코드의 (고정된) 비트 개수</li>
<li>Character repertoire : 문자 집합 (모든 문자의 부분집합)</li>
<li>Coded character set : 문자 집합의 모든 문자에 코드를 매핑한 집합</li>
<li>Character encoding scheme : 문자 코드를 비트 시퀀스로 인코딩하는 알고리즘</li>
</ul>
<p>** HTTP에서 이야기하는 charset은 Coded Character Set과 Character Encoding Scheme을 결합한 개념이다</p>
<hr>
<h2 id="✏️-코멘트">✏️ 코멘트</h2>
<hr>
<p>돌아왔습니다...ㅋㅋㅋ
6개월 동안 자격증도 좀 따고 인턴도 하고 졸업논문도 쓰면서 그렇게 살고 있었습니다.</p>
<p>인턴 기간도 끝나고 졸업요건도 다 채우고 났더니, 지금은 뭔가 붕 떠 있는 기분이네요.
이왕 붕 떠버린 김에 읽고 싶었던 책도 읽고 여행도 다니려고 하고 있습니다.
HTTP 책도 슬슬 갈무리 할 때가 오지 않았을까요. 분량을 조금 늘려서라도 2월까지 한 번 후딱 읽어보겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p372 ~ p375"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p372-p375</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p372-p375</guid>
            <pubDate>Fri, 06 Jun 2025 02:23:35 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-16-internationalization">Chapter 16. Internationalization</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-원문-번역">✏️ 원문 번역</h2>
<hr>
<h3 id="how-character-sets-and-encodings-work">How Character Sets and Encodings Work</h3>
<blockquote>
<p>Let’s see what character sets and encodings really do.</p>
</blockquote>
<ul>
<li>문자집합과 인코딩이 실제로 무엇을 하는지 살펴보겠습니다.</li>
</ul>
<blockquote>
<p>We want to convert from bits in a document into characters that we can display onscreen. But because there are many different alphabets, and many different ways of encoding characters into bits(each with advantages and disadvantages), we need a standard way to describe and apply the bits-to-character decoding algorithm.</p>
</blockquote>
<ul>
<li><p>문서의 비트를 화면에 표시할 수 있도록 문자로 변환해야 한다고 가정해봅시다.</p>
</li>
<li><p>문자가 다양하고 문자를 비트로 인코딩하는 방식 또한 다양하기 때문에 디코딩 알고리즘을 표현하고 적용하기 위한 표준이 필요합니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/aee54a3f-4ad8-4a92-b339-de833387ca1a/image.png" alt=""></p>
<blockquote>
<p>Bits-to-character conversions happen in two steps, as shown in Figure16-2:</p>
</blockquote>
<p>• In Figure 16-2a, bits from a document are converted into a character code that identifies a particular numbered character in a particular coded character set. In the example, the decoded character code is numbered 225.</p>
<blockquote>
</blockquote>
<p>• In Figure 16-2b, the character code is used to select a particular element of the coded character set. In iso-8859-6, the value 225 corresponds to “ARABIC LETTER FEH.” The algorithms used in Steps a and b are determined from the MIME charset tag.</p>
<ul>
<li><p>비트-문자 변환은 Figure 16-2에 나타난 것처럼 두 단계를 거칩니다.</p>
</li>
<li><p>Figure 16-2a에서 문서의 비트들은 정의된 문자집합의 문자 코드로 변환되어 특정 번호의 문자를 식별합니다. 예시에서 디코딩된 문자 코드는 225입니다.</p>
</li>
<li><p>Figure 16-2b에서 문자 코드는 문자집합에서 특정 요소를 선택하는 데 사용됩니다. iso-8859-6에서 225는 아랍어 문자 &quot;FEH&quot;에 해당합니다. a단계와 b단계에서 사용되는 알고리즘은 MIME charset 태그에 의해 결정됩니다.</p>
</li>
</ul>
<blockquote>
<p>A key goal of internationalized character systems is the isolation of the semantics(letters) from the presentation (graphical presentation forms). HTTP concerns itself only with transporting the character data and the associated language and charset labels. The presentation of the character shapes is handled by the user’s graphics display software (browser, operating system, fonts), as shown in Figure 16-2c.</p>
</blockquote>
<ul>
<li><p>국제화된 문자 시스템의 목표는 의미(문자)와 표현(시각적으로 표시되는 형태)를 분리시키는 것입니다.</p>
</li>
<li><p>HTTP는 문자 데이터와 관련 언어 및 문자집합 라벨을 전송하는 데만 관여합니다.</p>
</li>
<li><p>Figure 16-2c에 나타난 것처럼 문자의 형태를 표현하는 것은 사용자의 그래픽 디스플레이 소프트웨어(브라우저, 운영체제, 폰트 등)에 의해 제어됩니다.</p>
</li>
</ul>
<hr>
<h3 id="the-wrong-charset-gives-the-wrong-characters">The Wrong Charset Gives the Wrong Characters</h3>
<blockquote>
<p>If the client uses the wrong charset parameter, the client will display strange, bogus characters. Let’s say a browser got the value 225 (binary 11100001) from the body:</p>
</blockquote>
<ul>
<li><p>만약 클라이언트가 잘못된 charset 파라미터를 사용하면, 클라이언트는 요상한 가짜 문자를 표시할 것입니다.</p>
</li>
<li><p>브라우저가 본문으로부터 225(이진수 11100001)를 받았다고 가정해봅시다.</p>
</li>
</ul>
<blockquote>
<p>• If the browser thinks the body is encoded with iso-8859-1 Western European character codes, it will show a lowercase Latin “a” with acute accent:</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/01ce7f06-13e5-43bc-8811-edf81f24a84a/image.png" alt=""></p>
<ul>
<li>만약 브라우저가 해당 본문이 iso-8859-1 서유럽 문자 코드로 인코딩되었다고 생각한다면, á 로 표현될 것입니다.</li>
</ul>
<blockquote>
<p>• If the browser is using iso-8859-6 Arabic codes, it will show “FEH”:</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/f606544b-5c4f-4e42-bf04-9bb8cc309efd/image.png" alt=""></p>
<ul>
<li>만약 브라우저가 iso-8859-6 아랍어 코드를 사용한다면, &quot;FEH&quot;로 표현될 것입니다.</li>
</ul>
<blockquote>
<p>• If the browser is using iso-8859-7 Greek, it will show a small “Alpha”:</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/1e7e22e2-a400-4a6a-82bb-54a799ec5ba0/image.png" alt=""></p>
<ul>
<li>브라우저가 iso-8859-7 그리스어를 사용하고 있다면 소문자 &quot;alpha&quot;가 나타날 것입니다.</li>
</ul>
<blockquote>
<p>• If the browser is using iso-8859-8 Hebrew codes, it will show “BET”:</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/7e6dd309-b484-41f5-b3f7-6e853cc40cab/image.png" alt=""></p>
<ul>
<li>브라우저가 iso-8859-8 히브리어 코드를 사용하는 경우에는 &quot;BET&quot; 문자가 표시될 것입니다.</li>
</ul>
<hr>
<h3 id="standardized-mime-charset-values">Standardized MIME Charset Values</h3>
<blockquote>
<p>The combination of a particular character encoding and a particular coded character set is called a MIME charset. HTTP uses standardized MIME charset tags in the Content-Type and Accept-Charset headers. MIME charset values are registered with the IANA.* Table 16-1 lists a few MIME charset encoding schemes used by documents and browsers. A more complete list is provided in Appendix H.</p>
</blockquote>
<ul>
<li><p>특정 인코딩 기법과 문자집합의 조합을 MIME charset이라고 부릅니다.</p>
</li>
<li><p>HTTP는 <code>Content-Type</code> 헤더와 <code>Accept-Charset</code> 헤더에 표준화된 MIME charset 태그를 사용합니다.</p>
</li>
<li><p>MIME charset 값은 IANA에 등록되어 있습니다.</p>
</li>
<li><p>Table 16-1은 문서와 브라우저에서 사용되는 몇 가지 MIME charset 인코딩 기법을 나열하고 있습니다.</p>
</li>
<li><p>더 자세한 목록은 Appendix H에서 확인하실 수 있습니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/e7d2e8fd-e67b-4790-89be-bd5758094684/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/bb17cee9-2e84-439b-a9ed-feda77668da4/image.png" alt=""></p>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="how-character-sets-and-encodings-work-1">How Character Sets and Encodings Work</h3>
<ul>
<li><ol>
<li>문서의 비트를 문자집합의 숫자 코드로 디코딩</li>
</ol>
</li>
<li><ol start="2">
<li>그래픽 디스플레이 소프트웨어에서 숫자 코드를 문자 형태로 표현</li>
</ol>
</li>
</ul>
<hr>
<h3 id="standardized-mime-charset">Standardized MIME Charset</h3>
<p>: IANA에 등록되어 있는 표준 (인코딩, 문자집합) 조합</p>
<ul>
<li><code>Content-Type</code> 헤더와 <code>Accept-Charset</code> 헤더에서 사용</li>
<li>us-ascii, utf-8 등</li>
</ul>
<hr>
<h2 id="✏️-감상">✏️ 감상</h2>
<hr>
<h3 id="ianainternet-assigned-numbers-authority">IANA(Internet Assigned Numbers Authority)</h3>
<p>IANA는 도대체 뭘 하는 곳일까..?! IANA는 사실 MIME charset에 대한 표준을 관리하는 것만이 목적인 기관은 아니다. 이곳은 무려 HTTP에서 사용하는 MIME charset을 비롯한 인터넷 할당 번호를 전반적으로 관리하는 기관이다. IANA가 관리하는 가장 대표적인 번호가 바로 IP 주소와 최상위 도메인이다.</p>
<p>몰랐다면 이제 알아두자. 우리는 IANA가 없으면 인터넷을 정상적으로 못 쓴다...ㅋㅋㅋㅋㅋㅋ 굉장히 굉장히 중요한 기관이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p370 ~ p372"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p370-p372</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p370-p372</guid>
            <pubDate>Wed, 04 Jun 2025 08:20:05 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-16-internationalization">Chapter 16. Internationalization</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-원문-번역">✏️ 원문 번역</h2>
<hr>
<h3 id="preface">Preface</h3>
<blockquote>
<p>Every day, billions of people write documents in hundreds of languages. To live up to the vision of a truly world-wide Web, HTTP needs to support the transport and processing of international documents, in many languages and alphabets.</p>
</blockquote>
<ul>
<li><p>매일 수십억 명의 사람들이 수백 가지의 언어로 된 문서를 작성하고 있습니다.</p>
</li>
<li><p>진정한 World-wide Web의 비전에 부응하기 위해 HTTP는 다양한 언어와 알파벳으로 구성된 국제적인 문서를 전송하고 처리할 수 있도록 지원할 필요가 있습니다.</p>
</li>
</ul>
<blockquote>
<p>This chapter covers two primary internationalization issues for the Web: character set encodings and language tags. HTTP applications use character set encodings to request and display text in different alphabets, and they use language tags to describe and restrict content to languages the user understands. We finish with a brief chat about multilingual URIs and dates.</p>
</blockquote>
<ul>
<li><p>이번 챕터에서는 웹에서의 주요한 두 가지 국제화 이슈에 대해 다룹니다.</p>
</li>
<li><p>바로 문자집합의 인코딩과 언어 태그에 대한 문제입니다.</p>
</li>
<li><p>HTTP 응용 프로그램은 문자 집합 인코딩을 사용하여 다양한 언어의 텍스트를 요청하고 표현합니다.</p>
</li>
<li><p>언어 태그를 사용하면 사용자가 이해할 수 있는 언어로 콘텐츠를 묘사하고 제한할 수 있습니다.</p>
</li>
<li><p>마지막으로는 다국어 URI와 날짜에 대해 짧게 이야기하고 마치도록 하겠습니다.</p>
</li>
</ul>
<blockquote>
<p>This chapter:</p>
</blockquote>
<p>• Explains how HTTP interacts with schemes and standards for multilingual alphabets</p>
<blockquote>
</blockquote>
<p>• Gives a rapid overview of the terminology, technology, and standards to help HTTP programmers do things right (readers familiar with character encodings can skip this section)</p>
<blockquote>
</blockquote>
<p>• Explains the standard naming system for languages, and how standardized language tags describe and select content</p>
<blockquote>
</blockquote>
<p>• Outlines rules and cautions for international URIs</p>
<blockquote>
</blockquote>
<p>• Briefly discusses rules for dates and other internationalization issues</p>
<ul>
<li>이번 챕터에서 다루는 내용은 다음과 같습니다.<ul>
<li>HTTP가 다양한 언어로 된 기술 및 표준과 상호작용하는 방식을 설명합니다.</li>
<li>HTTP 개발자가 올바른 개발을 진행할 수 있도록 용어, 기술, 표준을 간단히 요약합니다(문자 인코딩에 익숙한 독자들은 해당 섹션을 건너뛰어도 무방합니다).</li>
<li>언어에 관한 표준 명명 시스템을 설명하고 표준화된 언어 태그가 콘텐츠를 묘사하고 선택하는 방식에 대해 설명합니다.</li>
<li>국제 URI 사용에 관한 규칙과 주의점을 설명합니다.</li>
<li>날짜와 기타 국제화 이슈에 대한 규칙을 간략히 논의합니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="http-support-for-international-content">HTTP Support for International Content</h3>
<blockquote>
<p>HTTP messages can carry content in any language, just as it can carry images, movies, or any other kind of media. To HTTP, the entity body is just a box of bits.</p>
</blockquote>
<ul>
<li><p>HTTP 메시지는 임의의 언어로 된 콘텐츠를 전송할 수 있습니다.</p>
</li>
<li><p>콘텐츠는 이미지나 영화일 수도 있고, 그 밖의 다른 종류의 미디어일 수도 있습니다.</p>
</li>
<li><p>HTTP에서 엔티티 본문은 비트들의 상자일 뿐입니다.</p>
</li>
</ul>
<blockquote>
<p>To support international content, servers need to tell clients about the alphabet and languages of each document, so the client can properly unpack the document bits into characters and properly process and present the content to the user.</p>
</blockquote>
<ul>
<li><p>국제적인 콘텐츠를 지원하기 위하여 서버는 클라이언트에게 각 문서의 알파벳과 언어에 대해 전달할 필요가 있습니다.</p>
</li>
<li><p>클라이언트가 메시지를 열었을 때 문서의 비트를 적절한 문자로 변환하고 가공하여 사용자에게 콘텐츠를 표현할 수 있게 하기 위함입니다.</p>
</li>
</ul>
<blockquote>
<p>Servers tell clients about a document’s alphabet and language with the HTTP Content-Type charset parameter and Content-Language headers. These headers describe what’s in the entity body’s “box of bits,” how to convert the contents into the proper characters that can be displayed on screen, and what spoken language the words represent.</p>
</blockquote>
<ul>
<li><p>서버는 클라이언트에게 HTTP Content-Type charset 파라미터와 Content-Language 헤더를 통해 문서의 알파벳과 언어를 표현할 수 있습니다.</p>
</li>
<li><p>이러한 헤더들은 엔티티 본문의 &quot;비트 상자&quot;에 무엇이 들어있으며 표현되는 언어는 무엇이고, 어떻게 스크린상의 언어로 적절하게 변환할 수 있는지를 나타냅니다.</p>
</li>
</ul>
<blockquote>
<p>At the same time, the client needs to tell the server which languages the user understands and which alphabetic coding algorithms the browser has installed. The client sends Accept-Charset and Accept-Language headers to tell the server which character set encoding algorithms and languages the client understands, and which of them are preferred.</p>
</blockquote>
<ul>
<li><p>반대로 클라이언트는 사용자가 이해할 수 있는 언어가 무엇이고, 브라우저에 어떤 인코딩 알고리즘이 설치되어 있는지 서버에게 전달해야 합니다.</p>
</li>
<li><p>클라이언트는 Accept-Charset과 Accept-Language 헤더를 사용하여 자신이 이해할 수 있는 문자집합 인코딩 알고리즘과 언어, 선호하는 알고리즘과 언어에 대한 정보까지 서버에 전달할 수 있습니다.</p>
</li>
</ul>
<blockquote>
<p>The following HTTP Accept headers might be sent by a French speaker who prefers his native language (but speaks some English in a pinch) and who uses a browser that supports the iso-8859-1 West European charset encoding and the UTF-8 Unicode charset encoding:</p>
</blockquote>
<pre><code>Accept-Language: fr, en;q=0.8
Accept-Charset: iso-8859-1, utf-8</code></pre><ul>
<li><p>다음의 HTTP Accept 헤더는 모국어를 선호하는(하지만 아주 조금은 영어를 사용할 수 있는) 프랑스인에 의해 작성되었을 수 있습니다.</p>
</li>
<li><p>해당 클라이언트는 iso-885901 West European 문자집합 인코딩과 UTF-8 유니코드 문자집합 인코딩을 지원하는 브라우저를 사용하고 있습니다.</p>
</li>
</ul>
<blockquote>
<p>The parameter “q=0.8” is a quality factor, giving lower priority to English (0.8) than to French (1.0 by default).</p>
</blockquote>
<ul>
<li><p>&quot;q=0.8&quot; 파라미터는 Quality Factor입니다.</p>
</li>
<li><p>0.8의 파라미터를 가진 영어는 프랑스어에 비해 우선순위가 낮습니다.</p>
</li>
</ul>
<hr>
<h3 id="charater-sets-and-http">Charater Sets and HTTP</h3>
<blockquote>
<p>So, let’s jump right into the most important (and confusing) aspects of web internationalization—international alphabetic scripts and their character set encodings.</p>
</blockquote>
<ul>
<li>이제 웹 국제화에서 가장 중요한 측면인 &quot;국제 알파벳 스크립트와 문자집합 인코딩&quot;에 대해 이야기해봅시다.</li>
</ul>
<blockquote>
<p>Web character set standards can be pretty confusing. Lots of people get frustrated when they first try to write international web software, because of complex and inconsistent terminology, standards documents that you have to pay to read, and unfamiliarity with foreign languages. This section and the next section should make it easier for you to use character sets with HTTP.</p>
</blockquote>
<ul>
<li><p>웹 문자집합 표준은 상당히 혼란스럽습니다.</p>
</li>
<li><p>처음 국제 웹 소프트웨어를 작성하려고 했을 무렵 많은 사람들이 복잡하고 일관되지 않은 용어와 대가를 지불해야 하는 표준 문서, 친숙하지 않은 외국어로 인해 고초를 겪었습니다.</p>
</li>
<li><p>이번 섹션과 다음 섹션을 통해 HTTP와 함께 문자집합을 쉽게 사용할 수 있게 되기를 바랍니다.</p>
</li>
</ul>
<h3 id="charset-is-a-character-to-bits-encoding">Charset Is a Character-to-Bits Encoding</h3>
<blockquote>
<p>The HTTP charset values tell you how to convert from entity content bits into characters in a particular alphabet. Each charset tag names an algorithm to translate bits to characters (and vice versa). The charset tags are standardized in the MIME character set registry, maintained by the IANA (see <a href="http://www.iana.org/assignments/character-sets">http://www.iana.org/assignments/character-sets</a>). Appendix H summarizes many of them.</p>
</blockquote>
<ul>
<li><p>HTTP 문자집합의 값은 엔티티의 콘텐츠 비트를 특정한 알파벳의 문자로 변환하는 방식을 의미합니다.</p>
</li>
<li><p>각각의 문자집합 태그는 비트를 문자로 변환하기 위한 알고리즘을 명명합니다.</p>
</li>
<li><p>문자집합 태그는 MIME 문자 집합 레지스트리에 표준화되어 있으며 IANA에 의해 유지 및 관리됩니다. (<a href="http://www.iana.org/assignments/character-sets">http://www.iana.org/assignments/character-sets</a>)</p>
</li>
<li><p>Appendix H는 이 중 일부를 요약하고 있습니다.</p>
</li>
</ul>
<blockquote>
<p>The following Content-Type header tells the receiver that the content is an HTML file, and the charset parameter tells the receiver to use the iso-8859-6 Arabic character set decoding scheme to decode the content bits into characters:</p>
</blockquote>
<pre><code>Content-Type: text/html; charset=iso-8859-6</code></pre><ul>
<li><p>다음의 Content-Type 헤더는 수신자에게 콘텐츠가 HTML 파일이라는 사실을 알립니다.</p>
</li>
<li><p>charset 파라미터는 iso-8859-6 아랍어 문자 집합을 사용하여 콘텐츠 비트를 문자로 디코딩해야 함을 의미합니다.</p>
</li>
</ul>
<blockquote>
<p>The iso-8859-6 encoding scheme maps 8-bit values into both the Latin and Arabic alphabets, including numerals, punctuation and other symbols.* For example, in Figure 16-1, the highlighted bit pattern has code value 225, which(under iso-8859-6) maps into the Arabic letter “FEH” (a sound like the English letter “F”).</p>
</blockquote>
<ul>
<li><p>iso-8859-6 인코딩 기법은 8비트의 값을 숫자, 구두점, 기타 기호를 포함하여 라틴어와 아랍어로 매핑합니다.</p>
</li>
<li><p>예를 들어, Figure 16-1에서 표시된 비트 패턴의 코드는 225입니다.</p>
</li>
<li><p>225는 iso-8859-6상에서 아랍어 문자 &quot;FEH(영문자 &quot;F&quot;와 비슷한 소리를 내는 문자)&quot;와 매핑됩니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/1dfdf595-45d1-4773-a720-2578a1b0cbf3/image.png" alt=""></p>
<blockquote>
<p>Some character encodings (e.g., UTF-8 and iso-2022-jp) are more complicated, variable-length codes, where the number of bits per character varies. This type of coding lets you use extra bits to support alphabets with large numbers of characters(such as Chinese and Japanese), while using fewer bits to support standard Latin characters.</p>
</blockquote>
<ul>
<li><p>UTF-8과 iso-2022-jp과 같은 일부 문자 인코딩은 더욱 복잡한 가변 길이의 코드를 가지고 있습니다.</p>
</li>
<li><p>길이가 가변이라는 것은 문자 하나당 비트의 개수가 상이함을 의미합니다.</p>
</li>
<li><p>이러한 유형의 코드는 추가적인 비트를 사용하여 더 많은 알파벳 문자를 지원할 수 있게 합니다.</p>
</li>
<li><p>표준 라틴 문자는 적은 비트로 지원 가능하지만, 중국어, 일본어 등의 문자 인코딩에는 더 많은 비트가 사용됩니다.</p>
</li>
</ul>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="charset">Charset</h3>
<p>: Character-to-Bits 인코딩</p>
<ul>
<li>클라이언트 : 이해할 수 있는 언어와 인코딩 알고리즘 전달<ul>
<li>Quality Factor를 활용해 선호도를 표현할 수 있다 (default 1)</li>
<li><code>Accept-Language</code> : 허용하는 언어</li>
<li><code>Accept-Charset</code> : 인코딩 알고리즘</li>
</ul>
</li>
<li>서버 : 엔티티 본문의 언어와 인코딩 알고리즘 전달<ul>
<li><code>Content-Language</code> : 엔티티 본문의 언어</li>
<li><code>Content-Type: charset</code> : 엔티티 본문에 적용된 인코딩 알고리즘</li>
</ul>
</li>
<li>HTTP Charset은 MIME 문자 집합 레지스트리에 표준화, IANA에서 관리</li>
</ul>
<hr>
<h2 id="✏️-감상">✏️ 감상</h2>
<hr>
<h3 id="국제화-표준을-위한-노력">국제화 표준을 위한 노력</h3>
<p>예전에 언어론 수업을 들을 때 유니코드 표준을 위한 합의를 보는 데 굉장히 오랜 시간이 걸렸다고 들었다. 대학에서 하는 간단한 팀플조차 의견을 맞추는 것이 어려운데 하물며 국제적인 수준의 합의는 어떻겠는가. 어떤 일이든 항상 공평한 표준을 정하는 것은 어려운 일인 것 같다.</p>
<p>후속 챕터에서 유니코드에 대해서 자세히 다룰지는 모르겠지만, 조만간 &#39;감상&#39; 부분에 유니코드에 대해서도 짧게 남겨보려고 한다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP :  The Definitive Guide "p365 ~ p369"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p365-p369</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p365-p369</guid>
            <pubDate>Mon, 02 Jun 2025 07:01:46 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-15-entities-and-encodings">Chapter 15. Entities and Encodings</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-원문-번역">✏️ 원문 번역</h2>
<hr>
<h3 id="delta-encoding">Delta Encoding</h3>
<blockquote>
<p>We have described different versions of a web page as different instances of a page. If a client has an expired copy of a page, it requests the latest instance of the page. If the server has a newer instance of the page, it will send it to the client, and it will send the full new instance of the page even if only a small portion of the page actually has changed.</p>
</blockquote>
<ul>
<li><p>지금까지 웹 페이지의 서로 다른 버전을 인스턴스로 표현해 왔습니다.</p>
</li>
<li><p>만약 클라이언트가 페이지의 만료된 사본을 가지고 있다면, 클라이언트는 페이지의 최신 인스턴스를 요청할 것입니다.</p>
</li>
<li><p>서버는 더 새로운 페이지 인스턴스를 보유하고 있는 경우 클라이언트에게 그것을 반환합니다.</p>
</li>
<li><p>아마도 페이지가 실제로 변화한 부분이 크지 않더라도 새로운 페이지 인스턴스전체를 전달할 것입니다.</p>
</li>
</ul>
<blockquote>
<p>Rather than sending it the entire new page, the client would get the page faster if the server sent just the changes to the client’s copy of the page (provided that the number of changes is small). Delta encoding is an extension to the HTTP protocol that optimizes transfers by communicating changes instead of entire objects. Delta encoding is a type of instance manipulation, because it relies on clients and servers exchanging information about particular instances of an object. RFC 3229 describes delta encoding.</p>
</blockquote>
<ul>
<li><p>만약 서버가 새 페이지를 통째로 전달하는 대신 클라이언트가 가진 사본과 다른 부분만 전송할 수 있다면 클라이언트는 더 빠르게 페이지를 얻을 수 있을 것입니다.</p>
</li>
<li><p>델타 인코딩은 전체 오브젝트 대신 변경사항만 송수신하여 전송을 최적화하는 HTTP 프로토콜의 확장 요소입니다.</p>
</li>
<li><p>델타 인코딩은 Instance Manipulation의 일종입니다.</p>
</li>
<li><p>클라이언트와 서버가 특정 오브젝트 인스턴스에 대해 정보를 교환하는 것에 의존하기 때문입니다.</p>
</li>
<li><p>RFC 3229에서 델타 인코딩에 대해 설명합니다.</p>
</li>
</ul>
<blockquote>
<p>Figure 15-10 illustrates more clearly the mechanism of requesting, generating, receiving, and applying a delta-encoded document. The client has to tell the server which version of the page it has, that it is willing to accept a delta from the latest version of page, and which algorithms it knows for applying those deltas to its current version.</p>
</blockquote>
<ul>
<li><p>Figure 15-10은 델타 인코딩된 문서를 요청, 생성, 수신, 적용하는 매커니즘을 더 명확하게 나타내고 있습니다.</p>
</li>
<li><p>클라이언트는 어떤 버전의 페이지를 가지고 있으며 최신 버전의 페이지로부터 델타를 허용할 의사가 있는지, 현재 버전에 델타를 적용하기 위해서 어떤 알고리즘을 사용할수 있는지 알려야 합니다.</p>
</li>
</ul>
<blockquote>
<p>The server has to check if it has the client’s version of the page and how to compute deltas from the latest version and the client’s version (there are several algorithms for computing the difference between two objects). It then has to compute the delta, send it to the client, let the client know that it’s sending a delta, and specify the new identifier for the latest version of the page (because this is the version that the client will end up with after it applies the delta to its old version).</p>
</blockquote>
<ul>
<li><p>서버는 클라이언트가 보유한 페이지의 버전을 확인한 후 최신 버전과 클라이언트 버전 사이의 변경사항을 어떻게 계산할 것인지 정해야 합니다.</p>
</li>
<li><p>두 오브젝트간의 차이를 계산하는 알고리즘에는 몇 가지 종류가 있습니다.</p>
</li>
<li><p>서버가 변경사항을 계산하여 클라이언트에게 전송하고 알림으로써 클라이언트는 페이지의 최신 버전에 대해 새로운 식별자를 지정할 수 있습니다.</p>
</li>
<li><p>최신 버전은 클라이언트가 보유하고 있는 버전에 변경사항을 적용한 이후 최종적으로 확보할 버전이기 때문입니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/b6892f2a-1090-4f54-8084-d11bad47b271/image.png" alt=""></p>
<blockquote>
<p>The client uses the unique identifier for its version of the page (sent by the server in its previous response to the client in the ETag header) in an If-None-Match header. This is the client’s way of telling the server, “if the latest version of the page you have does not have this same ETag, send me the latest version of the page.” Just the If-None-Match header, then, would cause the server to send the client the full latest version of the page (if it was different from the client’s version).</p>
</blockquote>
<ul>
<li><p>클라이언트는 <code>If-None-Match</code> 헤더에 페이지 버전에 대한 고유한 식별자를 사용합니다(해당 식별자는 클라이언트에 대한 이전 응답의 ETag 헤더 내부에 포함되어 전송되었습니다).</p>
</li>
<li><p>이것은 클라이언트가 서버에게 &quot;동일한 ETag를 가지고 있지 않은 최신 페이지가 있다면 그것을 전송하라&quot;고 서버에게 요청하는 방식입니다.</p>
</li>
<li><p>만약 클라이언트와 버전이 동일하지 않고 <code>If-None-Match</code> 헤더만 있다면 서버는 클라이언트에게 전체 최신 페이지를 반환할 것입니다.</p>
</li>
</ul>
<blockquote>
<p>The client can tell the server, however, that it is willing to accept a delta of the page by also sending an A-IM header. A-IM is short for Accept-Instance-Manipulation (“Oh, by the way, I do accept some forms of instance manipulation, so if you apply one of those you will not have to send me the full document.”). In the A-IM header, the client specifies the algorithms it knows how to apply in order to generate the latest version of a page given an old version and a delta. The server sends back the following: a special response code (226 IM Used) telling the client that it is sending it an instance manipulation of the requested object, not the full object itself; an IM (short for Instance-Manipulation) header, which specifies the algorithm used to compute the delta; the new ETag header; and a Delta-Base header, which specifies the ETag of the document used as the base for computing the delta (ideally, the same as the ETag in the client’s If-None-Match request!). The headers used in delta encoding are summarized in Table 15-5.</p>
</blockquote>
<ul>
<li><p>클라이언트는 <code>A-IM</code> 헤더를 함께 전송함으로써 페이지의 델타를 승인할 의사가 있는지 서버에게 전달할 수 있습니다.</p>
</li>
<li><p><code>A-IM</code>은 Accept-Instance-Manipulation의 약자입니다.</p>
</li>
<li><p>Instance Manipulation의 일부 형태를 승인할 것이니 헤더에 명시한 형태 중 한 가지를 적용한다면 전체 문서를 전송할 필요가 없다는 뜻입니다.</p>
</li>
<li><p>클라이언트는 주어진 기존 문서와 델타를 통해 최신 버전을 생성하기 위해 어떤 알고리즘을 적용할 수 있는지 <code>A-IM</code> 헤더에 지정합니다.</p>
</li>
<li><p>서버는 특수한 응답 코드인 226 IM Used와 함께 응답을 반환합니다.</p>
</li>
<li><p>226 응답은 서버가 요청받은 오브젝트 전체를 전송하지 않고 Instance Manipulation 하여 전송하고 있음을 클라이언트에게 알립니다.</p>
</li>
<li><p>Instance Manipulation의 약자인 <code>IM</code> 헤더는 델타 연산에 사용되는 알고리즘을 지정합니다.</p>
</li>
<li><p>새로운 <code>ETag</code> 헤더와 델타 연산의 기반으로 사용된 문서의 ETag 값이 담긴 <code>Delta-Base</code> 헤더도 함께 전송합니다.</p>
</li>
<li><p>이상적으로 <code>Delta-Base</code>의 값은 클라이언트가 If-None-Match 요청으로 전송한 ETag(클라이언트가 현재 갖고 있는 문서)와 동일할 것입니다.</p>
</li>
<li><p>델타 인코딩에서 사용되는 헤더는 Table 15-5에 요약 기술하고 있습니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/ecaf72df-be90-4f49-ad39-564ba0bfb196/image.png" alt=""></p>
<hr>
<h3 id="instance-manipulations-delta-generators-and-delta-appliers">Instance Manipulations, Delta Generators and Delta Appliers</h3>
<blockquote>
<p>Clients can specify the types of instance manipulation they accept using the A-IM header. Servers specify the type of instance manipulation used in the IM header. Just what are the types of instance manipulation that are accepted, and what do they do? Table 15-6 lists some of the IANA registered types of instance manipulations.</p>
</blockquote>
<ul>
<li><p>클라이언트는 <code>A-IM</code> 헤더를 통해 사용 가능한 Instance Manipulation의 유형을 명시할 수 있습니다.</p>
</li>
<li><p>서버는 <code>IM</code> 헤더를 통해 Instance Manipulation의 유형을 지정합니다.</p>
</li>
<li><p>이때 허용되는 Instance Manipulation의 종류에는 어떤 것이 있고, 각각의 IM은 어떤 역할을 수행할까요?</p>
</li>
<li><p>Table 15-6에서 IANA에 등록된 Instance Manipulation의 몇 가지 유형들을 나열하고 있습니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/472894e3-a1a3-4067-9a73-2e4ae64731fd/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/c5769868-b9cc-4d76-82f0-5875904c6397/image.png" alt=""></p>
<blockquote>
<p>A “delta generator” at the server, as in Figure 15-10, takes the base document and the latest instance of the document and computes the delta between the two using the algorithm specified by the client in the A-IM header. At the client side, a “delta applier” takes the delta and applies it to the base document to generate the latest instance of the document. For example, if the algorithm used to generate the delta is the Unix diff -e command, the client can apply the delta using the functionality of the Unix ed text editor, because diff -e &lt;file1&gt; &lt;file2&gt; generates the set of ed commands that will convert &lt;file1&gt; into &lt;file2&gt;. ed is a very simple editor with a few supported commands. In the example in Figure 15-10, 5c says delete line 5 in the base document, and chisels.&lt;cr&gt;. says add “chisels.”. That’s it. More complicated instructions can be generated for bigger changes. The Unix diff -e algorithm does a line-by-line comparison of files. This obviously is okay for text files but breaks down for binary files. The vcdiff algorithm is more powerful, working even for non-text files and generally producing smaller deltas thandiff -e.</p>
</blockquote>
<ul>
<li><p>Figure 15-10에서 나타난 것처럼 서버의 &quot;델타 생성기&quot;는 베이스 문서와 문서의 최신 인스턴스를 취하여 둘 사이의 변경사항을 계산합니다.</p>
</li>
<li><p>이때 적용되는 방식은 클라이언트가 <code>A-IM</code> 헤더에 지정한 알고리즘입니다.</p>
</li>
<li><p>클라이언트 측의 &quot;델타 적용기&quot;는 델타를 베이스 문서에 적용하여 문서의 최신 인스턴스를 생성합니다.</p>
</li>
<li><p>예를 들어 델타 생성 알고리즘이 Unix diff -e 명령이라면 클라이언트는 Unix ed 텍스트 에디터의 기능을 활용하여 델타를 적용할 수 있습니다.</p>
</li>
<li><p>diff -e &lt;file1&gt;&lt;file2&gt;는 &lt;file1&gt;을 &lt;file2&gt;로 변환하는 ed 명령어의 집합을 생성하기 때문입니다.</p>
</li>
<li><p>ed는 지원되는 명령이 적은 매우 단순한 에디터입니다.</p>
</li>
<li><p>Figure 15-10의 예시에서 <code>5c</code>는 베이스 문서에서 5번 라인을 삭제하라는 뜻이고 <code>chisels.&lt;cr\&gt;.</code>은 &quot;chisels.&quot;을 추가하라는 뜻입니다.</p>
</li>
<li><p>그게 전부입니다. 더 복잡한 명령은 더 큰 변화를 유발할 수 있습니다.</p>
</li>
<li><p>Unix diff -e 알고리즘은 파일을 라인 단위로 비교합니다.</p>
</li>
<li><p>따라서 텍스트 파일에는 적합하지만 바이너리 파일에서 제대로 동작하지 않습니다.</p>
</li>
<li><p>vcdiff 알고리즘은 비텍스트 파일에 대해서도 동작하며 일반적으로 diff -e 방식에 비해 작은 델타를 생성하므로 더 강력한 방식입니다.</p>
</li>
</ul>
<blockquote>
<p>The delta encoding specification defines the format of the A-IM and IM headers in detail. Suffice it to say that multiple instance manipulations can be specified in these headers(along with corresponding quality values). Documents can go through multiple instance manipulations before being returned to clients, in order to maximize compression. For example, deltas generated by the vcdiff algorithm may in turn be compressed using the gzip algorithm. The server response would then contain the header IM: vcdiff, gzip. The client would first gunzip the content, then apply the results of the delta to its base page in order to generate the final document.</p>
</blockquote>
<ul>
<li><p>델타 인코딩 명세에서는 <code>A-IM</code> 헤더와 <code>IM</code> 헤더의 포맷을 상세히 정의하고 있습니다.</p>
</li>
<li><p>이 헤더들에 해당하는 Q 값과 함께 다중의 Instance MAnipulation을 지정할 수 있다고 이야기하면 충분합니다.</p>
</li>
<li><p>문서는 여러 Instance Manipulation 과정을 거쳐 가능한 한 압축되어 클라이언트에 반환됩니다.</p>
</li>
<li><p>예를 들어 vcdiff 알고리즘에 의해 생성된 델타가 gzip 알고리즘을 사용하여 압축될 수 있습니다.</p>
</li>
<li><p>서버의 응답은 <code>IM: vcdiff, gzip</code> 헤더를 포함할 것입니다.</p>
</li>
<li><p>클라이언트는 최종 문서를 생성하기 위해 콘텐츠에 대한 gunzip을 우선 수행한 후 베이스 페이지에 델타 연산의 결과를 적용할 것입니다.</p>
</li>
</ul>
<blockquote>
<p>Delta encoding can reduce transfer times, but it can be tricky to implement. Imagine a page that changes frequently and is accessed by many different people. A server supporting delta encoding must keep all the different copies of that page as it changes over time, in order to figure out what’s changed between any requesting client’s copy and the latest copy. (If the document changes frequently, as different clients request the document, they will get different instances of the document. When they make subsequent requests to the server, they will be requesting changes between their instance of the document and the latest instance of the document. To be able to send them just the changes, the server must keep copies of all the previous instances that the clients have.) In exchange for reduced latency in serving documents, servers need to increase disk space to keep old instances of documents around. The extra disk space necessary to do so may quickly negate the benefits from the smaller transfer amounts.</p>
</blockquote>
<ul>
<li><p>델타 인코딩은 전송 시간을 단축시키지만 구현이 까다로울 수 있습니다.</p>
</li>
<li><p>많은 사람들이 접근하고 자주 수정하는 페이지를 생각해봅시다.</p>
</li>
<li><p>델타 인코딩을 지원하는 서버는 페이지에 변화가 발생할 때마다 서로 다른 사본들을 모두 유지해야 합니다.</p>
</li>
<li><p>요청 클라이언트의 사본과 최신 사본 사이에 어떤 변경사항이 발생했는지 확인해야 하기 때문입니다.</p>
</li>
<li><p>만약 문서가 자주 변경된다면 서로 다른 클라이언트가 문서를 요청할 때마다 서로 다른 문서의 인스턴스를 불러올 것입니다.</p>
</li>
<li><p>클라이언트는 서버에 추가적인 요청을 전송할 때 자신이 가진 인스턴스와 최신 인스턴스 사이의 델타를 요청할 수 있습니다.</p>
</li>
<li><p>서버가 딱 변경사항만 전송할 수 있으려면 클라이언트가 보유한 이전 인스턴스에 대한 사본까지도 모두 가지고 있어야 합니다.</p>
</li>
<li><p>문서를 제공하는 데 있어 지연을 줄이기 위한 비용으로 오래된 문서를 유지할 수 있는 디스크 공간을 지불하는 셈입니다.</p>
</li>
<li><p>델타 인코딩을 수행하기 위해서는 추가적인 디스크 공간이 필수적입니다.</p>
</li>
<li><p>이는 적은 전송량으로 얻은 이점을 무효화 할 수 있습니다.</p>
</li>
</ul>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="delta-encoding-1">Delta Encoding</h3>
<p>: 전체 오브젝트 대신 변경사항만 송수신하여 전송을 최적화하는 HTTP 프로토콜의 확장 요소 (RFC 3229)</p>
<ul>
<li>Instance Manipulation의 일종</li>
<li>요청<ul>
<li><code>A-IM</code> : 사용 가능한 Instance Manipulation의 유형 정의<ul>
<li>vcdiff, diffe, gdiff, gzip, deflate, range, identity 등</li>
<li>한 헤더에 여러 IM을 나열할 수 있다 (여러 IM을 동시에 적용할 수 있다)</li>
</ul>
</li>
<li><code>If-None-Match</code> : 현재 클라이언트가 보유한 인스턴스의 ETag</li>
</ul>
</li>
<li>응답 (226 IM Used)<ul>
<li><code>IM</code> : 적용한 Instance Manipulation의 유형 정의</li>
<li><code>ETag</code> : Base + Delta로 생성될 최종 사본의 ETag</li>
<li><code>Delta-Base</code> : Base로 사용된 사본의 ETag</li>
</ul>
</li>
<li>Trade-off<ul>
<li>장점 : 인스턴스의 전송 시간 단축</li>
<li>단점 : 서버 측에서 사본 관리를 위한 추가적인 디스크 공간 필요</li>
</ul>
</li>
</ul>
<hr>
<p>읽다가 지쳐서 오늘 감상은 생략.... 힛히
다음 게시글부터는 <code>Chapter 16 Internationalization</code>으로 새롭게 시작합니다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] HTTP : The Definitive Guide "p362 ~ p365"]]></title>
            <link>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p362-p365</link>
            <guid>https://velog.io/@dvlp-sy/TIL-HTTP-The-Definitive-Guide-p362-p365</guid>
            <pubDate>Fri, 30 May 2025 06:52:00 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="chapter-15-entities-and-encodings">Chapter 15. Entities and Encodings</h1>
<p>(해석 또는 이해가 잘못된 부분이 있다면 댓글로 편하게 알려주세요.)</p>
<hr>
<h2 id="✏️-원문-번역">✏️ 원문 번역</h2>
<hr>
<h3 id="conditionals-and-validators">Conditionals and Validators</h3>
<blockquote>
<p>Each conditional works on a particular validator. A validator is a particular attribute of the document instance that is tested. Conceptually, you can think of the validator like the serial number, version number, or last change date of a document. A wise client in Figure 15-8b would send a conditional validation request to the server saying, “send me the resource only if it is no longer Version 1; I have Version 1.” We discussed conditional cache revalidation in Chapter 7, but we’ll study the details of entity validators more carefully in this chapter.</p>
</blockquote>
<ul>
<li><p>각각의 조건은 특정 Validator에 의해 동작합니다.</p>
</li>
<li><p>Validator는 테스트하려는 문서 인스턴스의 특정 속성입니다.</p>
</li>
<li><p>개념적으로는 Validator를 개념적으로 일련번호나 버전 번호, 혹은 문서의 가장 최근 변경 시각 정도로 이해할 수 있습니다.</p>
</li>
<li><p>Figure 15-8b에 나타난 똑똑한 클라이언트는 서버에게 조건부 검증 요청을 전송하고 있습니다.</p>
</li>
<li><p>&quot;나는 Version 1의 리소스를 가지고 있으니 더 이상 버전 1이 아닌 경우에만 리소스를 전달할 것&quot;을 요구합니다.</p>
</li>
<li><p>조건부 캐시 검증에 대해서는 Chapter 7에서 이야기하였지만, 이번 챕터에서는 Entity Validator에 대해 조금 더 상세히 설명합니다.</p>
</li>
</ul>
<blockquote>
<p>The If-Modified-Since conditional header tests the last-modified date of a document instance, so we say that the last-modified date is the validator. The If-None-Match conditional header tests the ETag value of a document, which is a special keyword or version-identifying tag associated with the entity. Last-Modified and ETag are the two primary validators used by HTTP. Table 15-4 lists four of the HTTP headers used for conditional requests. Next to each conditional header is the type of validator used with the header.</p>
</blockquote>
<ul>
<li><p><code>If-Modified-Since</code> 조건부 헤더는 문서 인스턴스의 최종 변경 일시를 확인하므로 최종 변경 일시를 Validator로 간주합니다.</p>
</li>
<li><p><code>If-None-Match</code> 조건부 헤더는 문서의 ETag 값을 확인합니다.</p>
</li>
<li><p>ETag는 엔티티에 연결된 특수한 키워드나 버전 식별 태그입니다.</p>
</li>
<li><p><code>Last-Modified</code>와 <code>ETag</code>는 HTTP에서 사용되는 두 가지 주요한 Validator입니다.</p>
</li>
<li><p>Table 15-4는 조건부 요청에 사용되는 4가지 HTTP 헤더를 나열하고 있습니다.</p>
</li>
<li><p>각각의 조건부 헤더 옆에는 헤더와 함께 사용되는 Validator의 타입이 옵니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/84576bed-3d9c-4b1c-a91c-d03abcf7617d/image.png" alt=""></p>
<blockquote>
<p>HTTP groups validators into two classes: weak validators and strong validators. Weak validators may not always uniquely identify an instance of a resource; strong validators must. An example of a weak validator is the size of the object in bytes. The resource content might change even thought the size remains the same, so a hypothetical byte-count validator only weakly indicates a change. A cryptographic checksum of the contents of the resource (such as MD5), however, is a strong validator; it changes when the document changes.</p>
</blockquote>
<ul>
<li><p>HTTP는 Validator를 Weak Validator, Strong Validator 두 종류로 그룹화합니다.</p>
</li>
<li><p>Weak Validator는 리소스의 인스턴스를 고유하게 식별하지 않을 수도 있는 반면 Strong Validator는 항상 인스턴스를 고유하게 식별합니다.</p>
</li>
<li><p>Weak Validator의 예시로는 바이트로 표현한 오브젝트의 크기가 있습니다.</p>
</li>
<li><p>리소스 콘텐츠가 동일한 크기를 유지하면서 변경될 수도 있다는 점에서 가상의 바이트 연산 Validator는 변경을 약하게 표시합니다.</p>
</li>
<li><p>하지만 암호학에서 MD5와 같은 콘텐츠의 체크섬은 Strong Validator에 해당합니다.</p>
</li>
<li><p>체크섬의 값은 문서가 변경되었을 때만 달라지기 때문입니다.</p>
</li>
</ul>
<blockquote>
<p>The last-modified time is considered a weak validator because, although it specifies the time at which the resource was last modified, it specifies that time to an accuracy of at most one second. Because a resource can change multiple times in a second, and because servers can serve thousands of requests per second, the last-modified date might not always reflect changes. The ETag header is considered a strong validator, because the server can place a distinct value in the ETag header every time a value changes. Version numbers and digest checksums are good candidates for the ETag header, but they can contain any arbitrary text. ETag headers are flexible; they take arbitrary text values (“tags”), and can be used to devise a variety of client and server validation strategies.</p>
</blockquote>
<ul>
<li><p>최종 변경 시각은 아무리 리소스가 마지막에 수정된 시각을 초 단위로 지정한다고 하더라도 Weak Validator로 여겨집니다.</p>
</li>
<li><p>리소스가 1초 내에 여러 차례 수정되었을 가능성이 있고, 서버 또한 1초 내에 수천 개의 요청을 발행할 수 있기 때문에 최종 변경 시각이 항상 모든 변경사항을 반영할 수는 없습니다.</p>
</li>
<li><p>ETag 헤더는 Strong Validator로 여겨집니다.</p>
</li>
<li><p>값이 변화할 때마다 서버는 ETag 헤더에 서로 다른 값을 지정합니다.</p>
</li>
<li><p>버전 번호와 다이제스트 체크섬이 ETag 헤더에 적합한 후보지만, 임의의 텍스트가 ETag 헤더에 포함될 수도 있습니다.</p>
</li>
<li><p>ETag 헤더는 유동적입니다.</p>
</li>
<li><p>임의의 텍스트 값을 사용하며, 다양한 클라이언트와 서버의 검증 전략을 고안하는 데 사용될 수 있습니다.</p>
</li>
</ul>
<blockquote>
<p>Clients and servers may sometimes want to adopt a looser version of entity-tag validation. For example, a server may want to make cosmetic changes to a large, popular cached document without triggering a mass transfer when caches revalidate. In this case, the server might advertise a “weak” entity tag by prefixing the tag with “W/”. A weak entity tag should change only when the associated entity changes in a semantically significant way. A strong entity tag must change whenever the associated entity value changes in any way.</p>
</blockquote>
<ul>
<li><p>클라이언트와 서버는 Entity-tag 검증을 더 느슨하게 하기를 원할 수도 있습니다.</p>
</li>
<li><p>예를 들어 서버는 거대하고 인기 있는 캐싱 문서에 외관상 미미한 차이가 발생했을 때 캐시의 재검증 요청으로 인해 막대한 전송량을 유발하지 않기를 바랍니다.</p>
</li>
<li><p>이런 경우 서버는 태그 앞에 &quot;W/&quot; 접두사를 붙여 &quot;약한&quot; 엔티티 태그임을 알릴 수 있습니다.</p>
</li>
<li><p>약한 엔티티 태그는 연관된 엔티티가 의미적으로 중요한 변경사항이 발생했을 때만 변화해야 합니다.</p>
</li>
<li><p>강한 엔티티 태그는 연관된 엔티티 값이 변경될 때마다 바뀌어야 합니다.</p>
</li>
</ul>
<blockquote>
<p>The following example shows how a client might revalidate with a server using a weak entity tag. The server would return a body only if the content changed in a meaningful way from Version 4.0 of the document:</p>
</blockquote>
<pre><code>GET /announce.html HTTP/1.1
If-None-Match: W/&quot;v4.0&quot;</code></pre><ul>
<li><p>위의 구문은 클라이언트가 약한 엔티티 태그를 사용하여 서버에 재검증을 수행하도록 요청하는 예시입니다.</p>
</li>
<li><p>서버는 Version 4.0 이후로 콘텐츠에 유의한 변화가 발생했을 때만 본문을 반환합니다.</p>
</li>
</ul>
<blockquote>
<p>In summary, when clients access the same resource more than once, they first need to determine whether their current copy still is fresh. If it is not, they must get the latest version from the server. To avoid receiving an identical copy in the event that the resource has not changed, clients can send conditional requests to the server, specifying validators that uniquely identify their current copies. Servers will then send a copy of the resource only if it is different from the client’s copy. For more details on cache revalidation, please refer back to “Cache Processing Steps” in Chapter 7.</p>
</blockquote>
<ul>
<li><p>요약하자면 클라이언트는 동일한 리소스에 한 번 이상 접근할 때 현재 보유하고 있는 사본이 여전히 최신의 것인지 결정해야 합니다.</p>
</li>
<li><p>그렇지 않다면 서버로부터 가장 최신 버전을 받아와야 합니다.</p>
</li>
<li><p>서버측에서 리소스의 변경이 발생하지 않아 동일한 사본을 받아오는 것을 방지하기 위하여 클라이언트는 서버에 조건부 요청을 전송할 수 있습니다.</p>
</li>
<li><p>조건부 요청에는 현재 사본을 고유하게 식별할 수 있는 Validator를 지정합니다.</p>
</li>
<li><p>서버는 보유중인 리소스가 클라이언트의 사본과 일치하지 않는 경우에만 리소스의 사본을 전송할 것입니다.</p>
</li>
<li><p>캐시 재검증에 대한 자세한 내용은 Chapter 7의 &quot;Cache Processing Steps&quot;를 확인하여 주시기 바랍니다.</p>
</li>
</ul>
<hr>
<h3 id="range-requests">Range Requests</h3>
<blockquote>
<p>We now understand how a client can ask a server to send it a resource only if the client’s copy of the resource is no longer valid. HTTP goes further: it allows clients to actually request just part or a range of a document.</p>
</blockquote>
<ul>
<li><p>이제 클라이언트가 가진 리소스의 사본이 더 이상 유효하지 않을 때만 서버에게 리소스를 요청하는 방식을 이해했습니다.</p>
</li>
<li><p>HTTP는 더 나아가 클라이언트가 문서의 일부분 혹은 특정 범위에 대해서만 요청할 수 있도록 지원하고 있습니다.</p>
</li>
</ul>
<blockquote>
<p>Imagine if you were three-fourths of the way through downloading the latest hot software across a slow modem link, and a network glitch interrupted your connection. You would have been waiting for a while for the download to complete, and now you would have to start all over again, hoping the same thing does not happen again.</p>
</blockquote>
<ul>
<li><p>갓 출시된 따끈따끈한 소프트웨어를 아주 느린 모뎀 연결을 통해서 75% 정도 다운로드 받았을 무렵 네트워크 결함으로 인해 연결이 중단되었다고 생각해봅시다.</p>
</li>
<li><p>여러분은 다운로드가 완료되기를 한참 기다렸다가, 똑같은 상황이 발생하지 않기를 기도하면서 계속해서 다운로드 버튼을 누를 것입니다.</p>
</li>
</ul>
<blockquote>
<p>With range requests, an HTTP client can resume downloading an entity by asking for the range or part of the entity it failed to get (provided that the object did not change at the origin server between the time the client first requested it and its subsequent range request). For example:</p>
</blockquote>
<pre><code>GET /bigfile.html HTTP/1.1
Host: www.joes-hardware.com
Range: bytes=4000-
User-Agent: Mozilla/4.61 [en] (WinNT; I)
...</code></pre><ul>
<li><p>범위 요청을 사용하는 HTTP 클라이언트는 다운로드에 실패한 엔티티의 일부분을 다시 요청함으로써 엔티티의 다운로드를 재개할 수 있습니다.</p>
</li>
<li><p>클라이언트가 처음 요청을 받은 시점부터 추가적인 범위 요청이 이루어지는 시간 동안 원본 서버에서 오브젝트가 변경되지 않았다는 것을 전제합니다.</p>
</li>
<li><p>범위 요청은 다음과 같이 전송할 수 있습니다.</p>
<pre><code>GET /bigfile.html HTTP/1.1
Host: www.joes-hardware.com
Range: bytes=4000-
User-Agent: Mozilla/4.61 [en] (WinNT; I)
...</code></pre></li>
</ul>
<blockquote>
<p>In this example, the client is requesting the remainder of the document after the first 4,000 bytes (the end bytes do not have to be specified, because the size of the document may not be known to the requestor). Range requests of this form can be used for a failed request where the client received the first 4,000 bytes before the failure. The Range header also can be used to request multiple ranges (the ranges can be specified in any order and may overlap)—for example, imagine a client connecting to multiple servers simultaneously, requesting different ranges of the same document from different servers in order to speed up overall download time for the document. In the case where clients request multiple ranges in a single request, responses come back as a single entity, with a multipart body and a Content-Type: multipart/byteranges header.</p>
</blockquote>
<ul>
<li><p>해당 예시에서 클라이언트는 처음 4000 바이트 이후로 문서의 나머지 부분에 대해 요청하고 있습니다.</p>
</li>
<li><p>요청자가 문서의 크기가 얼마인지 정확히 알 수 없는 경우도 있으므로 종료 바이트를 반드시 지정할 필요는 없습니다.</p>
</li>
<li><p>이러한 형태의 범위 요청은 클라이언트가 처음 4000바이트를 받고 난 후 실패한 요청에 대해 사용될 수 있습니다.</p>
</li>
<li><p>또한 Range 헤더는 여러 개의 요청 범위에 대해 사용될 수 있습니다.</p>
</li>
<li><p>각 범위의 순서는 상관이 없으며 범위가 겹칠 수도 있습니다.</p>
</li>
<li><p>여러 서버에 동시에 연결되어 있는 클라이언트가 문서의 전체 다운로드 시간을 최적화하기 위해 서로 다른 서버로부터 서로 다른 범위의 동일 문서를 요청한다고 가정해봅시다.</p>
</li>
<li><p>클라이언트가 하나의 요청에 여러 개의 범위를 요청하는 경우 응답은 multipart 본문과 <code>Content-Type: multipart/byteranges</code> 헤더를 가진 하나의 엔티티로 반환되어야 합니다.</p>
</li>
</ul>
<blockquote>
<p>Not all servers accept range requests, but many do. Servers can advertise to clients that they accept ranges by including the header Accept-Ranges in their responses. The value of this header is the unit of measure, usually bytes.* For example:</p>
</blockquote>
<pre><code>HTTP/1.1 200 OK
Date: Fri, 05 Nov 1999 22:35:15 GMT
Server: Apache/1.2.4
Accept-Ranges: bytes
...</code></pre><ul>
<li><p>모든 서버가 범위 요청을 허용하지는 않지만 대부분 허용하는 경향이 있습니다.</p>
</li>
<li><p>서버는 응답에 <code>Accept-Ranges</code> 헤더를 포함하여 범위 요청의 허용 여부를 클라이언트에게 전달해야 합니다.</p>
</li>
<li><p>이 헤더의 값은 측정 단위이며 일반적으로 bytes(바이트)가 사용됩니다.</p>
</li>
</ul>
<blockquote>
<p>Figure 15-9 shows an example of a set of HTTP transactions involving ranges.</p>
</blockquote>
<ul>
<li>Figure 15-9는 범위를 포함하는 HTTP 트랜잭션 집합의 예시를 나타냅니다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dvlp-sy/post/aebabc80-f3dd-4268-a4ed-4af252decc5a/image.png" alt=""></p>
<blockquote>
<p>Range headers are used extensively by popular peer-to-peer file-sharing client software to download different parts of multimedia files simultaneously, from different peers.</p>
</blockquote>
<ul>
<li><p>Range 헤더는 P2P 파일 공유 클라이언트 소프트웨어에서 널리 사용됩니다.</p>
</li>
<li><p>해당 소프트웨어는 멀티미디어 파일의 서로 다른 부분을 다양한 Peer로부터 동시에 다운로드 받을 수 있도록 지원합니다.</p>
</li>
</ul>
<blockquote>
<p>Note that range requests are a class of instance manipulations, because they are exchanges between a client and a server for a particular instance of an object. That is, a client’s range request makes sense only if the client and server have the same version of a document.</p>
</blockquote>
<ul>
<li><p>범위 요청은 클라이언트와 서버 사이에서 특정 오브젝트의 인스턴스를 교환한다는 점에서 Instance Manipulation의 일종이라는 점을 다시 한 번 강조합니다.</p>
</li>
<li><p>즉, 클라이언트의 범위 요청은 클라이언트와 서버가 동일한 버전의 문서를 보유하고 있을 때에만 올바르게 이루어질 수 있습니다.</p>
</li>
</ul>
<hr>
<h2 id="✏️-요약">✏️ 요약</h2>
<hr>
<h3 id="http-validator">HTTP Validator</h3>
<p>: 인스턴스의 변경을 감지하기 위한 검증 요소</p>
<ul>
<li>Weak Validator : 변경을 일부 허용하면서 엔티티 검증을 느슨하게 수행<ul>
<li>오브젝트의 크기 : 리소스 콘텐츠가 동일한 크기를 유지하면서 변경될 수 있다 (&lt;-&gt; 체크섬은 Strong Validator, 전송중 엔티티가 변경되지 않았음을 보장)</li>
<li><code>Last-Modified</code> : 밀리초 단위로 수정되었을 가능성이 있다 &amp; 서버가 밀리초 단위로 수천 개의 요청을 발행할 가능성이 있다</li>
</ul>
</li>
<li>Strong Validator : 변경을 허용하지 않으면서 엔티티 검증을 엄격하게 수행<ul>
<li><code>ETag</code> : 값이 변화할 때마다 서버가 서로 다른 ETag 값을 할당한다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="conditional-request-types">Conditional Request Types</h3>
<p>: Validator에 따른 클라이언트의 조건부 요청 유형</p>
<ul>
<li><code>If-Modified-Since</code> : <code>Last-Modifed</code> 헤더를 Validator로 사용 -&gt; 리소스가 마지막으로 변경된 시점 이후로 변경이 발생한 경우 리소스 요청 (Weak Validator)</li>
<li><code>If-Unmodified-Since</code> : <code>Last-Modifed</code> 헤더를 Validator로 사용 -&gt; 리소스가 마지막으로 변경된 시점과 이전 응답의 Last-Modified 헤더 값이 일치하는 경우에만 리소스 요청</li>
<li><code>If-Match</code> : <code>ETag</code> 헤더를 Validator로 사용 -&gt; 문서의 ETag 값이 일치하는 경우 리소스 요청 (Strong Validator)</li>
<li><code>If-None-Match</code> : <code>ETag</code> 헤더를 Validator로 사용 -&gt; 문서의 ETag 값이 일치하지 않는 경우 리소스 요청 (Strong Validator)<br>
** Entity Tag<ul>
<li>Weak Entity Tag : 엔티티에 유의한 변경이 있을 때만 새롭게 부여<pre><code>If-None-Match: W/&quot;v4.0&quot;</code></pre></li>
<li>Strong Entity Tag : 엔티티 값이 변경될 때마다 새롭게 부여<pre><code>If-None-Match: &quot;v4.0&quot;</code></pre></li>
</ul>
</li>
</ul>
<hr>
<h3 id="range-requests-1">Range Requests</h3>
<p>: 리소스의 특정 범위에 대해 요청하는 것</p>
<ul>
<li>서버 &gt; 클라이언트 범위 요청 허용 여부 전달 : <code>Accept-Ranges</code> 헤더 사용<pre><code>HTTP/1.1 200 OK
Date: Fri, 05 Nov 1999 22:35:15 GMT
Server: Apache/1.2.4
Accept-Ranges: bytes
...</code></pre></li>
<li>요청 : <code>Range</code> 헤더를 통해 범위 명시 (여러 범위 가능)<pre><code>GET /bigfile.html HTTP/1.1
Host: www.joes-hardware.com
Range: Range: byte=-100, byte=101-200
...</code></pre></li>
<li>응답 : 여러 범위에 대해 요청이 온 경우 <code>Content-Type: multipart/byteranges</code> 헤더를 가진 하나의 엔티티로 반환</li>
<li>활용<ul>
<li>다운로드 재개 : 다운로드가 중단되었을 때 엔티티 일부분을 다시 요청</li>
<li>병렬 다운로드 : 여러 서버에 서로 다른 범위를 요청하여 속도 최적화</li>
</ul>
</li>
</ul>
<hr>
<h2 id="✏️-감상">✏️ 감상</h2>
<hr>
<h3 id="범위-요청을-통한-동영상-스트리밍">범위 요청을 통한 동영상 스트리밍</h3>
<p>Range Request 섹션을 읽으면서 Transfer Encoding과 Range Request를 적절히 활용하면 (클라이언트 입장에서) 무한한 동영상 스트림을 빠른 속도로 전달할 수 있을 것 같다는 생각이 들었다. 물론.. 단순히 빠른 전송이 목적이라면 TCP 기반의 HTTP/1.1 프로토콜을 굳이굳이 쓸 필요는 없다고 생각한다. UDP 기반의 응용 계층 프로토콜 중에 더 나은 선택지가 있을 것이다.</p>
<p>하지만 이미 서버에 저장된 비디오를 조회하는 기능을 구현한다고 가정해보면, Range Request를 통해 여러 개의 분산된 서버로부터 일정 바이트 단위로 데이터를 불러오는 것이 더 나을 수도 있겠다는 생각이 든다. 유튜브를 볼 때 동영상이 버퍼링에 안 걸리는 것도 중요하지만, 봤던 부분을 다시 돌려 볼 수 있게 하는 것도 중요하다. Range Request는 이런 요구사항을 해결할 수 있는 강력한 도구다.</p>
<p>지금 내가 읽고 있는 책은 HTTP/1.1이지만 그 사이에 세상이 많이 달라져서(?) 최근에는 HTTP/3도 자주 사용되는 것으로 알고 있다. HTTP/3는 TCP를 걷어냈기 때문에 버퍼링 문제를 해결하면서, 기본적으로 HTTP 기반이기 때문에 범위 요청으로 동영상 스트림을 불러올 수 있다. 이 프로토콜은 진짜 개쩌는 친구다. 내가 동영상 스트리밍 기능을 포함하는 소프트웨어를 개발할 일이 있다면 HTTP/3에 딥다이브 해볼 의향이 있다.</p>
<p>찾아보니 Spring 프레임워크에서도 범위 요청을 처리할 수 있는 클래스가 제공되고 있다고 한다. 개발자가 직접 헤더를 추출한 후 범위에 따라 분기시켜서 콘텐츠를 전송할 수도 있고, FileSystemResource 과 같은 클래스를 통해 범위 요청을 자동으로 처리할 수도 있다. FileSystemResource 객체를 반환하는 경우 개발자가 관여할 필요없이 알아서 Range 헤더가 처리되고, 헤더의 유무에 따라 200이나 206 응답을 생성한다.</p>
]]></description>
        </item>
    </channel>
</rss>