URI 삽질

URI는 원칙적으로는(…이게 문제) 다음과 같은 구조를 가질 수 있다. 정확히는 path 부분에만 주목하자.

(from wikipedia: URI_scheme)

<scheme name> : <hierarchical part> [? <query>] [# <fragment>]

eg) <http://> <user:pass@example.com> [?param=value] [#some_position]

이 중 hierarchical part에서 “아이디:패스워드”를 뺀 부분을 흔히 path 라고 부른다. 이건 이렇게 되어 있다.

/path/to/some/element

이런 형태의, “/”로 구분하는 문자열이다. 근데 여기서 한 가지 추가 사항을 말하자면, 이거보다 표준엔 내용이 더 있다.

/path;param1=val1/to;param2/some;param3/element.ext;param4=val

하는 형태로 각각의 세그먼트에 인자를 줄 수 있다. (그리고 실제론 거의 안 쓰인다)

— 여기까지 위키 백과 내용 요약 끝

최근에 python BaseHTTPServer 가지고 웹 프로그래밍(…이라고 부르긴 좀 민망하군)을 했는데, 여기서 일부 URI를 저런 형태로 만들어서 썼다. 그리곤 재앙의 시작…

CherryPy 를 가지고 이걸 다시 만들려 하는데, 아뿔싸!(…), Apache 웹 서버도 그렇지만, CherryPy도 저 규약 따윈 그냥 씹어 드신단다.

Update 2010-11-25: 이 부분은 schema(그러니까 http, ftp 같은 프로토콜) 에 따라 다르고, 각 구현 알고리즘(relative reference dereferencing algorithm)에 따라 다른 부분이다. 그러니 이 동작이 문제인 건 아님…

 

path 에 대한 인자(?)로 param1이 전달되는 게 아니라, /path 와 /path;param1 은 완전히 다른 URI가 돼버린다. 그래서 노가다로 cherrypy.tree.mount( )를 써서, 스크립트 경로 줘 가며 저걸 따로 인지하게 만든 듯.

얼마 전에 Hacker Monthly 에서 본 기사(What Every Developer Should Know About URLs)만 가지고 써 본건데, 제대로 당했다. (내용 자체는 위키 백과 내용을 좀 더 잘 풀어 써놨으니 이 글도 한 번 읽어두면 좋다; 좀 더 넓은 범주의 얘기도 나옴)

PS. 내가 이게 잘 돌 거라고 기대했던 원인이 하나 더 있다. Python의 urlparse 는 path의 param 부분을 제대로 구분해서 돌려준다. (물론 마지막 segment 에 속한 것만 그렇지만…)

Published by

rein

나는 ...

6 thoughts on “URI 삽질”

  1. HTTP 0.9시절부터 지금까지 관련 표준들을 봐 왔지만 처음 듣는 이야기라 오래간만에 (현재 URI 표준문서인) RFC-3986을 읽어봤습니다.

    3.3절 마지막 부분에 비슷한 이야기가 있긴 합니다만, 명백히 scheme specific, implementation dependent라고 했군요.
    아마도 snmp같은 scheme에서 사용하기 위해 segment의 semantic이 이런 형식으로 쓸 수 있다고 comment한 정도이지 http scheme에서의 URI (=URL)에서도 저런 식으로 해석해야 한다고 이야기 하는 것 같지는 않습니다. (사실 RFC-3986이 syntax에 대해서 이야기를 하는 것이지 (relative URI resolution을 제외하고) semantic에 대해서 이야기하는 것은 아니니까요.)

    “이거보다 표준엔 내용이 더 있다.”라고 말씀하시기에는 좀 무리가 있지 않나요?
    Apache와 CherryPy를 이야기 하시는 것을 보니 URL에 URI general syntax를 적용하려고 하신 것 같습니다만,
    좀 과하게 적용하신게 아닌가 합니다. (사실 RFC-1738은 살아있기도 하고…)

    왠지 님의 글을 보고 다른 분들이 “(외국 사람들도) 표준은 잘 안지키는 거야”라고 오해하실까 봐 장문의 댓글을 남겨 봅니다.

    1. 제가 본 표준은 RFC 2396(Uniform Resource Identifiers (URI): Generic Syntax) 입니다. 근데 이거 obsolete군요(by 3986).

      여기서는 ; 로 구분된 parameter 를 쓰는 경우에 대해, relative reference가 영향받지 않아야 한다는 내용이 있습니다(3.3). 그래서 경로 해석할 때 이거 무시하고 해석할거라고 기대한거고요(rfc3986에는 이 내용은 빠졌더군요).
      하지만 산오리님 말씀처럼 schema specific, referencing algorithm dependent 한거군요 -_-;
      저 부분 없이 생각해서 같은 경로(=같은 WSGI 핸들러)로 올거라고 생각했지요(하지만 python BaseHTTPServer + urlparse로 직접 처리했을 때 말곤 망했습니다만은;;; )

      ps. 이게 왜 나왔는지는 전 잘 이해가 안갑니다만은, 표준은 대부분의 경우 구현하는 쪽이 아는 만큼 + 그리고 필요한 만큼만 지켜지는 듯 합니다. 잘 알려진 예로 HTTP 301, 302, 303을 각 웹 브라우져들이 해석하는 방법은 꽤나 차이가 있죠…

Leave a Reply