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.
Files changed (61) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +56 -0
  5. data/Rakefile +12 -0
  6. data/http_objects.gemspec +20 -0
  7. data/lib/http_objects/hash.rb +51 -0
  8. data/lib/http_objects/headers/attributes.rb +38 -0
  9. data/lib/http_objects/headers/directives/cache.rb +80 -0
  10. data/lib/http_objects/headers/entity.rb +43 -0
  11. data/lib/http_objects/headers/general.rb +42 -0
  12. data/lib/http_objects/headers/request.rb +116 -0
  13. data/lib/http_objects/headers/response.rb +55 -0
  14. data/lib/http_objects/headers/tools.rb +29 -0
  15. data/lib/http_objects/headers.rb +27 -0
  16. data/lib/http_objects/headers_hash.rb +25 -0
  17. data/lib/http_objects/parameters/basic_rules.rb +62 -0
  18. data/lib/http_objects/parameters/date_time.rb +19 -0
  19. data/lib/http_objects/parameters/entity_tags.rb +27 -0
  20. data/lib/http_objects/parameters/language_tags.rb +16 -0
  21. data/lib/http_objects/parameters/media_type.rb +29 -0
  22. data/lib/http_objects/parameters/uri.rb +21 -0
  23. data/lib/http_objects/parameters.rb +15 -0
  24. data/lib/http_objects/version.rb +3 -0
  25. data/lib/http_objects.rb +5 -0
  26. data/test/http_objects/hash_test.rb +74 -0
  27. data/test/http_objects/headers/attributes_test.rb +26 -0
  28. data/test/http_objects/headers/directives/cache_test.rb +72 -0
  29. data/test/http_objects/headers/entity/allow_test.rb +13 -0
  30. data/test/http_objects/headers/entity/content_encoding_test.rb +13 -0
  31. data/test/http_objects/headers/entity/content_language_test.rb +13 -0
  32. data/test/http_objects/headers/entity/content_lenght_test.rb +13 -0
  33. data/test/http_objects/headers/entity/content_location_test.rb +13 -0
  34. data/test/http_objects/headers/entity/content_md5_test.rb +13 -0
  35. data/test/http_objects/headers/entity/content_type_test.rb +12 -0
  36. data/test/http_objects/headers/entity/expires_test.rb +12 -0
  37. data/test/http_objects/headers/entity/last_modified_test.rb +12 -0
  38. data/test/http_objects/headers/general_test.rb +59 -0
  39. data/test/http_objects/headers/request/host_test.rb +13 -0
  40. data/test/http_objects/headers/request/if_match_test.rb +21 -0
  41. data/test/http_objects/headers/request/if_modified_since_test.rb +13 -0
  42. data/test/http_objects/headers/request/if_none_match_test.rb +21 -0
  43. data/test/http_objects/headers/request/if_range_test.rb +21 -0
  44. data/test/http_objects/headers/request/if_unmodified_since_test.rb +13 -0
  45. data/test/http_objects/headers/request/max_forwards_test.rb +13 -0
  46. data/test/http_objects/headers/request/referer_test.rb +13 -0
  47. data/test/http_objects/headers/response/age_test.rb +13 -0
  48. data/test/http_objects/headers/response/etag_test.rb +13 -0
  49. data/test/http_objects/headers/response/location_test.rb +13 -0
  50. data/test/http_objects/headers/response/retry_after_test.rb +21 -0
  51. data/test/http_objects/headers/tools_test.rb +28 -0
  52. data/test/http_objects/headers_hash_test.rb +18 -0
  53. data/test/http_objects/http_objects_test.rb +4 -0
  54. data/test/http_objects/parameters/basic_rules_test.rb +73 -0
  55. data/test/http_objects/parameters/date_time_test.rb +43 -0
  56. data/test/http_objects/parameters/entity_tags_test.rb +43 -0
  57. data/test/http_objects/parameters/language_tags_test.rb +36 -0
  58. data/test/http_objects/parameters/media_type_test.rb +22 -0
  59. data/test/http_objects/parameters/uri_test.rb +36 -0
  60. data/test/test_helper.rb +7 -0
  61. metadata +202 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ tags
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in http_objects.gemspec
4
+ gemspec
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