-
Notifications
You must be signed in to change notification settings - Fork 1
RFC 3986
퍼센트 인코딩 메커니즘은 해당 옥텟의 해당 문자가 허용된 집합을 벗어나거나 컴포넌트의 구분 기호로 사용되거나 컴포넌트 내에서 사용되는 경우 컴포넌트에서 데이터 옥텟을 표현하는 데 사용됩니다. 퍼센트로 인코딩된 옥텟은 퍼센트 문자 "%"와 그 뒤에 해당 옥텟의 숫자 값을 나타내는 16진수 두 자리로 구성된 삼중 문자로 인코딩됩니다. 예를 들어 "%20"은 이진 옥텟 "00100000"의 퍼센트 인코딩(ABNF: %x20)이며, US-ASCII에서는 공백 문자(SP)에 해당합니다. 퍼센트 인코딩 및 디코딩이 적용되는 시기는 섹션 2.4에 설명되어 있습니다.
퍼센트 인코딩 = "%" 16진수 16진수
대문자 16진수 'A'부터 'F'까지는 각각 소문자 'a'부터 'f'까지와 동일합니다. 퍼센트 인코딩 옥텟에 사용되는 16진수 자릿수만 다른 경우 두 URI는 동일합니다. 일관성을 위해 URI 생성자와 정규화자는 모든 퍼센트 인코딩에 대해 대문자 16진수를 사용해야 합니다.
일반적인 상황에서 URI 내의 옥텟이 퍼센트 인코딩되는 유일한 경우는 구성 요소에서 URI를 생성하는 과정 중입니다. 이는 구현에서 하위 컴포넌트 구분자로 사용할 예약 문자와 데이터로 안전하게 사용할 수 있는 문자를 결정할 때입니다. 일단 생성된 URI는 항상 퍼센트 인코딩된 형태로 유지됩니다.
URI가 역참조될 때, 스키마별 역참조 프로세스에 중요한 컴포넌트와 하위 컴포넌트(있는 경우)를 파싱하고 분리해야 해당 컴포넌트 내의 퍼센트 인코딩된 옥텟을 안전하게 디코딩할 수 있으며, 그렇지 않으면 데이터가 컴포넌트 구분자로 오인될 수 있기 때문입니다. 유일한 예외는 예약되지 않은 집합의 문자에 해당하는 퍼센트 인코딩된 옥텟의 경우로, 언제든지 디코딩할 수 있습니다. 예를 들어, 물결표("") 문자에 해당하는 옥텟은 구형 URI 처리 구현에서 "%7E"로 인코딩되는 경우가 많으며, "%7E"는 해석을 변경하지 않고 ""로 대체할 수 있습니다.
퍼센트("%") 문자는 퍼센트 인코딩된 옥텟을 나타내는 역할을 하므로, 해당 옥텟이 URI 내에서 데이터로 사용되려면 "%25"로 퍼센트 인코딩되어야 합니다. 이미 디코딩된 문자열을 디코딩하면 퍼센트 데이터 옥텟이 퍼센트 인코딩의 시작 부분으로 잘못 해석될 수 있고, 이미 퍼센트 인코딩된 문자열을 퍼센트 인코딩하는 경우 그 반대의 경우도 발생할 수 있으므로 구현에서는 동일한 문자열을 두 번 이상 퍼센트 인코딩하거나 디코딩하지 않아야 합니다.
- 경로 컴포넌트는 일반적으로 계층적 형식으로 구성된 데이터를 포함하며, 비계층적 쿼리 컴포넌트(섹션 3.4)의 데이터와 함께 URI의 체계 및 명명 권한(있는 경우)의 범위 내에서 리소스를 식별하는 역할을 합니다.
- 경로는 첫 번째 물음표("?") 또는 숫자 기호("#") 문자 또는 URI의 끝으로 종료됩니다.
- URI에 권한 구성 요소가 포함된 경우 경로 구성 요소는 비어 있거나 슬래시("/") 문자로 시작해야 합니다.
- URI에 권한 구성 요소가 포함되어 있지 않은 경우 경로는 슬래시 문자("//") 두 개로 시작할 수 없습니다. 또한 URI 참조(섹션 4.1)는 상대 경로 참조일 수 있으며, 이 경우 첫 번째 경로 세그먼트는 콜론(":") 문자를 포함할 수 없습니다.
- ABNF는 이러한 경우를 명확히 구분하기 위해 5개의 개별 규칙을 요구하며, 이 중 하나만 주어진 URI 참조 내의 경로 부분 문자열과 일치합니다. 구문 분석기가 이러한 규칙 중 하나와 일치하는 URI 부분 문자열을 설명하기 위해 "경로 구성 요소"라는 일반적인 용어를 사용합니다.
path = path-abempty ; begins with "/" or is empty
/ path-absolute ; begins with "/" but not "//"
/ path-noscheme ; begins with a non-colon segment
/ path-rootless ; begins with a segment
/ path-empty ; zero characters
path-abempty = *( "/" segment )
path-absolute = "/" [ segment-nz *( "/" segment ) ]
path-noscheme = segment-nz-nc *( "/" segment )
path-rootless = segment-nz *( "/" segment )
path-empty = 0<pchar>
segment = *pchar
segment-nz = 1*pchar
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
; non-zero-length segment without any colon ":"
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
query = *( pchar / "/" / "?" )
fragment = *( pchar / "/" / "?" )
pct-encoded = "%" HEXDIG HEXDIG
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
- 경로는 슬래시("/") 문자로 구분된 일련의 경로 세그먼트로 구성됩니다. 경로는 항상 URI에 대해 정의되지만, 정의된 경로는 비어 있을 수 있습니다(길이가 0). 슬래시 문자를 사용하여 계층을 나타내는 것은 URI가 상대 참조의 컨텍스트로 사용될 때만 필요합니다.
- 예를 들어, URI mailto:fred@example.com은 경로가 "fred@example.com"인 반면, URI foo://info.example.com?fred은 경로가 비어 있습니다.
- 점 세그먼트라고도 하는 경로 세그먼트 "." 및 ".."는 경로 이름 계층 구조 내에서 상대 참조를 위해 정의됩니다. 이 세그먼트는 상대 경로 참조(4.2절)의 시작 부분에 사용하여 이름 계층 구조 트리 내에서 상대적인 위치를 표시하기 위한 것입니다. 이는 일부 운영 체제의 파일 디렉터리 구조에서 현재 디렉터리와 상위 디렉터리를 각각 나타내는 역할과 유사합니다. 그러나 파일 시스템과 달리 이러한 도트 세그먼트는 URI 경로 계층 구조 내에서만 해석되며 해석 프로세스의 일부로 제거됩니다(섹션 5.2).
- 계층적 경로의 점 세그먼트를 제외하고 경로 세그먼트는 일반 구문에서 불투명하게 간주됩니다. URI를 생성하는 애플리케이션은 종종 세그먼트에서 허용되는 예약 문자를 사용하여 스키마별 또는 역참조 핸들러별 하위 컴포넌트를 구분합니다. 예를 들어 세미콜론(";") 및 등호("=") 예약 문자는 해당 세그먼트에 적용되는 매개변수 및 매개변수 값을 구분하는 데 자주 사용됩니다. 쉼표(",") 예약 문자도 비슷한 용도로 자주 사용됩니다. 예를 들어, 한 URI 제작자는 "name;v=1.1"과 같은 세그먼트를 사용하여 "name"의 버전 1.1에 대한 참조를 나타내는 반면, 다른 제작자는 "name,1.1"과 같은 세그먼트를 사용하여 동일한 것을 나타낼 수 있습니다. 매개변수 유형은 스키마별 의미론에 의해 정의될 수 있지만, 대부분의 경우 매개변수의 구문은 URI의 역참조 알고리즘 구현에 따라 달라집니다.
- 쿼리 컴포넌트에는 Path 컴포넌트(섹션 3.3)의 데이터와 함께 URI의 체계 및 명명 권한(있는 경우)의 범위 내에서 리소스를 식별하는 역할을 하는 비계층적 데이터가 포함됩니다. 쿼리 컴포넌트는 첫 번째 물음표("?") 문자로 표시되고 숫자 기호(" #") 문자 또는 URI의 끝으로 끝납니다.
query = *( pchar / "/" / "?" )
- 슬래시("/")와 물음표("?")는 쿼리 컴포넌트 내의 데이터를 나타낼 수 있습니다.
- 일부 오래된 잘못된 구현에서는 계층 구분 기호를 찾을 때 쿼리 데이터와 경로(path) 데이터를 구분하지 못하기 때문에 이러한 데이터를 상대 참조의 기본 URI(Base URI for Relative References**)**로 사용할 때 올바르게 처리하지 못할 수 있습니다(섹션 5.1).
- 그러나 쿼리 구성 요소는 종종 "키=값" 쌍의 형태로 식별 정보를 전달하는 데 사용되며 자주 사용되는 값 중 하나가 다른 URI에 대한 참조이므로 이러한 문자를 퍼센트 인코딩하지 않는 것이 사용 편의성을 위해 더 나은 경우가 있습니다.
- URI의 조각 식별자 컴포넌트는 기본 리소스 및 추가 식별 정보를 참조하여 보조 리소스를 간접적으로 식별할 수 있게 해줍니다. 식별된 보조 리소스는 기본 리소스의 일부 또는 하위 집합, 기본 리소스의 표현에 대한 일부 보기, 또는 해당 표현에 의해 정의되거나 설명되는 다른 리소스일 수 있습니다. 조각 식별자 구성 요소는 숫자 기호("#") 문자가 있는 것으로 표시되며 URI의 끝으로 끝납니다.
fragment = *( pchar / "/" / "?" )
- 조각 식별자의 의미는 기본 리소스에 대한 검색 작업으로 인해 발생할 수 있는 표현 집합에 의해 정의됩니다. 따라서 조각의 형식과 해상도는 URI가 역참조된 경우에만 검색이 수행되더라도 잠재적으로 검색될 수 있는 표현의 미디어 유형[RFC2046]에 따라 달라집니다. 그러한 표현이 존재하지 않으면 조각의 의미는 알 수 없는 것으로 간주되며 사실상 제약이 없는 것으로 간주됩니다. 조각 식별자 의미는 URI 스킴과 독립적이므로 스킴 사양으로 재정의할 수 없습니다.
- 개별 미디어 유형은 해당 미디어 유형에서 보조 리소스로 식별할 수 있는 다양한 유형의 하위 집합, 보기 또는 외부 참조를 지정하기 위해 조각 식별자 구문 내에서 자체적인 제한 사항이나 구조를 정의할 수 있습니다. 검색 요청의 속성에 따라 표현이 선택되는 리소스(콘텐츠 협상이라고도 함)의 경우처럼 기본 리소스에 여러 가지 표현이 있는 경우, 조각으로 식별되는 것은 모든 표현에 걸쳐 일관성이 있어야 합니다. 각 표현은 조각이 어떻게 표현되는지에 관계없이 동일한 보조 리소스에 해당하도록 조각을 정의하거나 조각을 정의되지 않은 상태(즉, 찾을 수 없음)로 남겨 두어야 합니다.
- 다른 URI와 마찬가지로 조각 식별자 컴포넌트를 사용한다고 해서 검색 작업이 수행된다는 의미는 아닙니다. 조각 식별자가 포함된 URI는 기본 리소스에 액세스할 수 있거나 액세스할 것이라는 암시 없이 보조 리소스를 참조하는 데 사용될 수 있습니다.
- 조각 식별자는 정보 검색 시스템에서 클라이언트 측 간접 참조의 주요 형태로서 특별한 역할을 하며, 작성자가 리소스 소유자가 간접적으로만 제공하는 기존 리소스의 측면을 구체적으로 식별할 수 있게 해줍니다. 따라서 조각 식별자는 URI의 스키마별 처리에 사용되지 않고, 대신 조각 식별자는 역참조 전에 나머지 URI와 분리되며, 따라서 조각 자체 내의 식별 정보는 URI 스키마에 관계없이 사용자 에이전트에 의해 단독으로 역참조됩니다. 이러한 별도의 처리는 시간이 지남에 따라 리소스가 이동함에 따라 참조의 정확한 리디렉션을 위해 종종 정보 손실로 인식되지만, 정보 제공자가 참조 작성자가 리소스 내의 정보를 선택적으로 참조할 수 있는 권리를 거부하는 것을 방지하는 역할도 합니다. 또한 간접 참조는 새로운 미디어 유형을 정의하고 배포하기가 새로운 식별 체계보다 쉽기 때문에 URI를 사용하는 시스템에 추가적인 유연성과 확장성을 제공합니다.
- 슬래시("/") 및 물음표("?") 문자는 조각 식별자 내의 데이터를 나타낼 수 있습니다. 이 데이터를 상대 참조의 기본 URI로 사용할 때 일부 오래된 잘못된 구현에서는 이 데이터를 올바르게 처리하지 못할 수 있습니다(섹션 5.1).
-
의사 코드는 참조된 경로에서 특수한 "." 및 ".." 전체 경로 세그먼트를 해석하고 제거하기 위한 "remove_dot_segments" 루틴을 참조하기도 합니다.
-
이 작업은 경로가 상대 경로인지 여부에 관계없이 참조에서 경로를 추출한 후에 수행되며, 대상 URI를 형성하기 전에 유효하지 않거나 불필요한 도트 세그먼트를 제거하기 위해 수행됩니다.
-
이 제거 프로세스를 수행하는 방법은 여러 가지가 있지만, 여기서는 두 개의 문자열 버퍼를 사용하는 간단한 방법을 설명합니다.
-
입력 버퍼는 이제 추가된 경로 구성 요소로 초기화되고 출력 버퍼는 빈 문자열로 초기화됩니다.
-
입력 버퍼가 비어 있지 않은 동안 다음과 같이 반복합니다:
A. 입력 버퍼가 접두사 "../" 또는 "./"로 시작하면 입력 버퍼에서 해당 접두사를 제거하고, 그렇지 않으면 다른 조치를 취하세요.
B. 입력 버퍼가 접두사 "/./" 또는 "/."로 시작하는 경우(여기서 "."는 완전한 경로 세그먼트), 입력 버퍼에서 해당 접두사를 "/"로 바꾸고, 그렇지 않으면 다른 조치를 취하세요.
C. 입력 버퍼가 "/../" 또는 "/.."의 접두사로 시작하는 경우, 여기서 ".."는 완전한 경로 세그먼트인 경우, 입력 버퍼에서 해당 접두사를 "/"로 바꾸고 출력 버퍼에서 마지막 세그먼트와 그 앞의 "/"(있는 경우)를 제거합니다,
D. 입력 버퍼가 "." 또는 ".."로만 구성된 경우 입력 버퍼에서 해당 부분을 제거하고, 그렇지 않은 경우 다른 조치를 취하세요.
E. 입력 버퍼의 첫 번째 경로 세그먼트를 초기 "/"를 포함하여 출력 버퍼의 끝으로 이동합니다.
-
마지막으로, 출력 버퍼는 remove_dot_segments의 결과로 반환됩니다.
-
-
도트 세그먼트는 기본 URI의 이름 계층 구조에 상대적인 식별자를 표현하기 위해 URI 참조에 사용하기 위한 것입니다.
-
remove_dot_segments 알고리즘은 여분의 도트 세그먼트를 오류로 처리하거나 역참조 구현에서 잘못 해석하도록 두지 않고 제거함으로써 해당 계층 구조를 존중합니다.
-
다음은 병합된 경로의 두 가지 예에 대해 위의 단계를 적용하여 각 단계 이후의 두 버퍼의 상태를 보여주는 예시입니다.
-
일부 애플리케이션에서는 문자열이 아닌 두 개의 세그먼트 스택을 사용하여 remove_dot_segments 알고리즘을 구현하는 것이 더 효율적일 수 있습니다.
-
참고: 일부 오래된 잘못된 구현에서는 기본 경로와 참조 경로를 병합하기 전에 참조의 쿼리 구성 요소를 경로 구성 요소에서 분리하지 못하여 쿼리 구성 요소에 "/../" 또는 "/./" 문자열이 포함된 경우 상호 운용성 실패를 초래할 수 있으므로 주의하세요.
- 허용 함수 정리
- 소켓 프로그래밍
- CGI
- 가상 호스트
- NGINX autoindex 동작 정리
- HTTP Request 파싱
- HTTP Request 값 유효성 검사
- Config 파일 Parsing