2014-01-22 21 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

相关问题