前篇文章提到為解決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
{
    public class RouteConfig
    {
        public static void 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
{
    public class 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 -->
      <add name="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處理囉!


Comments

Be the first to post a comment

Post a comment