Skip to content

Resolver: allow to ignore custom domains #9089

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

Merged
merged 3 commits into from
Apr 26, 2022

Conversation

stsewd
Copy link
Member

@stsewd stsewd commented Apr 7, 2022

This is useful if we want to get all domains this
project can be served from (we have project.domains,
but we are missing the "normal" one).

Specially I'm going to use this on .com.

I have also brought the _use_cname check from .com, so we don't need to override that method on .com.

This is useful if we want to get all domains this
project can be served from (we have project.domains,
but we are missing the "normal" one).

Specially I'm going to use this on .com.
@stsewd stsewd requested a review from a team as a code owner April 7, 2022 20:44
Comment on lines 373 to 374
url = resolve_domain(project=self.pip, use_custom_domain=False)
self.assertEqual(url, "pip.readthedocs.io")
Copy link
Member Author

Choose a reason for hiding this comment

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

this is probably the main test, since the other ones should return the same response.

Copy link
Member

@humitos humitos left a comment

Choose a reason for hiding this comment

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

I'm not sure to understand how this PR will be used.

resolve_domain will return just one domain if the project has multiple custom domains configured, but the description of the PR says:

This is useful if we want to get all domains this project can be served from

So, it seems that it does not cover that case, right?

Copy link
Member

@humitos humitos left a comment

Choose a reason for hiding this comment

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

Also, instead of adding this extra complexity to the resolve_domain, why don't you create a new helper function that returns exactly what you need? Example,

def all_project_domains(project):
    all_domains = [f'{project.slug}.{settings.PUBLIC_DOMAIN}'] + project.domains.values_list('domain', flat=True)

That will be clearer and don't require modifying the code we are already using to always return the "user facing" domain where docs are served.

@stsewd
Copy link
Member Author

stsewd commented Apr 11, 2022

Mostly because this logic is already in the resolver

def _get_project_subdomain(self, project):
"""Determine canonical project domain as subdomain."""
subdomain_slug = project.slug.replace('_', '-')
return '{}.{}'.format(subdomain_slug, settings.PUBLIC_DOMAIN)

don't want to have duplicating that in other parts of our code

@ericholscher
Copy link
Member

ericholscher commented Apr 11, 2022

I think I agree with @humitos here. This feels like an odd special case to introduce into the resolver for a very specific use case. I'd like to keep the resolver as simple as possible given how important it is. If we don't want to duplicate code, let's just move that logic into a util function, and call it both places?

I'm 👍 on porting _use_cname changes, but the use_custom_domain flag feels like unneeded complexity.

@stsewd
Copy link
Member Author

stsewd commented Apr 13, 2022

Hmm, was changing this, but I just realized that I need to call to _get_canocical_project from the resolver

canonical_project = self._get_canonical_project(project)

this is in order to return the correct subdomain for translations and subprojects.

So, doesn't look like we can move this outside the resolver. We could do the get_canonical_project method public and use it outside, but feels like we would be duplicating the same the logic from the resolver.

@ericholscher
Copy link
Member

this is in order to return the correct subdomain for translations and subprojects.

This is a valid point, but it still feels like we're doing something weird here. We were just talking about #8250 -- if we were hoping to solve that problem, would this change to the resolver also help there? I think it might be useful to think a bit higher level about how we want domains to work, and see how we can improve the resolver to solve a few of these problems.

@stsewd
Copy link
Member Author

stsewd commented Apr 14, 2022

We were just talking about #8250 -- if we were hoping to solve that problem, would this change to the resolver also help there?

So, we do agree to always serve the documentation from the current domain instead of redirecting or making this an option?

But this change won't solve that, since the resolver may need to have access to the request or the current domain

@ericholscher
Copy link
Member

ericholscher commented Apr 19, 2022

But this change won't solve that, since the resolver may need to have access to the request or the current domain

I'm more thinking about how we would implement the proposed request, and if this code helps. Presumably to solve this issue we'd need to:

  • On incoming URL, determine if the project has a canonical URL, if so redirect
  • If no canonical URL, don't do any domain redirection. This could be achieved by returning a relative URL, or passing in the domain of the current request?

This logic doesn't need to be in the resolver, it could be in the redirect code, but we'd presumably call into the resolver with some specific argument. I'm wondering if it would be something like passing in the domain explicitly from the request?

It feels like this PR is mostly stuck, and we should get it merged. I think we're just trying to find a nicer abstraction for this code, or understand other use cases where this functionality might be useful to make it feel like less of a one-off special case.

@humitos
Copy link
Member

humitos commented Apr 20, 2022

It feels like this PR is mostly stuck, and we should get it merged. I think we're just trying to find a nicer abstraction for this code, or understand other use cases where this functionality might be useful to make it feel like less of a one-off special case.

I'm fine updating this PR to solve the special case using a helper instead of adding the logic inside the current flow as I suggested in #9089 (review).

We can find other use cases in the future and build a nicer abstraction with a refactor, but I'd prefer if we don't merge the special case into the current flow if that's possible.

@stsewd
Copy link
Member Author

stsewd commented Apr 20, 2022

I'm fine updating this PR to solve the special case using a helper instead of adding the logic inside the current flow as I suggested in #9089 (review).

As explained in #9089 (comment) isn't possible to use that solution, we need to use the logic that is inside the resolver

Copy link
Member

@ericholscher ericholscher left a comment

Choose a reason for hiding this comment

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

Given the conversation, we do need to use the resolver for understanding if a project is a subproject or similar. We don't want to reimplement that logic elsewhere, so I think this seems like the right place for this code. 👍

If we end up wanting to extend this, we can always change our internal implementation of this, since it isn't a public API or anything. I'm fine with the current approach for now, and we can easily refactor it later if needed, since we're only using it in 1 place.

@@ -731,9 +731,9 @@ def alias(self):
if self.is_subproject:
return self.superprojects.first().alias

def subdomain(self):
def subdomain(self, use_custom_domain=True):
Copy link
Member

Choose a reason for hiding this comment

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

Do we actually want use_canonical_domain here? Seems like that is the actual case where the domain would be changed, and is clearer in cases of multiple custom domains?

@@ -731,9 +731,9 @@ def alias(self):
if self.is_subproject:
return self.superprojects.first().alias

def subdomain(self):
def subdomain(self, use_custom_domain=True):
Copy link
Member

Choose a reason for hiding this comment

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

Do we actually want use_canonical_domain here? Seems like that is the actual case where the domain would be changed, and is clearer in cases of multiple custom domains?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure I understood what you meant p: do you mean changing the parameter to something else? or not exposing this "feature" on that method and instead manually call resolve_domain?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, changing the name of the kwarg.

@stsewd stsewd enabled auto-merge (squash) April 26, 2022 23:29
@stsewd stsewd merged commit 827e653 into main Apr 26, 2022
@stsewd stsewd deleted the resolver-allow-ignore-custom-domain branch April 26, 2022 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants