2014-01-22 67 views
2

這兩個請求應該有相同的結果,但第一個返回200(OK),第二個返回404(未找到)。這是爲什麼?爲什麼Ruby Net :: HTTP.get_response和Net :: HTTP.new(uri.host).request返回不同的東西?

require 'net/http' 

url = "http://readwrite.com/2013/12/04/google-compute-engine" 
uri = URI(url) 
Net::HTTP.get_response(uri) 
#=> #<Net::HTTPOK 200 OK readbody=true> 
Net::HTTP.new(uri.host).request(Net::HTTP::Get.new(url)) 
#=> #<Net::HTTPNotFound 404 Not Found readbody=true> 

它只發生了一些網址。我無法弄清楚這種模式。這是另一個例子:http://davidduchemin.com/2014/01/towards-mastery-again/

回答

4

首先,讓我們使用tcpdump觀察他們的實際HTTP請求比較兩個,所以我們可以得到什麼可能會發生一個想法:

tcpdump -vvASs 0 port 80 and host www.readwrite.com 
 
# Net::HTTP.get_response(uri) 

GET /2013/12/04/google-compute-engine HTTP/1.1 
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 
Accept: */* 
User-Agent: Ruby 
Host: readwrite.com 
 
# Net::HTTP.new(uri.host).request(Net::HTTP::Get.new(url)) 

GET http://readwrite.com/2013/12/04/google-compute-engine HTTP/1.1 
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 
Accept: */* 
User-Agent: Ruby 
Connection: close 
Host: readwrite.com 

我們可以看到,第二個請求錯誤地請求完整URL(與主機名)作爲路徑。這是因爲您將url傳遞給Net::HTTP::Get.new,這導致Net::HTTP::Get.new(url).path正如我們上面所看到的那樣:帶有主機名的完整URL。相反,URI實例(uri)傳遞給Net::HTTP::Get.new

Net::HTTP.new(uri.host).request(Net::HTTP::Get.new(uri)) 
#=> #<Net::HTTPOK 200 OK readbody=true> 

而且它的tcpdump是現在實際上是相同的,第一的:

 
GET /2013/12/04/google-compute-engine HTTP/1.1 
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 
Accept: */* 
User-Agent: Ruby 
Host: readwrite.com 
Connection: close 
+0

我曾經試過,但它返回NoMethodError:未定義的方法'空? 「爲#。儘管如此,Net :: HTTP.new(uri.host).request(Net :: HTTP :: Get.new(uri.path))完美地工作。謝謝! – sebagon

+0

另外,感謝您建議使用tcpdump進行調試。它在其他問題上也有很多幫助。 – sebagon

相關問題