Url and resource

January 07, 2019 · 5 mins to read

1. 서울에서 길 찾기

URL이야기에 앞서 뜬금없이 A가 강남역의 교보문고에 가서 책을 구입하는 이야기를 해보고자 한다. 먼저 집에서 나와 전철역으로 가서, 빨간 노선인 신분당선을 타고 강남역으로 이동한다. 강남역에 도착하면 10번출구로 나간뒤, 쭉 걸어가 교보타워를 찾는다. 건물을 찾았다면, 지하로 내려가 D 서가의 13번 책장을 찾아 책을 찾은 뒤, 계산을 하고 건물을 나선다. 책을 구입하고 난뒤 다른 곳에 볼일이 있어 택시를 타고 삼성동 127번지로 이동한다.

A는 약속된 형태의 분류기준을 잘 알고, 또 활용할 수 있기때문에 수월하게 모든 행동을 할 수 있었다. 택시기사도 마찬가지로 삼성동 127번지라고 말을 했을 뿐이지만, 그 말을 이해하고 올바로 목적지까지 직행했을 것이다.

이는 우리 주변의 리소스를 분류하기 위해 약속한 형태로 표준을 정했기 때문에 가능한 일이다. 거의 모든 사람들은 이 표준에 대해 이해하고 있고, 덕분에 리소스를 자유롭게 이용할 수 있다.

URL도 마찬가지다. 인터넷 세계에 있는 방대한 양의 리소스들의 위치와 접근방법(이용 방법)에 대해 알려준다.

2. URI, URL, URN

URI(Uniform Resource Identifier)는 인터넷의 리소스를 식별하는 역할을 하며, 다시 URL과 URN이라는 부분 집합으로 나뉜다.

  • URL(Uniform Resource Locator)는 위치를 설명하여 그 리소스를 식별하는 역할을 한다.
  • URN(Uniform Resource Name)은 위치가 아닌 리소스 그 자체를 설명하여 리소스를 식별하는 역할을 한다.

두 가지 방법에 차이가 있지만 목적은 똑같다. 리소스를 일관된 방식으로 지칭하여 모든 사람들이 같은 방식으로 리소스를 찾거나 이용할수 있도록 만들어 주는 것이다.

URL의 단점은 리소스의 위치가 옮겨지만 기존의 URL을 사용할 수 없다는 것이다. 그러한 단점을 보완하기 위해 PURL(Persistent URL; 지속적 URL) (opens new window)을 사용할 수 있다. 리소스와 사용자의 중간위치에서 간접적으로 리소스를 제공해 주게 된다. 사용자는 리소스를 요청할 수 있는 영구적인 URL을 요청 하며 그 것을 실제 URL로 연결해 준다.

이러한 상황을 타개하기 위해 고안된 것이 URN이다. URN은 위치와 상관없이 해당 리소스를 영구적으로 가리킬 수 있는 이름을 의미한다. mozilla에서 설명된 문서 (opens new window)에 의하면 URN은 다음과 같은 방식으로 기술된다.

urn:isbn:9780141036144 // George Orwell이 쓴 1984년이라는 책
urn:ietf:rfc:7230 // IETF 스펙 문서 7230

언뜻 보면 URN이 더 효율적인것 같은데 왜 널리 쓰이지 못하는 것일까? 당연하게도, 이미 거의 대부분의 인프라가 URL에 맞춰져 있기 때문이다. 때문에 URN을 정상적으로 사용하기 위해서는 상당한 시간이 소요될 것으로 본다.

3. URL 문법

대부분의 URL 문법은 일반적으로 9개 부분으로 나눌 수 있다.

<프로토콜>://<사용자이름><패스워드>@<호스트>:<포트>/<경로>;<파라미터>?<질의>#<프레그먼트>

각 부분은 component라고 불리며, 모든 component를 가지는 URL은 거의 없다. 필요에 따라 취사선택되며, 이 중에서 중요한 component는 프로토콜, 호스트, 경로이다.

프레그먼트 component가 조금 특이하게 동작하는데, 일단 이 component는 리소스의 일부분을 가리키는 이름이다. 이 component는 서버로 전송되지 않고 클라이언트에서만 사용한다. 브라우저가 프레그먼트가 포함된 URL로 서버에 리소스를 요청하면 일단 전체 text를 받아서 렌더링 한 뒤, 브라우저가 프레그먼트를 이용해 리소스의 일부를 보여주게 된다.

