요약
- RFC 3151은 XML 공개 식별자 문자열을 정규화한 뒤 공백, 구조 구분자, 리터럴 예약 문자를 결정론적인
urn:publicid:형태로 치환했다. 올바른 변환은 이름의 변형이었을 뿐, 유효한 소유자나 자원에 대한 증명은 아니었다. - 어휘적 동치는 의도적으로 좁게 정의되었다. 정규화 이후 두 네임스페이스 URN은 어휘적으로 동일할 때만 동등했다. 이름이 같아도 카탈로그 맥락, 검색된 바이트, 응용 프로그램 동작이 같다는 보장은 없었다.
- 해석(resolution)은 계속 복수로 남았다. 카탈로그, 로컬 경로 매핑, 내장 지식, 캐시가 모두 관여할 수 있었으므로, 리졸버 선택, 매핑, 검색, 파싱, 결과에는 URN 자체 이외의 근거가 필요했다.
영속성처럼 보이는 문자열이 URI 전용 세계를 만났다
XML 외부 엔티티는 두 개의 식별자를 가졌다. 시스템 식별자는 정의상 URI였고, 공개 식별자는 문자열이었다. 계승된 SGML 관행에서 시스템 식별자는 로컬 또는 시스템 고유의 위치를 가리키는 경우가 많았고, 공개 식별자가 더 이식성 있고 영속적인 이름을 제공했다.
이 구분은 새 규격들이 외부 식별자에 URI를 요구하기 시작하면서 흔들렸다. XSLT와 XML 는 맨 공개 식별자 문자열이 깔끔하게 들어맞지 않는 웹 아키텍처에 속했다. RFC 3151은 기존 이름을 버리지도 않았고, 모든 로컬 시스템 식별자가 영속화되었다고 가장하지도 않았다. 대신 공식 URN 네임스페이스publicid를 도입해 공개 식별자를 URI 구문으로 표현할 수 있게 했다.
URI 모양의 결과가 원본보다 더 권위 있어 보이기 때문에 이 구분은 놓치기 쉽다. 변환은 오래된 문자열에 운반 가능한 구문을 부여했을 뿐이다. 결과의 고유성과 영속성은 원래 공개 식별자의 것 그대로였다. 원본 소유자가 등록되지 않았거나 명명 정책이 허술하다면, 접두사가 그것을 고쳐 주지는 못했다.
이 RFC는 Informational 등급이었다. 인터넷 표준을 명시하지 않는다고 선언했고, 예제는 교육용이며 실제로 존재한다는 보장이 없었다. 이러한 지위 문장은 메커니즘의 경계에 속한다. 작동하는 변환 예는 알고리즘을 보여줄 뿐, 실제 네임스페이스 항목, 배치된 카탈로그, 접근 가능한 자원이 아니다.
정규화는 한 종류의 이력을 의도적으로 지웠다
치환에 앞서 XML 공개 식별자는 정규화되어야 했다. 공백, 탭, 캐리지 리턴, 줄 바꿈의 연속은 하나의 일반 공백으로 바뀌고, 앞뒤 공백은 사라졌다. RFC 3151은 인코딩을 논할 때 이 작업이 이미 끝났다고 가정했다.
이 규칙은 비교를 신뢰할 수 있게 했지만 무손실은 아니었다. 들여쓰기, 탭, 줄 바꿈만 다른 두 원본 캡처는 같은 정규화 문자열을 만들 수 있었다. URN만 남으면 원래의 공백 배치는 복원할 수 없었다. 따라서 정규화된 이름은 새로운 증거 아티팩트였지, 원본을 예쁘게 보여주는 표시가 아니었다.
공백은 이후+가 되었다. 정규화가 먼저 연속을 합치므로, 공백에서 생성된 인접한 플러스 기호는 규격을 따르는 출력에 나타날 수 없었다. 원본에 실제로 존재하던 플러스는 다른 경로를 거쳤다:%2B. 페이지에서는 사소한 차이지만 감사에서는 결정적이다. 하나의 플러스는 정규화된 공백을 기록하고, 다른 플러스는 리터럴 문자를 기록한다.
구현 근거는 원본 문자열, 문자 인코딩, 정규화된 문자열, 규칙 버전, 출력 바이트를 보관해야 한다. 최종 URN만 저장하는 데이터베이스는 이름을 비교할 수 있지만, 어떤 원본 공백이 버려졌는지, 정규화가 인코딩에 선행했는지는 설명할 수 없다.
구분자는 구조를 운반하되 검증하지 않았다
SGML은 정식 공개 식별자(FPI)를 구조화된 부분집합으로 정의했다. 일반적인 FPI는 소유자 식별자, 공개 텍스트 클래스, 설명, 언어 또는 지정 시퀀스, 선택적 표시 버전을 결합했다. 이중 슬래시가 다수의 필드를 구분했고, 이중 콜론은 구조화된 자료 안에 나타날 수 있었다. 소유자는-//나+//로 시작하는 경우가 많았다.
RFC 3151은 이 시각적 구조를 기계적으로 보존했다.//는:가 되었고,::는;가 되었다. 번역자가 전체 FPI 문법을 인식하거나 의미 필드 경계를 판단할 필요는 없었다. 유효한 FPI의 식별은 변환 알고리즘 밖의 일이었다.
이는 의도적으로 절제된 호환성 선택이었다. 소프트웨어는 SGML 권위 엔진을 내장하지 않고도 URI 전용 인터페이스를 통해 구조처럼 보이는 이름을 운반할 수 있었다. 동시에 출력이 증명하는 것도 한정된다.publicidURN의 콜론은 원본에//가 있었다는 증거일 수는 있지만, 원본이 유효한 FPI였거나 소유자가 등록되었거나 필드가 의미를 갖는다는 증명은 아니다.
리터럴 문자는 구분자와 구별 가능해야 했다.::밖의 리터럴 콜론은%3A,//밖의 리터럴 슬래시는%2F, 리터럴 세미콜론은%3B가 되었다. 아포스트로피, 물음표, 샵 기호, 퍼센트 기호도 퍼센트 인코딩을 받았다. 알고리즘은 치환 도입부의 구문과 이미 정규화된 이름에 있던 문자 사이의 가역적 구별을 보존했다.
따라서 증거 사슬에는 값뿐 아니라 위치도 포함된다. 순진한 전역 치환은 겹치는 쌍을 잘못된 순서로 소비하거나 리터럴 구분자를 구조로 착각할 수 있다. 테스트는 대표적인 정규화 입력을 왕복(round-trip)해야 하지만, 완벽한 왕복도 치환 계층만을 보증한다.
정확한 어휘 동일성이 동치 규칙의 전부였다
RFC 3151은 어휘 동치를 단호하게 정했다. 필수 원본 정규화 이후, 네임스페이스 안의 두 URN은 어휘적으로 동일할 때만 동등하다는 것이다. 대소문자 통합, 소유자 별칭, 의미 필드 비교, 동일 대상 추론은 제공하지 않았다.
이 좁음은 편리한 추측이 네임스페이스의 법칙이 되는 것을 막았다. 응용 프로그램이 로컬 카탈로그가 하나의 파일로 매핑한다는 이유만으로 두 표기, 두 이스케이프 방식, 두 소유자 문자열이 같은 이름이라고 조용히 판단할 수는 없었다. 카탈로그 정책은 그 다음 계층이었다.
또한 이름이 같다고 내용이 같은 것은 아니었다. RFC는 자원이 여러 공개 식별자를 가질 수 있음을 허용했다. 역의 문제도 가능했다. 어휘적으로 동일한 이름 하나가 서로 다른 카탈로그 스택, 기본 URI, 파일시스템, 캐시를 만나 다른 표현을 돌려줄 수 있었다. 이름 동일성, 매핑 동일성, 바이트 동일성, 동작 동일성은 네 개의 별개 검사였다.
이후 URI와 URN 규격들은 더 넓은 구문과 등록 체계를 바꿨다. 이는 파서와 레지스트리에 역사적 맥락을 제공할 뿐, 2001년 카탈로그가 무엇을 돌려주었는지 소급적으로 바꾸거나, 오래된 소유자를 검증하거나, 의미적 동치를 RFC 3151의 어휘적 동치로 바꾸지는 못한다.
네임스페이스는 소유자의 약점을 물려받았다
이 RFC는 모든 공개 식별자를 위한 중앙 할당 서비스를 만들지 않았다. 등록된 소유자 식별자를 갖는 정식 공개 식별자는 고유해야 했다. 비정식 식별자와 등록되지 않은 소유자의 FPI는 고유할 수도, 그렇지 않을 수도 있었으며, 문서는 어떤 집행 정책도 주장하지 않았다.
영속성도 같은 상속을 따랐다. 등록된 소유자는 비정식 문자열보다 강한 근거를 대체로 제공했지만, 네임스페이스는 하나의 영속성 정책으로 커버하기엔 용도가 너무 넓었다. 도메인 이름에서 등록된 소유자 식별자를 도출하는 IDN 방식은 도메인 이름의 영속성 약점을 적어도 물려받았다.
이것이 중요한 이유는 URN이라는 단어가 거짓 업그레이드 서사를 유발할 수 있기 때문이다. 허약한 공개 식별자를 인코딩한다고 소유자가 오래 살아남지 않는다. 소유자를 등록한다고 카탈로그가 온라인으로 유지되지 않는다. 정책이 있다고 발급된 이름이 실제로 고유했다는 증명은 아니다. 영속적인 이름이 그 아래 제공된 모든 표현을 보존하는 것도 아니다.
공개 식별자가 없는 자원은 먼저 해당 규칙에 따라 하나를 만들어야 했고, 그때에야 변환이publicidURN을 부여할 수 있었다. 자원이 여러 공개 식별자를 가질 수도 있다. 따라서 이름의 출처를 판단하려면 문자 자체 외에 발급 기록, 소유자 정책, 활성화 시각이 필요했다.
해석은 의도적으로 복수로 남았다
RFC 3151은 공개 식별자가 이미 해석되던 여러 방식을 기술했다. OASIS 카탈로그 파일은 공개 이름을 다른 식별자로 매핑할 수 있었다. 시스템은 구성 요소를 로컬 경로명 구성 요소로 매핑할 수 있었다. 소프트웨어는 알려진 공개 식별자의 고정 집합을 내장할 수 있었다. 캐시 같은 URI 고유 메커니즘도 관여할 수 있었다.
이는 공통 접두사 뒤에 숨은 하나의 글로벌 리졸버가 아니었다. 문맥적 메커니즘과 만나는 이식 가능한 이름이었다. 카탈로그 순서, 위임, 재작성 규칙, 기본 URI, 로컬 마운트, 네트워크 접근, 캐시 신선도가 모두 결과를 좌우할 수 있었다.
카탈로그 매치는 하나의 근거였다. 어떤 규칙이 대상을 선택했다는 기록이다. 검색은 또 다른 근거였다. 파일이나 응답이 바이트를 돌려주었다. 내용 동일성에는 다이제스트나 동등한 관찰이 필요했다. 파싱에는 실제 파서, 엔티티 정책, 버전이 필요했다. 응용 프로그램 성공에는 또 다른 관찰이 필요했다.resolved=true를 기록하는 것은 이 결정 사슬을 하나의 결론으로 압축하는 것이다.
이 문서는 검증 메커니즘을 규정하지 않았다. 보안 섹션도 일반적인 URN 사용과 해석 이외의 고려사항을 추가하지 않았다. 어느 문장도 소유자, 카탈로그, 캐시, 대상을 인증하지 않았다. 결정론적 인코더는 낡은 매핑, 치환된 로컬 파일, 침해된 응답, 취약한 파서와 공존할 수 있었다.
유용한 설계 통찰은 RFC 3151이 과잉 규격화를 피했다는 점이다. 기존 공개 이름을 URI 필드에 넣기 위해 필요한 최소한의 공유 다리를 제공하면서, 기존 카탈로그와 로컬 관행이 계속될 수 있도록 남겨둔 것이다. 이는 호환성을 장려했지만, 리졸버 출처 증명을 필수로 만들었다.
실행 동작은 완벽한 이름을 바로잡을 수 있었다
정규화된 공개 식별자가 완벽하게 치환되는 외부 엔티티를 생각해 보자. 파서는 사슬에서 첫 번째 카탈로그를 참조해 이름을 로컬 경로로 재작성하고 파일을 연다. 모든 구문 검사를 통과하면서 파일은 오래된 패키지 릴리스에 속할 수 있다. 어휘 URN은 올바르고, 매핑은 로컬 정책상 유효하지만, 바이트는 응용 프로그램에 맞지 않다.
또는 두 번째 기계가 같은 URN과 다른 카탈로그를 사용해 더 새로운 DTD를 돌려줄 수 있다. 이름은 동일하게 비교되지만 파서 동작은 갈라진다. 캐시는 소유자가 정책을 바꾼 뒤에도 이전 매핑을 유지할 수 있다. 내장 리졸버는 네트워크 자원이 사라진 뒤에도 계속 성공할 수 있다. 이 관찰 중 어느 하나가 전체 진실을 소유하지는 않는다.
실행 코드의 우위가 규격을 선택 사항으로 만들지는 않는다. 치환표는 URN이 정규화된 이름을 올바르게 운반하는지에 대한 권위이다. 실행 동작은 그다음 질문에 답한다. 어떤 리졸버가 돌았는지, 어떤 규칙이 매칭되었는지, 어떤 바이트가 도착했는지, 응용 프로그램이 무엇을 했는지. 각 계층은 앞 계층이 만든 과잉 주장을 바로잡을 수 있다.
따라서 역사적 성과는 정확하고 한정되어 있었다. 오래된 공개 이름은 위치를 가장하지 않으면서 URI 아키텍처로 넘어설 수 있었다. 그러나 구문 경계를 넘는 것이 자원으로 가는 여정을 끝내지는 않았다.
출처
회원 브리핑
프로필 심층 컨텍스트
올바른 멤버십 등급으로 로그인하면 전체 브리핑과 출처 노트를 볼 수 있습니다.
Strategic Circle 전용
Strategic Circle
모든 독자에게 공개됩니다. 가입 후 로그인하면 프로필 브리핑를 열람할 수 있습니다.
Strategic Circle 가입하기Leadership Alliance 전용
Leadership Alliance
자격을 갖춘 IP 자산 소유자 및 운영진을 위한 콘텐츠입니다. 로그인하면 Leadership Alliance 브리핑을 열람할 수 있습니다.
Leadership Alliance 가입하기





