-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Proxito: use unresolver in 404 handler #10074
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
Conversation
@stsewd heads up, I've added some commits here to make the refactor work, I'll take it for a test run and push changes directly unless you're working on it right now? |
…e-proxito-v2-in-404-handler
The PR currently looks a bit crazy until refactor-unresolver also has merged in the latest |
…ocs.org into use-proxito-v2-in-404-handler
|
||
def test_redirect_prefix_crossdomain_with_newline_chars(self): | ||
""" | ||
Overridden to make it compatible with the new implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also make the old implementation compatible, isn't a lot of code, but I'm not sure if we want to spend more time there... (but kind of already spent time debugging it :_)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The old implementation", is the one we are going to delete, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah
project = None | ||
version = None | ||
filename = None | ||
lang_slug = None | ||
version_slug = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is ready for review... but I don't like that we are defining lots of variables that are kind of related, this is kind of a copy/paste of the old implementation, but maybe there is a better way...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are mainly needed for custom redirects, maybe the answer is there... if we can simplify the redirects code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, yeah, we should be able to remove version_slug
and lang_slug
with #10112 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do x = y = z = None
, at least? But not a huge deal, I'm fine with the more explicit version, also :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I don't like too much the one-line assignment too much because it's harder to read the name of the variables. But that's a personal preference 😄
Is this ready to review? How does it relate to #9657? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a useful refactor, but want to make sure we aren't losing important context/comments in the refactor. Probably just needs to be compared again current main
, and adapted from all the previous reviews.
Really great work knocking down these refactors @stsewd 🎉
return HttpResponseRedirect(redirect_url) | ||
|
||
return None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't review the functions above too closely, since they are just copy/pasted from inside the views, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah logic is the same, copy/paste, just the variable names changed final_project -> project
, version_slug -> version.slug
and so.
readthedocs/proxito/views/serve.py
Outdated
# We force all storage calls to use the external versions storage, | ||
# since we are serving an external version. | ||
if unresolved_domain.is_from_external_domain: | ||
self.version_type = EXTERNAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there is a cleaner way to do this? Could we explicitly set a queryset manager or something here, instead of depending on the downstream code getting this passed in and interpretting it properly? Not 100% sure that makes sense, but would be good to be extra explicit to avoid issues around this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version that results from the unresolve_path()
call already is validated to use the correct manager, this is more like an extra protection (and to reuse the same methods with the older implementation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool 👍 . Probably worth noting that in the comment as well (I might like comments too much, but mission-critical code is important note this stuff), since I thought this was SECURITY CRITICAL
, instead of Be extra defensive
...
# We force all storage calls to use the external versions storage, | |
# since we are serving an external version. | |
if unresolved_domain.is_from_external_domain: | |
self.version_type = EXTERNAL | |
# We force all storage calls to use the external versions storage, | |
# since we are serving an external version. | |
# The version that results from the unresolve_path() call already is validated to use the correct manager, | |
# this is here to add defense in depth against serving the wrong version. | |
if unresolved_domain.is_from_external_domain: | |
self.version_type = EXTERNAL |
project = None | ||
version = None | ||
filename = None | ||
lang_slug = None | ||
version_slug = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do x = y = z = None
, at least? But not a huge deal, I'm fine with the more explicit version, also :)
except VersionNotFoundError as exc: | ||
project = exc.project | ||
lang_slug = project.language | ||
version_slug = exc.version_slug | ||
filename = exc.filename | ||
except TranslationNotFoundError as exc: | ||
project = exc.project | ||
lang_slug = exc.language | ||
version_slug = exc.version_slug | ||
filename = exc.filename | ||
except InvalidExternalVersionError as exc: | ||
project = exc.project | ||
except InvalidPathForVersionedProjectError as exc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could use comments explaining what the actual case here is. I can kind of tell from the explicit naming, but I think a bit more context is useful (eg. when might these things happen? Why do we only care about a subset of the variables in those cases?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put a comment at the top of the try, since an exception happened, we fill the other variables with the information that we have available.
request.path_project_slug = project.slug | ||
request.path_version_slug = version_slug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These variable names seem not super correct? Are we sure these were parsed from a path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the names aren't correct, we sometimes pass the slug from the external version domain or the default version on single version projects. But this is what we expect in the middleware
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably an area for further refactor, but not important in this PR. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to merge after my comment suggestions are added in :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. I left some small comments, tho.
|
||
def test_redirect_prefix_crossdomain_with_newline_chars(self): | ||
""" | ||
Overridden to make it compatible with the new implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The old implementation", is the one we are going to delete, right?
# If we were able to resolve to a valid version, it means that the | ||
# current file doesn't exist. So we check if we can redirect to its | ||
# index file if it exists before doing anything else. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by "redirect ot its index file"? /en/latest/file/
-> /en/latest/file/index.html
?
If that's correct, can you expand the comment with an example similar to the one I wrote?
project = None | ||
version = None | ||
filename = None | ||
lang_slug = None | ||
version_slug = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I don't like too much the one-line assignment too much because it's harder to read the name of the variables. But that's a personal preference 😄
This is on top of #10037 and requires #10044. I'll update this PR once those are merged.