[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]