summaryrefslogtreecommitdiff
path: root/lib/net
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-21 20:36:07 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-21 20:36:07 +0000
commit570b766901c1a80f5a317012eb81ee9d1f301073 (patch)
tree14d373b6b3a8f52d66970279004a545b174cc01e /lib/net
parent34a3668c30753dcd2632aaf84d3ee5d29599eac1 (diff)
* lib/net/http.rb: Requests may be created with a URI which sets the
Host header. Responses contain the requested URI for easier redirect following. [ruby-trunk - Feature #6482] * lib/net/http/generic_request.rb: ditto. * lib/net/http/response.rb: ditto.j * NEWS (net/http): Updated for above. * test/net/http/test_http.rb: Tests for above. * test/net/http/test_http.rb: ditto. * test/net/http/test_httpresponse.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38546 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net')
-rw-r--r--lib/net/http.rb38
-rw-r--r--lib/net/http/generic_request.rb35
-rw-r--r--lib/net/http/response.rb9
3 files changed, 70 insertions, 12 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 87cebb4a0c..7ae99a7ae5 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -93,7 +93,7 @@ module Net #:nodoc:
# uri = URI('http://example.com/some_path?query=string')
#
# Net::HTTP.start(uri.host, uri.port) do |http|
- # request = Net::HTTP::Get.new uri.request_uri
+ # request = Net::HTTP::Get.new uri
#
# response = http.request request # Net::HTTPResponse object
# end
@@ -111,6 +111,10 @@ module Net #:nodoc:
# will automatically open a connection to the server if one is not currently
# open. You can manually close the connection with #finish.
#
+ # For all the Net::HTTP request objects and shortcut request methods you may
+ # supply either a String for the request path or a URI from which Net::HTTP
+ # will extract the request path.
+ #
# === Response Data
#
# uri = URI('http://example.com/index.html')
@@ -168,7 +172,7 @@ module Net #:nodoc:
# creates a urlencoded POST body:
#
# uri = URI('http://www.example.com/todo.cgi')
- # req = Net::HTTP::Post.new(uri.path)
+ # req = Net::HTTP::Post.new(uri)
# req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
#
# res = Net::HTTP.start(uri.hostname, uri.port) do |http|
@@ -186,7 +190,7 @@ module Net #:nodoc:
# multipart/form-data use Net::HTTPRequest#body= and
# Net::HTTPRequest#content_type=:
#
- # req = Net::HTTP::Post.new(uri.path)
+ # req = Net::HTTP::Post.new(uri)
# req.body = multipart_data
# req.content_type = 'multipart/form-data'
#
@@ -203,7 +207,7 @@ module Net #:nodoc:
# uri = URI('http://example.com/cached_response')
# file = File.stat 'cached_response'
#
- # req = Net::HTTP::Get.new(uri.request_uri)
+ # req = Net::HTTP::Get.new(uri)
# req['If-Modified-Since'] = file.mtime.rfc2822
#
# res = Net::HTTP.start(uri.hostname, uri.port) {|http|
@@ -221,7 +225,7 @@ module Net #:nodoc:
#
# uri = URI('http://example.com/index.html?key=value')
#
- # req = Net::HTTP::Get.new(uri.request_uri)
+ # req = Net::HTTP::Get.new(uri)
# req.basic_auth 'user', 'pass'
#
# res = Net::HTTP.start(uri.hostname, uri.port) {|http|
@@ -238,7 +242,7 @@ module Net #:nodoc:
# uri = URI('http://example.com/large_file')
#
# Net::HTTP.start(uri.host, uri.port) do |http|
- # request = Net::HTTP::Get.new uri.request_uri
+ # request = Net::HTTP::Get.new uri
#
# http.request request do |response|
# open 'large_file', 'w' do |io|
@@ -257,7 +261,7 @@ module Net #:nodoc:
#
# Net::HTTP.start(uri.host, uri.port,
# :use_ssl => uri.scheme == 'https') do |http|
- # request = Net::HTTP::Get.new uri.request_uri
+ # request = Net::HTTP::Get.new uri
#
# response = http.request request # Net::HTTPResponse object
# end
@@ -472,7 +476,7 @@ module Net #:nodoc:
uri = uri_or_host
start(uri.hostname, uri.port,
:use_ssl => uri.scheme == 'https') {|http|
- return http.request_get(uri.request_uri, &block)
+ return http.request_get(uri, &block)
}
end
end
@@ -496,7 +500,7 @@ module Net #:nodoc:
# { "q" => "ruby", "max" => "50" }
#
def HTTP.post_form(url, params)
- req = Post.new(url.request_uri)
+ req = Post.new(url)
req.form_data = params
req.basic_auth url.user, url.password if url.user
start(url.hostname, url.port,
@@ -868,7 +872,7 @@ module Net #:nodoc:
conn_port = port
end
- D "opening connection to #{conn_address}..."
+ D "opening connection to #{conn_address}:#{conn_port}..."
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
}
@@ -884,8 +888,10 @@ module Net #:nodoc:
end
@ssl_context = OpenSSL::SSL::SSLContext.new
@ssl_context.set_params(ssl_parameters)
+ D "starting SSL for #{conn_address}:#{conn_port}..."
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
s.sync_close = true
+ D "SSL established"
end
@socket = BufferedIO.new(s)
@socket.read_timeout = @read_timeout
@@ -1077,7 +1083,9 @@ module Net #:nodoc:
public
- # Gets data from +path+ on the connected-to host.
+ # Retrieves data from +path+ on the connected-to host which may be an
+ # absolute path String or a URI to extract the path from.
+ #
# +initheader+ must be a Hash like { 'Accept' => '*/*', ... },
# and it defaults to an empty hash.
# If +initheader+ doesn't have the key 'accept-encoding', then
@@ -1403,6 +1411,9 @@ module Net #:nodoc:
begin
res = HTTPResponse.read_new(@socket)
end while res.kind_of?(HTTPContinue)
+
+ res.uri = req.uri
+
res.reading_body(@socket, req.response_body_permitted?) {
yield res if block_given?
}
@@ -1444,6 +1455,11 @@ module Net #:nodoc:
if not req.response_body_permitted? and @close_on_empty_response
req['connection'] ||= 'close'
end
+
+ host = req['host'] || address
+ host = $1 if host =~ /(.*):\d+$/
+ req.update_uri host, port, use_ssl?
+
req['host'] ||= addr_port()
end
diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb
index bcf87d35be..704f159245 100644
--- a/lib/net/http/generic_request.rb
+++ b/lib/net/http/generic_request.rb
@@ -7,10 +7,22 @@ class Net::HTTPGenericRequest
include Net::HTTPHeader
- def initialize(m, reqbody, resbody, path, initheader = nil)
+ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil)
@method = m
@request_has_body = reqbody
@response_has_body = resbody
+
+ if URI === uri_or_path then
+ @uri = uri_or_path.dup
+ host = @uri.hostname
+ host += ":#{@uri.port}" if @uri.port != @uri.class::DEFAULT_PORT
+ path = uri_or_path.request_uri
+ else
+ @uri = nil
+ host = nil
+ path = uri_or_path
+ end
+
raise ArgumentError, "no HTTP request path given" unless path
raise ArgumentError, "HTTP request path is empty" if path.empty?
@path = path
@@ -29,6 +41,7 @@ class Net::HTTPGenericRequest
initialize_http_header initheader
self['Accept'] ||= '*/*'
self['User-Agent'] ||= 'Ruby'
+ self['Host'] ||= host
@body = nil
@body_stream = nil
@body_data = nil
@@ -36,6 +49,7 @@ class Net::HTTPGenericRequest
attr_reader :method
attr_reader :path
+ attr_reader :uri
def inspect
"\#<#{self.class} #{@method}>"
@@ -82,6 +96,8 @@ class Net::HTTPGenericRequest
#
def exec(sock, ver, path) #:nodoc: internal use only
+ self['host'] = "#{@uri.host}:#{@uri.port}" if @uri
+
if @body
send_request_with_body sock, ver, path, @body
elsif @body_stream
@@ -93,6 +109,23 @@ class Net::HTTPGenericRequest
end
end
+ def update_uri(host, port, ssl) # :nodoc: internal use only
+ return unless @uri
+
+ @uri.host ||= host
+ @uri.port = port
+
+ scheme = ssl ? 'https' : 'http'
+
+ # convert the class of the URI
+ unless scheme == @uri.scheme then
+ new_uri = @uri.to_s.sub(/^https?/, scheme)
+ @uri = URI new_uri
+ end
+
+ @uri
+ end
+
private
class Chunker #:nodoc:
diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index 6b044c3d34..bde3b5b440 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -79,6 +79,7 @@ class Net::HTTPResponse
initialize_http_header nil
@body = nil
@read = false
+ @uri = nil
end
# The HTTP version supported by the server.
@@ -93,6 +94,10 @@ class Net::HTTPResponse
attr_reader :message
alias msg message # :nodoc: obsolete
+ # The URI used to fetch this response. The response URI is only available
+ # if a URI was used to create the request.
+ attr_reader :uri
+
def inspect
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
@@ -118,6 +123,10 @@ class Net::HTTPResponse
error! unless self.kind_of?(Net::HTTPSuccess)
end
+ def uri= uri # :nodoc:
+ @uri = uri.dup if uri
+ end
+
#
# header (for backward compatibility only; DO NOT USE)
#