如何使用GoLang通过HTTP的”Host”头部来定位特定的应用服务器。

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

How can I target a specific application server using the HTTP "Host" header (using GoLang)

问题

为什么在GoLang中无法使用服务器的IP地址作为请求URL和主机名作为“Host”头来定位服务器?为什么使用Python(2.7.6 - urllib2)可以成功实现相同的功能?

背景信息:
我正在编写一个系统测试,将向我正在测试和检查结果正确性的几个特定应用服务器发送HTTP请求。每个应用服务器具有相同的功能,并应返回相同的响应数据。这些服务器被分组在负载均衡器后面。然后,这些负载均衡器通过DNS解析,并将流量转发到相应的后端服务器。为了独立地定位每个服务器(用于测试),我在URL中使用每个服务器的IP地址,而不是通常的主机名,并将“Host” HTTP头设置为通常在URL中的主机名。这是为了确保SSL证书可以解码安全(HTTPS)请求。

当前状态:
我已经有一个发送这些测试请求的Python脚本。以下是该脚本的基本思路:

headers = {"Host": "<hostname>"} # 这个<hostname>通常是URL中的内容
request = urllib2.Request('https://<ip-address>/path?query=123', headers=headers)
response = urllib2.urlopen(request)
# 等等...

这段代码已经运行良好了几个月。我已经验证它确实定位到了正确的服务器,基于IP地址。

目标:
我想在GoLang中复制这个脚本,以利用Go的并发能力。我之所以使用Go,是因为我想一次发送更多的请求(使用goroutines)。

问题:
使用与上述相同的技术(但在Go中),我得到了以下错误:

Get https://<ip-address>/path?query=123: x509: cannot validate certificate for <ip-address> because it doesn't contain any IP SANs

以下是我编写的代码示例:

request, _ := http.NewRequest("GET", "https://<ip-address>/path?query=123", nil)
request.Header.Set("Host", "<hostname>")

client := &http.Client{}
response, err := client.Do(request)
// 等等...

为什么Python代码可以工作,而GoLang代码返回错误?

英文:

The question:

Why can't I target a server using it's IP address in the request URL and the hostname as the "Host" header using GoLang?
Why does the same thing work using python? (2.7.6 - urllib2)

Background:

I'm writing a systems test that will send HTTP requests to several specific application servers that I'm testing and inspect the results for correctness. Each application server has the same function and should return the same response data. These servers are grouped behind load balancers. These load balancers are then resolved by DNS and the traffic is forwarded to the backend servers as appropriate. In order to target each server independently (for the tests) I am using each server's IP address in the URL instead of the usual hostname and I'm setting the "Host" HTTP header to be the hostname that usually goes in the url. This is to make sure the SSL cert
can decode the secure (HTTPS) request.

Current status:

I already have a python script that sends these test requests. Here's the basic idea of that script:

headers = {&quot;Host&quot;: &quot;&lt;hostname&gt;&quot;} # this &lt;hostname&gt; is usually what would go in the URL on the next line
request = urllib2.Request(&#39;https://&lt;ip-address&gt;/path?query=123&#39;, headers=headers)
response = urllib2.urlopen(request)
# etc... 

This code has been working fine for several months now. I've verified that it is indeed targeting the correct servers, based on IP address.

Goal:

I want to replicate this script in golang to make use of the concurrent capabilities of go. The reason I'm using go is that I'd like to send lots more requests at a time (using goroutines).

Problem:

Using the same technique as shown above (but in Go) I get the following error:

Get https://&lt;ip-address&gt;/path?query=123: x509: cannot validate certificate for &lt;ip-address&gt; because it doesn&#39;t contain any IP SANs

Here's an example of the kind of code I have written:

request, _ := http.NewRequest(&quot;GET&quot;, &quot;https://&lt;ip-address&gt;/path?query=123&quot;, nil)
request.Header.Set(&quot;Host&quot;, &quot;&lt;hostname&gt;&quot;)

client := &amp;http.Client{}
response, err := client.Do(request)
// etc...

Again, why does the python code work while the GoLang code returns an error?

答案1

得分: 2

根据Python的文档

> 警告:HTTPS请求不会对服务器的证书进行任何验证。

要在Go中复制这种行为,请参见:https://stackoverflow.com/a/12122718/216488

英文:

As per the python documentation:

> Warning: HTTPS requests do not do any verification of the server’s certificate.

To replicate this behavior in Go see: https://stackoverflow.com/a/12122718/216488

huangapple
  • 本文由 发表于 2013年12月21日 04:34:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/20711542.html
匿名

发表评论

匿名网友

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

确定