전역 및 분산 재작성 규칙 사용하기

등록일시: 2008-07-21 13:28,  수정일시: 2013-11-17 14:51
조회수: 8,031
이 문서는 IIS 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.

본문에서는 URL 재작성 모듈이 지원하는 두 가지 유형의 규칙인, 전역 재작성 규칙과 분산 재작성 규칙에 관해서 살펴보고 각각의 규칙들을 설정하는 방법을 소개합니다.

배경

전역 재작성 규칙은 서버 수준에서 수행되는 재작성 로직을 정의하기 위한 용도로 사용됩니다. 이 규칙들은 applicationHost.config 파일의 내부에 정의되며, 사이트나 가상 디렉터리 같은 더 하위 수준의 구성 설정에서는 재작성되거나 비활성화 될 수 없습니다. 그리고, 전역 재작성 규칙은 항상 URL의 절대 경로를 기준으로 동작합니다. (즉, 요청받은 URL에서 서버의 이름 부분을 제외한 나머지 경로를 의미합니다.) 가령, http://localhost/directory1/directory2/index.html이라는 URL을 요청 받았다면 URL 재작성 모듈은 이 전체 URL 중에서 도메인 부분을 제외한 "directory1/directory2/index.html" 부분만 전역 규칙에 입력값으로 전달합니다.

반면, 분산 재작성 규칙은 특정 구성 설정 영역에 대한 URL 재작성 로직을 정의하기 위한 용도로 사용됩니다. 그리고, 파일 수준을 제외한 모든 수준의 구성 설정 Web.config 파일에 정의가 가능합니다. 지역 규칙은 항상 자신이 정의된 Web.config 파일의 위치에서 URL의 상대 경로를 기준으로 동작합니다. 가령, http://localhost/directory1/directory2/index.html이라는 URL을 요청 받았고 재작성 규칙이 directory1에 위치한 Web.config 파일에 정의되어 있다면, URL 재작성 모듈은 전체 URL에서 "directory2/index.html" 부분만 규칙에 입력값으로 전달합니다.

더불어, 전역 규칙에 대한 평가가 항상 선행으로 이뤄진 다음에 전역 규칙에 의해 처리된 URL 문자열을 대상으로 분산 규칙에 대한 평가가 다시 이뤄집니다.

전제조건

본문은 다음과 같은 조건들을 전제로 합니다:

  1. ASP.NET 역할 서비스가 설치된 IIS 7.0
  2. URL 재작성 모듈 CTP 버전 설치 *

* URL 재작성 모듈을 다운로드 받을 수 있는 경로는 이전 번역 문서에 소개되었습니다.

미리보기 시나리오 구성

전역 규칙과 지역 규칙이 어떤 방식으로 동작하는지 자세히 살펴보기 위해서, 디렉터리와 서브 도메인을 맵핑하는 일반적인 시나리오를 가정해 보겠습니다. 이런 기법을 사용하면 서브 도메인을 사용해서 한 사이트의 서로 다른 디렉터리에 존재하는 콘텐츠에 접근 가능합니다. 가령, http://mysite.com/blog 대신 http://blog.mysite.com/을 사용하거나 http://mysite.com/forum 대신 http://forum.mysite.com/으로 원하는 컨텐츠에 접근할 수 있습니다. *

