http_objects 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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