在前篇文章提到為解決HipChat開啟圖檔變下載困擾,我計劃寫一個簡易Proxy,接受httqs://another-server/proxy/files/1/3/KN2SPYfn4GfsvJh/upload.png格式URL,轉手向HipChat伺服器取得httqs://real-hipchat-server/files/1/3/KN2SPYfn4GfsvJh/upload.png圖檔傳回以避開Content-Disposition: attachment的干擾。
由於URL路徑要完全比照HipChat的規則(/files/1/3/KN2SPYfn4GfsvJh/upload.png),我打算借重MVC很彈性路由功能。先從一個簡單雛型開始,宣告一個FilesController Index(string id) Action,對應路由files/{id},希望在URL為files/darkthread.png時,由id參數取得"darkthread.png"。
路由設定如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Proxy
{
publicclass RouteConfig
{
publicstaticvoid RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "files/{id}",
defaults: new { controller = "Files", action = "Index",
id = UrlParameter.Optional }
);
}
}
}
FilesController邏輯如下(測試用途,故不真的取檔,僅回傳讀到的id參數):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Proxy.Controllers
{
publicclass FilesController : Controller
{
public ActionResult Index(string id)
{
return Content(id);
}
}
}
不過,事情沒這麼簡單,發現一旦後方串上包含".副檔名"的檔名參數,便會得到HTTP 404找不到檔案錯誤。
類似問題之前發生過!關鍵在於/files/darkthread.pdf被視為合法的靜態檔案URL,IIS優先將其解讀成網站資料夾相對位置的檔案處理,結局當然是查無此檔。要解決這個問題,只需在web.config中加上額外handler宣告,指定當path符合"/files/*"時,一律改由ASP.NET UrlRouting處理。
<system.webServer>
<handlers>
<!-- http://stackoverflow.com/questions/9273987/asp-net-mvc-url-route-supporting-dot -->
<addname="UrlRoutingHandler"
type="System.Web.Routing.UrlRoutingHandler,
System.Web, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
path="/files/*"
verb="GET"/>
</handlers>
</system.webServer>
加上設定,看似直接下載PDF檔案的URL也被導引到FilesController處理囉!