이 시나리오에 따라 플랫폼을 구성하기 위해서는 다음과 같은 과정을 거칩니다:

  1. %SystemDrive%\inetpub\wwwroot\ 폴더 하위에 "blog"와 "forum"이라는 이름으로 두 개의 새로운 폴더를 생성합니다.
  2. 다음 ASP.NET 코드를 복사해서 article.aspx라는 이름으로 파일을 %SystemDrive%\inetpub\wwwroot\blog 폴더에 만들고 붙여 넣습니다: **
    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>URL Rewrite Module Test</title>
    </head>
    <body>
        <h1>URL Rewrite Module Test Page</h1>
        <p>This page is located in blog subdomain.</p>
        <table>
            <tr>
                <th>Server Variable</th>
                <th>Value</th>
            </tr>
            <tr>
                <td>Original URL: </td>
                <td><%= Request.ServerVariables["HTTP_X_ORIGINAL_URL"] %></td>
            </tr>
            <tr>
                <td>Final URL: </td>
                <td><%= Request.ServerVariables["SCRIPT_NAME"] 
                    + "?" + Request.ServerVariables["QUERY_STRING"] %></td>
            </tr>
        </table>
    </body>
    </html>
  3. 다음 ASP.NET 코드를 복사하여 forum.aspx라는 이름으로 파일을 %SystemDrive%\inetpub\wwwroot\forum 폴더에 만들고 붙여 넣습니다: **
    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>URL Rewrite Module Test</title>
    </head>
    <body>
        <h1>URL Rewrite Module Test Page</h1>
        <p>This page is located in forum subdomain.</p>
        <table>
            <tr>
                <th>Server Variable</th>
                <th>Value</th>
            </tr>
            <tr>
                <td>Original URL: </td>
                <td><%= Request.ServerVariables["HTTP_X_ORIGINAL_URL"] %></td>
            </tr>
            <tr>
                <td>Final URL: </td>
                <td><%= Request.ServerVariables["SCRIPT_NAME"] 
                    + "?" + Request.ServerVariables["QUERY_STRING"] %></td>
            </tr>
        </table>
    </body>
    </html>
  4. 마지막으로 %SystemDrive%\windows\system32\drivers\etc\ 폴더에 존재하는 "hosts" 파일을 열어서 다음의 두 라인을 추가합니다: ***
    127.0.0.1 forum_localhost
    127.0.0.1 blog_localhost
  5. 설정을 모두 마쳤으면 웹 브라우저를 실행하고 http://blog_localhost/blog/article.aspx와 http://forum_localhost/forum/forum.aspx를 입력해서 페이지들이 올바르게 출력되는지 확인해봅니다.

* 기존에는 이런 서브 도메인 환경을 구성하기 위해서 동적으로 가상 웹 서버를 생성한 다음, 적절한 호스트 헤더를 지정하는 방법이 사용되었습니다. 이런 작업에는 ADSI나 WMI 등의 기술이 필요했기 때문에 일반적인 ASP, ASP.NET 개발자들이 어느 정도 부담을 느꼈던 것도 사실입니다. 본문에서 볼 수 있는 것처럼 IIS 7 환경에서는 URL 재작성 모듈을 사용해서 비교적 간단한 구현이 가능합니다.

** 이 두 개의 ASPX 파일은 동일한 내용을 담고 있습니다. 유일한 차이점은 P 태그로 표시된 문장뿐으로, 이를 바탕으로 현재 접근한 페이지가 둘 중 어떤 페이지인지 판단할 수 있습니다. 단지 그 뿐입니다.

*** 당연한 얘기지만 실제 운영 환경에서는 이 부분을 DNS 서버가 담당하게 됩니다.

전역 재작성 규칙 생성하기

먼저 호스트 헤더의 값을 기준으로 URL을 재작성하는 전역 재작성 규칙을 작성해보겠습니다. 가령, http://blog_localhost/article.aspx 같은 요청이 전달되면 전역 재작성 규칙에 의해 URL 경로가 "/blog/article.aspx"로 변경됩니다.

IIS 관리자의 URL 재작성 UI를 사용해서 전역 규칙을 작성하려면 다음과 같은 과정을 거칩니다:

  1. IIS 관리자를 실행합니다.
  2. 좌측의 트리뷰에서 재작성 규칙을 생성하고자 하는 서버 노드를 선택합니다.
  3. 기능 보기에서 "URL Rewrite Module" 아이콘을 더블 클릭합니다.
  4. "작업" 패인에서 "Add rule..." 링크 버튼을 클릭합니다.

그러면, 이제 실제로 재작성 규칙을 만들어볼 차례입니다. URL 재작성 모듈의 재작성 규칙은 다음과 같은 네 가지 필수적인 정보를 지정함으로서 이뤄집니다:

  • 규칙 이름
  • URL 문자열과 매칭시켜 볼 패턴
  • 선택적인 추가적인 조건들
  • 패턴이 일치하고 모든 조건을 만족할 때 실행될 동작

