Я в основном пытаюсь написать обратный прокси-сервер, чтобы при curl localhost:8080/get
он передавал запрос на https://nghttp2.org/httpbin/get
.
Примечание. Служба https://nghttp2.org/httpbin/get, указанная выше, является http / 2. Но такое поведение происходит и с http / 1, например https://httpbin.org/get.
Я использую httputil.ReverseProxy для этого, и я переписываю URL, настраивая заголовок Host
, чтобы не пропустить localhost:8080
в фактический бэкэнд.
Однако запрос по-прежнему попадает в бэкэнд с Host: localhost:8080
, независимо от того, сколько раз я устанавливал его в заголовке. Точно так же я использовал mitmproxy
для отслеживания запроса, и похоже, что net / http.Client устанавливает псевдо-заголовок :authority
в localhost:8080
Вот мой исходный код:
package main
import (
"log"
"net/http"
"net/http/httputil"
)
func main() {
proxy := &httputil.ReverseProxy{
Transport: roundTripper(rt),
Director: func(req *http.Request) {
req.URL.Scheme = "https"
req.URL.Host = "nghttp2.org"
req.URL.Path = "/httpbin" + req.URL.Path
req.Header.Set("Host", "nghttp2.org") // <--- I set it here first
},
}
log.Fatal(http.ListenAndServe(":8080", proxy))
}
func rt(req *http.Request) (*http.Response, error) {
log.Printf("request received. url=%s", req.URL)
req.Header.Set("Host", "nghttp2.org") // <--- I set it here as well
defer log.Printf("request complete. url=%s", req.URL)
return http.DefaultTransport.RoundTrip(req)
}
// roundTripper makes func signature a http.RoundTripper
type roundTripper func(*http.Request) (*http.Response, error)
func (f roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { return f(req) }
Когда я запрашиваю curl localhost:8080/get
, запрос перенаправляется на https://nghttp2.org/httpbin/get. Отраженный ответ показывает, что мои директивы, устанавливающие заголовок Host
, явно ничего не сделали:
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip",
"Host": "localhost:8080",
"User-Agent": "curl/7.54.0"
},
"origin": "2601:602:9c02:16c2:fca3:aaab:3914:4a71",
"url": "https://localhost:8080/httpbin/get"
}
отслеживание mitmproxy также ясно показывает, что запрос был сделан с псевдо-заголовком :authority
, установленным в localhost:8080
:
![mitmproxy output shows :authority pseudoheader set to localhost:8080](https://i.stack.imgur.com/fetxk.png)