In my particular case, I have the main drupal site on http://site.com and after I login, I want it to go to http://fourms.site.com. I want it to do this because I am using drupalVB module to provide single login/logout for a vBulletin forum. Apparently, in the drupal_goto() function, it ignores the domain name you supply for the destination variable, and uses the path only. Ideally, drupal_goto() should accept destination urls for domains that are 'trusted'.

Has anyone run into this issue?

Comments

movit’s picture

Think following patch for drupal_goto() do the job

replace this string

$url = url($path, $query, $fragment, TRUE); 

to this one

if (empty($host)){
   $url = url($path, $query, $fragment, TRUE); 
}
else{
   $url = url($scheme . '://' . $host . $path, $query, $fragment);
}

$scheme and $host variables appears from previous extract(...) calls

For all destinations set by current drupal code this patch works as before.
But if destination contain full URL "http://otherdomain.com/path/to/resource" patched drupal_goto will redirect
user to correct domain.

What drupal guru can say about session id in such redirection?

ttkaminski’s picture

This the the code I ended up using on the site. It works quite well.

function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
  if (isset($_REQUEST['destination'])) $url = $_REQUEST['destination'];
  else if (isset($_REQUEST['edit']['destination'])) $url = $_REQUEST['edit']['destination'];

  if($url) extract(parse_url(urldecode($url)));

  if($host==$_SERVER['SERVER_NAME'] || $host=='') {
     if($path=='/') $path = '';
     $url = url($path, $query, $fragment, TRUE);
  }

  // Before the redirect, allow modules to react to the end of the page request.
  module_invoke_all('exit', $url);

  header('Location: '. $url, TRUE, $http_response_code);

  // The "Location" header sends a REDIRECT status code to the http
  // daemon. In some cases this can go wrong, so we make sure none
  // of the code below the drupal_goto() call gets executed when we redirect.
  exit();
}
DerTobi75’s picture

Does this work with Drupal 5.8?

Ok, got it to work ;)

neclimdul’s picture

did you try passing http://forums.site.com to drupal_goto?
url() should allow you to take an absolute path as an argument. It will not try to modify it if it sees the http://

coltrane’s picture

Title: Destination parameter in drupal_goto doesn't support url on a different domain » Support external sites in drupal_goto
Version: 5.0-rc1 » 7.x-dev
Priority: Minor » Normal

I'd like to see support for this so just updating to HEAD. Also, this dev list thread is relevant: http://lists.drupal.org/pipermail/development/2008-May/029772.html

dave reid’s picture

There has never been a problem with drupal_goto and absolute urls. I use it in the FeedBurner module all the time to redirect requests to feedburner feeds.

coltrane’s picture

You are right, if you pass drupal_goto() a absolute URL it works fine, however follow me on an example to see how it can fail. Say you have a subdomain of your site that isn't Drupal and you have a link to log in via Drupal and you'd like the user to come back to the subdomain after login. Putting the URL http://www.example.com/user/login?destination=http://sub.example.com will not work because drupal_goto() only uses $path and ignores the other parts of the URL. Now, there are other ways around this problem of course, but I haven't seen or heard yet why drupal_goto() shouldn't use the rest of the destination.

coltrane’s picture

Title: Support external sites in drupal_goto » Support external sites in destination request in drupal_goto
dave reid’s picture

Title: Support external sites in destination request in drupal_goto » Support external sites in drupal_goto

@7: Well that's an easy fix. Assuming you are currently on www.example.com, you just need to use: drupal_goto('user/login', 'destination='. urlencode('http://sub.example.com'));

coltrane’s picture

@Dave Reid, that doesn't solve my example, and while just an example it highlights that drupal_goto() relying on the destination doesn't support external sites.

roychri’s picture

I have a similar problem in D5 which might be totally related.

I have a link like this:

l(t('Click here'), 'vote', array('TARGET' => '_blank'), 'value=1&destination='. urlencode('ext_url?url=http://example.org'))

which produce:

<a href="/vote?value=1&amp;destination=ext_url%3Furl%3Dhttp%3A%2F%2Fexample.org" TARGET="_blank">Click here</a>

When you click on the link I want the user to be sent to the vote url which will cast a vote.
The vote callback happens to use drupal_goto() at the end so the user is redirected to the front page or the destination when present.
In this case, the destination is ext_url?url=http://example.org which simply present a page that inform the user he is about to leave the site before redirecting him to the external site. I am using the contrib module http://drupal.org/project/ext_link_page for that.

The problem occurs in drupal_goto()

Maybe the problem come from my version of PHP 5.2.3 ?

Here is the rundown:
First, this code is execute:

  if (isset($_REQUEST['destination'])) {
    extract(parse_url(urldecode($_REQUEST['destination'])));
  }

At this point the value of $_REQUEST['destination'] is "ext_url?url=http://example.org"
When this value is passed to parse_url(), is what is returned:

array (
  'host' => 'ext_url?url=http',
  'path' => '//example.org',
)

which is totally wrong.
that is because:

Note: This function doesn't work with relative URLs.

I am not inventing this, I took that straight from http://php.net/parse_url in the Notes section.
Yet, that is exacly what drupal_goto() is doing. It is using parse_url() for partial urls since destination values are more than 50% of the time relative urls.

I just checked D6 and D7 and they still use parse_url() on partial urls.

Granted, the documentation also says:

Partial URLs are also accepted, parse_url() tries its best to parse them correctly.

However, I think this is clear: when using partial urls, it might not work! When I see "tries its best", it means that is was clearly not meant to handle them.

I wish I had a solution to propose for this. If I come up with something, I will let you know.

roychri’s picture

Title: Support external sites in drupal_goto » Support external sites in destination request in drupal_goto
Category: feature » bug

Because of my comment above, I think this should be handled as a bug, not as a feature.

roychri’s picture

Status: Active » Closed (duplicate)
michaelfavia’s picture

Subscribe.