규칙 이름 지정

예를 들어서, "Subdomain mapping" 같은 규칙을 식별할 수 있는 이름을 "Name" 텍스트 박스에 입력합니다.

패턴 정의

다음 문자열을 "Pattern" 텍스트 박스에 입력합니다:

(.*)

이 패턴 문자열은 정규 표현식으로, 빈 문자열을 포함한 모든 문자열과 일치하며 역참조로 사용하기 위해 문자열을 캡춰합니다.

조건 정의

조건을 정의하려면 "Add Conditions" 버튼을 클릭합니다:

그리고, 다시 "Add..." 버튼을 클릭해서 조건을 정의하기 위한 대화 상자를 띄웁니다.

먼저, "Condition input:" 텍스트 박스에는 "{HTTP_HOST}"를 입력합니다. 이 값을 입력하면 URL 재작성 규칙은 조건의 입력값으로 HTTP 요청 호스트 헤더값을 사용하게 됩니다.

그리고, 드롭다운 콤보 박스에서 "Matches the pattern" 항목을 선택합니다.

마지막으로, "Pattern" 텍스트 박스에 "^([^_]+)_[^_]+"를 입력합니다. 이 정규 표현식은 입력된 호스트 헤더의 값이 본문의 앞 부분에서 생성했던 도메인들(blog_localhost 및 forum_localhost)과 일치하는지 판단하는데 사용되며, "_" 문자의 앞 부분을 역참조로 캡춰하게 됩니다. 가령, "blog_localhost"라는 문자열에서 "blog" 부분을 역참조로 갈무리합니다.

모든 속성들을 올바르게 지정했다면 조건 대화 상자는 다음과 같은 모습을 하고 있을 것입니다:

이제 "OK" 버튼을 클릭해서 조건을 저장하고 "Add Rule" UI로 돌아갑니다.

동작 정의

이 규칙은 URL 재작성을 전제로 하고 있으므로, "Action" 그룹 박스에서 "Rewrite" 동작 유형을 선택합니다. 그리고, "Rewrite URL:" 텍스트 박스에 다음 문자열을 입력합니다:

{C:1}/{R:1}

이 문자열은 원본 URL이 재작성될 새로운 형태의 URL 형식을 지정합니다. 조건의 역참조인 {C:1}은 폴더의 이름으로 사용되며, 규칙의 역참조인 {R:1}은 규칙 패턴이 캡춰해두었던 모든 내용들을 의미합니다. *

그 밖의 다른 설정들은 기본값을 그대로 사용합니다. 이제 "Edit Rule" 속성 페이지는 다음과 같은 모습을 하고 있을 것입니다:

마지막으로, 우측에 위치한 "Apply" 링크 버튼을 클릭해서 규칙을 저장합니다.

이 전역 재작성 규칙이 동작하는 과정을 살펴보기 위해서, HTTP 클라이언트가 http://blog_localhost/article.aspx?id=323라는 URL을 요청한 경우 URL 재작성 모듈이 동작하는 과정을 한 단계씩 살펴보도록 하겠습니다: *

  1. 먼저 URL 재작성 모듈이 "article.aspx?id=323"을 재작성 규칙에 입력 URL로 넘기고, 이 문자열은 규칙 패턴과 일치하므로 규칙 역참조 {R:1}에 캡춰됩니다.
  2. 호스트 헤더 값("blog_localhost")이 정규 표현식 "^([^_]+)_[^_]+"와 일치하므로, "blog" 문자열이 조건 역참조 {C:1}에 캡춰됩니다.
  3. 결과적으로 대체 문자열 {C:1}/{R:1}에 의해 원본 URL이 "blog/article.aspx?id=323"으로 재작성됩니다.

* 조건 역참조인 {C:n}과 규칙 역참조인 {R:n}간의 차이점을 명확히 구분하시기 바랍니다. 이는 각각의 역참조가 어디에서 캡춰된 것인지를 구분하기 위한 것입니다.

규칙 테스트

전역 재작성 규칙이 올바르게 URL 재작성을 수행하는지 테스트해보려면 웹 브라우저에 http://blog_localhost/article.aspx?id=123 같은 형태의 URL을 입력해봅니다:

그러면, URL 재작성 모듈에 의해 원본 URL이 재작성되고, 그 결과 "blog" 디렉터리에 위치한 Article.aspx 파일이 출력되는 것을 확인할 수 있습니다. 이 결과는 호스트 헤더에서 추출한 정보를 근거로한 URL 재작성 모듈의 작업에 의해 이뤄진 것입니다. *

같은 논리로 웹 브라우저에 http://forum_localhost/forum.aspx?id=345를 입력해보면 요청한 원본 URL이 "/forum/forum.aspx?id=345"로 재작성되는 것을 확인할 수 있습니다.

* 이 이미지에는 오류가 존재합니다. "This page is located at blog sub-domain"이라는 문장이 출력돼야 정상인데 이 문장이 없습니다. 아마도 원문의 작성자가 이미지를 재활용(?)하다가 실수한 것이 아닌가 추측됩니다.

분산 재작성 규칙 생성하기

지금까지 작성한 전역 규칙은 호스트 헤더에서 추출한 정보를 기반으로 폴더에 요청을 맵핑하는 작업을 수행합니다. 이번에는 쿼리스트링이 없는 URL을 사용할 수 있게 해주는 분산 재작성 규칙을 작성해보겠습니다. 이 분산 규칙은 이미 전역 규칙이 수행된 결과 문자열을 입력 URL로 전달받고, 그에 더해 추가적인 변경 작업을 수행하게 됩니다. 즉:

  • "blog" 폴더의 재작성 규칙은 "article/234/some-title" 형태의 URL을 "article.aspx?id=234&title=some-title" 형태로 재작성합니다.
  • "forum" 폴더의 재작성 규칙은 "topic/123/some-topic-title" 형태의 URL을 "forum.aspx?topic=some-topic-title&id=123" 형태로 재작성합니다.

지역 규칙은 IIS 관리자를 사용하거나 Web.config 파일을 편집해서 작성 가능합니다. 미리보기라는 본문의 특성상 이번에는 Web.config 파일을 직접 편집해서 규칙을 작성해보겠습니다.

분산 재작성 규칙을 작성하려면:

  1. %SystemDrive%\inetpub\wwwroot\blog 폴더에 빈 Web.config 파일을 생성합니다. 그리고, 텍스트 편집기로 파일을 열어서 다음 XML 코드를 붙여 넣으십시오:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="Rewrite to article.aspx">
              <match url="^article/([0-9]+)/([_0-9a-z-]+)"/>
              <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}"/>
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>
  2. %SystemDrive%\inetpub\wwwroot\forum 폴더에 빈 Web.config 파일을 생성합니다. 그리고, 텍스트 편집기로 파일을 열어서 다음 XML 코드를 붙여 넣으십시오:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="Rewrite to forum.aspx">
              <match url="^topic/([0-9]+)/([_0-9a-z-]+)"/>
              <action type="Rewrite" url="forum.aspx?topic={R:2}&amp;id={R:1}"/>
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>

전역 규칙 및 분산 규칙 복합 테스트

모든 재작성 규칙이 복합적으로 올바르게 동작하는지 테스트해보려면 웹 브라우저에 http://blog_localhost/article/234/some-title을 요청해봅니다. 그러면, 일단 전역 재작성 규칙에 의해 재작성된 다음, 분산 재작성 규칙에 의해 다시 재작성된 최종 URL이 출력되는 것을 확인할 수 있습니다.

동일한 논리로 웹 브라우저의 주소창에 http://forum_localhost/topic/123/some-topic-title을 요청해보면, 원본 URL이 URL 재작성 모듈에 의해 "/forum/forum.aspx?topic=some-topic-title&id=123"으로 변경되는 것을 확인할 수 있습니다.

요약

본문에서는 전역 규칙을 사용해서 서브 도메인 맵핑 시나리오를 구현해보고, 분산 규칙을 사용하여 해당 서브 도메인 폴더들의 컨텐츠를 대상으로 하는 사용자 친화적 URL을 구현해봤습니다.