为什么两个不同的http.Request结构体的http.Request.URL.Host地址相同?

huangapple go评论92阅读模式
英文:

Why is the address of http.Request.URL.Host same for 2 different http.Request structures?

问题

这段代码是一个自包含的示例,用于尝试复制一个错误。当运行此程序时,&request.URL.Host&request1.URL.Host的地址是相同的。为什么会这样?根据我的理解,这是两个不同的结构,所以URL.Host不应该有相同的地址。

package main

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	hostname := "www.google.com"
	uri, err := url.Parse("http://www.google.com/")
	if err != nil {
		panic(err)
	}
	var tlsConfig *tls.Config
	tlsConfig = &tls.Config{
		ServerName:         hostname,
		InsecureSkipVerify: true,
	}

	client := &http.Client{
		Transport: &http.Transport{
			DisableKeepAlives: true,
			TLSClientConfig:   tlsConfig,
		},
	}
	request1 := &http.Request{
		Header: http.Header{"User-Agent": {"Foo"}},
		Host:   hostname,
		Method: "GET",
		URL:    uri,
	}
	request2 := &http.Request{
		Header: http.Header{"User-Agent": {"Foo"}},
		Host:   hostname,
		Method: "GET",
		URL:    uri,
	}

	fmt.Printf("Address1: %s, Address2: %s\n", &request1.URL.Host, &request2.URL.Host)
	resp, err := client.Do(request1)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	fmt.Printf("\nResponse: %s", resp)
}

希望这可以帮助你解决问题。

英文:

This code is a self-contained example from a large code base to try to replicate a bug. When this program is run, the address of both &request.URL.Host and &request1.URL.Host is same. Why? From my understanding, these are 2 different structures so URL.Host should not have the same address.

package main

import (
        "crypto/tls"
        "fmt"
        "net/http"
        "net/url"
)

func main() {
        hostname := "www.google.com"
        uri, err := url.Parse("http://www.google.com/")
        if err != nil {
                panic(err)
        }
        var tlsConfig *tls.Config
        tlsConfig = &tls.Config{
                ServerName:         hostname,
                InsecureSkipVerify: true,
        }

        client := &http.Client{
                Transport: &http.Transport{
                        DisableKeepAlives: true,
                        TLSClientConfig:   tlsConfig,
                },
        }
        request1 := &http.Request{
                Header: http.Header{"User-Agent": {"Foo"}},
                Host:   hostname,
                Method: "GET",
                URL:    uri,
        }
        request2 := &http.Request{
                Header: http.Header{"User-Agent": {"Foo"}},
                Host:   hostname,
                Method: "GET",
                URL:    uri,
        }

        fmt.Printf("Address1: %s, Address2: %s\n", &request1.URL.Host, &request2.URL.Host)
        resp, err := client.Do(request1)
        if err != nil {
                panic(err)
        }
        defer resp.Body.Close()
        fmt.Printf("\nResponse: %s", resp)
}

答案1

得分: 1

http.Request 是一个结构体,其中的 URL 字段是一个指针

URL *url.URL

在你的代码中,你有一个名为 uri 的变量,它持有一个 *url.URL 类型的指针。

然后你创建了两个请求,将这些指针存储在 request1request2 变量中,但是你给它们的 URL 字段赋予了相同的值,即相同的指针。

因此,存在一个单独的 url.URL 值,并且你将其地址分别赋给了 request1.URLrequest2.URL。然后你打印了 request1.URL.Hostrequest2.URL.Host 的地址,但是由于 request1.URLrequest2.URL 都指向同一个 url.URL(结构体)值,所以该结构体的 Host 字段的地址将是相同的。对于这两个请求结构体来说,并不存在不同的 url.URL 值。

英文:

http.Request is a struct, whose URL field is a pointer:

URL *url.URL

In your code you have a single uri variable holding a pointer of type *url.URL.

Then you create 2 requests, storing the pointers in request1 and request2 variables, but you assign the same value, the same pointer to their URL field.

So there is a single url.URL value, and you assign its address to both request1.URL and request2.URL. Then you print the addresses of request1.URL.Host and request2.URL.Host, but since both request1.URL and request2.URL point to the same and only url.URL (struct) value, the address of the Host field of that struct will be the same. There are no distinct url.URL values for the 2 request structs.

huangapple
  • 本文由 发表于 2017年6月1日 21:12:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/44308536.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定