1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/net/http.rb (GenericRequest#initialize): check if path begins with '/'.

* lib/net/http.rb: def m( arg ) -> def m(arg)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2003-12-29 11:08:47 +00:00
parent d993e38f18
commit ef70baa40a
2 changed files with 142 additions and 152 deletions

View file

@ -1,3 +1,10 @@
Mon Dec 29 20:08:17 2003 Minero Aoki <aamine@loveruby.net>
* lib/net/http.rb (GenericRequest#initialize): check if path
begins with '/'.
* lib/net/http.rb: def m( arg ) -> def m(arg)
Mon Dec 29 12:51:02 2003 Dave Thomas <dave@pragprog.com> Mon Dec 29 12:51:02 2003 Dave Thomas <dave@pragprog.com>
* eval.c: Add RDoc for Kernel global functions. * eval.c: Add RDoc for Kernel global functions.

View file

@ -340,7 +340,7 @@ module Net # :nodoc:
# This method does not open the TCP connection. # This method does not open the TCP connection.
def initialize(address, port = nil) def initialize(address, port = nil)
@address = address @address = address
@port = port || HTTP.default_port @port = (port || HTTP.default_port)
@curr_http_version = HTTPVersion @curr_http_version = HTTPVersion
@seems_1_0_server = false @seems_1_0_server = false
@ -483,7 +483,6 @@ module Net # :nodoc:
# #
def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil) def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
return self unless p_addr return self unless p_addr
delta = ProxyDelta delta = ProxyDelta
proxyclass = Class.new(self) proxyclass = Class.new(self)
proxyclass.module_eval { proxyclass.module_eval {
@ -557,8 +556,6 @@ module Net # :nodoc:
module ProxyDelta #:nodoc: internal use only module ProxyDelta #:nodoc: internal use only
private private
# with proxy
def conn_address def conn_address
proxy_address() proxy_address()
end end
@ -687,6 +684,7 @@ module Net # :nodoc:
# f.write str # f.write str
# end # end
# } # }
#
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+ def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
res = nil res = nil
request(Post.new(path, initheader), data) {|r| request(Post.new(path, initheader), data) {|r|
@ -703,7 +701,7 @@ module Net # :nodoc:
def put(path, data, initheader = nil) #:nodoc: def put(path, data, initheader = nil) #:nodoc:
res = request(Put.new(path, initheader), data) res = request(Put.new(path, initheader), data)
@newimpl or res.value res.value unless @newimpl
res res
end end
@ -733,7 +731,7 @@ module Net # :nodoc:
# } # }
# #
def request_get(path, initheader = nil, &block) # :yield: +response+ def request_get(path, initheader = nil, &block) # :yield: +response+
request Get.new(path, initheader), &block request(Get.new(path, initheader), &block)
end end
# Sends a HEAD request to the +path+ and gets a response, # Sends a HEAD request to the +path+ and gets a response,
@ -747,7 +745,7 @@ module Net # :nodoc:
# p response['content-type'] # p response['content-type']
# #
def request_head(path, initheader = nil, &block) def request_head(path, initheader = nil, &block)
request Head.new(path, initheader), &block request(Head.new(path, initheader), &block)
end end
# Sends a POST request to the +path+ and gets a response, # Sends a POST request to the +path+ and gets a response,
@ -775,6 +773,7 @@ module Net # :nodoc:
# print str # print str
# end # end
# } # }
#
def request_post(path, data, initheader = nil, &block) # :yield: +response+ def request_post(path, data, initheader = nil, &block) # :yield: +response+
request Post.new(path, initheader), data, &block request Post.new(path, initheader), data, &block
end end
@ -816,6 +815,7 @@ module Net # :nodoc:
# Returns a HTTPResponse object. # Returns a HTTPResponse object.
# #
# This method never raises Net::* exceptions. # This method never raises Net::* exceptions.
#
def request(req, body = nil, &block) # :yield: +response+ def request(req, body = nil, &block) # :yield: +response+
unless started? unless started?
start { start {
@ -858,11 +858,10 @@ module Net # :nodoc:
def end_transport(req, res) def end_transport(req, res)
@curr_http_version = res.http_version @curr_http_version = res.http_version
if not res.body and @close_on_empty_response if not res.body and @close_on_empty_response
D 'Conn close' D 'Conn close'
@socket.close @socket.close
elsif keep_alive? req, res elsif keep_alive?(req, res)
D 'Conn keep-alive' D 'Conn keep-alive'
if @socket.closed? if @socket.closed?
D 'Conn (but seems 1.0 server)' D 'Conn (but seems 1.0 server)'
@ -875,16 +874,13 @@ module Net # :nodoc:
end end
def keep_alive?(req, res) def keep_alive?(req, res)
/close/i === req['connection'].to_s and return false return false if /close/i =~ req['connection'].to_s
@seems_1_0_server and return false return false if @seems_1_0_server
return true if /keep-alive/i =~ res['connection'].to_s
/keep-alive/i === res['connection'].to_s and return true return false if /close/i =~ res['connection'].to_s
/close/i === res['connection'].to_s and return false return true if /keep-alive/i =~ res['proxy-connection'].to_s
/keep-alive/i === res['proxy-connection'].to_s and return true return false if /close/i =~ res['proxy-connection'].to_s
/close/i === res['proxy-connection'].to_s and return false (@curr_http_version == '1.1')
@curr_http_version == '1.1' and return true
false
end end
# #
@ -898,11 +894,10 @@ module Net # :nodoc:
end end
def D(msg) def D(msg)
if @debug_output return unless @debug_output
@debug_output << msg @debug_output << msg
@debug_output << "\n" @debug_output << "\n"
end end
end
end end
@ -974,18 +969,19 @@ module Net # :nodoc:
@header.dup @header.dup
end end
# As for #each_header, except the keys are provided in # As for #each_header, except the keys are provided in capitalized form.
# canonical form, which is to say, capitalized. def each_capitalized
def canonical_each
@header.each do |k,v| @header.each do |k,v|
yield canonical(k), v yield capitalize(k), v
end end
end end
def canonical( k ) alias canonical_each each_capitalized
def capitalize(k)
k.split(/-/).map {|i| i.capitalize }.join('-') k.split(/-/).map {|i| i.capitalize }.join('-')
end end
private :canonical private :capitalize
# Returns a Range object which represents Range: header field, # Returns a Range object which represents Range: header field,
# or +nil+ if there is no such header. # or +nil+ if there is no such header.
@ -1009,30 +1005,25 @@ module Net # :nodoc:
# length from it (arg i&len). # length from it (arg i&len).
def range=(r, fin = nil) def range=(r, fin = nil)
r = (r ... r + fin) if fin r = (r ... r + fin) if fin
case r case r
when Numeric when Numeric
s = r > 0 ? "0-#{r - 1}" : "-#{-r}" rangestr = (r > 0 ? "0-#{r.to_i - 1}" : "-#{-r.to_i}")
when Range when Range
first = r.first first = r.first
last = r.last last = r.last
if r.exclude_end? last -= 1 if r.exclude_end?
last -= 1
end
if last == -1 if last == -1
s = first > 0 ? "#{first}-" : "-#{-first}" rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
else else
first >= 0 or raise HTTPHeaderSyntaxError, 'range.first is negative' raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
last > 0 or raise HTTPHeaderSyntaxError, 'range.last is negative' raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
first < last or raise HTTPHeaderSyntaxError, 'must be .first < .last' raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
s = "#{first}-#{last}" rangestr = "#{first}-#{last}"
end end
else else
raise TypeError, 'Range/Integer is required' raise TypeError, 'Range/Integer is required'
end end
@header['range'] = "bytes=#{rangestr}"
@header['range'] = "bytes=#{s}"
r r
end end
@ -1041,10 +1032,9 @@ module Net # :nodoc:
# Returns an Integer object which represents the Content-Length: header field # Returns an Integer object which represents the Content-Length: header field
# or +nil+ if that field is not provided. # or +nil+ if that field is not provided.
def content_length def content_length
s = @header['content-length'] or return nil len = @header['content-length'].to_s.slice(/\d+/) or
m = /\d+/.match(s) or
raise HTTPHeaderSyntaxError, 'wrong Content-Length format' raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
m[0].to_i len.to_i
end end
# Returns "true" if the "transfer-encoding" header is present and # Returns "true" if the "transfer-encoding" header is present and
@ -1052,24 +1042,24 @@ module Net # :nodoc:
# the content to be sent in "chunks" without at the outset # the content to be sent in "chunks" without at the outset
# stating the entire content length. # stating the entire content length.
def chunked? def chunked?
s = @header['transfer-encoding'] field = @header['transfer-encoding'] or return false
(s and /(?:\A|[^\-\w])chunked(?:[^\-\w]|\z)/i === s) ? true : false (/(?:\A|[^\-\w])chunked(?:[^\-\w]|\z)/i =~ field) ? true : false
end end
# Returns a Range object which represents Content-Range: header field. # Returns a Range object which represents Content-Range: header field.
# This indicates, for a partial entity body, where this fragment # This indicates, for a partial entity body, where this fragment
# fits inside the full entity body, as range of byte offsets. # fits inside the full entity body, as range of byte offsets.
def content_range def content_range
s = @header['content-range'] or return nil return nil unless @header['content-range']
m = %r<bytes\s+(\d+)-(\d+)/(?:\d+|\*)>i.match(s) or m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(@header['content-range']) or
raise HTTPHeaderSyntaxError, 'wrong Content-Range format' raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
m[1].to_i .. m[2].to_i + 1 m[1].to_i .. m[2].to_i + 1
end end
# The length of the range represented in Range: header. # The length of the range represented in Range: header.
def range_length def range_length
r = self.content_range r = content_range() or return nil
r and (r.end - r.begin) r.end - r.begin
end end
# Set the Authorization: header for "Basic" authorization. # Set the Authorization: header for "Basic" authorization.
@ -1103,13 +1093,14 @@ module Net # :nodoc:
@method = m @method = m
@request_has_body = reqbody @request_has_body = reqbody
@response_has_body = resbody @response_has_body = resbody
raise ArgumentError, "invalid request path: #{path.inspect}" unless %r<\A/> =~ path
@path = path @path = path
@header = {} @header = {}
return unless initheader return unless initheader
initheader.each do |k,v| initheader.each do |k,v|
key = k.downcase key = k.downcase
$stderr.puts "net/http: warning: duplicated HTTP header: #{k}" if @header.key?(key) and $VERBOSE warn "net/http: warning: duplicated HTTP header: #{k}" if @header.key?(key) and $VERBOSE
@header[key] = v.strip @header[key] = v.strip
end end
@header['accept'] ||= '*/*' @header['accept'] ||= '*/*'
@ -1138,7 +1129,8 @@ module Net # :nodoc:
def exec(sock, ver, path, body) #:nodoc: internal use only def exec(sock, ver, path, body) #:nodoc: internal use only
if body if body
check_body_permitted raise ArgumentError, 'HTTP request body is not permitted' \
unless request_body_permitted?
send_request_with_body sock, ver, path, body send_request_with_body sock, ver, path, body
else else
request sock, ver, path request sock, ver, path
@ -1147,27 +1139,20 @@ module Net # :nodoc:
private private
def check_body_permitted
request_body_permitted? or
raise ArgumentError, 'HTTP request body is not permitted'
end
def send_request_with_body(sock, ver, path, body) def send_request_with_body(sock, ver, path, body)
@header['content-length'] = body.length.to_s @header['content-length'] = body.length.to_s
@header.delete 'transfer-encoding' @header.delete 'transfer-encoding'
unless @header['content-type'] unless @header['content-type']
$stderr.puts 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
@header['content-type'] = 'application/x-www-form-urlencoded' @header['content-type'] = 'application/x-www-form-urlencoded'
end end
request sock, ver, path request sock, ver, path
sock.write body sock.write body
end end
def request(sock, ver, path) def request(sock, ver, path)
buf = "#{@method} #{path} HTTP/#{ver}\r\n" buf = "#{@method} #{path} HTTP/#{ver}\r\n"
canonical_each do |k,v| each_capitalized do |k,v|
buf << k + ': ' + v + "\r\n" buf << k + ': ' + v + "\r\n"
end end
buf << "\r\n" buf << "\r\n"
@ -1545,7 +1530,7 @@ module Net # :nodoc:
httpv, code, msg = read_status_line(sock) httpv, code, msg = read_status_line(sock)
res = response_class(code).new(httpv, code, msg) res = response_class(code).new(httpv, code, msg)
each_response_header(sock) do |k,v| each_response_header(sock) do |k,v|
if res.key? k if res.key?(k)
res[k] << ', ' << v res[k] << ', ' << v
else else
res[k] = v res[k] = v
@ -1561,7 +1546,7 @@ module Net # :nodoc:
str = sock.readline str = sock.readline
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or
raise HTTPBadResponse, "wrong status line: #{str.dump}" raise HTTPBadResponse, "wrong status line: #{str.dump}"
m.to_a[1,3] m.captures
end end
def response_class(code) def response_class(code)
@ -1698,7 +1683,6 @@ module Net # :nodoc:
raise IOError, "#{self.class}\#read_body called twice" if dest or block raise IOError, "#{self.class}\#read_body called twice" if dest or block
return @body return @body
end end
to = procdest(dest, block) to = procdest(dest, block)
stream_check stream_check
if @body_exist if @body_exist
@ -1737,25 +1721,24 @@ module Net # :nodoc:
def read_body_0(dest) def read_body_0(dest)
if chunked? if chunked?
read_chunked dest read_chunked dest
else return
end
clen = content_length() clen = content_length()
if clen if clen
@socket.read clen, dest, true # ignore EOF @socket.read clen, dest, true # ignore EOF
else return
end
clen = range_length() clen = range_length()
if clen if clen
@socket.read clen, dest @socket.read clen, dest
else return
end
@socket.read_all dest @socket.read_all dest
end end
end
end
end
def read_chunked(dest) def read_chunked(dest)
len = nil len = nil
total = 0 total = 0
while true while true
line = @socket.readline line = @socket.readline
hexlen = line.slice(/[0-9a-fA-F]+/) or hexlen = line.slice(/[0-9a-fA-F]+/) or