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 ;-)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies