Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Luc van Soest 13 posts 148 karma points
    Jan 04, 2016 @ 09:19
    Luc van Soest
    0

    Custom controller to media (Umbraco 7)

    I'm trying to create a custom controller for media for adding an extra http-header to files based on a setting in the backend.

    I found this article http://umbracodevelopers.sdesign1dev.co.uk/2015/6/18/securing-the-media-section/ which describes a method for hijacking the media route with a custom controller. I implemented this before in Umbraco 6 and this method works perfect but when I try to implement this in Umbraco 7, I can't get it to work.

    I already tried to inherit my custom controller from PluginController instead of Controller like in the article but it doesn't hit the custom action.

    It does work when I leave out the image-extension in the path, so the issue is probably related to the handling of static files, but I was in the assumption that RouteTable.Routes.RouteExistingFiles = true; would solve this.

    ~/App_Code/StartupHandler.cs

    public class StartupHandler : IApplicationEventHandler
    {
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            RouteTable.Routes.RouteExistingFiles = true;
    
            //Create a custom routes
            RouteTable.Routes.MapRoute(
                "MediaRoute",
                "Media/{id}/{file}",
                new
                {
                    controller = "Media",
                    action = "Index",
                    id = UrlParameter.Optional,
                    file = UrlParameter.Optional
                }
            );
        }
    
        public void OnApplicationInitialized(
            UmbracoApplicationBase umbracoApplication,
            ApplicationContext applicationContext)
        {
        }
    
        public void OnApplicationStarting(
            UmbracoApplicationBase umbracoApplication,
            ApplicationContext applicationContext)
        {
        }
    }
    

    ~/Controllers/MediaController.cs

    public class MediaController : PluginController
    {
        public MediaController()
            : this(UmbracoContext.Current)
        {
        }
    
        public MediaController(UmbracoContext umbracoContext)
            : base(umbracoContext)
        {
        }
    
        public ActionResult Index(string id, string file)
        {
            string mediaPath = "/media/" + id + "/" + file;
    
            IMediaService mediaService = ApplicationContext.Current.Services.MediaService;
    
            IMedia media = mediaService.GetMediaByPath(mediaPath);
    
            if (media != null)
            {
                bool hideFromSearchEngines = media.GetValue<bool>("hideFromSearchEngines");
    
                if (hideFromSearchEngines == true)
                {
                    System.Web.HttpContext.Current.Response.AddHeader("X-Robots-Tag", "noindex, nofollow");
                }
    
                FileStream fileStream = new FileStream(Server.MapPath(mediaPath), FileMode.Open);
    
                return new FileStreamResult(fileStream, MimeMapping.GetMimeMapping(file));
            }
            else
            {
                return HttpNotFound();
            }
        }
    }
    
  • Luc van Soest 13 posts 148 karma points
    Jan 05, 2016 @ 09:12
    Luc van Soest
    0

    I'm not able to deploy this yet to the production environment but I can imagine this might has something to do with a difference in handling of http-requests between IISExpress and IIS.

    I'm surely not the first person trying to do this, anyone got any ideas?

  • Luc van Soest 13 posts 148 karma points
    Jan 06, 2016 @ 10:25
    Luc van Soest
    0

    Still no success here...

    I tried adding this to web.config

      <location path="media">
    <system.web> 
      <httpHandlers>
        <add verb="GET" path="*" type="System.Web.Handlers.TransferRequestHandler" />
      </httpHandlers>
    </system.web>
    <system.webServer>
      <handlers>
        <clear />
        <add name="Media" path="*" verb="GET"  type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" allowPathInfo="true" resourceType="File" />
      </handlers>
    </system.webServer>
    

    I thought, this way I could force the handling of static files.

    Any advice and suggestions will be greatly appreciated

  • Luc van Soest 13 posts 148 karma points
    Jan 06, 2016 @ 12:29
    Luc van Soest
    103

    I think figured it out. I believe the ImageProcessorModule is handling the image-routing and that's why my own handler isn't getting hit. That also explains why my code is working in Umbraco 6 but not in 7. (ImageProcessorModule is introduced in 7.(1)?)

    Lucky for me, I actually only need to add these http-headers to 'document'-files and not to images.

    So my code is working now with all types of images with the exception of image-files. Had to alter my controller though.

    public class MediaController : Controller
    {
        // GET: Media
        public ActionResult Index(string id, string file)
        {
            string mediaPath = "/media/" + id + "/" + file;
    
            IMediaService mediaService = ApplicationContext.Current.Services.MediaService;
    
            IMedia media = mediaService.GetMediaByPath(mediaPath);
    
            if (media != null)
            {
                bool hideFromSearchEngines = media.GetValue<bool>("hideFromSearchEngines");
    
                if (hideFromSearchEngines == true)
                {
                    System.Web.HttpContext.Current.Response.AddHeader("X-Robots-Tag", "noindex, nofollow");
                }
    
                FileStream fileStream = new FileStream(Server.MapPath(mediaPath), FileMode.Open);
    
                return new FileStreamResult(fileStream, MimeMapping.GetMimeMapping(file));
            }
            else
            {
                return HttpNotFound();
            }
        }
    }
    

    Hope someone finds my research useful ;-)

Please Sign in or register to post replies

Write your reply to:

Draft