Permalink
Browse files

Add experimental 'strict' mode for matching headers with '-' and '_' …

…characters; add pending specs for future 'fields' method
  • Loading branch information...
1 parent 11f1131 commit c9916ef0fefc56ffc5d00571f51bffd9c5f4712c @jsl committed Dec 3, 2010
Showing with 48 additions and 9 deletions.
  1. +17 −9 lib/http_headers.rb
  2. +31 −0 spec/http_headers_spec.rb
View
@@ -1,33 +1,41 @@
# Class HttpHeaders parses a http header_str from Curl::Easy into component parts.
class HttpHeaders
- attr_reader :content
-
- def initialize(str)
+ attr_reader :content, :strict_mode
+
+ DEFAULTS = { :strict => true }
+
+ def initialize(str, opts = {})
+ @strict_mode = opts.keys.include?(:strict) ? opts[:strict] : DEFAULTS[:strict]
@content = str.split(/\\r\\n|\n|\r/)
end
def version
- @content[0].match(/HTTP\/\d\.\d/)[0]
+ content[0].match(/HTTP\/\d\.\d/)[0]
end
def response_code
- @content[0].match(/HTTP\/\d\.\d (\d{3}.*)/)[1]
+ content[0].match(/HTTP\/\d\.\d (\d{3}.*)/)[1]
end
def method_missing(sym, *args)
detect_multi_value_keys(sym)
end
-
+
private
# Turns the given sym into a String after replacing the '_' character with the '-'
- def method_sym_to_http_key(sym)
- sym.to_s.gsub('_', '-')
+ def method_sym_to_http_pattern(sym)
+ sym_s = sym.to_s
+ if strict_mode
+ sym_s.gsub('_', '-')
+ else
+ sym_s.gsub('_', "[-_]")
+ end
end
def detect_multi_value_keys(tag)
- tag = method_sym_to_http_key(tag)
+ tag = method_sym_to_http_pattern(tag)
regexp = /^#{tag}:/i
results = @content.select{|e| e =~ regexp }.map{|e| value_from(e)}
results.size <= 1 ? results.first : results
@@ -41,6 +41,23 @@
HttpHeaders.new('Pragma: no-cache').pragma.should == 'no-cache'
end
+ describe "#fields" do
+
+ before {pending}
+
+ it "should return a collection of fields in the HTTP header" do
+ HttpHeaders.new('Pragma: no-cache\r\nCache-Control: private').field_names.should == ['Pragma', 'Cache-Control']
+ end
+
+ it "should not include the header" do
+ HttpHeaders.new('HTTP/1.1 200 OK\r\n').response_code.should == [ ]
+ end
+
+ it "should remove duplicates from the list" do
+ HttpHeaders.new('Set-Cookie: foo\r\nSet-Cookie: bar').field_names.should == ['Set-Cookie']
+ end
+ end
+
describe "breaking lines in header" do
it "should parse fields when separated by a normal newline" do
header = HttpHeaders.new(<<-EOS)
@@ -57,6 +74,20 @@
end
end
+ describe "strict mode" do
+ it "should not recognize headers with values containing _ if strict mode is on" do
+ HttpHeaders.new("Foo_bar: baz", :strict => true).foo_bar.should be_nil
+ end
+
+ it "should recognize headers with values containing _ if strict mode is off" do
+ HttpHeaders.new("Foo_bar: baz", :strict => false).foo_bar.should == 'baz'
+ end
+
+ it "should have strict mode on by default" do
+ HttpHeaders.new("Foo_bar: baz").strict_mode.should be_true
+ end
+ end
+
describe "multi-valued keys" do
before do
@headers = <<EOS

0 comments on commit c9916ef

Please sign in to comment.