요약

  • RFC 3510은 인터넷 인쇄 프로토콜(IPP) 서비스와 Job에 절대ipp:로케이터를 부여했지만, Job URL에서 그 Job을 만든 프린터 URL로 되돌아가는 변환은 명시되지 않았다고 분명히 밝혔다.
  • 경로 구성 요소를 하나 추가하는 것은 상호 운용성을 개선했을 뿐, Job URL을 영속적으로 만들거나, 엔드포인트를 인증하거나, 요청 수락을 증명하거나, 용지가 장비에서 나왔음을 보여 주지 않았다.

RFC 3510에서 가장 많은 것을 드러내는 문장은 표준 문서치고는 이례적으로 직설적이다.job-printer-uri에 대한 이전 설명은 Job URI만 있는 상황에서 클라이언트가 그 Job을 만든 프린터를 식별할 수 있게 해 준다고 했다. RFC 3510은 그 진술이 거짓이라고 답했다. IPP 모델도, 그 전송 명세도 역방향 변환을 정의하지 않았던 것이다.

이 정정은 주소를 읽는 방식의 일반적 약점을 드러낸다. 로케이터는 인터페이스에 도착할 때 영수증처럼 보이는 경우가 많다. 스킴, 호스트, 경로, 때로는 내구성 있는 기록처럼 보이는 번호까지 갖추고 있다. 그러나 각 구성 요소는 네이밍과 전송 계약에 속할 뿐, 문자열에서 사람들이 추론하는 운영 이력을 자동으로 증명해 주는 것은 하나도 없다.

2003년 4월에 Standards Track으로 발행된 RFC 3510은 RFC 2910의 IPP URL 절을 확장하고 명확히 했다. 그 임무는 의도적으로 좁았다.ipp:스킴이 적용되는 범위를 정의하고, 기본 포트로 631을 지정하고, 스킴을application/ipp와 연결하고, 인코딩과 구문을 명세하고, 그런 URL의 비교 방식을 정했다. 새 URL 매개변수는 하나도 추가하지 않았다.

이 스킴은 IPP 인쇄 서비스나 그 서비스가 관리하는 네트워크 자원, 예컨대 Job을 이름 지을 수 있었다. 절대 URL만 허용되었고, 상대 IPP URL은 금지되었다. 이 스킴은 RFC 2911의 추상 모델을 RFC 2910이 정의한 HTTP 전송에 묶었다. 다른 전송 바인딩이라면 다른 스킴이 필요했다. 이 구분이 중요한 이유는ipp:가 단순히 "어딘가의 인쇄"를 뜻하는 것이 아니라, 특정한 방식으로 운반되는 특정한 프로토콜 모델을 이름 지었기 때문이다.

URL이 포트를 생략하면 클라이언트는 그것을 631로 해석해야 했다. 비교를 위해 비어 있거나 없는 포트는 명시적:631과 동등했다. 경로가 없으면 HTTP Request-URI는/가 되었다. 해당 메시지는application/ipp미디어 타입을 사용했다. 이 규칙들은 피할 수 있는 불일치를 제거했다. 두 철자가 같은 엔드포인트를 가리킬 수 있고, 클라이언트는 어떤 초기 전송 가정을 해야 하는지 알 수 있었다.

그러나 경로는 물리적 토폴로지를 기술하지 않았다. RFC 3510의 예시는 여러 프린터 URL을 같은 호스트에 둔다. 한 경로는 물리 장비를, 다른 경로는 부하 분산 스풀러를, 또 다른 경로는 프린터 집합을 나타낼 수 있고, 나머지 둘은 한 장비에서 서로 다른 사람 수신자를 위한 큐일 수 있다. 모두 논리적으로 독립적인 IPP 프린터 객체처럼 동작한다.

대문자로 쓰인 이 단어가 중요하다. IPP 프린터는 Job이나 연산을 받아들이는 소프트웨어 객체다. 스풀러, 게이트웨이, 물리 프린터 위에 존재할 수 있다. 그 객체에 도달하는 URL은 어느 하드웨어가 최종적으로 용지에 표시할지, 작업이 다른 곳에서 분산될지, 사람의 큐가 목적지를 결정할지를 드러내지 않는다. 네이밍 계층은 물리적 투명성을 약속하지 않으면서 논리적 독립성만을 보존한다.

Job URL은 이 한계를 더 선명하게 만든다. Print-Job 응답은ipp://example.com/printer/123같은 것을 반환할 수 있다. 시각적 중첩은 클라이언트에게/123을 떼어 내고 나머지가 Job을 만든 프린터라고 가정하도록 유도한다. 그러나 RFC 2911은 정확한 형식이 구현에 의존한다고 선언해 두었다. 그리하여 RFC 3510은 제출된printer-uri와 반환된job-uri사이의 관계 역시 구현에 의존한다고 말했다.

그 해법은 관행이었다. 규격을 따르는 프린터는 해당 프린터 URL에 정확히 하나의 경로 구성 요소를 추가함으로써 Job URL을 생성하는 것을권고(SHOULD)했다. 이는 그 권고를 따르기로 한 구현을 위한 예측 가능한 순방향 규칙을 만든다. 이미 유통 중인 모든 URL에 대한 보편적 정리가 아니다.SHOULD는 정당한 예외를 허용하며, 오래된 구현은 다를 수 있고, 게이트웨이는 다른 곳에서 물려받은 네이밍 체계를 노출할 수도 있다.

