fabianmichael/kirby-imagekit

Image-Discovery seems to not work when using specific routing

wottpal opened this issue · 4 comments

Hey,
I've just noted that automatic discovery seems not to work when I use the following routing-setup. (Which is basically just the Omitting the blog folder in URLs example from the Kirby Docs).

c::set('routes', [

  // Rewrite all 'items/...' URLs to be at the root of the site
  // and '/items' itself to the root '/'
  [
    'pattern' => '(:any)',
    'action'  => function($uid) {

      $page = page($uid);

      // if($uid == 'items') go('/');
      if(!$page) $page = page('items/' . $uid);
      if(!$page) $page = site()->errorPage();

      return site()->visit($page);
    }
  ],
  [
    'pattern' => 'items/(:any)',
    'action'  => function($uid) {
      go($uid);
    }
  ]

]);

Am I doing something wrong here? If I remove these two rules it starts discovering all pages unter items/ just properly.

Dennis

I actually never tested this setup, but I am sure about why this fails: ImageKit’s crawler will not follow redirects. The crawler uses output buffering whenever a page is requested and overrides the original headers of requested pages if they return a redirect header, so the AJAX request will not fail. The main reason for that is to prevent XHR errors, when the redirect links to a different domain (which not not make sense for ImageKit, even if it would work).

A possible solution is to examine if the target URL of a redirect points to the same domain as the Kirby installation and then crawls it. I just have to ensure, that only real Kirby-pages are crawled and that XHR will never try to fetch e.g. that 1.5 GB demo reel someone uploaded to show his/her AfterEffects skills.

Oh okay, that makes sense. Any idea for a quick workaround until 1.2.0?

ImageKit sends a custom HTTP header when crawling the site. You can catch that header before sending your redirect.:

if(isset($_SERVER['HTTP_X_IMAGEKIT_INDEXING'])) {
  // render page like Kirby would normally do
} else {
  // redirect
  go(…);
}

That should do the trick. While seeing this solution, it might be much easier if I would just implement an API function to catch redirects, rather than trying to analyze URLs, because this will possibly create new issues with other setups e.g. offering file downloads which are served by Kirby. I think, as soon as there is some special setup, it might be easier to provide sth. like ImageKit::isCrawlerRequest() than having to guess from the server-side. Nevertheless, I’ll add this to the documentation.

Please tell me, if my proposed solution works for you, but leave this issue open, so I have a reminder to add it to the readme file.

Hey, thanks as always.

It worked, I've changed the latter of the above routes in the following way:

  [
    'pattern' => 'items/(:any)',
    'action'  => function($uid) {
      // Intercept ImageKit Request
      if (isset($_SERVER['HTTP_X_IMAGEKIT_INDEXING'])) {
        $page = page("items/${uid}");
        if(!$page) $page = site()->errorPage();
        return site()->visit($page);
      }

      go($uid);
    }
  ]

But maybe I will just drop the URL-abbreviation. Not sure yet.

Dennis