와일드카드 스크립트 매핑과 IIS 7 통합 파이프라인

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

IIS 7 통합 요청 처리 파이프라인을 통해서 얻을 수 있는 가장 큰 이점은 ASP.NET의 모든 유용한 고성능 기능들을 ASP.NET 관련 콘텐츠를 비롯해서 웹 사이트에 존재하는 모든 유형의 콘텐츠를 대상으로 적용할 수 있다는 점입니다. 가령, ASP.NET SQL 기반 멤버십 기능을 정적 파일이나 폴더를 보호하기 위한 용도로 사용하는 것이 가능합니다. 뿐만 아니라, IHttpHandler나 IHttpModule 같은 ASP.NET 확장성 API들을 이용해서 비 ASP.NET 콘텐츠까지 포괄적으로 적용가능한 사용자 정의 처리기나 모듈을 작성할 수도 있습니다. *

그러나, IIS 6에서는 이런 수준의 통합이 불가능합니다. IIS 6의 ASP.NET은 단지 ISAPI 확장이 하나 더 끼워넣어진 것에 불과하며, 기본적으로 해당 ISAPI 확장에 매핑된 요청들만 처리하도록 구성되어 있습니다. 대표적인 예로 ".aspx"라는 문자열로 끝나는 요청들만 ASP.NET 확장에 의해서 처리됩니다. 이 점은 ASP.NET의 기능들을 웹 사이트의 모든 콘텐츠에 적용하고 싶어하는 고객들에게는 상당히 치명적인 단점입니다. IIS 6에서 이 단점을 해소할 수 있는 가장 일반적인 방법은 "와일드카드 스크립트 매핑 (Wildcard script mapping)" 기능을 사용하는 것입니다. 본문에서는 IIS 6에서 와일드카드 스크립트 매핑을 사용하던 응용 프로그램을 IIS 7으로 마이그레이션하는 방법에 관해서 살펴봅니다.

본문에서는 여러분이 이미 IIS 6의 와일드카드 스크립트 매핑 기능으로 ASP.NET이 모든 요청들을 처리하도록 구성해본 경험이 있다고 가정합니다. 이를테면, ASP.NET URL 재작성 모듈을 이용해서 확장자가 존재하지 않는 URL들을 처리해봤다고 가정할 수 있습니다.

일반적으로 IIS 6 관리자에서 웹 서버나 웹 사이트에 대한 등록 정보 대화 상자를 열고, "홈 디렉터리" 탭을 선택한 다음, "구성" 버튼을 클릭하고 "와일드카드 응용 프로그램 매핑(실팽순서)" 영역의 "삽입" 버튼을 클릭해서 와일드카드 스크립트 맵 구성을 수행합니다:

그러나, 이제 해당 응용 프로그램을 IIS 7으로 이전하게 되었으며 ASP.NET이 동일하게 동작하도록 구성하고자 합니다. 이 경우, 여러분이 선택할 수 있는 방법에는 두 가지 선택 가능한 옵션이 존재하는데, 클래식 파이프라인 모드를 이용하는 방법과 통합 파이프라인 모드를 이용하는 방법이 바로 그것입니다.

* 본문을 보다 잘 이해하기 위해서는, 먼저 ASP.NET 과 IIS7 의 통합, 최상의 통합 모드 구성, 응용 프로그램 마이그레이션 등의 문서를 살펴보는 것이 좋습니다.

IIS 7 클래식 파이프라인 모드 와일드카드 스크립트 매핑

클래식 파이프라인 모드에서는 ASP.NET이 ISAPI 확장의 형태로 IIS 요청 처리 파이프라인에 끼워 넣어지는데 이 방식은 기존 IIS 6의 방식과 정확히 동일한 것입니다. %WINDIR%\system32\inetsrv\config\applicationHost.config 파일을 열고 <handlers> 섹션을 살펴보면 IIS가 ASP.NET 관련 요청들을 aspnet_isapi.dll에 매핑하도록 구성되어 있다는 사실을 확인할 수 있습니다:

<handlers accessPolicy="Read, Script"> 
  ...
  <add name="PageHandlerFactory-ISAPI-2.0" 
       path="*.aspx" verb="GET,HEAD,POST,DEBUG" 
       modules="IsapiModule" 
       scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" 
       preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> 
  ...
</handlers> 

이 처리기 매핑에서 preCondition 어트리뷰트의 값에 주의하시기 바랍니다. 이 어트리뷰트는 다른 두 가지 값과 더불어 classicMode로 값이 설정되어 있는데, 그 결과 이 처리기 매핑은 응용 프로그램 풀이 클래식 모드로 동작하게 구성된 경우에만 유효하게 됩니다.

클래식 파이프라인 모드에서 동작하는 ASP.NET에 대한 와일드카드 매핑을 구성하려면, IIS 관리자에서 "처리기 매핑"을 선택하고 우측 작업 패인에서 "와일드카드 스크립트 매핑 추가..." 링크 버튼을 클릭합니다.

그리고, 실행 파일에 aspnet_isapi.dll을 선택한 다음, 스크립트 매핑에 ASP.NET-ISAPI-2.0-Wildcard 같은 기억하기 쉬운 이름을 지정합니다. 그리고, "확인" 버튼을 클릭한 다음, 나타나는 "와일드카드 스크립트 매핑 추가" 대화 상자에서 "예" 버튼을 클릭합니다.

이제, 우측 패인에서 "정렬된 목록 보기..." 링크 버튼을 클릭해서 처리기 매핑들의 정렬된 목록으로 화면을 전환한 다음, 새로 생성된 매핑을 StaticFile 처리기 매핑 바로 위까지 아래로 이동합니다:

