URL을 파일시스템 위치로 대응하기 - Apache HTTP Server

Apache HTTP Server Version 2.0

Apache > HTTP Server > Documentation > Version 2.0

# URL을 파일시스템 위치로 대응하기

가능한 언어: en | ja | ko

이 문서는 요청의 URL을 가지고 아파치가 어떻게 서비스할 파일의 파일시스템상 위치를 찾는지 설명한다.

## 관련된 모듈과 지시어들

관련된 모듈 | 관련된 지시어
--- | ---
`mod_alias` `mod_proxy` `mod_rewrite` `mod_userdir` `mod_speling` `mod_vhost_alias` | `Alias` `AliasMatch` `CheckSpelling` `DocumentRoot` `ErrorDocument` `Options` `ProxyPass` `ProxyPassReverse` `Redirect` `RedirectMatch` `RewriteCond` `RewriteMatch` `ScriptAlias` `ScriptAliasMatch` `UserDir`

## DocumentRoot

요청을 받은 아파치는 어떤 파일을 서비스할지 결정하기위해 기본적으로 요청의 URL-경로(URL에서 호스트명과 포트 뒤에 나오는 부분)를 설정파일에서 지정한 `DocumentRoot` 뒤에 붙인다. 그래서 `DocumentRoot` 아래있는 파일과 디렉토리들은 웹에서 보게될 기본적인 내용이다.

## DocumentRoot 밖에 있는 파일들

종종 파일시스템에서 `DocumentRoot` 아래 있지않은 부분을 웹에서 접근할 필요가 있다. 아파치는 이 경우 여러가지 방법을 사용할 수 있다. 유닉스 시스템에서 심볼링크를 사용하여 파일시스템의 다른 부분을 `DocumentRoot` 아래에 둘 수 있다. 보안을 위해 아파치는 해당 디렉토리의 `Options` 설정에 `FollowSymLinks`나 `SymLinksIfOwnerMatch`가 있는 경우에만 심볼링크를 따라간다.

또, `Alias` 지시어는 파일시스템의 특정 부분을 웹공간에 대응한다. 예를 들어 다음과 같다면

`Alias /docs /var/web`

URL `http://www.example.com/docs/dir/file.html`은 `/var/web/dir/file.html`을 가지고 서비스한다. 지정한 경로에 있는 모든 내용을 CGI 스크립트로 취급하는 것을 제외하고는 `ScriptAlias` 지시어도 같은 일을 한다.

`AliasMatch`와 `ScriptAliasMatch` 지시어의 강력한 정규표현식기반 대응과 대치를 사용하여 더 유연한 설정이 가능하다. 예를 들어,

`ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) /home/$1/cgi-bin/$2`

는 `http://example.com/~user/cgi-bin/script.cgi`로의 요청을 경로 `/home/user/cgi-bin/script.cgi`로 대응하고, 해당 파일을 CGI 스크립트로 취급한다.

## 사용자 디렉토리

유닉스 시스템은 전통적으로 특정 사용자 user의 홈디렉토리를 `~user/`로 지칭한다. `mod_userdir` 모듈은 이 개념을 웹에까지 확장하여, 다음과 같은 URL을 가지고 각 사용자 홈디렉토리 안에 있는 파일을 서비스한다.

`http://www.example.com/~user/file.html`

보안상 웹에서 사용자 홈디렉토리로 직접 접근할 수 있으면 안된다. 그래서 `UserDir` 지시어는 사용자 홈디렉토리에서 웹용 파일들이 있을 디렉토리를 지정한다. 기본 설정 `Userdir public_html`을 사용하고 `/home/user/`가 `/etc/passwd`에 지정된 사용자 홈디렉토리라면, 위의 URL은 파일 `/home/user/public_html/file.html`에 대응한다.

또, `Userdir` 지시어는 `/etc/passwd`에 홈디렉토리의 위치가 저장되지않는 시스템을 위해 여러 다른 형태를 사용할 수 있다.

어떤 사람은 (보통 웹에서 `%7e`로 인코딩되는) "~" 기호가 이상하여 다른 방식으로 사용자 디렉토리를 나타내고 싶어한다. 이 기능은 mod_userdir이 제공하지않는다. 그러나 사용자 홈디렉토리가 규칙적인 방법으로 구성되있다면, `AliasMatch` 지시어를 사용하여 원하는 효과를 얻을 수 있다. 예를 들어, 다음의 `AliasMatch` 지시어를 사용하면 `http://www.example.com/upages/user/file.html`이 `/home/user/public_html/file.html`에 대응한다:

`AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) /home/$1/public_html/$2`

## URL 리다이렉션(Redirection)

앞에서 설명한 설정 지시어들은 아파치가 파일시스템의 특정 장소에 있는 내용을 클라이언트에게 보내게 만든다. 그러나 때때로 요청한 내용이 다른 URL에 있다고 클라이언트에게 알려주어, 클라이언트가 새로 그 URL을 요청하도록 만드는 것이 좋을 때가 있다. 이를 리다이렉션(redirection)이라고 하며, `Redirect` 지시어를 사용한다. 예를 들어, `DocumentRoot` 아래 `/foo/` 디렉토리의 내용을 새로 `/bar/` 디렉토리로 옮겼다면 다음과 같이 클라이언트가 새로운 위치를 요청하도록 한다:

