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

* lib/uri/common.rb (URI.encode_www_form): new method to

generate URL-encoded form data. [ruby-dev:39246]

* lib/uri/common.rb (URI.encode_www_component,
  URI.decode_www_component): new method for encode/decode
  a name/value of HTML form.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2010-03-12 09:00:48 +00:00
parent d7cc39658c
commit 8212cdf176
3 changed files with 120 additions and 0 deletions

View file

@ -1,3 +1,12 @@
Fri Mar 12 17:14:12 2010 NARUSE, Yui <naruse@ruby-lang.org>
* lib/uri/common.rb (URI.encode_www_form): new method to
generate URL-encoded form data. [ruby-dev:39246]
* lib/uri/common.rb (URI.encode_www_component,
URI.decode_www_component): new method for encode/decode
a name/value of HTML form.
Fri Mar 12 17:36:35 2010 NARUSE, Yui <naruse@ruby-lang.org>
* lib/webrick/httpservlet/cgihandler.rb

View file

@ -716,6 +716,92 @@ module URI
DEFAULT_PARSER.make_regexp(schemes)
end
# :nodoc:
TBLENCWWWCOMP_ = {}
# :nodoc:
TBLDECWWWCOMP_ = {}
# Encode given +str+ to URL-encoded form data.
#
# This doesn't convert *, -, ., 0-9, A-Z, _, a-z,
# does convert SP to +, and convert others to %XX.
#
# This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
#
# See URI.decode_www_component(str), URI.encode_www_form(enum)
def self.encode_www_component(str)
if TBLENCWWWCOMP_.empty?
256.times do |i|
case i
when 0x20
TBLENCWWWCOMP_[' '] = '+'
when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A
else
TBLENCWWWCOMP_[i.chr] = '%%%X' % i
end
end
TBLENCWWWCOMP_.freeze
end
str = str.dup.force_encoding(Encoding::ASCII_8BIT)
str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
str
end
# Decode given +str+ of URL-encoded form data.
#
# This decods + to SP.
#
# See URI.encode_www_component(str)
def self.decode_www_component(str)
if TBLDECWWWCOMP_.empty?
256.times do |i|
case i
when 0x20
TBLDECWWWCOMP_['+'] = ' '
else
h, l = i>>4, i&15
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
end
end
TBLDECWWWCOMP_.freeze
end
str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_)
end
# Generate URL-encoded form data from given +enum+.
#
# This generates application/x-www-form-urlencoded data defined in HTML5
# from given an Enumerable object.
#
# This internally uses URI.encode_www_component(str).
#
# This doesn't convert encodings of give items, so convert them before call
# this method if you want to send data as other than original encoding or
# mixed encoding data.
#
# This doesn't treat files. When you send a file, use multipart/form-data.
#
# This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
#
# See URI.encode_www_component(str)
def self.encode_www_form(enum)
str = nil
enum.each do |k,v|
if str
str << '&'
else
str = ''.force_encoding(Encoding::US_ASCII)
end
str << encode_www_component(k)
str << '='
str << encode_www_component(v)
end
str
end
end
module Kernel

View file

@ -49,6 +49,31 @@ class TestCommon < Test::Unit::TestCase
assert_equal(expected, Kernel::URI("http://www.ruby-lang.org/"))
assert_raise(NoMethodError) { Object.new.URI("http://www.ruby-lang.org/") }
end
def test_encode_www_component
assert_equal("+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
"AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E",
URI.encode_www_component(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~"))
end
def test_decode_www_component
assert_equal(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~",
URI.decode_www_component(
"+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
"AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E"))
end
def test_encode_www_form
assert_equal("a=1", URI.encode_www_form("a" => "1"))
assert_equal("a=1", URI.encode_www_form(a: 1))
assert_equal("a=1", URI.encode_www_form([["a", "1"]]))
assert_equal("a=1", URI.encode_www_form([[:a, 1]]))
expected = "a=1&%E3%81%82=%E6%BC%A2"
assert_equal(expected, URI.encode_www_form("a" => "1", "\u3042" => "\u6F22"))
assert_equal(expected, URI.encode_www_form(a: 1, :"\u3042" => "\u6F22"))
assert_equal(expected, URI.encode_www_form([["a", "1"], ["\u3042", "\u6F22"]]))
assert_equal(expected, URI.encode_www_form([[:a, 1], [:"\u3042", "\u6F22"]]))
end
end