Repository: readthedocs/readthedocs.org
Issue: How to enable query parameters in redirects?

I don't really understand how any of this works under the covers, but since  #5081 has been merged this should be supported, right?

For example, I have set the default version of my project to `0.6.0`, so it correctly redirects https://nbsphinx.readthedocs.io/ to https://nbsphinx.readthedocs.io/en/0.6.0/.

However, when I use the search URL with a query parameter, the parameter is somehow lost in redirection:

## Expected Result

https://nbsphinx.readthedocs.io/search.html?q=readthedocs should get redirected to https://nbsphinx.readthedocs.io/en/0.6.0/search.html?q=readthedocs

## Actual Result

https://nbsphinx.readthedocs.io/search.html?q=readthedocs gets redirected to https://nbsphinx.readthedocs.io/en/0.6.0/search.html

Changed files:
readthedocs/proxito/views/serve.py, readthedocs/proxito/tests/handler_404_urls.py, readthedocs/proxito/tests/test_full.py, readthedocs/proxito/views/mixins.py

diff --git a/readthedocs/proxito/tests/handler_404_urls.py b/readthedocs/proxito/tests/handler_404_urls.py
index c918a7093..f39180c8e 100644
--- a/readthedocs/proxito/tests/handler_404_urls.py
+++ b/readthedocs/proxito/tests/handler_404_urls.py
@@ -25,7 +25,7 @@ def map_proxito_path(view_func):
         return view_func(
             request,
             *args,
-            proxito_path=request.get_full_path(),
+            proxito_path=request.path,
             **kwargs,
         )
     return inner_view
diff --git a/readthedocs/proxito/tests/test_full.py b/readthedocs/proxito/tests/test_full.py
index 2d91803e4..d02284682 100644
--- a/readthedocs/proxito/tests/test_full.py
+++ b/readthedocs/proxito/tests/test_full.py
@@ -333,8 +333,7 @@ class TestAdditionalDocViews(BaseDocServing):
         self.project.versions.update(active=True, built=True)
         # Confirm we've serving from storage for the `index-exists/index.html` file
         response = self.client.get(
-            reverse('proxito_404_handler', kwargs={
-                    'proxito_path': '/en/latest/index-exists?foo=bar'}),
+            reverse('proxito_404_handler', kwargs={'proxito_path': '/en/latest/index-exists'}) + '?foo=bar',
             HTTP_HOST='project.readthedocs.io',
         )
         self.assertEqual(
diff --git a/readthedocs/proxito/views/mixins.py b/readthedocs/proxito/views/mixins.py
index 4d62afe53..8931e87ee 100644
--- a/readthedocs/proxito/views/mixins.py
+++ b/readthedocs/proxito/views/mixins.py
@@ -205,6 +205,8 @@ class ServeRedirectMixin:
         """
 
         schema, netloc, path, params, query, fragments = urlparse(proxito_path)
+        # `proxito_path` doesn't include query params.
+        query = urlparse(request.get_full_path()).query
         new_path = urlunparse((schema, netloc, redirect_path, params, query, fragments))
 
         # Re-use the domain and protocol used in the current request.
diff --git a/readthedocs/proxito/views/serve.py b/readthedocs/proxito/views/serve.py
index 91f844d3b..5ad268315 100644
--- a/readthedocs/proxito/views/serve.py
+++ b/readthedocs/proxito/views/serve.py
@@ -235,7 +235,13 @@ class ServeError404Base(ServeRedirectMixin, ServeDocsMixin, View):
                     new_path = parts.path.rstrip('/') + f'/{tryfile}'
                 else:
                     new_path = parts.path.rstrip('/') + '/'
-                new_parts = parts._replace(path=new_path)
+
+                # `proxito_path` doesn't include query params.`
+                query = urlparse(request.get_full_path()).query
+                new_parts = parts._replace(
+                    path=new_path,
+                    query=query,
+                )
                 redirect_url = new_parts.geturl()
 
                 # TODO: decide if we need to check for infinite redirect here