권고된 관행 안에서라도 맥락이 중요하다. 클라이언트는 실제로 사용한printer-uri, 반환된job-uri, 인증된 서버 신원, 응답, 시각을 보존해야 한다. 사후 문자열 조작은 거래 기록보다 약한 근거다. 경로 구성 요소는 복사되거나 프록시되거나 재할당될 수 있지만, 캡처된 요청-응답 쌍은 어느 교환에서 누가 그 이름을 발행했는지 말해 준다.

시간은 이름을 더욱 제한한다. RFC 3510은 Job URL이 Job 완료까지, 그리고 그 이후 구현이 정의한 지속 기간까지 유효하고 의미를 갖는다고 말한다. 따라서 북마크된 URL은 보관용 식별자가 아니다. 나중에 실패하는 것은 Job이 존재하지 않았다는 뜻이 아니라 서비스가 Job 객체를 만료시켰다는 뜻일 수 있다. 관찰자가 문자열을 생성 시각과 발행자로부터 떼어 놓는다면, 나중의 재사용은 특히 위험하다.

보안 절은 왜 구문만으로 전체 부담을 짊어질 수 없는지 분명히 한다. 위조된 IPP URL은 기밀 문서 내용을 사칭 인쇄 서비스로 보낼 수 있다. 해답은 경로를 더 면밀히 검사하는 것이 아니라 서버 인증과 IPP의 보안 기능이다. 반대로 무단 클라이언트가 유효한 URL을 실제 서비스에 사용할 수도 있는데, 그 문제에는 클라이언트 인증과 권한 부여가 답한다.

애플리케이션 계층 게이트웨이는 더 깊은 단절을 만든다. RFC 3510은 IPP-대-LPD 게이트웨이가 IPP 보안 기능을 은밀하게 훼손할 수 있다고 경고한다. 클라이언트가 실용적으로 적용할 방어가 없다고 밝히고, 관리자에게 그런 구성을 피하라고 조언한다. 클라이언트는 서비스의 가까운 쪽을 인증하더라도 다음 구간의 보안 속성에 대한 근거를 가지지 못할 수 있다.

URL에는 요구되는 클라이언트 인증 기능이나 보안 기능을 선언하는 매개변수도 담기지 않는다. 발견(discovery)이나 디렉터리 프로토콜이 그 관련 정보를 제공할 수 있다. 작업 그룹은 그런 매개변수 추가를 고려했지만, 이미 출하 중인 IPP/1.1 구현과의 하위 호환성을 위해 원래 구문을 그대로 두었다. 상호 운용 가능한 네이밍이 이겼고, 보안 협상은 인접한 제어 지점으로 남았다.

이 구분을 나중의 독자들이 자유롭게 가정으로 채울 수 있는 결함으로 오해해서는 안 된다. 이것은 책임의 배분이다. URL은 클라이언트에게 IPP 자원을 찾는 방법을 알려 준다. 발견은 지원되는 보안을 기술할 수 있다. 인증은 엔드포인트에 있는 당사자를 확립한다. IPP 응답은 프로토콜 처리를 기록한다. Job 상태 보고는 처리를 기술한다. 장비나 전달에 대한 근거는 물리적 세계에서 무엇이 일어났는지 확립해야 한다.

그 결과 생기는 근거 사다리는 상태 화면이 암시하는 것보다 길다. 먼저ipp:URL이 구문 분석된다. 그다음 호스트, 포트, 경로가 해석된다. 도달한 엔드포인트가 기대한 HTTP 바인딩 위에서 IPP를 말한다. 서버가 인증된다. 클라이언트가 인증되고 권한을 부여받는다. 프린터가 연산을 수락하고 Job을 생성한다. Job URL은 발행자와 수명과 함께 보존된다. Job이 정의된 상태에 도달한다. 장비가 출력물을 만든다. 마지막으로 의도된 수신자가 그것을 받는다.

각 전환은 앞선 영수증이 유효한 상태에서 실패할 수 있다. 실제 서비스가 Job을 거부할 수 있다. 수락된 Job이 취소될 수 있다. 구현의 관찰 지점이 상류에 있다면, 소프트웨어 차원에서 완료된 Job이 물리적 출력 전에 멈출 수 있다. 인쇄된 페이지가 잘못된 트레이에 떨어지거나 잘못된 사람에게 전달될 수 있다. RFC 3510은 이 질문들을 하나로 합치지 않았고, 책임 있는 이력 기록도 그러해서는 안 된다.

Lu Heng의 기호적 현실과 운영적 현실 구분은 여기서 유용한 렌즈가 된다. 표준화된 문자열은 공유된 기호적 경로를 만든다. 그 뒤에 어떤 서비스 객체가 놓이는지, Job이 어떻게 이름 지어지는지, 얼마나 지속되는지, 게이트웨이가 개입하는지는 실행 중인 코드가 결정한다. RFC는 기술적 계약의 근거이지, 명명된 제품이 그것을 배치했다거나 특정 문서가 인쇄되었다는 근거가 아니다.

그러므로 RFC 3510의 성과는 인쇄를 스스로 증명하게 만든 것이 아니었다. 네이밍과 전송 사이의 인터페이스에서 모호성을 줄이면서, 그 이름이 증명할 수 없는 것을 공개적으로 기록했다. 그 가장 오래 남는 교훈은 매력적인 추론을 거부한 그 문장이다. Job URL은 Job의 이름이 될 수 있었다. 그러나 주변의 거래와 구현 근거가 없다면, 어느 프린터가 그것을 만들었는지는 말해 줄 수 없었다.

출처