We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Away-from-origin redirects should add a new host header
Prompted by #310

Away-from-origin redirects currently remove the `Host` header, without adding a new one.
I think we ought to be using `headers['Host'] = url.authority.encode("ascii")` instead of simply deleting the header.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `httpx/middleware.py`
Content:
```
1 import functools
2 import typing
3 from base64 import b64encode
4 
5 from .config import DEFAULT_MAX_REDIRECTS
6 from .exceptions import RedirectBodyUnavailable, RedirectLoop, TooManyRedirects
7 from .models import URL, AsyncRequest, AsyncResponse, Cookies, Headers
8 from .status_codes import codes
9 
10 
11 class BaseMiddleware:
12     async def __call__(
13         self, request: AsyncRequest, get_response: typing.Callable
14     ) -> AsyncResponse:
15         raise NotImplementedError  # pragma: no cover
16 
17 
18 class BasicAuthMiddleware(BaseMiddleware):
19     def __init__(
20         self, username: typing.Union[str, bytes], password: typing.Union[str, bytes]
21     ):
22         if isinstance(username, str):
23             username = username.encode("latin1")
24 
25         if isinstance(password, str):
26             password = password.encode("latin1")
27 
28         userpass = b":".join((username, password))
29         token = b64encode(userpass).decode().strip()
30 
31         self.authorization_header = f"Basic {token}"
32 
33     async def __call__(
34         self, request: AsyncRequest, get_response: typing.Callable
35     ) -> AsyncResponse:
36         request.headers["Authorization"] = self.authorization_header
37         return await get_response(request)
38 
39 
40 class CustomAuthMiddleware(BaseMiddleware):
41     def __init__(self, auth: typing.Callable[[AsyncRequest], AsyncRequest]):
42         self.auth = auth
43 
44     async def __call__(
45         self, request: AsyncRequest, get_response: typing.Callable
46     ) -> AsyncResponse:
47         request = self.auth(request)
48         return await get_response(request)
49 
50 
51 class RedirectMiddleware(BaseMiddleware):
52     def __init__(
53         self,
54         allow_redirects: bool = True,
55         max_redirects: int = DEFAULT_MAX_REDIRECTS,
56         cookies: typing.Optional[Cookies] = None,
57     ):
58         self.allow_redirects = allow_redirects
59         self.max_redirects = max_redirects
60         self.cookies = cookies
61         self.history: typing.List[AsyncResponse] = []
62 
63     async def __call__(
64         self, request: AsyncRequest, get_response: typing.Callable
65     ) -> AsyncResponse:
66         if len(self.history) > self.max_redirects:
67             raise TooManyRedirects()
68         if request.url in (response.url for response in self.history):
69             raise RedirectLoop()
70 
71         response = await get_response(request)
72         response.history = list(self.history)
73 
74         if not response.is_redirect:
75             return response
76 
77         self.history.append(response)
78         next_request = self.build_redirect_request(request, response)
79 
80         if self.allow_redirects:
81             return await self(next_request, get_response)
82 
83         response.call_next = functools.partial(self, next_request, get_response)
84         return response
85 
86     def build_redirect_request(
87         self, request: AsyncRequest, response: AsyncResponse
88     ) -> AsyncRequest:
89         method = self.redirect_method(request, response)
90         url = self.redirect_url(request, response)
91         headers = self.redirect_headers(request, url, method)  # TODO: merge headers?
92         content = self.redirect_content(request, method)
93         cookies = Cookies(self.cookies)
94         cookies.update(request.cookies)
95         return AsyncRequest(
96             method=method, url=url, headers=headers, data=content, cookies=cookies
97         )
98 
99     def redirect_method(self, request: AsyncRequest, response: AsyncResponse) -> str:
100         """
101         When being redirected we may want to change the method of the request
102         based on certain specs or browser behavior.
103         """
104         method = request.method
105 
106         # https://tools.ietf.org/html/rfc7231#section-6.4.4
107         if response.status_code == codes.SEE_OTHER and method != "HEAD":
108             method = "GET"
109 
110         # Do what the browsers do, despite standards...
111         # Turn 302s into GETs.
112         if response.status_code == codes.FOUND and method != "HEAD":
113             method = "GET"
114 
115         # If a POST is responded to with a 301, turn it into a GET.
116         # This bizarre behaviour is explained in 'requests' issue 1704.
117         if response.status_code == codes.MOVED_PERMANENTLY and method == "POST":
118             method = "GET"
119 
120         return method
121 
122     def redirect_url(self, request: AsyncRequest, response: AsyncResponse) -> URL:
123         """
124         Return the URL for the redirect to follow.
125         """
126         location = response.headers["Location"]
127 
128         url = URL(location, allow_relative=True)
129 
130         # Facilitate relative 'Location' headers, as allowed by RFC 7231.
131         # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
132         if url.is_relative_url:
133             url = request.url.join(url)
134 
135         # Attach previous fragment if needed (RFC 7231 7.1.2)
136         if request.url.fragment and not url.fragment:
137             url = url.copy_with(fragment=request.url.fragment)
138 
139         return url
140 
141     def redirect_headers(self, request: AsyncRequest, url: URL, method: str) -> Headers:
142         """
143         Return the headers that should be used for the redirect request.
144         """
145         headers = Headers(request.headers)
146 
147         if url.origin != request.url.origin:
148             # Strip Authorization headers when responses are redirected away from
149             # the origin.
150             del headers["Authorization"]
151             del headers["Host"]
152 
153         if method != request.method and method == "GET":
154             # If we've switch to a 'GET' request, then strip any headers which
155             # are only relevant to the request body.
156             del headers["Content-Length"]
157             del headers["Transfer-Encoding"]
158 
159         return headers
160 
161     def redirect_content(self, request: AsyncRequest, method: str) -> bytes:
162         """
163         Return the body that should be used for the redirect request.
164         """
165         if method != request.method and method == "GET":
166             return b""
167         if request.is_streaming:
168             raise RedirectBodyUnavailable()
169         return request.content
170
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/httpx/middleware.py b/httpx/middleware.py
--- a/httpx/middleware.py
+++ b/httpx/middleware.py
@@ -148,7 +148,7 @@
             # Strip Authorization headers when responses are redirected away from
             # the origin.
             del headers["Authorization"]
-            del headers["Host"]
+            headers["Host"] = url.authority
 
         if method != request.method and method == "GET":
             # If we've switch to a 'GET' request, then strip any headers which

{"golden_diff": "diff --git a/httpx/middleware.py b/httpx/middleware.py\n--- a/httpx/middleware.py\n+++ b/httpx/middleware.py\n@@ -148,7 +148,7 @@\n             # Strip Authorization headers when responses are redirected away from\n             # the origin.\n             del headers[\"Authorization\"]\n-            del headers[\"Host\"]\n+            headers[\"Host\"] = url.authority\n \n         if method != request.method and method == \"GET\":\n             # If we've switch to a 'GET' request, then strip any headers which\n", "issue": "Away-from-origin redirects should add a new host header\nPrompted by #310\r\n\r\nAway-from-origin redirects currently remove the `Host` header, without adding a new one.\r\nI think we ought to be using `headers['Host'] = url.authority.encode(\"ascii\")` instead of simply deleting the header.\n", "before_files": [{"content": "import functools\nimport typing\nfrom base64 import b64encode\n\nfrom .config import DEFAULT_MAX_REDIRECTS\nfrom .exceptions import RedirectBodyUnavailable, RedirectLoop, TooManyRedirects\nfrom .models import URL, AsyncRequest, AsyncResponse, Cookies, Headers\nfrom .status_codes import codes\n\n\nclass BaseMiddleware:\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        raise NotImplementedError  # pragma: no cover\n\n\nclass BasicAuthMiddleware(BaseMiddleware):\n    def __init__(\n        self, username: typing.Union[str, bytes], password: typing.Union[str, bytes]\n    ):\n        if isinstance(username, str):\n            username = username.encode(\"latin1\")\n\n        if isinstance(password, str):\n            password = password.encode(\"latin1\")\n\n        userpass = b\":\".join((username, password))\n        token = b64encode(userpass).decode().strip()\n\n        self.authorization_header = f\"Basic {token}\"\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        request.headers[\"Authorization\"] = self.authorization_header\n        return await get_response(request)\n\n\nclass CustomAuthMiddleware(BaseMiddleware):\n    def __init__(self, auth: typing.Callable[[AsyncRequest], AsyncRequest]):\n        self.auth = auth\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        request = self.auth(request)\n        return await get_response(request)\n\n\nclass RedirectMiddleware(BaseMiddleware):\n    def __init__(\n        self,\n        allow_redirects: bool = True,\n        max_redirects: int = DEFAULT_MAX_REDIRECTS,\n        cookies: typing.Optional[Cookies] = None,\n    ):\n        self.allow_redirects = allow_redirects\n        self.max_redirects = max_redirects\n        self.cookies = cookies\n        self.history: typing.List[AsyncResponse] = []\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        if len(self.history) > self.max_redirects:\n            raise TooManyRedirects()\n        if request.url in (response.url for response in self.history):\n            raise RedirectLoop()\n\n        response = await get_response(request)\n        response.history = list(self.history)\n\n        if not response.is_redirect:\n            return response\n\n        self.history.append(response)\n        next_request = self.build_redirect_request(request, response)\n\n        if self.allow_redirects:\n            return await self(next_request, get_response)\n\n        response.call_next = functools.partial(self, next_request, get_response)\n        return response\n\n    def build_redirect_request(\n        self, request: AsyncRequest, response: AsyncResponse\n    ) -> AsyncRequest:\n        method = self.redirect_method(request, response)\n        url = self.redirect_url(request, response)\n        headers = self.redirect_headers(request, url, method)  # TODO: merge headers?\n        content = self.redirect_content(request, method)\n        cookies = Cookies(self.cookies)\n        cookies.update(request.cookies)\n        return AsyncRequest(\n            method=method, url=url, headers=headers, data=content, cookies=cookies\n        )\n\n    def redirect_method(self, request: AsyncRequest, response: AsyncResponse) -> str:\n        \"\"\"\n        When being redirected we may want to change the method of the request\n        based on certain specs or browser behavior.\n        \"\"\"\n        method = request.method\n\n        # https://tools.ietf.org/html/rfc7231#section-6.4.4\n        if response.status_code == codes.SEE_OTHER and method != \"HEAD\":\n            method = \"GET\"\n\n        # Do what the browsers do, despite standards...\n        # Turn 302s into GETs.\n        if response.status_code == codes.FOUND and method != \"HEAD\":\n            method = \"GET\"\n\n        # If a POST is responded to with a 301, turn it into a GET.\n        # This bizarre behaviour is explained in 'requests' issue 1704.\n        if response.status_code == codes.MOVED_PERMANENTLY and method == \"POST\":\n            method = \"GET\"\n\n        return method\n\n    def redirect_url(self, request: AsyncRequest, response: AsyncResponse) -> URL:\n        \"\"\"\n        Return the URL for the redirect to follow.\n        \"\"\"\n        location = response.headers[\"Location\"]\n\n        url = URL(location, allow_relative=True)\n\n        # Facilitate relative 'Location' headers, as allowed by RFC 7231.\n        # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')\n        if url.is_relative_url:\n            url = request.url.join(url)\n\n        # Attach previous fragment if needed (RFC 7231 7.1.2)\n        if request.url.fragment and not url.fragment:\n            url = url.copy_with(fragment=request.url.fragment)\n\n        return url\n\n    def redirect_headers(self, request: AsyncRequest, url: URL, method: str) -> Headers:\n        \"\"\"\n        Return the headers that should be used for the redirect request.\n        \"\"\"\n        headers = Headers(request.headers)\n\n        if url.origin != request.url.origin:\n            # Strip Authorization headers when responses are redirected away from\n            # the origin.\n            del headers[\"Authorization\"]\n            del headers[\"Host\"]\n\n        if method != request.method and method == \"GET\":\n            # If we've switch to a 'GET' request, then strip any headers which\n            # are only relevant to the request body.\n            del headers[\"Content-Length\"]\n            del headers[\"Transfer-Encoding\"]\n\n        return headers\n\n    def redirect_content(self, request: AsyncRequest, method: str) -> bytes:\n        \"\"\"\n        Return the body that should be used for the redirect request.\n        \"\"\"\n        if method != request.method and method == \"GET\":\n            return b\"\"\n        if request.is_streaming:\n            raise RedirectBodyUnavailable()\n        return request.content\n", "path": "httpx/middleware.py"}], "after_files": [{"content": "import functools\nimport typing\nfrom base64 import b64encode\n\nfrom .config import DEFAULT_MAX_REDIRECTS\nfrom .exceptions import RedirectBodyUnavailable, RedirectLoop, TooManyRedirects\nfrom .models import URL, AsyncRequest, AsyncResponse, Cookies, Headers\nfrom .status_codes import codes\n\n\nclass BaseMiddleware:\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        raise NotImplementedError  # pragma: no cover\n\n\nclass BasicAuthMiddleware(BaseMiddleware):\n    def __init__(\n        self, username: typing.Union[str, bytes], password: typing.Union[str, bytes]\n    ):\n        if isinstance(username, str):\n            username = username.encode(\"latin1\")\n\n        if isinstance(password, str):\n            password = password.encode(\"latin1\")\n\n        userpass = b\":\".join((username, password))\n        token = b64encode(userpass).decode().strip()\n\n        self.authorization_header = f\"Basic {token}\"\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        request.headers[\"Authorization\"] = self.authorization_header\n        return await get_response(request)\n\n\nclass CustomAuthMiddleware(BaseMiddleware):\n    def __init__(self, auth: typing.Callable[[AsyncRequest], AsyncRequest]):\n        self.auth = auth\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        request = self.auth(request)\n        return await get_response(request)\n\n\nclass RedirectMiddleware(BaseMiddleware):\n    def __init__(\n        self,\n        allow_redirects: bool = True,\n        max_redirects: int = DEFAULT_MAX_REDIRECTS,\n        cookies: typing.Optional[Cookies] = None,\n    ):\n        self.allow_redirects = allow_redirects\n        self.max_redirects = max_redirects\n        self.cookies = cookies\n        self.history: typing.List[AsyncResponse] = []\n\n    async def __call__(\n        self, request: AsyncRequest, get_response: typing.Callable\n    ) -> AsyncResponse:\n        if len(self.history) > self.max_redirects:\n            raise TooManyRedirects()\n        if request.url in (response.url for response in self.history):\n            raise RedirectLoop()\n\n        response = await get_response(request)\n        response.history = list(self.history)\n\n        if not response.is_redirect:\n            return response\n\n        self.history.append(response)\n        next_request = self.build_redirect_request(request, response)\n\n        if self.allow_redirects:\n            return await self(next_request, get_response)\n\n        response.call_next = functools.partial(self, next_request, get_response)\n        return response\n\n    def build_redirect_request(\n        self, request: AsyncRequest, response: AsyncResponse\n    ) -> AsyncRequest:\n        method = self.redirect_method(request, response)\n        url = self.redirect_url(request, response)\n        headers = self.redirect_headers(request, url, method)  # TODO: merge headers?\n        content = self.redirect_content(request, method)\n        cookies = Cookies(self.cookies)\n        cookies.update(request.cookies)\n        return AsyncRequest(\n            method=method, url=url, headers=headers, data=content, cookies=cookies\n        )\n\n    def redirect_method(self, request: AsyncRequest, response: AsyncResponse) -> str:\n        \"\"\"\n        When being redirected we may want to change the method of the request\n        based on certain specs or browser behavior.\n        \"\"\"\n        method = request.method\n\n        # https://tools.ietf.org/html/rfc7231#section-6.4.4\n        if response.status_code == codes.SEE_OTHER and method != \"HEAD\":\n            method = \"GET\"\n\n        # Do what the browsers do, despite standards...\n        # Turn 302s into GETs.\n        if response.status_code == codes.FOUND and method != \"HEAD\":\n            method = \"GET\"\n\n        # If a POST is responded to with a 301, turn it into a GET.\n        # This bizarre behaviour is explained in 'requests' issue 1704.\n        if response.status_code == codes.MOVED_PERMANENTLY and method == \"POST\":\n            method = \"GET\"\n\n        return method\n\n    def redirect_url(self, request: AsyncRequest, response: AsyncResponse) -> URL:\n        \"\"\"\n        Return the URL for the redirect to follow.\n        \"\"\"\n        location = response.headers[\"Location\"]\n\n        url = URL(location, allow_relative=True)\n\n        # Facilitate relative 'Location' headers, as allowed by RFC 7231.\n        # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')\n        if url.is_relative_url:\n            url = request.url.join(url)\n\n        # Attach previous fragment if needed (RFC 7231 7.1.2)\n        if request.url.fragment and not url.fragment:\n            url = url.copy_with(fragment=request.url.fragment)\n\n        return url\n\n    def redirect_headers(self, request: AsyncRequest, url: URL, method: str) -> Headers:\n        \"\"\"\n        Return the headers that should be used for the redirect request.\n        \"\"\"\n        headers = Headers(request.headers)\n\n        if url.origin != request.url.origin:\n            # Strip Authorization headers when responses are redirected away from\n            # the origin.\n            del headers[\"Authorization\"]\n            headers[\"Host\"] = url.authority\n\n        if method != request.method and method == \"GET\":\n            # If we've switch to a 'GET' request, then strip any headers which\n            # are only relevant to the request body.\n            del headers[\"Content-Length\"]\n            del headers[\"Transfer-Encoding\"]\n\n        return headers\n\n    def redirect_content(self, request: AsyncRequest, method: str) -> bytes:\n        \"\"\"\n        Return the body that should be used for the redirect request.\n        \"\"\"\n        if method != request.method and method == \"GET\":\n            return b\"\"\n        if request.is_streaming:\n            raise RedirectBodyUnavailable()\n        return request.content\n", "path": "httpx/middleware.py"}]}