問題:api.xxx.com.cn 是私有云中的域名,解析出來的IP地址不能在外網訪問,BUT api.xxx.com.cn 竟然在外網被解析到一個可以訪問的IP,於是curl傻傻的連接到這個IP去了。
需求:curl ( "https://api.xxx.com.cn/api/get_user_score") -- 網絡包發到--> 私有云的IP,如上圖箭頭所於。
預想方案:指定curl 的dst host ip addr
實踐一:靜態路由
改 /etc/hosts,加一條記錄
api.xxx.com.cn 10.23.xx.xx
考慮到未來server數量水平擴展時,運維人員需要做代碼部署之外的工作,而人也很容易忘記這些步驟,不採用
實踐二:PHP手冊
當前的PHP curl 的手冊中,只找到下圖中的選項可以實現同樣的功能,但需要PHP7,而項目中使用的是PHP5.6。pass
http://php.net/manual/en/function.curl-setopt.php
實踐三:thinking
1)想起了終端下的curl命令有個 --resolve 選項可以指定目標的IP
2)想起PHP接口的底層代碼幾乎就是和C語言代碼一模一樣,找了一下 /usr/include/curl/curl.h 文件,果然找到了,
從C言的這個宏看出,--resolve 對應的選項常量的名字是 CURLOPT_RESOLVE,找了一下PHP的curl文檔,竟然沒有看到這個常量的定義 http://php.net/manual/en/function.curl-setopt.php
依然考慮到 PHP接口的底層代碼幾乎就是和C語言代碼一模一樣,推測這個常量在PHP中也是同樣的值,雖然PHP文檔沒有寫,但直接傳入這個常理的值應該是通的。
寫出如下實驗代碼,測試了一下,可然成功了。
問題解決~
----------------------------------------- 補充另一種方法 ----------------------------------------
這種方法通過有 url scheme中的hostname部分換成目標IP地址,再在http 頭部指定Host。
爲什麼這種方法可行?留給聰明的你去鍛鍊一下思維。
答案Tips:考慮一下在Apach/Nginx中你是怎麼配置虛擬主機的,其中的Host部分起了什麼作用?
BUT ,沒錯這是大寫,這種方法只對HTTP纔會100%成功,對於HTTPS會這樣
嗯,和證書籤名裏的host name不匹配,就是這麼絕情,這麼安全 -->