Permalink
Browse files

Better URI escaping and encoding handling

* use escaping routines from standard library
* add automatic encoding detection (OSX uses utf-8, Windows ISO-8859-1)
  • Loading branch information...
georgi committed Jan 21, 2013
1 parent d002af1 commit 6b78fdf96617159f681f16f029c3abdf102ed998
Showing with 45 additions and 6 deletions.
  1. +5 −6 lib/rack_dav/controller.rb
  2. +28 −0 lib/rack_dav/string.rb
  3. +12 −0 spec/controller_spec.rb
View
@@ -1,4 +1,7 @@
require 'uri'
+
+require_relative 'string'
+
module RackDAV
class Controller
@@ -15,15 +18,11 @@ def initialize(request, response, options)
end
def url_escape(s)
- s.gsub(/([^\/a-zA-Z0-9_.-]+)/n) do
- '%' + $1.unpack('H2' * ($1.respond_to?(:bytesize) ? $1.bytesize : $1.size)).join('%').upcase
- end.tr(' ', '+')
+ URI.escape(s)
end
def url_unescape(s)
- s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
- URI.unescape($1).to_s
- end.to_s
+ URI.unescape(s).force_valid_encoding
end
def options
View
@@ -0,0 +1,28 @@
+class String
+
+ if RUBY_VERSION >= "1.9"
+ def force_valid_encoding
+ find_encoding(Encoding.list.to_enum)
+ end
+ else
+ def force_valid_encoding
+ self
+ end
+ end
+
+ private
+
+ def find_encoding(encodings)
+ if valid_encoding?
+ self
+ else
+ force_next_encoding(encodings)
+ end
+ end
+
+ def force_next_encoding(encodings)
+ force_encoding(encodings.next)
+ find_encoding(encodings)
+ end
+
+end
View
@@ -166,6 +166,18 @@ def initialize_with_original(*args)
)
end
+ describe "uri escaping" do
+ it "allows url escaped utf-8" do
+ put('/D%C3%B6ner').should be_ok
+ get('/D%C3%B6ner').should be_ok
+ end
+
+ it "allows url escaped iso-8859" do
+ put('/D%F6ner').should be_ok
+ get('/D%F6ner').should be_ok
+ end
+ end
+
describe "OPTIONS" do
it "is successful" do
options('/').should be_ok

0 comments on commit 6b78fdf

Please sign in to comment.