4. 상대 URL과 절대 URL

우리가 일반적으로 개발을 할 때 사용하는 경로와 마찬가지로 URL도 상대 URL과 절대 URL이 존재한다. 절대 URL은 우리가 흔히 봐왔던 것으로, 리소스에 접근하는 모든 경로를 갖고있다.

그와는 다르게 상대 URL은 모든 정보를 담고 있지 않아 부족한 정보를 채우기 위해 base URL이 필요하다. Base URL은 HTML의 <base> tag를 이용해서 명시적으로 제공해 줄 수도 있고 해당 리소스의 URL을 암시적으로 base URL로 사용할 수도 있다. 예를들어 HTML 내에

<a href="./test.html">Test</a>

라는 tag가 있는 경우 base URL은 해당 HTML을 요청한 URL이 된다.

상대 URL과 절대 URL 둘 중 무엇이 낫다고 말 할수는 없다. 각각 필요한 상황이 존재하고, 특히 이 글 (opens new window)을 보게 되면 개발과 SEO의 관점에서 다른 가치를 지닌다는 것을 알 수 있다.

상대 참조를 해석하는 알고리즘은 RFC 2396 (opens new window)에 포함되어 있다.

image

5. URL 확장

브라우저의 내장 기능으로 URL입력 중이거나 입력한 다음, 사용자가 채우지 못했다고 생각되는 부분을 스스로 판단하여 확장(채워)준다. 보통의 경우 두 가지 기능을 제공한다.

  • host name 확장: 단순 휴리스틱 기법을 이용, host name을 채워준다. 예를들면 example만 입력했을 때 www. 등을 자동으로 붙여주게 된다.
  • history 확장: 사용자가 기존에 입력했던 URL을 제시한다.

이러한 확장 기능들은 proxy를 사용했을 시 문제가 발생할 여지가 있다고 하는데, 책의 뒷부분에 설명되어있다고 하니 그때 정리해서 올리면 좋을 것 같다.

6. 안전하지 않은 문자

URL은 SMTP와 다르게 문자가 제거되는 일이 없으면서도 가독성이 있어야 한다는 사실을 염두에 두고 설계되었다. 처음에는 US-ASCII 문자집합 내의 알파벳만 지원 되었는데, 나중에는 알파벳 이외의 문자를 포함할 수도 있다는 것을 알게 되었다. 그래서 이스케이프 기능을 추가하여 안전하지 않은 문자(US-ASCII 문자집합 내의 알파벳이 아닌 문자)를 안전한 문자로 encoding할 수 있게 하였다.

  • encoding 체계 안전하지 않은 문자 encoding은 % 기호로 시작하여 ASCII 코드로 표현되는 두 개의 16진수 숫자로 이루어진 이스케이프 문자로 바꾸는 것을 의미한다. |문자|ASCII code|16진수|이스케이프 문자| |-|-|-|-| |~|126|0x7E|%7E| |white space|32|0x20|%20| |%|37|0x25|%25|
  • 예약 문자 몇몇 문자들은 URL내에서 특별한 의미를 지니기 때문에, 먼저 선점되어 일반적인 용도로는 사용하지 못하게 되어있다. 몇몇 프로토콜에서 사용되거나 URL 문법 자체에서 의미를 갖기 때문인데, 일반 용도로 혼용하여 사용할 경우 혼란을 줄 염려가 있기 때문에 무조건 피해야 한다.

    예약 문자를 확인하기 위해서는 RFC 3986 (opens new window)을 참고하면 좋다.

7. Conclusion

HTTP 완벽 가이드 (opens new window)의 2장을 가볍게 정리해 보았다. 다행히 개발자로 일하기 전 정보보안 파트에서 일하면서 습득한 것들이 도움이 많이 되었다. 늘 느끼는 부분이지만 겉만 알고있던 부분을 자세히 알게되고 알고 있던 부분은 다시 remind할 수 있어서 좋은 기회였다는 생각이 든다.

FE개발자에게 HTTP라는 것은 뗄레야 뗄수없는 존재라고 생각한다. 그렇기 때문에 지금이라도 이 책을 읽게되어 다행이며, 몇몇 장을 제외하고는 완독할 때 까지 정리해 놓을 생각이다.


참고


© 2021, Built with Gatsby