Skip to content

Commit

Permalink
Backport URI.encode_www_form_component instead.
Browse files Browse the repository at this point in the history
This is better than the cgi/util.rb backport:
- Faster (https://gist.github.com/952373)
- More spec compliant
- Doesn't produce warnings if cgi.rb is required elsewhere
  • Loading branch information
John Firebaugh committed May 2, 2011
1 parent b8d3592 commit f0beb34
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 32 deletions.
28 changes: 0 additions & 28 deletions lib/rack/backports/cgi/util.rb

This file was deleted.

64 changes: 64 additions & 0 deletions lib/rack/backports/uri/common.rb
@@ -0,0 +1,64 @@
# :stopdoc:

# Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x
#
# https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb
#
#

module URI
TBLENCWWWCOMP_ = {} # :nodoc:
TBLDECWWWCOMP_ = {} # :nodoc:

# Encode given +str+ to URL-encoded form data.
#
# This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
# (ASCII space) to + and converts others to %XX.
#
# This is an implementation of
# http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
#
# See URI.decode_www_form_component, URI.encode_www_form
def self.encode_www_form_component(str)
if TBLENCWWWCOMP_.empty?
tbl = {}
256.times do |i|
tbl[i.chr] = '%%%02X' % i
end
tbl[' '] = '+'
begin
TBLENCWWWCOMP_.replace(tbl)
TBLENCWWWCOMP_.freeze
rescue
end
end
str = str.to_s
str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
end

# Decode given +str+ of URL-encoded form data.
#
# This decods + to SP.
#
# See URI.encode_www_form_component, URI.decode_www_form
def self.decode_www_form_component(str, enc=nil)
if TBLDECWWWCOMP_.empty?
tbl = {}
256.times do |i|
h, l = i>>4, i&15
tbl['%%%X%X' % [h, l]] = i.chr
tbl['%%%x%X' % [h, l]] = i.chr
tbl['%%%X%x' % [h, l]] = i.chr
tbl['%%%x%x' % [h, l]] = i.chr
end
tbl['+'] = ' '
begin
TBLDECWWWCOMP_.replace(tbl)
TBLDECWWWCOMP_.freeze
rescue
end
end
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%]+)*\z/ =~ str
str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
end
end
8 changes: 4 additions & 4 deletions lib/rack/utils.rb
Expand Up @@ -6,9 +6,9 @@

if RUBY_VERSION[/^\d+\.\d+/] == '1.8'
# pull in backports
require 'rack/backports/cgi/util'
require 'rack/backports/uri/common'
else
require 'cgi/util'
require 'uri/common'
end

module Rack
Expand All @@ -18,13 +18,13 @@ module Rack
module Utils
# URI escapes a string.
def escape(s)
CGI.escape(s.to_s)
URI.encode_www_form_component(s)
end
module_function :escape

# Unescapes a URI escaped string.
def unescape(s)
CGI.unescape(s)
URI.decode_www_form_component(s)
end
module_function :unescape

Expand Down

0 comments on commit f0beb34

Please sign in to comment.