2016-11-16 27 views
8

Làm cách nào để buộc golang https nhận được yêu cầu sử dụng địa chỉ IP cụ thể. Tôi muốn bỏ qua độ phân giải DNS và tự cung cấp IP. Tương đương trong curl sẽ là một - giải quyết như minh họa dưới đây.golang lực http yêu cầu ip cụ thể (tương tự như curl --resolve)

curl https://domain.com/dir/filename --resolve "domain.com:443:10.10.10.10"

Do đây là ssl Tôi muốn tránh thay thế trong IP cho tên miền như trong ví dụ sau.

curl https://10.10.10.10/dir/filename --header "Máy chủ: domain.com"

Trả lời

14

Bạn có thể cung cấp một tùy chỉnh Transport.DialContext chức năng.

func main() { 
    dialer := &net.Dialer{ 
     Timeout: 30 * time.Second, 
     KeepAlive: 30 * time.Second, 
     DualStack: true, 
    } 
    // or create your own transport, there's an example on godoc. 
    http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { 
     if addr == "google.com:443" { 
      addr = "216.58.198.206:443" 
     } 
     return dialer.DialContext(ctx, network, addr) 
    } 
    resp, err := http.Get("https://google.com") 
    log.Println(resp.Header, err) 
} 
+0

Cảm ơn, điều này đã hiệu quả, tôi phải thực hiện một điều chỉnh để chuyển đổi "https" trong "addr" thành "443" –

+0

@RyanD. Tôi sẽ cập nhật câu trả lời. – OneOfOne

+1

@ OneOfOne Tôi gặp sự cố khi chỉ định địa chỉ IPv6 addr = "2001: 558: fe0d: 23 :: 2: 443", tôi đoán do nhầm lẫn xung quanh dấu phân cách dấu hai chấm ":". Tôi nghĩ rằng tôi thấy một ví dụ nơi họ đặt [] xung quanh địa chỉ ipv6 như thế này "[2001: 558: fe0d: 23 :: 2]: 443" và tôi nghĩ rằng tôi đã làm việc này nhưng nó cũng thất bại. Đấu tranh để tìm các ví dụ về IPv6. Ý tưởng nào? –

3

Câu trả lời của OneOfOne ở trên rất tuyệt vời. Tôi đăng tải mã gói làm việc đầy đủ ở đây để giúp các noobs dễ dàng hơn như tôi. Tôi đã thêm một vài println để bạn có thể thấy giá trị addr trước và sau khi sửa đổi.

package main 

import (
    "context" 
    "fmt" 
    "log" 
    "net" 
    "net/http" 
    "time" 
) 

func main() { 
    dialer := &net.Dialer{ 
     Timeout: 30 * time.Second, 
     KeepAlive: 30 * time.Second, 
     DualStack: true, 
    } 
    // or create your own transport, there's an example on godoc. 
    http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { 
     fmt.Println("address original =", addr) 
     if addr == "google.com:443" { 
      addr = "216.58.198.206:443" 
      fmt.Println("address modified =", addr) 
     } 
     return dialer.DialContext(ctx, network, addr) 
    } 
    resp, err := http.Get("https://google.com") 
    log.Println(resp.Header, err) 
} 
Các vấn đề liên quan