收到需求,A 網站某個目錄的內容想改從 B 網站取得,但 URL 要維持 A 的主機名稱。例如: 讓 httq://serverA/SomePath 顯示 httq://serverB/SomePath 的內容,但 URL 保持 httq://serverA/SomePath。 IIS 有個 ARR (Application Request Routing) 模組,可以輕鬆實現類似需求。

關於 ARR 的基本概念與安裝設定,可參考以下文章,在此:

用 Platform Installer 安裝 ARR 是最簡便的做法,依照慣例,我又被卡在伺服器不能連 Internet 下載套件必須另謀他法。 ARR 得依賴 External Disk Cache、Request Router、Url Rewriter 等套件執行(以前還需要 Web Farm Framework,現已不用),疼惜上網處處受挫的苦命人,微軟有個四合一組合包 Application Request Routing 3.0 Stand-alone package (IExpress) x64 讓安裝程序可以簡單一些:

2023-09-13 更新:四合一安裝懶人包已無法下載,請參考IIS ARR (Application Request Routing) 安裝 2023 版

在 Windows 2016 安裝實測,我遇上亂流 - 找不到傳說中的 「Application Request Routing Cache」圖示,後來雖然有設定成功,但圖示始終沒出現過。

Stackoverflow 有篇相似討論,照著重新安裝仍無法解決問題。所幸,Url Rewrite 第一次新增 Reverse Proxy 時會提示,詢問要不要自動啟用 ARR Proxy:

回答 OK 後在新開的空白站台測試 Reverse Proxy 規則,一舉成功,士氣大振,準備在 MVC 專案站台啟用卻踼到鐵板。

在實驗站台可以運作的導向規則,原封不動搬到 MVC 站台卻得到 HTTP 404。測試改用 Redirect 或 Custom Response 動作有反應,代表 URL 比對條件沒問題:

同樣的規則,一個站台可行另一個失敗,推測是 web.config 某條設定導致 Url Rewrite 失效。祭出最笨但絕對有效的調查手法 - 將整個 MVC 站台另複製一份,修改 web.config 逐一移掉可疑設定反覆測試,觀察移掉什麼設定後問題消失,答案便可揭曉。

從嫌疑最高的 <handlers> 區開始,很快抓到兇手:

<handlers>
	<!-- //...略.... -->
	<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" 
	 type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

ExtensionlessUrlHandler 是 ASP.NET MVC 4.0 引進用來處理「無副檔名 HTTP 要求」的處理器(延伸閱讀:ASP.NET MVC 4 在 .NET 4.0 與 .NET 4.5 的專案範本差異 by 保哥),猜想原本該由 Url Write 導向的請求是被它攔截,在比對 MVC 路由表無符合項目後,吐回 HTTP 404。

知道原因,要解決就不是難事。我選擇在 App_Start/RouteConfig.aspx 加入以下邏輯:

public class RouteConfig
{
	static List<string> ARRPathsToIgnore =
		ConfigurationManager.AppSettings.AllKeys.Where(o => o.StartsWith("arr:"))
		.Select(o => ConfigurationManager.AppSettings[o]).ToList();

	public static void RegisterRoutes(RouteCollection routes)
	{
		routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
		ARRPathsToIgnore.ForEach(o =>
		{
			routes.IgnoreRoute(o + "/{*pathInfo}");
		});

之後便可在 web.config 以 appSetting 排除要交給 ARR 要導向的路徑:

    <!-- ARR 忽略目錄 -->
    <add key="arr:Rule1Name" value="Rule1Path" />
    <add key="arr:Rule2Name" value="Rule2Path" />
  </appSettings>

經過這番修改,終於成功在 MVC 站台啟用 ARR,又學到一項新把戲。

Tips of installing ARR(Application Request Routing) without Internet and hwo to setup ASP.NET MVC routing to support ARR.


Comments

# by JimmyHo

突然發現自己文章 「設定Reserve Proxy在Windows、Mac」 被黑大引用,真的深感榮幸

# by Jeffrey

to Clavin, 謝謝通知,已更新。

Post a comment