xenon-routing 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/{xenon-routing/lib → lib}/xenon/api.rb +20 -11
  3. data/{xenon-routing/lib → lib}/xenon/marshallers.rb +24 -14
  4. data/{xenon-routing/lib → lib}/xenon/request.rb +10 -2
  5. data/{xenon-routing/lib → lib}/xenon/response.rb +0 -0
  6. data/{xenon-routing/lib → lib}/xenon/routing.rb +0 -0
  7. data/{xenon-routing/lib → lib}/xenon/routing/context.rb +0 -0
  8. data/{xenon-routing/lib → lib}/xenon/routing/directives.rb +1 -0
  9. data/{xenon-routing/lib → lib}/xenon/routing/header_directives.rb +0 -0
  10. data/lib/xenon/routing/marshalling_directives.rb +24 -0
  11. data/{xenon-routing/lib → lib}/xenon/routing/method_directives.rb +10 -4
  12. data/{xenon-routing/lib → lib}/xenon/routing/param_directives.rb +0 -0
  13. data/{xenon-routing/lib → lib}/xenon/routing/path_directives.rb +0 -0
  14. data/{xenon-routing/lib → lib}/xenon/routing/route_directives.rb +0 -0
  15. data/{xenon-routing/lib → lib}/xenon/routing/security_directives.rb +6 -0
  16. data/{xenon-routing/lib → lib}/xenon/routing_version.rb +0 -0
  17. data/{xenon-http/spec → spec}/spec_helper.rb +0 -0
  18. data/{xenon-routing/xenon-routing.gemspec → xenon-routing.gemspec} +2 -2
  19. metadata +25 -80
  20. data/.codeclimate.yml +0 -18
  21. data/.gitignore +0 -25
  22. data/.rspec +0 -3
  23. data/.travis.yml +0 -6
  24. data/Gemfile +0 -20
  25. data/Guardfile +0 -16
  26. data/LICENSE +0 -22
  27. data/README.md +0 -116
  28. data/Rakefile +0 -40
  29. data/VERSION +0 -1
  30. data/examples/hello_world/config.ru +0 -3
  31. data/examples/hello_world/hello_world.rb +0 -27
  32. data/xenon-http/lib/xenon/auth.rb +0 -63
  33. data/xenon-http/lib/xenon/errors.rb +0 -5
  34. data/xenon-http/lib/xenon/etag.rb +0 -48
  35. data/xenon-http/lib/xenon/headers.rb +0 -112
  36. data/xenon-http/lib/xenon/headers/accept.rb +0 -34
  37. data/xenon-http/lib/xenon/headers/accept_charset.rb +0 -59
  38. data/xenon-http/lib/xenon/headers/accept_encoding.rb +0 -63
  39. data/xenon-http/lib/xenon/headers/accept_language.rb +0 -59
  40. data/xenon-http/lib/xenon/headers/authorization.rb +0 -50
  41. data/xenon-http/lib/xenon/headers/cache_control.rb +0 -56
  42. data/xenon-http/lib/xenon/headers/content_type.rb +0 -23
  43. data/xenon-http/lib/xenon/headers/if_match.rb +0 -53
  44. data/xenon-http/lib/xenon/headers/if_modified_since.rb +0 -22
  45. data/xenon-http/lib/xenon/headers/if_none_match.rb +0 -53
  46. data/xenon-http/lib/xenon/headers/if_range.rb +0 -45
  47. data/xenon-http/lib/xenon/headers/if_unmodified_since.rb +0 -22
  48. data/xenon-http/lib/xenon/headers/user_agent.rb +0 -65
  49. data/xenon-http/lib/xenon/headers/www_authenticate.rb +0 -71
  50. data/xenon-http/lib/xenon/http.rb +0 -7
  51. data/xenon-http/lib/xenon/http_version.rb +0 -3
  52. data/xenon-http/lib/xenon/media_type.rb +0 -162
  53. data/xenon-http/lib/xenon/parsers/basic_rules.rb +0 -86
  54. data/xenon-http/lib/xenon/parsers/header_rules.rb +0 -60
  55. data/xenon-http/lib/xenon/parsers/media_type.rb +0 -53
  56. data/xenon-http/lib/xenon/quoted_string.rb +0 -20
  57. data/xenon-http/spec/xenon/etag_spec.rb +0 -19
  58. data/xenon-http/spec/xenon/headers/accept_charset_spec.rb +0 -31
  59. data/xenon-http/spec/xenon/headers/accept_encoding_spec.rb +0 -40
  60. data/xenon-http/spec/xenon/headers/accept_language_spec.rb +0 -33
  61. data/xenon-http/spec/xenon/headers/accept_spec.rb +0 -54
  62. data/xenon-http/spec/xenon/headers/authorization_spec.rb +0 -47
  63. data/xenon-http/spec/xenon/headers/cache_control_spec.rb +0 -64
  64. data/xenon-http/spec/xenon/headers/if_match_spec.rb +0 -73
  65. data/xenon-http/spec/xenon/headers/if_modified_since_spec.rb +0 -19
  66. data/xenon-http/spec/xenon/headers/if_none_match_spec.rb +0 -79
  67. data/xenon-http/spec/xenon/headers/if_range_spec.rb +0 -45
  68. data/xenon-http/spec/xenon/headers/if_unmodified_since_spec.rb +0 -19
  69. data/xenon-http/spec/xenon/headers/user_agent_spec.rb +0 -67
  70. data/xenon-http/spec/xenon/headers/www_authenticate_spec.rb +0 -43
  71. data/xenon-http/spec/xenon/media_type_spec.rb +0 -267
  72. data/xenon-http/xenon-http.gemspec +0 -25
  73. data/xenon-routing/spec/spec_helper.rb +0 -94
  74. data/xenon.gemspec +0 -26