만약, web.config 파일을 열어서 <handlers> 섹션을 살펴보면 방금 작성한 ASP.NET 와일드카드 스크립트 맵 구성이 StaticFile 처리기 구성 바로 앞 부분에 자리잡고 있는 것을 확인할 수 있을 것입니다.

<handlers accessPolicy="Read, Script"> 
  ...
  <add name="ASP.NET-ISAPI-2.0-Wildcard"
     path="*" verb="GET,HEAD,POST,DEBUG"
     modules="IsapiModule"
     scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
     preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
  <add name="StaticFile" 
     path="*" verb="*" 
     modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" 
     resourceType="Either" requireAccess="Read" /> 
</handlers>

와일드카드 처리기 매핑의 상대적인 순서는 매우 중요한데, 만약 이 매핑이 "StaticFile" 처리기 매핑 다음에 위치하고 있다면 "StaticFile" 처리기가 모든 요청을 처리하게 되고 ASP.NET 와일드카드 처리기로는 어떠한 요청도 전달되지 않을 것입니다.

아마 여러분도 IIS 7 ASP.NET 와일드카드 처리기 매핑 방식에 IIS 6에서 발생하던 것과 동일한 성능상의 한계가 존재할 수 밖에 없다는 점을 이미 짐작할 수 있을 것입니다. 이 처리기 매핑 방식에 존재하는 문제점은 정적 파일에 대한 요청을 비롯한 모든 요청이 해당 처리기에 의한 처리를 거치게 된다는 점입니다. ASP.NET 정적 파일 처리기는 IIS 네이티브 정적 파일 처리기처럼 강력하지 않습니다. 게다가 ASP.NET에 의해서 제공되는 정적 파일들은 서버 측에 캐시되지도 않을 뿐만 아니라, 웹 브라우저 측에도 캐시되지 않을 것입니다. 바로 이런 성능상의 한계로 인해, IIS7 통합 파이프라인을 이용해서 IIS 6 와일드카드 매핑과 같은 기능을 구성하는 것이 권장됩니다.

IIS 7 통합 파이프라인을 이용한 와일드카드 스크립트 매핑 대체

통합 파이프라인 모드에서는 ASP.NET의 기능들이 IIS의 핵심 요청 처리 과정과 완벽하게 통합되어 있으므로, 결과적으로 모든 유형의 요청들을 대상으로 ASP.NET의 모든 기능들을 사용할 수 있습니다. 사실상 이로 인해서 와일드카드 처리기 매핑에 대한 필요성 자체가 없어졌습니다. 이제 기존에 작성했던 ASP.NET 모듈들을 모든 요청을 대상으로 사용할 수 있습니다.

가령, ASP.NET에서 URL 재작성 모듈을 사용한다고 가정해보면, IIS 6에서는 해당 모듈이 다음처럼 web.config 파일의 <system.web> 섹션 내부에 등록됩니다:

<system.Web> 
  <httpModules> 
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules" /> 
    ...
  </httpModules> 
</system.Web>

그리고, IIS 6까지 해당 모듈은 관리되는 콘텐츠에 대해서만 실행되었는데, 가령 http://example.com/archive/2008/08/26/post-title.aspx 같이 .aspx 확장자를 갖고 있는 URL들만을 대상으로 동작했습니다. 따라서, 확장자가 없는 URL들을 처리하려면 ASP.NET에 대한 와일드카드 스크립트 매핑을 구성할 수 밖에 없었습니다. 그러나, IIS 7 통합 파이프라인 모드에서는 더 이상 그럴 필요가 전혀 없습니다. 이 모듈을 확장자 없는 URL들에 대해서 적용하고자 하는 경우에는 다음과 같이 모듈을 <system.webServer> 섹션에 등록하기만 하면 됩니다:

<system.webServer> 
  <modules> 
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules" 
         preCondition="" /> 
    ...
  </modules> 
<system.webServer>

이 때, 반드시 preCondition 어트리뷰트 값을 비워놔야만 ASP.NET 관련 콘텐츠에 대한 요청뿐만 아니라 모든 요청을 대상으로 모듈이 실행된다는 점에 주의하십시오.

이 방식으로 관리되는 모듈을 등록하면 와일드카드 스크립트 매핑을 사용하는 경우처럼 심각한 성능적 손상이 발생하지 않습니다. 비록, 웹 응용 프로그램에 대한 모든 요청을 대상으로 모듈이 동작하기는 하지만, 기존의 모든 처리기 매핑이 여전히 적용되므로 결과적으로 정적 파일들은 여전히 IIS 네이티브 정적 파일 처리기에 의해 처리됩니다. 그리고, 모듈을 이런 방식으로 등록하는 경우 얻을 수 있는 또 하나의 이점은, 해당 모듈이 PHP, ASP 또는 그 밖의 동적 페이지들을 대상으로도 적용된다는 점입니다. 이런 장점은 와일드카드 스크립트 매핑으로는 결코 얻을 수 없습니다.

본문에서 마지막으로 다룰 내용은 <modules> 섹션에서 지정할 수 있는 runAllManagedModulesForAllRequests라는 어트리뷰트에 관한 것입니다.

<system.webServer> 
  <modules runAllManagedModulesForAllRequests="True" > 
    ...
    <add name="MyUrlRewrite" 
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules" 
         preCondition="ManagedHandler" /> 
    ...
  </modules> 
<system.webServer>

이 어트리뷰트는 강제로 IIS로 하여금 preCondition="managedHandler" 어트리뷰트를 무시하도록 만들어서, 모든 관리되는 모듈들이 웹 응용 프로그램에 대한 모든 요청들을 대상으로 동작하도록 만듭니다.