jsl-http_headers 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +56 -0
- data/Rakefile +25 -0
- data/http_headers.gemspec +35 -0
- data/lib/http_headers.rb +41 -0
- data/spec/fixtures/headers.txt +1 -0
- data/spec/fixtures/headers2.txt +11 -0
- data/spec/http_headers_spec.rb +70 -0
- data/spec/spec_helper.rb +9 -0
- metadata +66 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Justin S. Leitgeb
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= HttpHeaders
|
2
|
+
|
3
|
+
HttpHeaders is a library for parsing HTTP-compliant header strings. It was designed to process the
|
4
|
+
results from the header_str method on Curl::Easy objects in Ruby, but should work for other HTTP-compliant
|
5
|
+
string formats.
|
6
|
+
|
7
|
+
It correctly parses the content type, response code and most other key-value fields from the HTTP response header,
|
8
|
+
including keys that may appear multiple times in the header such as Set-Cookie.
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
Set up your machine to pull gems from gems.github.com if you haven't already. Then:
|
13
|
+
|
14
|
+
sudo gem install jsl-http_headers
|
15
|
+
|
16
|
+
== Quick Start
|
17
|
+
|
18
|
+
Just require the library, create a new HttpHeaders object with the header string and start invoking methods.
|
19
|
+
|
20
|
+
require 'http_headers'
|
21
|
+
h = HttpHeaders.new(header_str)
|
22
|
+
h.content_type
|
23
|
+
h.etag
|
24
|
+
h.set_cookie # Will return an Array of String values if more than one match is found
|
25
|
+
|
26
|
+
Other methods should just work for arbitrary attributes by lowercasing the attribute name and substituting
|
27
|
+
hyphens with underscores.
|
28
|
+
|
29
|
+
== Implementation
|
30
|
+
|
31
|
+
HttpHeaders uses ruby's +method_missing+ in order to build queries for the given parameter dynamically, so
|
32
|
+
it doesn't need to parse values for every field at the time that the HttpHeader object is instantiated with
|
33
|
+
a HTTP header string.
|
34
|
+
|
35
|
+
== Possible Limitations
|
36
|
+
|
37
|
+
Some attributes, such as Set-Cookie, may appear listed multiple times in the header. Where this occurs,
|
38
|
+
we try to find all instances of the key and return an Array if multiple occurrences are found. Otherwise,
|
39
|
+
nothing is done in the case where there are multiple values for a cookie given as values of a particular key -
|
40
|
+
at this point the values won't be magically turned into an Array and it will be up to the user to program the
|
41
|
+
desired behavior in a client library.
|
42
|
+
|
43
|
+
== Feedback
|
44
|
+
|
45
|
+
Please write the author if you have any questions or feedback about this library. Patches are welcome if you have ideas
|
46
|
+
about how the behavior of HttpHeaders can be improved for particular cases. Please include specs using the associated
|
47
|
+
test suite if you make improvements, and I would also be happy to receive more fixtures consisting of HTTP strings of
|
48
|
+
failure cases indicating where the library can be improved.
|
49
|
+
|
50
|
+
== References
|
51
|
+
|
52
|
+
* The HTTP Header Field Definitions - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
53
|
+
|
54
|
+
== Author
|
55
|
+
|
56
|
+
Justin S. Leitgeb, <justin@phq.org>
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
|
8
|
+
desc 'Test the plugin.'
|
9
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
10
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run all the tests"
|
16
|
+
task :default => :spec
|
17
|
+
|
18
|
+
desc 'Generate documentation for the hashback plugin.'
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'HTTP Headers'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "http_headers"
|
3
|
+
s.version = "0.0.2"
|
4
|
+
s.date = "2009-05-22"
|
5
|
+
s.summary = "Library for parsing the Curl header_str into attributes"
|
6
|
+
s.email = "justin@phq.org"
|
7
|
+
s.homepage = "http://github.com/jsl/hashback"
|
8
|
+
s.description = "Creates an object from the attributes in a header_str from Curl"
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.authors = ["Justin Leitgeb"]
|
11
|
+
s.files = [
|
12
|
+
"Rakefile",
|
13
|
+
"http_headers.gemspec",
|
14
|
+
"LICENSE",
|
15
|
+
"README.rdoc",
|
16
|
+
"Rakefile",
|
17
|
+
"spec/http_headers_spec.rb",
|
18
|
+
"spec/fixtures/headers.txt",
|
19
|
+
"spec/fixtures/headers2.txt",
|
20
|
+
"lib/http_headers.rb"
|
21
|
+
]
|
22
|
+
s.test_files = [
|
23
|
+
"spec/http_headers_spec.rb",
|
24
|
+
"spec/spec_helper.rb"
|
25
|
+
]
|
26
|
+
|
27
|
+
s.extra_rdoc_files = [ "README.rdoc" ]
|
28
|
+
|
29
|
+
s.rdoc_options += [
|
30
|
+
'--title', 'HttpHeaders',
|
31
|
+
'--main', 'README.rdoc',
|
32
|
+
'--line-numbers',
|
33
|
+
'--inline-source'
|
34
|
+
]
|
35
|
+
end
|
data/lib/http_headers.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Class HttpHeaders parses a http header_str from Curl::Easy into component parts.
|
2
|
+
class HttpHeaders
|
3
|
+
|
4
|
+
attr_reader :content
|
5
|
+
|
6
|
+
def initialize(str)
|
7
|
+
@content = str.split(/\\r\\n|\n|\r/)
|
8
|
+
end
|
9
|
+
|
10
|
+
def version
|
11
|
+
@content[0].match(/HTTP\/\d\.\d/)[0]
|
12
|
+
end
|
13
|
+
|
14
|
+
def response_code
|
15
|
+
@content[0].match(/HTTP\/\d\.\d (\d{3}.*)/)[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(sym, *args)
|
19
|
+
detect_multi_value_keys(sym)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Turns the given sym into a String after replacing the '_' character with the '-'
|
25
|
+
def method_sym_to_http_key(sym)
|
26
|
+
sym.to_s.gsub('_', '-')
|
27
|
+
end
|
28
|
+
|
29
|
+
def detect_multi_value_keys(tag)
|
30
|
+
tag = method_sym_to_http_key(tag)
|
31
|
+
regexp = /^#{tag}:/i
|
32
|
+
results = @content.select{|e| e =~ regexp }.map{|e| value_from(e)}
|
33
|
+
results.size <= 1 ? results.first : results
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the key from this tag, which should be a string with key separated
|
37
|
+
# from val by ':'
|
38
|
+
def value_from(tag)
|
39
|
+
tag.split(/:\W+/)[1]
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
HTTP/1.1 200 OK\r\nServer: Sun-ONE-Web-Server/6.1\r\nDate: Fri, 22 May 2009 12:53:02 GMT\r\nContent-type: text/html\r\nSet-cookie: RMID=21167df34c454a16a02ee2e1; expires=Saturday, 22-May-2010 12:53:02 GMT; path=/; domain=.nytimes.com\r\nSet-cookie: adxcs=-; path=/; domain=.nytimes.com\r\nSet-cookie: adxcs=-; path=/; domain=.nytimes.com\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\nCache-control: no-cache\r\nPragma: no-cache\r\nTransfer-encoding: chunked\r\n\r\n
|
@@ -0,0 +1,11 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Last-Modified: Fri, 22 May 2009 15:35:08 GMT
|
3
|
+
ETag: pnDSjJtGvlc2WrX6VND/w0qxEc8
|
4
|
+
Content-Type: text/xml; charset=utf-8
|
5
|
+
Date: Fri, 22 May 2009 18:18:08 GMT
|
6
|
+
Expires: Fri, 22 May 2009 18:18:08 GMT
|
7
|
+
Cache-Control: private, max-age=0
|
8
|
+
X-Content-Type-Options: nosniff
|
9
|
+
Server: GFE/2.0
|
10
|
+
Transfer-Encoding: chunked
|
11
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[spec_helper])
|
2
|
+
|
3
|
+
describe HttpHeaders do
|
4
|
+
before do
|
5
|
+
@h = HttpHeaders.new(File.read(File.join(File.dirname(__FILE__), %w[fixtures headers.txt])))
|
6
|
+
@h2 = HttpHeaders.new(File.read(File.join(File.dirname(__FILE__), %w[fixtures headers2.txt])))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have text/html as the content_type" do
|
10
|
+
@h.version.should == 'HTTP/1.1'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have 200 OK as the response code" do
|
14
|
+
@h.response_code.should == '200 OK'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have a nil etag for the first header file" do
|
18
|
+
@h.etag.should be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have an etag of pnDSjJtGvlc2WrX6VND/w0qxEc8" do
|
22
|
+
@h2.etag.should == 'pnDSjJtGvlc2WrX6VND/w0qxEc8'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have Fri, 22 May 2009 18:18:08 GMT for date" do
|
26
|
+
@h2.date.should == 'Fri, 22 May 2009 18:18:08 GMT'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have Fri, 22 May 2009 18:18:08 GMT for expires" do
|
30
|
+
@h2.expires.should == 'Fri, 22 May 2009 18:18:08 GMT'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have private, max-age=0 for cache_control" do
|
34
|
+
@h2.cache_control.should == 'private, max-age=0'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have Fri, 22 May 2009 15:35:08 GMT for last_modified" do
|
38
|
+
@h2.last_modified.should == 'Fri, 22 May 2009 15:35:08 GMT'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have GFE/2.0 for server" do
|
42
|
+
@h2.server.should == 'GFE/2.0'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have no-cache for pragma" do
|
46
|
+
@h.pragma.should == 'no-cache'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have chunked for transfer_encoding" do
|
50
|
+
@h2.transfer_encoding.should == 'chunked'
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "multi-valued keys like Set-cookie:" do
|
54
|
+
before do
|
55
|
+
@c = @h.set_cookie
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return an Array if multiple values are present" do
|
59
|
+
@c.should be_a(Array)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have three cookies" do
|
63
|
+
@c.size.should == 3
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have adxcs=-; path=/; domain=.nytimes.com as value for one cookie" do
|
67
|
+
@c.include?("adxcs=-; path=/; domain=.nytimes.com").should be_true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsl-http_headers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Leitgeb
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-22 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Creates an object from the attributes in a header_str from Curl
|
17
|
+
email: justin@phq.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- Rakefile
|
26
|
+
- http_headers.gemspec
|
27
|
+
- LICENSE
|
28
|
+
- README.rdoc
|
29
|
+
- spec/http_headers_spec.rb
|
30
|
+
- spec/fixtures/headers.txt
|
31
|
+
- spec/fixtures/headers2.txt
|
32
|
+
- lib/http_headers.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/jsl/hashback
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options:
|
37
|
+
- --title
|
38
|
+
- HttpHeaders
|
39
|
+
- --main
|
40
|
+
- README.rdoc
|
41
|
+
- --line-numbers
|
42
|
+
- --inline-source
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.2.0
|
61
|
+
signing_key:
|
62
|
+
specification_version: 2
|
63
|
+
summary: Library for parsing the Curl header_str into attributes
|
64
|
+
test_files:
|
65
|
+
- spec/http_headers_spec.rb
|
66
|
+
- spec/spec_helper.rb
|