컴퓨터를 공부하고자 마음먹은지 N일차
[246일차]URL 본문
Reference
HTTP 완벽가이드
[미래인터넷] URN(Uniform Resource Name) 표준 규격 업데이트 현황
[StackOverFlow]url-matrix-parameters-vs-query-parameters
URL과 리소스
출처 - tutorialkart
인터넷에는 수많은 서버와 그 서버 안의 리소스들이 존재한다.
수많은 서버 중 네이버를 예시로 들어보자. 네이버에는 뉴스리소스, 이미지 리소스, 자체적인 뼈대를 구성하는 html리소스,
그리고 웹툰 리소스 등이 있다. 네이버라는 서비스 하나에만 해도 수많은 리소스들이 존재하는데,
어떻게 그 많은 서버들 중 네이버 서버에서 내가 보고싶은 웹툰 한편을 가져올 수 있을까?
바로 인터넷의 리소스를 가리키는 표준 이름인 URI(Uniform Resource Identifier)덕분이다.
URI는 감사하게도 수많은 리소스들 중 원하는 리소스를 불러올 수 있게 확실히 구분을 해준다.
이 전 포스팅에서 설명했듯 URI는 URL이나 URN를 포괄하는 상위의 개념이다. URI는 이 두개의 부분집합으로 이루어져있다.
URN은 현재 그 리소스가 어디에 존재하든 상관없이 그 이름만으로 리소스를 식별하는데 비해
URL은 리소스가 어디 있는지 설명해서 리소스를 식별한다. 그러나 URN은 아직 채택이 되지않아서 접할 기회가 없었을 것이다.
따라서 대부분의 URI는 URL을 가리킨다고 생각하면 된다.
인터넷의 리소스를 직접 탐색해보자
우리의 웹 브라우저(크롬, Whale 등)는 흔히들 주소창이라고 불리는 URL을 입력하는 공간이 있다.
URL은 앞서 말했듯 리소스가 어디 있는지 설명해서 리소스를 식별한다.
내가 좋아하는 웹툰 중 하나인 '연애혁명'의 URL을 간략하게 살펴보자.
https://
위 URL의 시작인 https는 URL의 스킴이라는 것이다. 스킴은 웹 클라이언트가 리소스에 어떻게 접근하는지 알려준다.
위와 같은 경우에는 URL이 HTTPS 프로토콜을 사용한다. HTTPS에 대해 간략히 설명하자면,
기존 HTTP프로토콜과 똑같지만 보안적인 문제를 해결하기위해 메세지를 암호화해주는 성질을 추가한것이다.
comic.naver.com
두번째 부분인 comic.naver.com은 서버의 위치를 뜻한다. 리소스가 속해있는 서버를 알려준다.
comic.naver.com 같은 경우에는 네이버 웹툰의 서버가 위치한 IP의 도메인이다.
/webtoon/detail.nhn
그리고 세 번째 부분인 /webtoon/detail.nhn은 리소스의 경로다.
서버에 존재하는 리소스들 중 어떤 리소스를 요청받았는지 알려준다.
webtoon이라는 경로에 들어가 detail.nhn에 해당하는 리소스를 가져온다.
위 url의 프로토콜은 HTTP가 아닌 다른 애플리케이션 프로토콜을 사용할 수도 있다.
예를들면 ftp라는 파일전송 프로토콜을 활용할 수 있고, mailto라는 이메일 전용 프로토콜을 사용할 수 있다.
URL 문법
일반적으로 URL 문법은 9개 부분으로 나뉜다.
<스킴>://<사용자 이름>:<비밀번호>@<호스트>:<포트>/<경로>;<매트릭스 파라미터>?<쿼리 파라미터>#<프래그먼트>
꺽새로 구분되어있는 부분 하나하나를 URL에서는 컴퍼넌트라고 한다.
흔히 볼 수 없는것도 있을것이고, 인터넷을 개통하고나서 한번도 본적없는 컴퍼넌트도 있을것이다.
이 모든 컴퍼넌트를 가지는 URL은 거의 없다. 각 컴퍼넌트의 역할이 무엇인지 알아보자.
스킴: 사용할 프로토콜
스킴은 주어진 리소스에 어떤 프로토콜을 사용해서 접근할지 알려주는 중요한 정보다.
위에 예시로 들어본 네이버 웹툰의 스킴은 http이다.
스킴 컴포넌트는 알파벳으로 시작해야 하고 다음 컴퍼넌트와의 구분은 콜론과 두개의 빗금(://) 으로 구분한다.
스킴은 대소문자를 가리지 않으므로 만약 http://www.google.com 이 아닌 HTTP://www.google.com 으로 해도
구글에 정상적으로 접속이 되는걸 확인 할 수 있다.
호스트와 포트
네트워크에서 호스트란 네트워크에 연결된 컴퓨터 혹은 그 외의 장치의 IP를 주로 의미한다.
인터넷에 있는 리소스를 찾으려면 우선, 그 리소스가 위치한 서버가 어디있는지 알아야한다.
이전 포스팅에서 설명했듯 서버의 위치를 찾아서 접속하게 해주는건 IP와 목적지 PORT의 역할이다.
그 IP를 사람이 알기쉽게 바꿔준게 도메인이다. 결론적으로 접속하려는 서버의 IP나 도메인을 알아야한다.
내부적으로 TCP 프로토콜을 사용하는 HTTP는 기본포트로 80을 사용하기 때문에,
호스트 뒤에 포트를 적어주지 않아도 접속이 됐었을 것이다.
우리가 흔히 보는 URL들은 호스트뒤에 http포트인 80이 생략된 형태이다.
사용자 이름과 비밀번호
http에서 사용자 이름과 비밀번호를 사용하는곳은 거의없다.
그래서 http URL은 보통 <사용자 이름>:<비밀번호>@
이 부분이 생략된 경우가 많다.
원한다면 http://아무이름:아무비번@www.naver.com
으로 접속해보라 될것이다.
보통은 기본값으로 설정되어있어서 우리가 흔히 접속하는 사이트들은 이름과 비밀번호 컴퍼넌트는 생략되어있다.
실제로 사용하는 경우를 살펴보고싶다면 ftp프로토콜에 대해서 조사를 해보자.
경로
URL의 경로 컴퍼넌트는 원하는 리소스가 서버속에서 어디에 있는지 알려준다.
이러한 위치구조는 웹툰 폴더에 detail.nhn이라는게 있구나 정도로만 알면된다.
빗금'/' 으로 구분된 각각의 위치구조를 경로조각이라고 부르는데,
경로조각들은 각각 자체만의 파라미터 컴포넌트를 가질 수 있다. 파라미터는 뭘까?
파라미터
서버의 수 많은 리소스들 중 원하는 리소스를 불러올 때, 다른 형태로 불러오고 싶을 수 있다.
불러오고 싶은 리소스가 이름과 전화번호라면, 예쁜 명함형식으로 리소스를 불러오고 싶을 수 있고,이름: 졸린새, 번호: 010-1111-2222
라는 문자형태로만 불러오고 싶을 수 있다.
또 서버 개발자 입장에서는 특정 리소스는 fa2Fw12b7u
같이 암호화된 코드를 가지고있는 사람만
접근하게 하고싶을 수 있다.
또, 어떤 커뮤니티에 접속한다고 생각했을 때, 서버에 있는 모든 글이 아니라 최근에 올라온 30개의 글만
불러오고 싶을 수 있다.
그러나 스킴과 호스트, 그리고 경로조각 만으로는 이것을 실현하기에는 불가능 하다.
그래서 URL은 파라미터 컴포넌트를 가지고있는데, 이 컴퍼넌트는 이름과 값 쌍의 리스트를 가진다.
즉 이 쌍을 하나만 가질 수도 있고, 여러개를 가질 수 있다.
그런데 이 파라미터는 세미콜론(;)으로 시작하는 매트릭스 파라미터가 있고, 물음표(?)로 시작하는 쿼리파라미터가 있다.
http://www.name-phone.com/memberinfo/1;type=text
->매트릭스 파라미터
http://www.name-phone.com/memberinfo/1?type=text
->쿼리 파라미터
사용하는 방법이 비슷해 보이지만 이 둘은 큰 차이가 있다.
http://example.com/res/categories;name=foo/objects;name=green/?page=1
->매트릭스 파라미터
http://example.com/res?categories_name=foo&objects_name=green&page=1
->쿼리 파라미터
둘의 중요한 차이점은 매트릭스 파라미터는 각 경로조각마다 적용이 가능한 반면에
쿼리 파라미터는 한URL에 한번만 적용이 되며, 마지막 경로에 시작을 한다.
쿼리 파라미터에 비해 매트릭스 파라미터가 매우 유용해보이지만, 실제로 쓰이는 URL을 잘 본적이 없었을것이다.
매트릭스 파라미터는 특정 프레임워크 (대표적으로 JAX-RS)만 지원을 하기 때문이고,
여러 경로에 파라미터를 넣는 구조가 URL의 복잡함을 높이는 경우도 많아서 최근 파라미터라고 하면,
대부분 쿼리파라미터를 의미한다고 생각하면 된다.
이 파라미터는 앞서 예시를 든것처럼 굉장히 다양하게 활용할 수 있다.
url에 secret 코드를 넣는다던지, 전체게시글의 제한된 범위를 정해준다던지 등 다양한 활용이 가능하다.
http://comunity.com/post?limit=20&offset=20
-> 21번째 게시물부터(limit=20) 20개의 게시글을 원한다(offset=20)
예시와 같이 '&'로 나뉜 여러개의 '이름=값'을 가질 수 있다.
프래그먼트
우리가 보는 웹페이지는 여러개의 HTML 요소들로 이루어 져있다.#
으로 시작하는 프래그먼트는 그 많은 요소들 중 일부로 스크롤을 이동하거나 보여주는 역할을 한다.
MDN문서의 쿼리라는 제목을 가진 문단으로 스크롤이 바로 이동하는것을 볼 수 있다.
원하는 문단의 제목이나 HTML요소에 id를 주면, 프래그먼트로 호출해서 스크롤을 이동시킬 수 있다.
눈치를 챘을 수도 있겠지만 프래그먼트는 서버로 전달되지 않는다.
프래그먼트를 넣으면 브라우저 내에서 해당하는 id를 가진 리소스로 스크롤을 이동시켜줄 뿐이다.
페이지 설계에 따라서 유용하게 쓰일 수 있다.
안전하지 않은 문자
URL은 어떤 인터넷 프로토콜을 통해서든 안전하게 전송될 수 있도록 설계 되어야 한다.
안전한 전송이란, URL에 포함된 정보가 유실될 위험 없이 전송할 수 있다는 것을 의미한다.
프로토콜에 따라서 알파벳이 아닌 다른 언어나 특수문자 경우 제거처리가 될 수 있다.
URL 설계자들은 모든 프로토콜을 통해 URL이 전송되 설계되는것과 함께 가독성 또한 잇기를 바랐다.
그래서 출력이 되지 않거나 보이지 않는 문자(ex. 공백등)를 변환할 수 있다고 하더라도, URL에서 사용하는것을 금지했다.
그러나 URL에 일반적으로 안전한 알파벳 외의 문자도 포함하려고 할때가 있었다.
그래서 이스케이프라는 기능을 추가하여, 안전하지 않은 문자를 안전한 문자로 바꿀 수 있게 하였다.
hello와 world사이에 공백을 브라우저에서 바꿔주는것을 볼 수 있다.
URL 문자 집합
컴퓨터 시스템의 기본 문자집합은 보통 영어 중심으로 설정되어 있다.
간혹 일러스트 툴로 한글로된 파일을 불러오는데 실패하는 경우가 있는것처럼 프로그래밍에서는 리소스이름을
영어로 통일하는것을 권장한다. URL도 마찬가지다.
많은 컴퓨터 앱들이 US-ASCII 문자 집합을 사용해왔다. US-ASCII 는 문자를 서식화하고 하드웨어상에서
신호를 주고받기 위해, 7비트(2^7)수를 사용하여 영문 자판에 있는 키 대부분과 몇몇 문자들을 표현한다.
다만 한국어나, 다른 전세계언어까지 지원해주는게 아니기 때문에 URL에서는 위에 공백을 %20
으로 바꾼것처럼
이스케이프 문자열로 변환시킬 수 있게 함으로써 이동성과 완성도를 높였다.
인코딩 체계
안전하지 않는 문자열을 안전한 문자열인 이스케이프문자열로 바꾸는데에도 체계가 갖춰져있다.
인코딩 되는 안전하지 않은 문자는 %
기호로 시작해, ASCII 코드의 16진수 숫자로 이루어진다.
아래는 예시이다.
문자 | ASCII 코드 => 16진수 | URL예시 |
---|---|---|
공백(Space) | 32 => 0x20 | http://www.google.com/search?q=will%20smith |
공백의 ASCII코드는 32이고 이것을 16진수로 바꾸면 0x20이다. 앞의 0x를 떼고 %를 붙이면 URL에서는 공백으로 취급한다.
어떤걸 이스케이프문자열로 바꿔주는게 좋을까?
URL의 구조에서 이미 선점하고있는 %
, /
, .
등과 같은것들이나, 특정 스킴에서 특별한 의미가 있는 @
, &
, =
과 같은 것들은 제한 하는것이 좋고, 기타 앱의 성격상 인코딩이 필요한 부분들을 추가적으로 제한하는 방식으로
설계하는것이 좋다.( 안전하지않은 문자? )
책 에서는 개발자들이 안전하지 않은 문자를 인코딩하지 않는 것은 실수라고 한다.
그러나 구글검색같은 경우에도 몇몇 안전하지 않는 문자를 인코딩하지 않거나 제한하지 않는다.
따라서 앱의 성격과, 앱애서 선점하고 있는것들을 고려해서 제한하는것이 좋을것같다.
개인적인 생각이지만 구체적인 설계가 어려울 때는 URL표준에서 제안하는 공식에 맞춰 설계하는것도 좋은 방법인것 같다.
'🌏Network' 카테고리의 다른 글
[239일차]네트워크 전반과 HTTP를 개괄적으로 알아보자 (0) | 2021.05.10 |
---|---|
[206일차]TCP 3-way Handshaking (0) | 2021.04.07 |
[191일차] RESTful API란? 그리고 장점까지 (0) | 2021.03.23 |