Download & Extend

Problems with custom_url_rewrite_outbound

Project:Global Redirect
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed (duplicate)

Issue Summary

If you are using the function custom_url_rewrite_outbound() and custom_url_rewrite_inbound() global redirect is getting into an endless loop.

function custom_url_rewrite_outbound(&$path, &$options, $original_path) {

  if (preg_match('|^user(/.*)|', $path, $matches)) {
    $path = 'new-user-url'. $matches[1];
  }

}

function custom_url_rewrite_inbound(&$result, $path, $path_language) {

    if (preg_match('|^new-user-url(/.*)|', $path, $matches)) {
      $result= 'user'. $matches[1];
    }
}

Comments

#1

You can solute this problem with following code - better ideas are welcome!

before:

    if ($_REQUEST['q'] != $prefix . $alias) {

      drupal_goto($alias, $query_string, NULL, 301);
    }

add:

    if (function_exists('custom_url_rewrite_inbound')) {
        custom_url_rewrite_inbound($custom_path, $_REQUEST['q'], '');
        if($custom_path != '') {
            $_REQUEST['q'] = $custom_path;
        }
    }

#2

Status:active» postponed (maintainer needs more info)

Surely we'd need to apply the custom_url_rewrite_inbound to $_REQUEST['q'] at the very beginning so it effects all the redirects (frontpage, '/0' trimming, etc).

Also - is this problem due to not using custom_url_rewrite_inbound OR is it relating to outbound (as the subject suggests)?

Any thoughts?

#3

The subject is wrong. It should be mean "Problems with custom_url_rewrite_inbound". I think there are many situations that need both functions in the interplay use. But the problem with global redirect is just to find in custom_url_rewrite_inbound().

-I used this code above for a productiv website and there are no problems.
-I used custom_url_rewrite_inbound() in settings.php.

#4

I have a better patch here. And it is a severe problem. First here are my rewrite functions

<?php
/**
* rewrite incoming urls to drupal urls
*
* @param result
* the resulting path, input value is the current path, and function should
* change this value
*
* @param path
* the path (?q=PATH)
*
* @param path_language
* not used by us. What do with it?
*/
function custom_url_rewrite_inbound(&$result, $path, $path_language) {
  global
$conf;

 
// remove community url prefix which shouldn't be used as an arg()
  // the homepage is an example since apache strips the last / so we test differently for this case
 
if (!empty($conf['community_config_url_prefix'])) {
    if (
substr($conf['community_config_url_prefix'], 0, -1) == $result) {
     
$result = $conf['site_frontpage'];
    }
    elseif (
strpos($result, $conf['community_config_url_prefix']) === 0) {
    
$result = substr_replace($result, '', 0, strlen($conf['community_config_url_prefix']));
    }
  }
  static
$uid_cache = array(); // static cache the uids
 
$args = explode('/', $result);
  if (
custom_url_skip($args)) {
    return;
  }
  if ((
$args[0] == 'user' || $args[0] == 'blog') && isset($args[1])) {
    if (isset(
$uid_cache[$args[1]])) {
     
$uid = $uid_cache[$args[1]];
    }
    else {
     
$uid = ($GLOBALS['user']->uid && $args[1] == $GLOBALS['user']->name) ? $GLOBALS['user']->uid : db_result(db_query("SELECT uid FROM {users} WHERE name ='%s'", $args[1]));
     
$uid_cache[$args[1]] = $uid;
    }
   
$result = str_replace($args[0] .'/'. $args[1], $args[0] .'/'. $uid, $result);
  }
}

/**
* rewrite internal paths into user facing paths
*
* @param path
* This is the pass by refrence variable. This value should be changed to the
* desired path
*
* @param options
* array of link options. @see url()
*
* @param orginal_path
* the orginal, internal path generated by url() function
*/
function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
  global
$conf;
  static
$user_names = array();
 
$arg = explode('/', $original_path);
 
  if ((
$arg[0] == 'user' || $arg[0] == 'blog') && is_numeric($arg[1])) {
    if (
$arg[1] == $GLOBALS['user']->uid) {
     
$name = $GLOBALS['user']->name;
    }
    else {
     
// the same username can appear more than once on a page so we static cache the result
     
if (!isset($user_names[$arg[1]])) {
       
$name = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $arg[1]));
       
$user_names[$arg[1]] = $name;
      }
      else {
       
$name = $user_names[$arg[1]];
      }
    }
   
// Drupal paths are case senstive, since it does things like arg(0) == 'node'
    // make sure usernames are lowercase for paths & links as well
   
$name = strtolower($name);

   
$path = str_replace($arg[0] .'/'. $arg[1], $arg[0] .'/'. check_plain($name), $original_path);
  }

 
// add in community url prefix to all URLs to segment content but not act as a real arg()
 
$path = $conf['community_config_url_prefix'] . $path;
}
?>

Basically, what they do is rewrite the user/ID/* urls to user/NAME/*. This in conjunction with global redirect makes user/NAME/* redirect forever.

Why this happens

drupal_get_path_alias() returns either an alias url (from the url_alias table) or the drupal_normal_path (user/1/*). Global redirect assumes that if the $alias (which is from drupal_get_path_alias()) doesn't match the $_REQUEST['q'] then we need to redirect. The problem with that is an aliased path can come from the url_alias table, and it can come from custom_url_rewrite_* (which drupal_get_path_alias() ignores). So the $_REQUEST['q'] = user/scott but $request = user/1 and alias = user/1.

Thus this simple patch.

AttachmentSizeStatusTest resultOperations
globalredirect.patch1.1 KBIgnored: Check issue status.NoneNone

#5

Status:postponed (maintainer needs more info)» needs review

plz review

#6

patch in #4 works great for me - thanks Scott :)

#7

if looking for ways to test this patch try drupal.org/project/spaces

That too will make globalredirect cry out in pain :-D, this patch should fix that.

#8

It fixed my use case which was just a simple menu item path rewrite, where it would get stuck in a loop.

I think this will also fix the issue when using this module with the subdomain module. Will be testing that later this week.

Thanks again

Ben

#9

I think this will also fix the issue when using this module with the subdomain module. Will be testing that later this week.

After testing, this patch doesn't fix the issue with subdomain module after all - that needs some further changes to work.

#10

Status:needs review» needs work

DOH! this breaks the de-slashing.

#11

Status:needs work» needs review

Here is a naive fix.

AttachmentSizeStatusTest resultOperations
redirect.patch1.12 KBIgnored: Check issue status.NoneNone

#12

Ok so this is a real fix :-D

Basic idea is we need to find the 'alias'. And it can exists in two spots, the url_alias table or via custom_url_rewrite_* functions.

I like this patch so much better, its clean.

AttachmentSizeStatusTest resultOperations
cvs_redirect.patch989 bytesIgnored: Check issue status.NoneNone

#13

Status:needs review» closed (duplicate)

#346911: Redirect Loop and custom_url_rewrite ignored

nobody click here