mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
34a3668c30
commit
570b766901
7 changed files with 149 additions and 12 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
Sat Dec 22 05:34:54 2012 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
Sat Dec 22 02:35:00 2012 Zachary Scott <zachary@zacharyscott.net>
|
||||
|
||||
* lib/irb/slex.rb(#match): Typo, should be D_DETAIL
|
||||
|
|
4
NEWS
4
NEWS
|
@ -205,6 +205,10 @@ with all sufficient information, see the ChangeLog file.
|
|||
default. See Net::HTTP for details.
|
||||
* SSL sessions are now reused across connections for a single instance.
|
||||
This speeds up connection by using a previously negotiated session.
|
||||
* Requests may be created from a URI which sets the request_uri and host
|
||||
header of the request (but does not change the host connected to).
|
||||
* Responses contain the URI requested which allows easier implementation of
|
||||
redirect following.
|
||||
* new methods:
|
||||
* Net::HTTP#local_host
|
||||
* Net::HTTP#local_host=
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
#
|
||||
|
|
|
@ -409,6 +409,8 @@ module TestNetHTTP_version_1_2_methods
|
|||
_test_request__HEAD http
|
||||
_test_request__POST http
|
||||
_test_request__stream_body http
|
||||
_test_request__uri http
|
||||
_test_request__uri_host http
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -488,6 +490,51 @@ module TestNetHTTP_version_1_2_methods
|
|||
assert_equal data, res.body
|
||||
end
|
||||
|
||||
def _test_request__path(http)
|
||||
uri = URI 'https://example/'
|
||||
req = Net::HTTP::Get.new('/')
|
||||
|
||||
res = http.request(req)
|
||||
|
||||
assert_kind_of URI::Generic, req.uri
|
||||
|
||||
refute_equal uri, req.uri
|
||||
|
||||
assert_equal uri, res.uri
|
||||
|
||||
refute_same uri, req.uri
|
||||
refute_same req.uri, res.uri
|
||||
end
|
||||
|
||||
def _test_request__uri(http)
|
||||
uri = URI 'https://example/'
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
|
||||
res = http.request(req)
|
||||
|
||||
assert_kind_of URI::Generic, req.uri
|
||||
|
||||
refute_equal uri, req.uri
|
||||
|
||||
assert_equal req.uri, res.uri
|
||||
|
||||
refute_same uri, req.uri
|
||||
refute_same req.uri, res.uri
|
||||
end
|
||||
|
||||
def _test_request__uri_host(http)
|
||||
uri = URI 'http://example/'
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
req['host'] = 'other.example'
|
||||
|
||||
res = http.request(req)
|
||||
|
||||
assert_kind_of URI::Generic, req.uri
|
||||
|
||||
assert_equal URI("http://example:#{http.port}"), res.uri
|
||||
end
|
||||
|
||||
def test_send_request
|
||||
start {|http|
|
||||
_test_send_request__GET http
|
||||
|
@ -837,3 +884,4 @@ class TestNetHTTPLocalBind < Test::Unit::TestCase
|
|||
assert_equal(http.local_port, res.body)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -203,6 +203,21 @@ EOS
|
|||
assert_equal 'hello', body
|
||||
end
|
||||
|
||||
def test_uri_equals
|
||||
uri = URI 'http://example'
|
||||
|
||||
response = Net::HTTPResponse.new '1.1', 200, 'OK'
|
||||
|
||||
response.uri = nil
|
||||
|
||||
assert_nil response.uri
|
||||
|
||||
response.uri = uri
|
||||
|
||||
assert_equal uri, response.uri
|
||||
refute_same uri, response.uri
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dummy_io(str)
|
||||
|
|
Loading…
Reference in a new issue