http_objects 0.0.1
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +56 -0
- data/Rakefile +12 -0
- data/http_objects.gemspec +20 -0
- data/lib/http_objects/hash.rb +51 -0
- data/lib/http_objects/headers/attributes.rb +38 -0
- data/lib/http_objects/headers/directives/cache.rb +80 -0
- data/lib/http_objects/headers/entity.rb +43 -0
- data/lib/http_objects/headers/general.rb +42 -0
- data/lib/http_objects/headers/request.rb +116 -0
- data/lib/http_objects/headers/response.rb +55 -0
- data/lib/http_objects/headers/tools.rb +29 -0
- data/lib/http_objects/headers.rb +27 -0
- data/lib/http_objects/headers_hash.rb +25 -0
- data/lib/http_objects/parameters/basic_rules.rb +62 -0
- data/lib/http_objects/parameters/date_time.rb +19 -0
- data/lib/http_objects/parameters/entity_tags.rb +27 -0
- data/lib/http_objects/parameters/language_tags.rb +16 -0
- data/lib/http_objects/parameters/media_type.rb +29 -0
- data/lib/http_objects/parameters/uri.rb +21 -0
- data/lib/http_objects/parameters.rb +15 -0
- data/lib/http_objects/version.rb +3 -0
- data/lib/http_objects.rb +5 -0
- data/test/http_objects/hash_test.rb +74 -0
- data/test/http_objects/headers/attributes_test.rb +26 -0
- data/test/http_objects/headers/directives/cache_test.rb +72 -0
- data/test/http_objects/headers/entity/allow_test.rb +13 -0
- data/test/http_objects/headers/entity/content_encoding_test.rb +13 -0
- data/test/http_objects/headers/entity/content_language_test.rb +13 -0
- data/test/http_objects/headers/entity/content_lenght_test.rb +13 -0
- data/test/http_objects/headers/entity/content_location_test.rb +13 -0
- data/test/http_objects/headers/entity/content_md5_test.rb +13 -0
- data/test/http_objects/headers/entity/content_type_test.rb +12 -0
- data/test/http_objects/headers/entity/expires_test.rb +12 -0
- data/test/http_objects/headers/entity/last_modified_test.rb +12 -0
- data/test/http_objects/headers/general_test.rb +59 -0
- data/test/http_objects/headers/request/host_test.rb +13 -0
- data/test/http_objects/headers/request/if_match_test.rb +21 -0
- data/test/http_objects/headers/request/if_modified_since_test.rb +13 -0
- data/test/http_objects/headers/request/if_none_match_test.rb +21 -0
- data/test/http_objects/headers/request/if_range_test.rb +21 -0
- data/test/http_objects/headers/request/if_unmodified_since_test.rb +13 -0
- data/test/http_objects/headers/request/max_forwards_test.rb +13 -0
- data/test/http_objects/headers/request/referer_test.rb +13 -0
- data/test/http_objects/headers/response/age_test.rb +13 -0
- data/test/http_objects/headers/response/etag_test.rb +13 -0
- data/test/http_objects/headers/response/location_test.rb +13 -0
- data/test/http_objects/headers/response/retry_after_test.rb +21 -0
- data/test/http_objects/headers/tools_test.rb +28 -0
- data/test/http_objects/headers_hash_test.rb +18 -0
- data/test/http_objects/http_objects_test.rb +4 -0
- data/test/http_objects/parameters/basic_rules_test.rb +73 -0
- data/test/http_objects/parameters/date_time_test.rb +43 -0
- data/test/http_objects/parameters/entity_tags_test.rb +43 -0
- data/test/http_objects/parameters/language_tags_test.rb +36 -0
- data/test/http_objects/parameters/media_type_test.rb +22 -0
- data/test/http_objects/parameters/uri_test.rb +36 -0
- data/test/test_helper.rb +7 -0
- metadata +202 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Roger Leite
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# HttpObjects
|
2
|
+
|
3
|
+
HTTP 1.1 by the spec, specially headers.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'http_objects'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install http_objects
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
#require 'rubygems'
|
23
|
+
require 'http_objects'
|
24
|
+
|
25
|
+
headers = HttpObjects::HeadersHash.new
|
26
|
+
|
27
|
+
# it's a normal hash (for normal keys)
|
28
|
+
headers["key"] = "value"
|
29
|
+
|
30
|
+
# for HTTP headers, you have objects
|
31
|
+
headers["Content-Type"] = "text/html;Charset=utf-8"
|
32
|
+
|
33
|
+
# one can check if header exist
|
34
|
+
puts headers.content_type? # => true
|
35
|
+
|
36
|
+
# one can access raw value
|
37
|
+
puts headers.content_type! # => "text/html;Charset=utf-8"
|
38
|
+
|
39
|
+
# one can access the value
|
40
|
+
puts headers.content_type.value # => "text/html"
|
41
|
+
|
42
|
+
# one can read directives
|
43
|
+
puts headers.content_type['charset'] # => "utf-8"
|
44
|
+
|
45
|
+
# finally one can access the object
|
46
|
+
puts headers.content_type.inspect # => #<HttpObjects::EntityHeaders::ContentType ...>
|
47
|
+
|
48
|
+
```
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rake/testtask"
|
4
|
+
|
5
|
+
ENV["RUBYOPT"] = "rubygems" if ENV["RUBYOPT"].nil?
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << "test"
|
9
|
+
t.test_files = FileList['test/http_objects/**/*_test.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :test
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/http_objects/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Roger Leite"]
|
6
|
+
gem.email = ["roger.barreto@gmail.com"]
|
7
|
+
gem.description = %q{HTTP 1.1 by the spec, specially headers}
|
8
|
+
gem.summary = %q{HTTP 1.1 by the spec, specially headers}
|
9
|
+
gem.homepage = "https://github.com/rogerleite/http_objects"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
|
+
gem.name = "http_objects"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = HttpObjects::VERSION
|
16
|
+
|
17
|
+
gem.add_development_dependency "rake"
|
18
|
+
gem.add_development_dependency "minitest", "~> 3"
|
19
|
+
gem.add_development_dependency "minitest-reporters", "~> 0.7.0"
|
20
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module HttpObjects
|
2
|
+
|
3
|
+
class Hash < ::Hash
|
4
|
+
extend HttpObjects::Headers::Attributes
|
5
|
+
|
6
|
+
# Public: Block that creates method based on attribute name.
|
7
|
+
MethodCreator = Proc.new do |name, header|
|
8
|
+
attr_name = name.downcase.gsub("-", "_")
|
9
|
+
self.class_eval(%{
|
10
|
+
def #{attr_name} # def content_type
|
11
|
+
self.fetch("#{name}", nil) # self.fetch("Content-Type", nil)
|
12
|
+
end # end
|
13
|
+
def #{attr_name}! # def content_type!
|
14
|
+
self.#{attr_name}.raw if #{attr_name}? # self.content_type.raw if content_type?
|
15
|
+
end # end
|
16
|
+
def #{attr_name}? # def content_type?
|
17
|
+
!!self.fetch("#{name}", nil) # !!self.fetch("Content-Type", nil)
|
18
|
+
end # end
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: Register attribute class with *MethodCreator* block.
|
23
|
+
def self.add_attribute(attr_class)
|
24
|
+
register_attribute(attr_class.header_name, attr_class, &MethodCreator)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.new(hash = nil)
|
28
|
+
hash.kind_of?(HttpObjects::Hash) ? hash : super(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(hash = nil)
|
32
|
+
super()
|
33
|
+
hash.each { |(key, value)| self[key] = value } unless hash.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
# Public: Associates key with value. If key is a valid HTTP Header name,
|
37
|
+
# like "Content-Type", it parses as HTTP Object.
|
38
|
+
#
|
39
|
+
# key - key or HTTP Header name.
|
40
|
+
# value - object. If key is HTTP Header name, value should be a String.
|
41
|
+
def []=(key, value)
|
42
|
+
if (header_class = self.class.attributes[key])
|
43
|
+
value = header_class.parse(value)
|
44
|
+
end
|
45
|
+
super(key, value)
|
46
|
+
end
|
47
|
+
alias :store :[]=
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module HttpObjects::Headers
|
2
|
+
|
3
|
+
# Public: Extend this module and you be able to retrieve and register
|
4
|
+
# attributes in your class.
|
5
|
+
#
|
6
|
+
# Examples
|
7
|
+
#
|
8
|
+
# class SampleAttributes
|
9
|
+
# extend HttpObjects::Headers::Attributes
|
10
|
+
# register_attribute "MyAttributeName", MyObject do |object|
|
11
|
+
# # optional hook
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# SampleAttributes.attributes # => {"MyAttributeName" => MyObject}
|
16
|
+
module Attributes
|
17
|
+
|
18
|
+
# Returns Hash of registered attributes.
|
19
|
+
def attributes
|
20
|
+
@attributes ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Public: Register on *attributes*, the pair name and attr_class.
|
24
|
+
#
|
25
|
+
# name - String identifying attribute.
|
26
|
+
# attr_class - Class to identify the attribute.
|
27
|
+
#
|
28
|
+
# Yields name and attr_class informed. Optional.
|
29
|
+
#
|
30
|
+
# Returns nothing.
|
31
|
+
def register_attribute(name, attr_class)
|
32
|
+
attributes[name] = attr_class
|
33
|
+
yield(name, attr_class) if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module HttpObjects::Headers
|
2
|
+
module Directives
|
3
|
+
|
4
|
+
BasicRules = HttpObjects::Parameters::BasicRules
|
5
|
+
|
6
|
+
class RawValue < BasicRules::Base
|
7
|
+
def self.parse(value)
|
8
|
+
self.new(value, value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Cache-Control = "Cache-Control" ":" 1#cache-directive
|
13
|
+
#
|
14
|
+
# cache-directive = cache-request-directive
|
15
|
+
# | cache-response-directive
|
16
|
+
#
|
17
|
+
# cache-request-directive =
|
18
|
+
# "no-cache" ; Section 14.9.1
|
19
|
+
# | "no-store" ; Section 14.9.2
|
20
|
+
# | "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4
|
21
|
+
# | "max-stale" [ "=" delta-seconds ] ; Section 14.9.3
|
22
|
+
# | "min-fresh" "=" delta-seconds ; Section 14.9.3
|
23
|
+
# | "no-transform" ; Section 14.9.5
|
24
|
+
# | "only-if-cached" ; Section 14.9.4
|
25
|
+
# | cache-extension ; Section 14.9.6
|
26
|
+
#
|
27
|
+
# cache-response-directive =
|
28
|
+
# "public" ; Section 14.9.1
|
29
|
+
# | "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
|
30
|
+
# | "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1
|
31
|
+
# | "no-store" ; Section 14.9.2
|
32
|
+
# | "no-transform" ; Section 14.9.5
|
33
|
+
# | "must-revalidate" ; Section 14.9.4
|
34
|
+
# | "proxy-revalidate" ; Section 14.9.4
|
35
|
+
# | "max-age" "=" delta-seconds ; Section 14.9.3
|
36
|
+
# | "s-maxage" "=" delta-seconds ; Section 14.9.3
|
37
|
+
# | cache-extension ; Section 14.9.6
|
38
|
+
#
|
39
|
+
# cache-extension = token [ "=" ( token | quoted-string ) ]
|
40
|
+
class Cache < HttpObjects::Hash
|
41
|
+
|
42
|
+
# token [ "=" ( token | quoted-string ) ]
|
43
|
+
TOKEN = /([^,=]+)(?:=\s*(?:\"([^\"]*)\"|\'([^\']*)\'|([^,]*)))?/
|
44
|
+
|
45
|
+
attr_reader :raw, :value
|
46
|
+
|
47
|
+
register_attribute "no-cache", RawValue, &MethodCreator
|
48
|
+
register_attribute "no-store", RawValue, &MethodCreator
|
49
|
+
register_attribute "max-age", BasicRules::Digit, &MethodCreator
|
50
|
+
register_attribute "max-stale", BasicRules::Digit, &MethodCreator
|
51
|
+
register_attribute "min-fresh", BasicRules::Digit, &MethodCreator
|
52
|
+
register_attribute "no-transform", RawValue, &MethodCreator
|
53
|
+
register_attribute "only-if-cached", RawValue, &MethodCreator
|
54
|
+
register_attribute "public", RawValue, &MethodCreator
|
55
|
+
register_attribute "private", RawValue, &MethodCreator
|
56
|
+
register_attribute "must-revalidate", RawValue, &MethodCreator
|
57
|
+
register_attribute "proxy-revalidate", RawValue, &MethodCreator
|
58
|
+
register_attribute "s-maxage", BasicRules::Digit, &MethodCreator
|
59
|
+
|
60
|
+
def self.parse(value)
|
61
|
+
cache = self.new(value)
|
62
|
+
value.scan(TOKEN).each do |key, v1, v2, v3|
|
63
|
+
key = key.strip
|
64
|
+
next if key.length.zero?
|
65
|
+
key.downcase!
|
66
|
+
key_value = (v1 || v2 || v3).to_s
|
67
|
+
cache[key] = key_value.strip
|
68
|
+
end
|
69
|
+
cache
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(value)
|
73
|
+
@raw = value
|
74
|
+
@value = value
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module HttpObjects::Headers::Entity
|
2
|
+
|
3
|
+
extend HttpObjects::Headers::Tools
|
4
|
+
|
5
|
+
# 14.7 Allow
|
6
|
+
# Allow: GET, HEAD, PUT
|
7
|
+
Allow = Header("Allow", HttpObjects::Parameters::BasicRules::UpAlpha)
|
8
|
+
|
9
|
+
# 14.11 Content-Encoding
|
10
|
+
# Pending: implement spec
|
11
|
+
ContentEncoding = Header("Content-Encoding", HttpObjects::Parameters::BasicRules::LoAlpha)
|
12
|
+
|
13
|
+
# 14.12 Content-Language
|
14
|
+
# Content-Language: mi, en
|
15
|
+
ContentLanguage = Header("Content-Language", HttpObjects::Parameters::LanguageTags)
|
16
|
+
|
17
|
+
# 14.13 Content-Length
|
18
|
+
# Content-Length: 3495
|
19
|
+
ContentLength = Header("Content-Length", HttpObjects::Parameters::BasicRules::Digit)
|
20
|
+
|
21
|
+
# 14.14 Content-Location
|
22
|
+
ContentLocation = Header("Content-Location", HttpObjects::Parameters::Uri)
|
23
|
+
|
24
|
+
# 14.15 Content-MD5
|
25
|
+
ContentMD5 = Header("Content-MD5", HttpObjects::Parameters::BasicRules::Token)
|
26
|
+
|
27
|
+
# 14.16 Content-Range
|
28
|
+
# Pending: implement spec
|
29
|
+
ContentRange = Header("Content-Range", HttpObjects::Parameters::BasicRules::Token)
|
30
|
+
|
31
|
+
# 14.21 Expires
|
32
|
+
# Expires: Thu, 01 Dec 1994 16:00:00 GMT
|
33
|
+
Expires = Header("Expires", HttpObjects::Parameters::DateTime)
|
34
|
+
|
35
|
+
# 14.23 Content-Type
|
36
|
+
# Content-Type: text/html; charset=ISO-8859-4
|
37
|
+
ContentType = Header("Content-Type", HttpObjects::Parameters::MediaType)
|
38
|
+
|
39
|
+
# Last-Modified
|
40
|
+
# Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
|
41
|
+
LastModified = Header("Last-Modified", HttpObjects::Parameters::DateTime)
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module HttpObjects::Headers::General
|
2
|
+
|
3
|
+
extend HttpObjects::Headers::Tools
|
4
|
+
|
5
|
+
# 14.9 Cache-Control
|
6
|
+
# Pending: implement spec
|
7
|
+
CacheControl = Header("Cache-Control", HttpObjects::Headers::Directives::Cache)
|
8
|
+
|
9
|
+
# 14.10 Connection
|
10
|
+
# Connection: close
|
11
|
+
Connection = Header("Connection", HttpObjects::Parameters::BasicRules::Token)
|
12
|
+
|
13
|
+
# 14.18 Date
|
14
|
+
# Date: Tue, 15 Nov 1994 08:12:31 GMT
|
15
|
+
Date = Header("Date", HttpObjects::Parameters::DateTime)
|
16
|
+
|
17
|
+
# 14.32 Pragma
|
18
|
+
Pragma = Header("Pragma", HttpObjects::Parameters::BasicRules::Token)
|
19
|
+
|
20
|
+
# 14.40 Trailer
|
21
|
+
Trailer = Header("Trailer", HttpObjects::Parameters::BasicRules::Token)
|
22
|
+
|
23
|
+
# 14.41 Transfer-Encoding
|
24
|
+
# Transfer-Encoding: chunked
|
25
|
+
# Pending: implement spec
|
26
|
+
TransferEncoding = Header("Transfer-Encoding", HttpObjects::Parameters::BasicRules::Token)
|
27
|
+
|
28
|
+
# 14.42 Upgrade
|
29
|
+
# Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
|
30
|
+
Upgrade = Header("Upgrade", HttpObjects::Parameters::BasicRules::Token)
|
31
|
+
|
32
|
+
# 14.45 Via
|
33
|
+
# Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
|
34
|
+
# Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
|
35
|
+
# Pending: implement spec
|
36
|
+
Via = Header("Via", HttpObjects::Parameters::BasicRules::Token)
|
37
|
+
|
38
|
+
# 14.46 Warning
|
39
|
+
# Pending: implement spec
|
40
|
+
Warning = Header("Warning", HttpObjects::Parameters::BasicRules::Token)
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module HttpObjects::Headers::Request
|
2
|
+
|
3
|
+
extend HttpObjects::Headers::Tools
|
4
|
+
|
5
|
+
# 14.1 Accept
|
6
|
+
# Accept: audio/*; q=0.2, audio/basic
|
7
|
+
# Pending: implement spec
|
8
|
+
Accept = Header("Accept", HttpObjects::Parameters::BasicRules::Token)
|
9
|
+
|
10
|
+
# 14.2 Accept-Charset
|
11
|
+
# Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
|
12
|
+
# Pending: implement spec
|
13
|
+
AcceptCharset = Header("Accept-Charset", HttpObjects::Parameters::BasicRules::Token)
|
14
|
+
|
15
|
+
# 14.3 Accept-Encoding
|
16
|
+
# Accept-Encoding: compress, gzip
|
17
|
+
# Accept-Encoding:
|
18
|
+
# Accept-Encoding: *
|
19
|
+
# Accept-Encoding: compress;q=0.5, gzip;q=1.0
|
20
|
+
# Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
|
21
|
+
# Pending: implement spec
|
22
|
+
AcceptEncoding = Header("Accept-Encoding", HttpObjects::Parameters::BasicRules::Token)
|
23
|
+
|
24
|
+
# 14.4 Accept-Language
|
25
|
+
# Accept-Language: da, en-gb;q=0.8, en;q=0.7
|
26
|
+
# Pending: implement spec
|
27
|
+
AcceptLanguage = Header("Accept-Language", HttpObjects::Parameters::BasicRules::Token)
|
28
|
+
|
29
|
+
# 14.8 Authorization
|
30
|
+
# Pending: implement spec
|
31
|
+
Authorization = Header("Authorization", HttpObjects::Parameters::BasicRules::Token)
|
32
|
+
|
33
|
+
# 14.20 Expect
|
34
|
+
# Pending: implement spec
|
35
|
+
Expect = Header("Expect", HttpObjects::Parameters::BasicRules::Token)
|
36
|
+
|
37
|
+
# 14.22 From
|
38
|
+
# From: webmaster@w3.org
|
39
|
+
# Pending: implement spec
|
40
|
+
From = Header("From", HttpObjects::Parameters::BasicRules::Token)
|
41
|
+
|
42
|
+
# 14.23 Host
|
43
|
+
# Host: www.w3.org
|
44
|
+
Host = Header("Host", HttpObjects::Parameters::Uri)
|
45
|
+
|
46
|
+
# 14.24 If-Match
|
47
|
+
# If-Match: "xyzzy"
|
48
|
+
# If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
|
49
|
+
# If-Match: *
|
50
|
+
IfMatch = Header("If-Match") do
|
51
|
+
# ( "*" | 1#entity-tag )
|
52
|
+
def self.parse(value)
|
53
|
+
if value == "*"
|
54
|
+
HttpObjects::Parameters::BasicRules::Token.parse("*")
|
55
|
+
else
|
56
|
+
HttpObjects::Parameters::EntityTags.parse(value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# 14.25 If-Modified-Since
|
62
|
+
# If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
|
63
|
+
IfModifiedSince = Header("If-Modified-Since", HttpObjects::Parameters::DateTime)
|
64
|
+
|
65
|
+
# 14.26 If-None-Match
|
66
|
+
# If-None-Match: "xyzzy"
|
67
|
+
# If-None-Match: W/"xyzzy"
|
68
|
+
# If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
|
69
|
+
# If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
|
70
|
+
# If-None-Match: *
|
71
|
+
IfNoneMatch = Header("If-None-Match", IfMatch)
|
72
|
+
|
73
|
+
# 14.27 If-Range
|
74
|
+
IfRange = Header("If-Range") do
|
75
|
+
# ( entity-tag | HTTP-date )
|
76
|
+
def self.parse(value)
|
77
|
+
result = HttpObjects::Parameters::EntityTags.parse(value)
|
78
|
+
if value != "" && result.value == ""
|
79
|
+
result = HttpObjects::Parameters::DateTime.parse(value)
|
80
|
+
end
|
81
|
+
result
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# 14.28 If-Unmodified-Since
|
86
|
+
# If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
|
87
|
+
IfUnmodifiedSince = Header("If-Unmodified-Since", HttpObjects::Parameters::DateTime)
|
88
|
+
|
89
|
+
# 14.31 Max-Forwards
|
90
|
+
MaxForwards = Header("Max-Forwards", HttpObjects::Parameters::BasicRules::Digit)
|
91
|
+
|
92
|
+
# 14.34 Proxy-Authorization
|
93
|
+
# Pending: implement spec
|
94
|
+
ProxyAuthorization = Header("Proxy-Authorization", HttpObjects::Parameters::BasicRules::Token)
|
95
|
+
|
96
|
+
# 14.35 Range
|
97
|
+
# Pending: implement spec
|
98
|
+
Range = Header("Range", HttpObjects::Parameters::BasicRules::Token)
|
99
|
+
|
100
|
+
# 14.36 Referer
|
101
|
+
# Referer: http://www.w3.org/hypertext/DataSources/Overview.html
|
102
|
+
Referer = Header("Referer", HttpObjects::Parameters::Uri)
|
103
|
+
|
104
|
+
# 14.39 TE
|
105
|
+
# TE: deflate
|
106
|
+
# TE:
|
107
|
+
# TE: trailers, deflate;q=0.5
|
108
|
+
# Pending: implement spec
|
109
|
+
TE = Header("TE", HttpObjects::Parameters::BasicRules::Token)
|
110
|
+
|
111
|
+
# 14.43 User-Agent
|
112
|
+
# User-Agent: CERN-LineMode/2.15 libwww/2.17b3
|
113
|
+
# Pending: implement spec
|
114
|
+
UserAgent = Header("User-Agent", HttpObjects::Parameters::BasicRules::Token)
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module HttpObjects::Headers::Response
|
2
|
+
|
3
|
+
extend HttpObjects::Headers::Tools
|
4
|
+
|
5
|
+
# 14.5 Accept-Ranges
|
6
|
+
# Pending: implement spec
|
7
|
+
AcceptRanges = Header("Accept-Ranges", HttpObjects::Parameters::BasicRules::Token)
|
8
|
+
|
9
|
+
# 14.6 Age
|
10
|
+
Age = Header("Age", HttpObjects::Parameters::BasicRules::Digit)
|
11
|
+
|
12
|
+
# 14.19 ETag
|
13
|
+
# ETag: "xyzzy"
|
14
|
+
# ETag: W/"xyzzy"
|
15
|
+
# ETag: ""
|
16
|
+
ETag = Header("ETag", HttpObjects::Parameters::EntityTags)
|
17
|
+
|
18
|
+
# 14.30 Location
|
19
|
+
# Location: http://www.w3.org/pub/WWW/People.html
|
20
|
+
Location = Header("Location", HttpObjects::Parameters::Uri)
|
21
|
+
|
22
|
+
# 14.36 Proxy-Authenticate
|
23
|
+
# Pending: implement spec
|
24
|
+
ProxyAuthenticate = Header("Proxy-Authenticate", HttpObjects::Parameters::BasicRules::Token)
|
25
|
+
|
26
|
+
# 14.37 Retry-After
|
27
|
+
# Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
|
28
|
+
# Retry-After: 120
|
29
|
+
RetryAfter = Header("Retry-After") do
|
30
|
+
|
31
|
+
# Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
|
32
|
+
def self.parse(value)
|
33
|
+
header_obj = HttpObjects::Parameters::DateTime.parse(value)
|
34
|
+
if header_obj.value.nil?
|
35
|
+
header_obj = HttpObjects::Parameters::BasicRules::Digit.parse(value)
|
36
|
+
end
|
37
|
+
header_obj
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# 14.38 Server
|
43
|
+
# Server: CERN/3.0 libwww/2.17
|
44
|
+
# Pending: implement spec
|
45
|
+
Server = Header("Server", HttpObjects::Parameters::BasicRules::Token)
|
46
|
+
|
47
|
+
# 14.44 Vary
|
48
|
+
# Pending: implement spec
|
49
|
+
Vary = Header("Vary", HttpObjects::Parameters::BasicRules::Token)
|
50
|
+
|
51
|
+
# 14.47 WWW-Authenticate
|
52
|
+
# Pending: implement spec
|
53
|
+
WWWAuthenticate = Header("WWW-Authenticate", HttpObjects::Parameters::BasicRules::Token)
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HttpObjects
|
2
|
+
module Headers
|
3
|
+
|
4
|
+
# **Extend** this and be happy declaring HTTP Headers
|
5
|
+
module Tools
|
6
|
+
|
7
|
+
def Header(name, klass = nil, &block)
|
8
|
+
header_class = if block_given?
|
9
|
+
Class.new(&block)
|
10
|
+
else
|
11
|
+
Class.new(klass)
|
12
|
+
end
|
13
|
+
header_class.instance_eval %{
|
14
|
+
def header_name
|
15
|
+
"#{name}"
|
16
|
+
end
|
17
|
+
}
|
18
|
+
header_class
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns Array of Header classes.
|
22
|
+
def headers
|
23
|
+
self.constants.map { |header| self.const_get(header) }
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "http_objects/headers/tools"
|
2
|
+
require "http_objects/headers/attributes"
|
3
|
+
require "http_objects/hash"
|
4
|
+
|
5
|
+
require "http_objects/headers/directives/cache"
|
6
|
+
|
7
|
+
require "http_objects/headers/entity"
|
8
|
+
require "http_objects/headers/general"
|
9
|
+
require "http_objects/headers/request"
|
10
|
+
require "http_objects/headers/response"
|
11
|
+
|
12
|
+
module HttpObjects
|
13
|
+
|
14
|
+
module Headers
|
15
|
+
|
16
|
+
# Returns Array of all HTTP Headers
|
17
|
+
def self.headers
|
18
|
+
[HttpObjects::Headers::General,
|
19
|
+
HttpObjects::Headers::Entity,
|
20
|
+
HttpObjects::Headers::Request,
|
21
|
+
HttpObjects::Headers::Response].inject([]) do |headers, header_module|
|
22
|
+
headers.concat(header_module.headers)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HttpObjects
|
2
|
+
|
3
|
+
# Public: Hash with HTTP Headers methods.
|
4
|
+
#
|
5
|
+
# Examples
|
6
|
+
#
|
7
|
+
# headers = HttpObjects::Headers.new
|
8
|
+
# headers["key"] = "value" # is kind of Hash
|
9
|
+
#
|
10
|
+
# # And for HTTP headers, you have objects
|
11
|
+
# headers["Content-Type"] = "text/html;Charset=utf-8"
|
12
|
+
# headers.content_type? # => true
|
13
|
+
# headers.content_type! # => "text/html;Charset=utf-8"
|
14
|
+
# headers.content_type.value # => "text/html"
|
15
|
+
# headers.content_type['charset'] # => "utf-8"
|
16
|
+
# headers.content_type.inspect # => #<HttpObjects::Headers::MediaType ...>
|
17
|
+
class HeadersHash < HttpObjects::Hash
|
18
|
+
|
19
|
+
HttpObjects::Headers.headers.each do |header|
|
20
|
+
add_attribute(header)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|