ruby-changes:28155
From: akr <ko1@a...>
Date: Tue, 9 Apr 2013 19:53:51 +0900 (JST)
Subject: [ruby-changes:28155] akr:r40207 (trunk): * lib/open-uri.rb: Support multiple fields with same field
akr 2013-04-09 19:53:41 +0900 (Tue, 09 Apr 2013) New Revision: 40207 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40207 Log: * lib/open-uri.rb: Support multiple fields with same field name (like Set-Cookie). (OpenURI::Meta#metas): New accessor to obtain fields as a Hash from field name (string) to field values (array of strings). [ruby-core:37734] [Bug #4964] reported by ren li. Modified files: trunk/ChangeLog trunk/NEWS trunk/lib/open-uri.rb trunk/test/open-uri/test_open-uri.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 40206) +++ ChangeLog (revision 40207) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Apr 9 19:45:44 2013 Tanaka Akira <akr@f...> + + * lib/open-uri.rb: Support multiple fields with same field + name (like Set-Cookie). + (OpenURI::Meta#metas): New accessor to obtain fields as a Hash from + field name (string) to field values (array of strings). + [ruby-core:37734] [Bug #4964] reported by ren li. + Tue Apr 9 15:26:12 2013 Nobuyoshi Nakada <nobu@r...> * compile.c (iseq_compile_each): append keyword hash to argument array Index: lib/open-uri.rb =================================================================== --- lib/open-uri.rb (revision 40206) +++ lib/open-uri.rb (revision 40207) @@ -336,7 +336,7 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L336 io = buf.io io.rewind io.status = [resp.code, resp.message] - resp.each {|name,value| buf.io.meta_add_field name, value } + resp.each_name {|name| buf.io.meta_add_field2 name, resp.get_fields(name) } case resp when Net::HTTPSuccess when Net::HTTPMovedPermanently, # 301 @@ -405,13 +405,14 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L405 obj.extend Meta obj.instance_eval { @base_uri = nil - @meta = {} + @meta = {} # name to string. legacy. + @metas = {} # name to array of strings. } if src obj.status = src.status obj.base_uri = src.base_uri - src.meta.each {|name, value| - obj.meta_add_field(name, value) + src.metas.each {|name, values| + obj.meta_add_field2(name, values) } end end @@ -425,8 +426,16 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L426 # returns a Hash that represents header fields. # The Hash keys are downcased for canonicalization. + # The Hash values are a field body. + # If there are multiple field with same field name, + # the field values are concatenated with a comma. attr_reader :meta + # returns a Hash that represents header fields. + # The Hash keys are downcased for canonicalization. + # The Hash value are an array of field values. + attr_reader :metas + def meta_setup_encoding # :nodoc: charset = self.charset enc = nil @@ -446,15 +455,17 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L455 end end - def meta_add_field(name, value) # :nodoc: + def meta_add_field2(name, values) # :nodoc: name = name.downcase - @meta[name] = value + @metas[name] = values + @meta[name] = values.join(', ') meta_setup_encoding if name == 'content-type' end # returns a Time that represents the Last-Modified field. def last_modified - if v = @meta['last-modified'] + if vs = @metas['last-modified'] + v = vs.join(', ') Time.httpdate(v) else nil @@ -469,9 +480,9 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L480 # :startdoc: def content_type_parse # :nodoc: - v = @meta['content-type'] + vs = @metas['content-type'] # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045. - if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v + if vs && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ vs.join(', ') type = $1.downcase subtype = $2.downcase parameters = [] @@ -523,8 +534,8 @@ module OpenURI https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb#L534 # as an Array of String. # The encodings are downcased for canonicalization. def content_encoding - v = @meta['content-encoding'] - if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v + vs = @metas['content-encoding'] + if vs && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ (v = vs.join(', ')) v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase} else [] Index: NEWS =================================================================== --- NEWS (revision 40206) +++ NEWS (revision 40207) @@ -46,6 +46,9 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L46 * Pathname#write * Pathname#binwrite +* open-uri + * Support multiple fields with same field name (like Set-Cookie). + * Resolv * New methods: * Resolv::DNS.fetch_resource Index: test/open-uri/test_open-uri.rb =================================================================== --- test/open-uri/test_open-uri.rb (revision 40206) +++ test/open-uri/test_open-uri.rb (revision 40207) @@ -502,6 +502,21 @@ class TestOpenURI < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/open-uri/test_open-uri.rb#L502 } end if defined?(Zlib::GzipWriter) + def test_multiple_cookies + with_http {|srv, dr, url| + srv.mount_proc("/mcookie/") {|req, res| + res.cookies << "name1=value1; blabla" + res.cookies << "name2=value2; blabla" + res.body = "foo" + } + open("#{url}/mcookie/") {|f| + assert_equal("foo", f.read) + assert_equal(["name1=value1; blabla", "name2=value2; blabla"], + f.metas['set-cookie'].sort) + } + } + end + # 192.0.2.0/24 is TEST-NET. [RFC3330] def test_ftp_invalid_request -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/