Files
llm-wiki/raw/official-docs/rfc3986-uri-generic-syntax.md

95 lines
9.3 KiB
Markdown

---
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` (생성 시)