--- title: "official-doc / RFC 3986 — URI Generic Syntax (Berners-Lee et al., IETF, January 2005)" source_type: official-doc url: https://www.rfc-editor.org/rfc/rfc3986 archive_url: related_branches: [feature-resource-identifier-contract] related_projects: [ca-skeleton] tags: [official-doc, ca-skeleton, api-design, networking, api-contract] created: 2026-05-31 --- # RFC 3986 — URI Generic Syntax > Layer: `raw/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**. > 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. ## Parent / 활용 branch (필수, 최소 1개+) > 이 자료는 **혼자 존재하지 않는다.** 어느 branch의 구현 결정의 **근거**로서 보관됨. | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-resource-identifier-contract]] | D2 (charset / encoding) — URL path 에서 안전한 문자 집합 정의 + D3 (URL-safe + case sensitivity) — `unreserved` 문자 집합 정의 및 scheme·host 는 case-insensitive, path 는 case-sensitive 라는 normalization 규칙 | ## 출처 / Source - 원본 URL: https://www.rfc-editor.org/rfc/rfc3986 - 아카이브 URL: (미설정) - 저자 / 조직: Tim Berners-Lee, Roy T. Fielding, Larry Masinter — IETF (Internet Engineering Task Force) - 발행일: January 2005 (Standards Track, STD 66) - 마지막 확인일: 2026-05-31 ## 왜 저장했는지 / Why archived ca-skeleton 의 resource ID 형식 결정 (branch: `feature-resource-identifier-contract`) 에서 URL path 에 허용된 문자 집합과 대소문자 정규화 규칙을 normative standard 로 확정해야 한다. RFC 3986 은 URI generic syntax 의 IETF 표준 사양이며, `unreserved` 문자 집합 (`ALPHA / DIGIT / "-" / "." / "_" / "~"`) 과 path component 의 case-sensitivity 정책을 규범적으로 정의하므로 D2·D3 결정의 최고 등급 근거(`official-standard`)로 보관한다. ## 핵심 인용 / Key quotes (verbatim, 5문장) > [§2.3] "Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde." > [§2.3 ABNF] `unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"` > [§2.2] "URIs that differ in the replacement of a reserved character with its corresponding percent-encoded octet are not equivalent. Percent-encoding a reserved character, or decoding a percent-encoded octet that corresponds to a reserved character, will change how the URI is interpreted by most applications." > [§6.2.2.1] "When a URI uses components of the generic syntax, the component syntax equivalence rules always apply; namely, that the scheme and host are case-insensitive and therefore should be normalized to lowercase." > [§6.2.2.1] "The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3)." ## Claims Extracted / 추출된 주장 > 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기에 쓰지 않는다. | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | RFC3986-C1 | URI 에서 예약 목적 없이 사용할 수 있는 문자(unreserved)는 ALPHA, DIGIT, 하이픈, 마침표, 밑줄, 물결표이며 ABNF 로 `ALPHA / DIGIT / "-" / "." / "_" / "~"` 로 정의된다 | [§2.3] "Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde." + ABNF `unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"` | `official-standard` | RFC 3986 을 따르는 모든 URI | base64 표준(+, /, =), base62(대소문자+숫자만) 등 다른 encoding 의 URL-safety 를 직접 평가하지 않음 | | RFC3986-C2 | reserved 문자를 percent-encode 하거나 reserved 문자에 해당하는 percent-encoded octet 을 decode 하면 URI 의 의미가 달라진다 | [§2.2] "URIs that differ in the replacement of a reserved character with its corresponding percent-encoded octet are not equivalent. Percent-encoding a reserved character, or decoding a percent-encoded octet that corresponds to a reserved character, will change how the URI is interpreted by most applications." | `official-standard` | URI 에서 gen-delims / sub-delims 를 데이터로 사용해야 하는 모든 경우 | reserved 문자의 구체적인 처리 방식(scheme-specific 허용 여부)은 각 scheme 사양에서 정의됨 | | RFC3986-C3 | URI path component (및 기타 generic syntax component) 는 scheme 이 달리 정의하지 않는 한 case-sensitive 로 가정해야 한다 | [§6.2.2.1] "The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3)." | `official-standard` | HTTP(S) URI path 를 비교·normalize 해야 하는 모든 구현 | scheme 이 명시적으로 case-insensitive 를 선언한 component 에는 적용되지 않음 | | RFC3986-C4 | scheme 과 host component 는 case-insensitive 이므로 lowercase 로 normalize 해야 한다 | [§6.2.2.1] "When a URI uses components of the generic syntax, the component syntax equivalence rules always apply; namely, that the scheme and host are case-insensitive and therefore should be normalized to lowercase." | `official-standard` | 모든 RFC 3986 준수 URI 구현 | path / query / fragment 에는 이 case-insensitive 규칙이 적용되지 않음 | | RFC3986-C5 | URI path 의 pchar 는 unreserved / pct-encoded / sub-delims / ":" / "@" 로 구성된다 | [§3.3 ABNF] `pchar = unreserved / pct-encoded / sub-delims / ":" / "@"` | `official-standard` | URI path segment 에 포함될 수 있는 문자를 결정해야 하는 구현 | pchar 에 sub-delims (!, $, &, ' 등) 포함이 허용된다고 해서 resource ID 에 자유롭게 사용해도 됨을 의미하지 않음 — ID 의 ID format policy 는 별도 결정 필요 | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것:** - RFC3986-C1: URL path 에 percent-encoding 없이 안전하게 사용할 수 있는 문자는 정확히 `ALPHA / DIGIT / "-" / "." / "_" / "~"` 임. - RFC3986-C2: `+`, `/`, `=` (base64 standard charset) 는 reserved 또는 non-unreserved 문자이므로 path segment 에 raw 사용 불가. URL-safe base64 (`-`, `_`) 는 unreserved 에 포함됨. - RFC3986-C3: HTTP URI path (resource ID 포함) 는 case-sensitive 이며, `abc` 와 `ABC` 는 다른 자원을 가리킬 수 있음. - RFC3986-C4: `http://` 와 `HTTP://`, `example.com` 과 `EXAMPLE.COM` 은 동등하게 정규화되어야 함. - RFC3986-C5: path segment 에 허용되는 전체 문자 집합의 상한(pchar). - **이 자료가 증명하지 않는 것:** - 특정 ID format (UUID, ULID, NanoID 등) 중 무엇을 선택해야 하는지 — 그것은 ID format policy 결정. - base32 Crockford 나 base62 같은 encoding 이 RFC 3986 unreserved charset 의 부분집합인지 — 추가 분석 필요 (단, RFC3986-C1 의 chareset 정의로 부분집합 여부 판정 가능). - case-insensitive ID format (예: ULID base32) 을 lowercase normalize 해야 하는지 여부 — RFC 는 path 가 case-sensitive 라고만 말하며, 어플리케이션 레벨 normalize 정책은 추가 결정 사항. - percent-encoding 을 실제로 수행해야 하는 시점의 구체적인 구현 방법. - **ca-skeleton 에 적용하려면 추가 확인이 필요한 것:** - ULID 의 Crockford base32 charset (`0-9A-Z`, case-insensitive) 이 RFC3986-C1 unreserved 의 부분집합임을 확인 (ALPHA + DIGIT 이므로 부분집합이지만, uppercase 고정 시 path case-sensitive 규칙과의 정합 확인 필요). - NanoID 기본 charset (`A-Za-z0-9_-`) 이 RFC3986-C1 unreserved 의 부분집합임을 확인 (`_`, `-` 포함이므로 부분집합). - base64 standard (`+/=`) 를 포함하는 ID format 사용 금지 — RFC3986-C1·C2 로 직접 차단. ## 메모 / Notes - RFC 3986 은 2005년 발행 STD 66 으로, 현재까지 HTTP URI 의 normative standard. HTTP/1.1, HTTP/2, HTTP/3 모두 이 spec 을 참조함. - `unreserved` charset 에 `~` (tilde) 가 포함되어 있음 — 일부 legacy 구현이 `%7E` 로 인코딩하는 경우가 있으나 RFC3986-C1 에 따르면 decode 되어야 함 (§6.2.2.2 Percent-Encoding Normalization 참조). - path 의 경우 `pchar` (C5) 에 sub-delims 포함이 허용되지만, resource ID 는 delimiter 로 오해될 가능성을 배제하기 위해 unreserved charset 만 사용하는 것이 safe subset 전략. - 추가로 봐야 할 동일 출처 섹션: §6.2.2.2 Percent-Encoding Normalization (unreserved 문자의 percent-encoded octet decode 권고), §6.2.2.3 Path Segment Normalization (dot-segment 제거). ## Related / 관련 - 같은 주제 다른 official-doc (예정): - [[raw/official-docs/rfc9562-uuid.md]] — UUID v4·v7 format spec (D1 결정 근거) - [[raw/official-docs/ulid-spec.md]] — ULID 26자 base32 + monotonic spec (D1 결정 근거) - [[raw/official-docs/google-aip-122-resource-names.md]] — Google AIP-122 resource name 정책 (D6 prefix 정책 참조) - 이 자료를 인용할 wiki 요약: `wiki/concepts/uri-charset-and-case-normalization` (생성 시)