@@ -1,45 +0,0 @@
1
- require 'xenon/headers'
2
- require 'xenon/parsers/header_rules'
3
- require 'xenon/errors'
4
- require 'xenon/etag'
5
-
6
- module Xenon
7
- class Headers
8
- # http://tools.ietf.org/html/rfc7233#section-3.2
9
- class IfRange < Header 'If-Range'
10
- attr_reader :date, :etag
11
-
12
- def initialize(value)
13
- case value
14
- when Time, DateTime, Date then @date = value
15
- when ETag then @etag = value
16
- when String then @etag = ETag.parse(value)
17
- else raise ArgumentError, 'Value must be a time or an etag.'
18
- end
19
-
20
- raise ProtocolError, 'If-Range headers must use strong ETags.' if @etag && @etag.weak?
21
- end
22
-
23
- def self.parse(s)
24
- tree = Parsers::IfRangeHeader.new.parse(s)
25
- Parsers::IfRangeHeaderTransform.new.apply(tree)
26
- end
27
-
28
- def to_s
29
- @etag ? @etag.to_s : @date.httpdate
30
- end
31
- end
32
- end
33
-
34
- module Parsers
35
- class IfRangeHeader < Parslet::Parser
36
- include ETagHeaderRules
37
- rule(:if_range) { (etag | http_date).as(:if_range) }
38
- root(:if_range)
39
- end
40
-
41
- class IfRangeHeaderTransform < ETagHeaderTransform
42
- rule(if_range: simple(:v)) { Headers::IfRange.new(v) }
43
- end
44
- end
45
- end
@@ -1,22 +0,0 @@
1
- require 'xenon/headers'
2
-
3
- module Xenon
4
- class Headers
5
- # http://tools.ietf.org/html/rfc7232#section-3.4
6
- class IfUnmodifiedSince < Header 'If-Unmodified-Since'
7
- attr_reader :date
8
-
9
- def initialize(date)
10
- @date = date
11
- end
12
-
13
- def self.parse(s)
14
- new(Time.httpdate(s))
15
- end
16
-
17
- def to_s
18
- @date.httpdate
19
- end
20
- end
21
- end
22
- end
@@ -1,65 +0,0 @@
1
- require 'xenon/headers'
2
- require 'xenon/parsers/header_rules'
3
-
4
- module Xenon
5
- class Product
6
- attr_reader :name, :version, :comment
7
-
8
- def initialize(name, version = nil, comment = nil)
9
- @name = name
10
- @version = version
11
- @comment = comment
12
- end
13
-
14
- def to_s
15
- s = ''
16
- s << @name if @name
17
- s << '/' << @version if @version
18
- if @comment
19
- s << ' ' unless s.empty?
20
- s << '(' << @comment << ')'
21
- end
22
- s
23
- end
24
- end
25
-
26
- class Headers
27
- # http://tools.ietf.org/html/rfc7231#section-5.5.3
28
- class UserAgent < Header 'User-Agent'
29
- attr_reader :products
30
-
31
- def initialize(*products)
32
- @products = products
33
- end
34
-
35
- def self.parse(s)
36
- tree = Parsers::UserAgentHeader.new.parse(s)
37
- Parsers::UserAgentHeaderTransform.new.apply(tree)
38
- end
39
-
40
- def to_s
41
- @products.map(&:to_s).join(' ')
42
- end
43
- end
44
- end
45
-
46
- module Parsers
47
- class UserAgentHeader < Parslet::Parser
48
- include HeaderRules
49
- rule(:product) { (token.as(:name) >> (str('/') >> token.as(:version)).maybe >> (rws >> comment.as(:comment)).maybe).as(:product) }
50
- rule(:product_comment) { comment.as(:product_comment) }
51
- rule(:user_agent) { (product >> (rws >> (product | product_comment)).repeat).as(:user_agent) }
52
- root(:user_agent)
53
- end
54
-
55
- class UserAgentHeaderTransform < HeaderTransform
56
- rule(product: { name: simple(:p), version: simple(:v), comment: simple(:c) }) { Product.new(p, v, c) }
57
- rule(product: { name: simple(:p), version: simple(:v) }) { Product.new(p, v) }
58
- rule(product: { name: simple(:p), comment: simple(:c) }) { Product.new(p, nil, c) }
59
- rule(product: { name: simple(:p) }) { Product.new(p) }
60
- rule(product_comment: simple(:c)) { Product.new(nil, nil, c) }
61
- rule(user_agent: sequence(:p)) { Headers::UserAgent.new(*p) }
62
- rule(user_agent: simple(:p)) { Headers::UserAgent.new(p) }
63
- end
64
- end
65
- end
@@ -1,71 +0,0 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
2
- require 'forwardable'
3
- require 'xenon/headers'
4
- require 'xenon/parsers/header_rules'
5
- require 'xenon/quoted_string'
6
-
7
- module Xenon
8
- class Headers
9
- class Challenge
10
- extend Forwardable
11
- using QuotedString
12
-
13
- attr_reader :auth_scheme
14
- def_delegators :@params, :key?, :include?, :[]
15
-
16
- def initialize(auth_scheme, params = {})
17
- @auth_scheme = auth_scheme
18
- @params = params.with_indifferent_access
19
- end
20
-
21
- def method_missing(name, *args, &block)
22
- name = name.to_sym
23
- @params.key?(name) ? @params[name] : super
24
- end
25
-
26
- def respond_to_missing?(name, include_all)
27
- @params.key?(name.to_sym) || super
28
- end
29
-
30
- def to_s
31
- param_string = @params.map { |k, v| "#{k}=#{v.quote}"}.join(', ')
32
- "#{@auth_scheme} #{param_string}"
33
- end
34
- end
35
-
36
- # https://tools.ietf.org/html/rfc7235#section-4.1
37
- class WWWAuthenticate < ListHeader 'WWW-Authenticate'
38
- def initialize(*challenges)
39
- super(challenges)
40
- end
41
-
42
- alias_method :challenges, :values
43
-
44
- def self.parse(s)
45
- tree = Parsers::WWWAuthenticateHeader.new.parse(s)
46
- Parsers::WWWAuthenticateHeaderTransform.new.apply(tree)
47
- end
48
-
49
- def to_s
50
- challenges.map(&:to_s).join(', ')
51
- end
52
- end
53
- end
54
-
55
- module Parsers
56
- class WWWAuthenticateHeader < Parslet::Parser
57
- include AuthHeaderRules
58
- rule(:challenge) { (auth_scheme >> sp >> (auth_params | token68)).as(:challenge) }
59
- rule(:www_authenticate) { (challenge >> (comma >> challenge).repeat).as(:www_authenticate) }
60
- root(:www_authenticate)
61
- end
62
-
63
- class WWWAuthenticateHeaderTransform < HeaderTransform
64
- rule(auth_param: { name: simple(:n), value: simple(:v) }) { Tuple.new(n, v) }
65
- rule(challenge: { auth_scheme: simple(:s), auth_params: simple(:p) }) { Headers::Challenge.new(s, Hash[*p.to_a]) }
66
- rule(challenge: { auth_scheme: simple(:s), auth_params: sequence(:p) }) { Headers::Challenge.new(s, Hash[p.map(&:to_a)]) }
67
- rule(www_authenticate: simple(:c)) { Headers::WWWAuthenticate.new(c) }
68
- rule(www_authenticate: sequence(:c)) { Headers::WWWAuthenticate.new(*c) }
69
- end
70
- end
71
- end
@@ -1,7 +0,0 @@
1
- require 'xenon/http_version'
2
- require 'xenon/auth'
3
- require 'xenon/errors'
4
- require 'xenon/etag'
5
- require 'xenon/headers'
6
- require 'xenon/media_type'
7
- require 'xenon/quoted_string'
@@ -1,3 +0,0 @@
1
- module Xenon
2
- HTTP_VERSION = File.read(File.join(__dir__, '..', '..', '..', 'VERSION'))
3
- end
@@ -1,162 +0,0 @@
1
- require 'xenon/errors'
2
- require 'xenon/parsers/media_type'
3
-
4
- module Xenon
5
-
6
- # A media type.
7
- #
8
- # @see ContentType
9
- # @see MediaRange
10
- class MediaType
11
- attr_reader :type, :subtype, :params
12
-
13
- # Initializes a new instance of MediaType.
14
- #
15
- # @param type [String] The main type, e.g. 'application'.
16
- # @param subtype [String] The subtype, e.g. 'json'.
17
- # @param params [Hash] Any params for the media type; don't use 'q' or 'charset'.
18
- def initialize(type, subtype, params = {})
19
- @type = type
20
- @subtype = subtype
21
- @params = params
22
- end
23
-
24
- # Parses a media type.
25
- #
26
- # @param s [String] The media type string.
27
- # @return [MediaType] The media type.
28
- def self.parse(s)
29
- tree = Parsers::MediaType.new.parse(s)
30
- Parsers::MediaTypeTransform.new.apply(tree)
31
- rescue Parslet::ParseFailed
32
- raise Xenon::ParseError.new("Invalid media type (#{s}).")
33
- end
34
-
35
- %w(application audio image message multipart text video).each do |type|
36
- define_method "#{type}?" do
37
- @type == type
38
- end
39
- end
40
-
41
- def experimental?
42
- @subtype.start_with?('x.') # not x- see http://tools.ietf.org/html/rfc6838#section-3.4
43
- end
44
-
45
- def personal?
46
- @subtype.start_with?('prs.')
47
- end
48
-
49
- def vendor?
50
- @subtype.start_with?('vnd.')
51
- end
52
-
53
- %w(ber der fastinfoset json wbxml xml zip).each do |format|
54
- define_method "#{format}?" do
55
- @subtype == format || @subtype.end_with?("+#{format}")
56
- end
57
- end
58
-
59
- # Creates a {MediaRange} using this media type with a quality factor.
60
- #
61
- # @param q [Numeric] A value between 1.0 (most desirable) and 0.0 (not acceptable).
62
- # @return [MediaRange] The media range.
63
- def with_q(q)
64
- MediaRange.new(self, q)
65
- end
66
-
67
- # Creates a {ContentType} using this media type with a charset.
68
- #
69
- # @param charset [String] The desired charset, e.g. 'utf-8'.
70
- # @return [ContentType] The content type.
71
- def with_charset(charset)
72
- ContentType.new(self, charset)
73
- end
74
-
75
- def to_s
76
- "#{@type}/#{@subtype}" << @params.map { |n, v| v ? "; #{n}=#{v}" : "; #{n}" }.join
77
- end
78
-
79
- JSON = MediaType.new('application', 'json')
80
- XML = MediaType.new('application', 'xml')
81
- end
82
-
83
- # A content type.
84
- class ContentType
85
- attr_reader :media_type, :charset
86
-
87
- DEFAULT_CHARSET = 'utf-8' # historically iso-8859-1 but see http://tools.ietf.org/html/rfc7231#appendix-B
88
-
89
- def initialize(media_type, charset = DEFAULT_CHARSET)
90
- @media_type = media_type
91
- @charset = charset
92
- end
93
-
94
- def self.parse(s)
95
- media_type = MediaType.parse(s)
96
- charset = media_type.params.delete('charset') || DEFAULT_CHARSET
97
- ContentType.new(media_type, charset)
98
- end
99
-
100
- def to_s
101
- "#{@media_type}; charset=#{@charset}"
102
- end
103
- end
104
-
105
- class MediaRange
106
- include Comparable
107
-
108
- DEFAULT_Q = 1.0
109
-
110
- attr_reader :type, :subtype, :q, :params
111
-
112
- def initialize(type, subtype, params = {})
113
- @type = type
114
- @subtype = subtype
115
- @q = Float(params.delete('q')) rescue DEFAULT_Q
116
- @params = params
117
- end
118
-
119
- def self.parse(s)
120
- tree = Parsers::MediaRange.new.parse(s)
121
- Parsers::MediaTypeTransform.new.apply(tree)
122
- rescue Parslet::ParseFailed
123
- raise Xenon::ParseError.new("Invalid media range (#{s})")
124
- end
125
-
126
- def <=>(other)
127
- dt = compare_types(@type, other.type)
128
- return dt if dt != 0
129
- ds = compare_types(@subtype, other.subtype)
130
- return ds if ds != 0
131
- dp = params.size <=> other.params.size
132
- return dp if dp != 0
133
- @q <=> other.q
134
- end
135
-
136
- def =~(media_type)
137
- (type == '*' || type == media_type.type) &&
138
- (subtype == '*' || subtype == media_type.subtype) &&
139
- params.all? { |n, v| media_type.params[n] == v }
140
- end
141
-
142
- alias_method :===, :=~
143
-
144
- def to_s
145
- s = "#{@type}/#{@subtype}"
146
- s << @params.map { |n, v| v ? "; #{n}=#{v}" : "; #{n}" }.join
147
- s << "; q=#{@q}" if @q != DEFAULT_Q
148
- s
149
- end
150
-
151
- private
152
-
153
- def compare_types(a, b)
154
- if a == b then 0
155
- elsif a == '*' then -1
156
- elsif b == '*' then 1
157
- else 0
158
- end
159
- end
160
- end
161
-
162
- end
@@ -1,86 +0,0 @@
1
- require 'parslet'
2
-
3
- module Xenon
4
- module Parsers
5
-
6
- # Parslet doesn't match sequence of sequences (i.e. [['foo', 'bar']]) as a sequence(:v) in transform
7
- # rules so this is a little wrapper class that allows smuggling an array through the matcher rules,
8
- # for example above would be [Tuple.new('foo', 'bar')], when no 'proper' class is required.
9
- class Tuple
10
- def initialize(*values)
11
- @values = values
12
- end
13
-
14
- def to_a
15
- @values
16
- end
17
- end
18
-
19
- module BasicRules
20
- include Parslet
21
-
22
- # http://tools.ietf.org/html/rfc5234#appendix-B.1
23
- rule(:alpha) { match(/[a-z]/i) }
24
- rule(:bit) { match(/[01]/) }
25
- rule(:char) { match(/[\u0001-\u007f]/) }
26
- rule(:digit) { match(/[0-9]/) }
27
- rule(:hexdig) { match(/[a-f0-9]/i)}
28
- rule(:vchar) { match(/[\u0021-\u007e]/) }
29
- rule(:alphanum) { alpha | digit }
30
-
31
- rule(:sp) { str(' ') }
32
- rule(:sp?) { sp.repeat }
33
- rule(:htab) { str("\t") }
34
- rule(:wsp) { sp | htab }
35
- rule(:lwsp) { (crlf.maybe >> wsp).repeat }
36
-
37
- rule(:cr) { str("\r") }
38
- rule(:lf) { str("\n") }
39
- rule(:crlf) { cr >> lf }
40
- rule(:dquote) { str('"') }
41
-
42
- # http://tools.ietf.org/html/rfc7230#section-3.2.3
43
- rule(:ows) { wsp.repeat }
44
- rule(:rws) { wsp.repeat(1) }
45
- rule(:bws) { wsp.repeat }
46
-
47
- # http://tools.ietf.org/html/rfc7230#section-3.2.6
48
- rule(:tchar) { alpha | digit | match(/[!#\$%&'\*\+\-\.\^_`\|~]/) }
49
- rule(:token) { tchar.repeat(1) }
50
-
51
- # http://tools.ietf.org/html/rfc7231#section-7.1.1.1
52
- rule(:day_name) { str('Mon') | str('Tue') | str('Wed') | str('Thu') | str('Fri') | str('Sat') | str('Sun') }
53
- rule(:day) { digit.repeat(2) }
54
- rule(:month) { (str('Jan') | str('Feb') | str('Mar') | str('Apr') | str('May') | str('Jun') | str('Jul') | str('Aug') | str('Sep') | str('Oct') | str('Nov') | str('Dec')) }
55
- rule(:year) { digit.repeat(4) }
56
- rule(:date1) { day >> sp >> month >> sp >> year }
57
- rule(:gmt) { str('GMT') }
58
- rule(:hour) { digit.repeat(2) }
59
- rule(:minute) { digit.repeat(2) }
60
- rule(:second) { digit.repeat(2) }
61
- rule(:time_of_day) { hour >> str(':') >> minute >> str(':') >> second }
62
- rule(:imf_fixdate) { day_name >> str(',') >> sp >> date1 >> sp >> time_of_day >> sp >> gmt }
63
- rule(:day_name_l) { str('Monday') | str('Tuesday') | str('Wednesday') | str('Thursday') | str('Friday') | str('Saturday') | str('Sunday') }
64
- rule(:year2) { digit.repeat(2) }
65
- rule(:date2) { day >> str('-') >> month >> str('-') >> year2 }
66
- rule(:rfc850_date) { day_name_l >> str(',') >> sp >> date2 >> sp >> time_of_day >> sp >> gmt }
67
- rule(:day1) { sp >> digit }
68
- rule(:date3) { month >> sp >> (day | day1) }
69
- rule(:asctime_date) { day_name >> sp >> date3 >> sp >> time_of_day >> sp >> year }
70
- rule(:obs_date) { rfc850_date | asctime_date }
71
- rule(:http_date) { (imf_fixdate | obs_date).as(:http_date) }
72
-
73
- # extras -- TODO: move these into header rules?
74
- rule(:comma) { str(',') >> sp? }
75
- rule(:semicolon) { str(';') >> sp? }
76
- end
77
-
78
- class BasicTransform < Parslet::Transform
79
- rule(simple(:v)) { v.respond_to?(:str) ? v.str : v }
80
-
81
- rule(quoted_string: simple(:qs)) { qs[1..-2].gsub(/\\(.)/, '\1') }
82
- rule(http_date: simple(:str)) { Time.httpdate(str) }
83
- end
84
-
85
- end
86
- end