Bug Report #4288

Redirect on HTTPS site does not function properly in 3.2.0

Added by Dustin Masters 8 months ago. Updated 4 months ago.

Status:Closed Start date:09/29/2011
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:Core
Target version:-
Resolution:duplicate Points:1

Description

On a site with HTTPS enabled, making a call to $this->request->redirect('page') always redirects to just normal HTTP. For example:

On site https://localhost:81/kohana/home, calling:
$this->request->redirect('page');

Will redirect to:
http://localhost:81/kohana/page

The docs at: http://kohanaframework.org/3.2/guide/api/Request#redirect state that request.php contains this function:

public function redirect($url = '', $code = 302)
{
    $referrer = $this->uri();
    $protocol = ($this->secure()) ? 'https' : TRUE;

    if (strpos($referrer, '://') === FALSE)
    {
        $referrer = URL::site($referrer, $protocol, ! empty(Kohana::$index_file));
    }

    if (strpos($url, '://') === FALSE)
    {
        // Make the URI into a URL
        $url = URL::site($url, TRUE, ! empty(Kohana::$index_file));
    }

    if (($response = $this->response()) === NULL)
    {
        $response = $this->create_response();
    }

    echo $response->status($code)
        ->headers('Location', $url)
        ->headers('Referer', $referrer)
        ->send_headers()
        ->body();

    // Stop execution
    exit;
}

But it actually contains:

public function redirect($url = '', $code = 302)
    {
        $referrer = $this->uri();

        if (strpos($referrer, '://') === FALSE)
        {
            $referrer = URL::site($referrer, TRUE, Kohana::$index_file);
        }

        if (strpos($url, '://') === FALSE)
        {
            // Make the URI into a URL
            $url = URL::site($url, TRUE, Kohana::$index_file);
        }

        if (($response = $this->response()) === NULL)
        {
            $response = $this->create_response();
        }

        echo $response->status($code)
            ->headers('Location', $url)
            ->headers('Referer', $referrer)
            ->send_headers()
            ->body();

        // Stop execution
        exit;
    }

Even the $protocol line is inserted, I still had to change TRUE to $protocol in the line:
$url = URL::site($url, TRUE, ! empty(Kohana::$index_file));

After fixing that line, the redirect worked properly.


Related issues

duplicates Kohana v3.x - Bug Report #4135: Request protocol not correctly being set to https v3.2.1 Closed 07/26/2011 07/26/2011

History

Updated by Jeremy Bush 8 months ago

redirect() uses `url::base()`. Is your base_url set correctly in your bootstrap?

Updated by Dustin Masters 8 months ago

I will try specifically putting the site's base url including https in the base_url, but we need it to be able to detect whether it's on a https site via the $protocol variable. The functionality seems to be there, just half-complete (two changes to the source code and it seems to work great without the bootstrap workaround)

Updated by Mason Schoolworthy 6 months ago

I think the issue is in URL::base. There's a line in there that uses ->protocol() from Request::$initial to determine whether it's "http" or "https". It should be using the newly added ->secure(). I think there was some confusion switching $protocol from meaning either "http" or "https" to "HTTP/1.1". And it gets even more complicated in URL::base because the variable $protocol is first used to get the initial request.

Here's the code from 3.2.0

        if ($protocol === TRUE)
        {
            // Use the initial request to get the protocol
            $protocol = Request::$initial;
        }

        if ($protocol instanceof Request)
        {
            // Use the current protocol
            list($protocol) = explode('/', strtolower($protocol->protocol()));

        }

It should be something like this instead

        if ($protocol === TRUE)
        {
            // Use the initial request to get the protocol
            $initial_request = Request::$initial;
        }

        if ($initial_request instanceof Request)
        {
            // Use the current protocol
              if ($initial_request->secure()) {
                $protocol = 'https';
              } else {
                $protocol = 'http';
              }

        }

Updated by Dustin Masters 5 months ago

Looks like that did the trick, with a small modification. I changed this code block in system/classes/kohana/url.php from this:

// Start with the configured base URL
$base_url = Kohana::$base_url;

if ($protocol === TRUE)
{
    // Use the initial request to get the protocol
    $protocol = Request::$initial;
}

if ($protocol instanceof Request)
{
    // Use the current protocol
    list($protocol) = explode('/', strtolower($protocol->protocol()));
}

To this:

// Start with the configured base URL
$base_url = Kohana::$base_url;

if ($protocol === TRUE)
{
    // Use the initial request to get the protocol
    $initial_request = Request::$initial;
    if ($initial_request instanceof Request)
    {
        // Use the current protocol
        if ($initial_request->secure()) {
            $protocol = 'https';
        } else {
            $protocol = 'http';
        }
    }
}

And now everything works great.

Updated by Woody Gilk 4 months ago

  • Category set to Core
  • Status changed from New to Closed
  • Resolution set to duplicate

Also available in: Atom PDF