Skip to content

feat: improve multiple domain support #6759

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from

Conversation

kenjis
Copy link
Member

@kenjis kenjis commented Oct 26, 2022

Description
Fixes #5807
Related #6746

  • add Config\App::$allowedHostnames
  • update Config\App::$baseURL in IncomingRequest if HTTP_HOST is an allowed hostname

Changes:

  • current_url(), base_url(), site_url() will return the URL with allowed HTTP_HOST
  • previous_url() will return the site URL with allowed HTTP_HOST when cannot get it from session nor HTTP_REFERER

The following functions/methods are affected (There may be others):

  • Using site_url()
    • form_open()
    • audio()
    • embed()
    • img()
    • link_tag()
    • object()
    • script_tag()
    • source()
    • video()
    • RedirectResponse::route()
    • RedirectResponse::to()
    • Toolbar::prepare()
    • Toolbar::respond()
    • anchor()
    • anchor_popup()
    • base_url()
    • previous_url()
    • url_to()
  • Using base_url()
    • RedirectException in CodeIgnter.php L377
    • UserAgent::isReferral()
  • Using current_url()
    • ChromeLoggerHandler::__construct()
    • CodeIgniter::storePreviousURL()
    • Pager::ensureGroup()
    • Toolbar::run()

Ref #4651

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjis kenjis added enhancement PRs that improve existing functionalities 4.3 labels Oct 26, 2022
@@ -198,6 +196,7 @@ public function detectLocale($config)
protected function detectURI(string $protocol, string $baseURL)
{
// Passing the config is unnecessary but left for legacy purposes
// @TODO For what? Why clone?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clone prevents URI testing from changing the App Config globally.

Copy link
Member Author

@kenjis kenjis Oct 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for clone is only for testing, I would like to remove it.

--- a/system/HTTP/IncomingRequest.php
+++ b/system/HTTP/IncomingRequest.php
@@ -195,12 +195,7 @@ class IncomingRequest extends Request
      */
     protected function detectURI(string $protocol, string $baseURL)
     {
-        // Passing the config is unnecessary but left for legacy purposes
-        // @TODO For what? Why clone?
-        $config          = clone $this->config;
-        $config->baseURL = $baseURL;
-
-        $this->setPath($this->detectPath($protocol), $config);
+        $this->setPath($this->detectPath($this->config->uriProtocol), $this->config);
     }
 
     /**

Copy link
Member

@MGatner MGatner Oct 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And deprecate the baseURL input? Is that really only for testing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both $protocol and $baseURL of detectURI() are not needed.

__construct():

$this->detectURI($config->uriProtocol, $config->baseURL);

protected function detectURI(string $protocol, string $baseURL)
{
// Passing the config is unnecessary but left for legacy purposes
$config = clone $this->config;
$config->baseURL = $baseURL;
$this->setPath($this->detectPath($protocol), $config);
}

Copy link
Member

@michalsn michalsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be very useful feature.

At some point we probably should consider providing some easy function (helper) to generate a URL to a different host than this defined in baseURL.

@kenjis kenjis force-pushed the improve-subdomain-support branch from b984b8f to 52a8589 Compare October 27, 2022 04:53
@kenjis kenjis force-pushed the improve-subdomain-support branch from 52a8589 to b6e0976 Compare October 27, 2022 05:08
@kenjis
Copy link
Member Author

kenjis commented Oct 27, 2022

Is this a breaking change?

Copy link
Member

@MGatner MGatner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is mostly okay. I want to hear more about the write-back to App Config - that seems like a pretty big possibility for issues to creep in, and ones that would be difficult to trace. As far as I can tell the logic here is all self-contained, and since current_url() uses this class we shouldn't need to touch the Config.

@@ -395,33 +399,61 @@ public function setPath(string $path, ?App $config = null)

$config ??= $this->config;

if ($config->baseURL === '') {
// @codeCoverageIgnoreStart
exit('You have an empty or invalid base URL. The baseURL value must be set in Config\App.php, or through the .env file.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to be conditional on !is_cli() - what is the justification or precedent for requiring CLI to have this set?

Comment on lines +420 to +423
// Update Config\App::$baseURL
$uri = new URI($baseURL);
$uri->setHost($host);
$this->config->baseURL = $uri;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like components updating global Config values. This seems like a bad idea. What does this fix?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, all helpers will return "old" URLs, not one of those defined in allowedHostnames. That's basically the whole point of all these changes.

I have an app where subdomains and custom domains are used, but I use a more dynamic approach and handle it via Registrars. I would recommend this way, but the only downside is that we can't make it work with one config variable - it's a bit more complicated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the current real baseURL with allowedHostnames in somewhere.
I think Config\App::$baseURL in shared Config object is best,
because the baseURL is only one in a request and never changes. I don't see any problems.

But if something wrong that I miss, we need to save the current baseURL somewhere else.
Where?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather see anything that needs to rely on "URL for the incoming request" to use a component that represents that (IncomingRequest, current_url(), etc). It seems very counterintuitive that our Config values are dependent on infrastructure context.

I get that this is the most straightforward approach to a fix, but I think it pokes a new hole in our architecture that is liable to leak, grow bigger, etc.

I'm not a fan of the proliferation of global URL helpers we already have but I would prefer something like current_base_url() to this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: Registrars... I think that is a great solution at the project level, and would encourage it for individuals who need this currently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it may seem counter-intuitive that the value of one Config object changes dynamically.
I think it is better that the URI object in IncomingRequest has all the URL related data including the current baseURL.

@kenjis
Copy link
Member Author

kenjis commented Oct 29, 2022

Go to #6785

@kenjis kenjis closed this Oct 29, 2022
@kenjis kenjis deleted the improve-subdomain-support branch October 29, 2022 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement PRs that improve existing functionalities
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants