// HttpTestOnceHostBindIp http请求测试,指定目的IP地址
func HttpTestOnceHostBindIp(ipAddr, serviceUrl string, hostContainPort bool) (responseCode int, Host string) {
//异常处理
defer func() {
//捕获异常
err := recover()
if err != nil { //条件判断,是否存在异常
//存在异常,抛出异常
//fmt.Println(err)
fmt.println("http请求serviceUrl 一次出错:%v", err)
responseCode = -8888
}
}()
responseCode = -8888
urlObj, err := url.Parse(serviceUrl)
if err != nil {
fmt.println("url.Parse(serviceUrl) Error: %v", err)
}
// 获取传入URL的端口是什么,有指定获取指定的,没有指定根据http/https协议默认端口传入
var port string
// 1. 有指定端口
if strings.Contains(urlObj.Host, ":") {
hostSlice := strings.Split(urlObj.Host, ":")
if len(hostSlice) >= 1 {
port = hostSlice[1]
}
} else {
// 2. 没有指定端口 使用默认端口
if urlObj.Scheme == "https" {
port = "443"
} else if urlObj.Scheme == "http" {
port = "80"
}
}
//fmt.Println("urlObj.Host: ", urlObj.Host) // 根据url获取Host
//fmt.Println("urlObj.Scheme: ", urlObj.Scheme) // http请求协议,http或者https
//port := "80"
request, err := http.NewRequest("GET", urlObj.String(), bytes.NewBuffer([]byte{}))
// 规则要求带端口的url如果Host不包含Port就把 HTTP请求的Host头里的:端口号去掉
if !hostContainPort {
if strings.Contains(urlObj.Host, ":") {
hostSlice := strings.Split(urlObj.Host, ":")
if len(hostSlice) >= 1 {
request.Host = hostSlice[0]
}
}
}
defer request.Body.Close() //
var response *http.Response
// 一、 绑定固定的IP
// 1. 先准备一个Dialer对象
dialer := &net.Dialer{
Timeout: 7 * time.Second,
KeepAlive: 30 * time.Second,
}
transport := &http.Transport{
// 2. 插入特别的改写条件,然后继续利用原先的DialContext逻辑
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
addr = ipAddr + ":" + port
//if addr == "api.lewinblog.com:80" {
// addr = "127.0.0.1:80"
//}
return dialer.DialContext(ctx, network, addr)
},
}
// 客户端禁止重定向
client := &http.Client{
CheckRedirect: noRedirect, //http客户端禁止重定向
Transport: transport,
}
//response, err = http.DefaultClient.Do(request)
response, err = client.Do(request)
if err != nil {
fmt.println("client.Do(request) Error:%v", err)
}
if response != nil {
responseCode = response.StatusCode
if response.Body != nil {
err = response.Body.Close() //必须关闭否则自动打开的goroutine无法关闭
if err != nil {
fmt.println("response.Body.Close()Error:%v", err)
}
}
fmt.println("serviceUrl %v ip: %s response Code: %v", serviceUrl, ipAddr, responseCode)
}
Host = request.Host
return
}