`Redirect permanent /foo/ http://www.example.com/bar/`

그러면 `www.example.com` 서버의 `/foo/`로 시작하는 URL-경로는 `/foo/`를 `/bar/`로 바꾼 URL로 리다이렉션된다. 클라이언트를 원래 서버외에 어떤 다른 서버로도 리다이렉션할 수 있다.

또, 아파치는 더 복잡한 재작성 문제를 위해 `RedirectMatch` 지시어를 제공한다. 예를 들어, 다른 요청은 그대로 두고 사이트 홈페이지에 대한 요청만을 다른 사이트로 리다이렉션하려면:

`RedirectMatch permanent ^/$ http://www.example.com/startpage.html`

임시로 사이트의 모든 페이지를 다른 사이트의 특정 페이지로 리다이렉션하려면:

`RedirectMatch temp .* http://othersite.example.com/startpage.html`

## 역프록시(Reverse Proxy)

아파치는 다른 서버에 있는 문서를 서버의 URL 공간으로 가져올 수 있다. 이 경우 웹서버가 원격 서버에서 문서를 가져와서 클라이언트에게 전달하는 프록시 서버와 같이 동작하기때문에 이런 방법을 역프록시(reverse proxying)라고 한다. 클라이언트의 입장에서 역프록시 서버가 문서를 보내주는 것처럼 보이므로 일반 프록시와는 다르다.

아래 설정에서 클라이언트가 `/foo/`에 있는 문서를 요청하면, 서버는 `internal.example.com`의 `/bar/` 디렉토리에서 문서를 가져와서 문서가 마치 서버에 있었던 것처럼 클라이언트에게 보낸다.

`ProxyPass /foo/ http://internal.example.com/bar/
ProxyPassReverse /foo/ http://internal.example.com/bar/`

`ProxyPass`는 서버가 적절한 문서를 가져오도록 설정하며, `ProxyPassReverse` 지시어는 `internal.example.com`이 보내는 리다이렉션을 재작성하여 리다이렉션이 현재 서버의 적절한 디렉토리를 가리키도록 한다. 그러나 문서 안에 있는 링크는 재작성하지 않음을 주의하라. `internal.example.com`에 대한 절대링크는 클라이언트가 프록시서버가 아니라 `internal.example.com`으로 직접 요청하게 한다.

## 재작성 엔진 (Rewriting Engine)

더 강력한 치환이 필요할때 `mod_rewrite`의 재작성 엔진이 도움이 된다. 이 모듈의 지시어는 브라우저 종류나 클라이언트의 IP 주소 등 요청의 특징을 가지고 어디에 있는 내용을 서비스할지 결정할 수 있다. 또, mod_rewrite는 요청을 어떻게 처리할지 결정하기위해 외부 데이터베이스 파일이나 프로그램을 사용할 수 있다. 재작성 엔진은 위에서 다룬 세 종류 대응, 즉, 내부 리다이렉션 (alias), 외부 리다이렉션, 프록시, 모두를 지원한다. mod_rewrite를 사용하는 실제 예는 URL 제작성 지침서에서 설명한다.

## File Not Found

결국 요청한 URL에 대응하는 파일을 파일시스템에서 찾지 못한 경우이다. 여러 가지 이유가 있다. 어떤 경우 문서를 다른 곳으로 옮겼기 때문일 수 있다. 이 경우 클라이언트에게 URL 리다이렉션으로 자원의 새로운 위치를 알려주는 방법이 제일 좋다. 그러면 자원을 옮겨도 오래된 북마크나 링크가 계속 유효하다.

"File Not Found" 오류의 다른 일반적인 원인은 브라우저에 직접 혹은 HTML 링크에 URL이 잘못 입력된 경우이다. 아파치는 `mod_speling` (맞춤법이 틀리지 않았음) 모듈로 이와 같은 문제를 돕는다. 이 모듈을 사용하면 "File Not Found" 오류가 발생하는 경우 비슷한 파일명을 가진 자원을 찾는다. 만약 발견하면 mod_speling은 클라이언트를 올바른 위치로 HTTP 리다이렉션한다. "비슷한" 파일이 여러개 있다면 클라이언트에게 목록을 보낸다.

mod_speling의 특히 유용한 장점은 대소문자를 구별하지않고 파일명을 비교하는 기능이다. 그래서 유닉스 파일시스템과 URL의 대소문자 성질을 알지못하는 사용자가 있는 시스템에 도움이 된다. 그러나 mod_speling이 자주 URL을 고쳐야한다면, "잘못된" 요청때마다 URL 리다이렉션과 클라이언트의 새로운 요청이 일어나므로 서버에 부담이 된다.

찾는 시도가 모두 실패하면 아파치는 HTTP status code 404 (file not found) 오류페이지를 보낸다. 이 페이지의 내용은 `ErrorDocument` 지시어로 조절하며, 사용자정의 오류 응답과 다국어 서버 오류문 문서를 참고하여 사용자정의할 수 있다.

가능한 언어: en | ja | ko