accept_headers 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -3
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -1
- data/README.md +43 -4
- data/Rakefile +1 -1
- data/accept_headers.gemspec +1 -1
- data/lib/accept_headers/middleware.rb +1 -0
- data/lib/accept_headers/negotiatable.rb +5 -0
- data/lib/accept_headers/version.rb +1 -1
- data/spec/encoding/negotiator_spec.rb +6 -0
- data/spec/language/negotiator_spec.rb +6 -0
- data/spec/media_type/negotiator_spec.rb +6 -0
- data/spec/middleware_spec.rb +64 -0
- data/wercker.yml +2 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28f7499031d0c1e01152c3d059446928393d03e9
|
4
|
+
data.tar.gz: 2b2f7c553ed27941005df86490e53364c6037098
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3632e3031010af9c2938a49dd71e6461d8ba6d4efb442b04c6146146a2a64a4051a46da92a3e12e1c2ffec1a67cba66b8b1959a65d9d4417e643955f09d8e57d
|
7
|
+
data.tar.gz: 7b2c81b0d7614051d15cd760a95b8489efcc5509ac775dcacd45a71a5e1e0d9e5efc47385ab390eae5f3f037e5421798d0935296e4c7ff63035e2e5948de164b
|
data/.travis.yml
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
3
|
+
- 2.2.6
|
4
|
+
- 2.3.3
|
5
5
|
- rbx
|
6
6
|
- ruby-head
|
7
7
|
- jruby-head
|
8
8
|
|
9
9
|
matrix:
|
10
10
|
allow_failures:
|
11
|
+
- rvm: rbx
|
11
12
|
- rvm: ruby-head
|
12
13
|
- rvm: jruby-head
|
13
14
|
|
14
15
|
addons:
|
15
16
|
code_climate:
|
16
|
-
repo_token: 50c636c924d1aa253e29c57822931c1a172cd65675ad66396bba39d255373a58
|
17
|
+
repo_token: 50c636c924d1aa253e29c57822931c1a172cd65675ad66396bba39d255373a58
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## HEAD
|
2
2
|
|
3
|
+
## 0.0.9 / December 1, 2016
|
4
|
+
|
5
|
+
* Require ruby 2.2 minimum.
|
6
|
+
* Add `#to_s` method for all Negotiators
|
7
|
+
* Return no header if parse header is nil
|
8
|
+
* First attempt at rack middleware with simple specs.
|
9
|
+
|
3
10
|
## 0.0.8 / November 23, 2014
|
4
11
|
|
5
12
|
* Change `#negotiate` to return the type instead of a hash. In the case of `MediaType` it'll also populate `extensions` from the matching accept header media type.
|
data/Gemfile
CHANGED
@@ -4,7 +4,6 @@ source "https://rubygems.org"
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
group :test do
|
7
|
-
gem "ruby_gntp"
|
8
7
|
gem "minitest-focus"
|
9
8
|
gem "codeclimate-test-reporter", require: false
|
10
9
|
gem "simplecov", require: false
|
@@ -13,4 +12,5 @@ end
|
|
13
12
|
group :development, :test do
|
14
13
|
gem "pry"
|
15
14
|
gem "awesome_print"
|
15
|
+
gem "rack-test"
|
16
16
|
end
|
data/README.md
CHANGED
@@ -168,11 +168,50 @@ AcceptHeaders::Language.new('en', 'us')
|
|
168
168
|
languages.accept?('en-gb') # true
|
169
169
|
```
|
170
170
|
|
171
|
-
##
|
171
|
+
## Rack Middleware
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
173
|
+
Add the middleware:
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
require 'accept_headers/middleware'
|
177
|
+
use AcceptHeaders::Middleware
|
178
|
+
run YourApp
|
179
|
+
```
|
180
|
+
|
181
|
+
Simple way to set the content response headers based on the request accept headers and the supported media types, encodings, and languages provided by the app or route.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
class YourApp
|
185
|
+
def initialize(app)
|
186
|
+
@app = app
|
187
|
+
end
|
188
|
+
|
189
|
+
def call(env)
|
190
|
+
# List your arrays of supported media types, encodings, languages. This can be global or per route/controller
|
191
|
+
supported_media_types = %w[application/json application/xml text/html text/plain]
|
192
|
+
supported_encodings = %w[gzip identify]
|
193
|
+
supported_languages = %w[en-US en-GB]
|
194
|
+
|
195
|
+
# Call the Negotiators and pass in the supported arrays and it'll return the best match
|
196
|
+
matched_media_type = env["accept_headers.media_types"].negotiate(supported_media_types)
|
197
|
+
matched_encoding = env["accept_headers.encodings"].negotiate(supported_encodings)
|
198
|
+
matched_language = env["accept_headers.languages"].negotiate(supported_languages)
|
199
|
+
|
200
|
+
# Set a default, in this case an empty string, in case of a bad header that cannot be parsed
|
201
|
+
# The return value is a MediaType, Encoding, or Language depending on the case:
|
202
|
+
# On MediaType, you can call #type ('text'), #subtype ('html'), #media_range ('text/html') to get the stringified parts
|
203
|
+
# On Encoding, you can call #encoding to get the string encoding ('gzip')
|
204
|
+
# On Language, you can call #primary_tag ('en'), #subtag ('us'), or #language_tag ('en-us')
|
205
|
+
headers = {
|
206
|
+
'Content-Type' => matched_media_type ? matched_media_type.media_range : '',
|
207
|
+
'Content-Encoding' => matched_encoding ? matched_encoding.encoding : '',
|
208
|
+
'Content-Language' => matched_language ? matched_language.language_tag : '',
|
209
|
+
}
|
210
|
+
|
211
|
+
[200, headers, ["Hello World!"]]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
```
|
176
215
|
|
177
216
|
## Contributing
|
178
217
|
|
data/Rakefile
CHANGED
data/accept_headers.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.required_ruby_version = '>= 2.
|
21
|
+
spec.required_ruby_version = '>= 2.2.0'
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -34,6 +34,10 @@ module AcceptHeaders
|
|
34
34
|
negotiate(other) ? true : false
|
35
35
|
end
|
36
36
|
|
37
|
+
def to_s
|
38
|
+
list.join(',')
|
39
|
+
end
|
40
|
+
|
37
41
|
private
|
38
42
|
def no_header
|
39
43
|
raise NotImplementedError.new("#no_header is not implemented")
|
@@ -44,6 +48,7 @@ module AcceptHeaders
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def parse(header, &block)
|
51
|
+
return no_header unless header
|
47
52
|
header = header.dup
|
48
53
|
header.sub!(/\A#{self.class::HEADER_PREFIX}\s*/, '')
|
49
54
|
header.strip!
|
@@ -77,6 +77,12 @@ describe AcceptHeaders::Encoding::Negotiator do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
describe "#to_s" do
|
81
|
+
it "returns a string of each encoding #to_s joined by a comma" do
|
82
|
+
subject.new("compress,gzip;q=0.9").to_s.must_equal "compress;q=1,gzip;q=0.9"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
80
86
|
describe "negotiate supported encodings" do
|
81
87
|
it "returns a best matching encoding" do
|
82
88
|
n = subject.new('deflate; q=0.5, gzip, compress; q=0.8, identity')
|
@@ -69,6 +69,12 @@ describe AcceptHeaders::Language::Negotiator do
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
describe "#to_s" do
|
73
|
+
it "returns a string of each language #to_s joined by a comma" do
|
74
|
+
subject.new("en-us, en-gb;q=0.9").to_s.must_equal "en-us;q=1,en-gb;q=0.9"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
72
78
|
describe "negotiate supported languages" do
|
73
79
|
it "returns a best matching language" do
|
74
80
|
match = language.new('en', 'us')
|
@@ -106,6 +106,12 @@ describe AcceptHeaders::MediaType::Negotiator do
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
+
describe "#to_s" do
|
110
|
+
it "returns a string of each media type #to_s joined by a comma" do
|
111
|
+
subject.new("text/html;level=1, text/plain;q=0.9").to_s.must_equal "text/html;q=1;level=1,text/plain;q=0.9"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
109
115
|
describe "#negotiate" do
|
110
116
|
it "returns a best matching media type" do
|
111
117
|
all_browsers.each do |browser|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
require "accept_headers/middleware"
|
3
|
+
require "rack/test"
|
4
|
+
|
5
|
+
describe AcceptHeaders::Middleware do
|
6
|
+
subject do
|
7
|
+
AcceptHeaders::Middleware
|
8
|
+
end
|
9
|
+
|
10
|
+
def app(
|
11
|
+
supported_media_types: ['application/json'],
|
12
|
+
supported_encodings: ['identity'],
|
13
|
+
supported_languages: ['en-US']
|
14
|
+
)
|
15
|
+
Rack::Builder.new do
|
16
|
+
use AcceptHeaders::Middleware
|
17
|
+
run ->(env) do
|
18
|
+
matched_media_type = env["accept_headers.media_types"].negotiate(supported_media_types)
|
19
|
+
matched_encoding = env["accept_headers.encodings"].negotiate(supported_encodings)
|
20
|
+
matched_language = env["accept_headers.languages"].negotiate(supported_languages)
|
21
|
+
headers = {
|
22
|
+
'Content-Type' => matched_media_type ? matched_media_type.media_range : '',
|
23
|
+
'Content-Encoding' => matched_encoding ? matched_encoding.encoding : '',
|
24
|
+
'Content-Language' => matched_language ? matched_language.language_tag : '',
|
25
|
+
}
|
26
|
+
|
27
|
+
[ 200, headers, [ '' ] ]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def responds_with_content_type(accept, supported_media_types, expected_content_type)
|
33
|
+
response = Rack::MockRequest.new(app(supported_media_types: supported_media_types)).get('/', { 'HTTP_ACCEPT' => accept } )
|
34
|
+
response.headers['Content-Type'].must_equal expected_content_type
|
35
|
+
end
|
36
|
+
|
37
|
+
def responds_with_encoding(accept_encoding, supported_encodings, expected_encoding)
|
38
|
+
response = Rack::MockRequest.new(app(supported_encodings: supported_encodings)).get('/', { 'HTTP_ACCEPT_ENCODING' => accept_encoding } )
|
39
|
+
response.headers['Content-Encoding'].must_equal expected_encoding
|
40
|
+
end
|
41
|
+
|
42
|
+
def responds_with_languages(accept_language, supported_languages, expected_language)
|
43
|
+
response = Rack::MockRequest.new(app(supported_languages: supported_languages)).get('/', { 'HTTP_ACCEPT_LANGUAGE' => accept_language } )
|
44
|
+
response.headers['Content-Language'].must_equal expected_language
|
45
|
+
end
|
46
|
+
|
47
|
+
it "reads the accept header" do
|
48
|
+
responds_with_content_type("application/json", ['application/json'], 'application/json')
|
49
|
+
responds_with_content_type("application/json;q=0.9,*/*;q0.8", ['application/json'], 'application/json')
|
50
|
+
responds_with_content_type("application/json/error", ['application/json'], '')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "reads the accept encoding header" do
|
54
|
+
responds_with_encoding("gzip,identity", ['gzip', 'identity'], 'gzip')
|
55
|
+
responds_with_encoding("gzip;q=0.8,identity", ['gzip', 'identity'], 'identity')
|
56
|
+
responds_with_encoding("gzip error", ['gzip'], '')
|
57
|
+
end
|
58
|
+
|
59
|
+
it "reads the accept language header" do
|
60
|
+
responds_with_languages("en-us", ['en-us'], 'en-us')
|
61
|
+
responds_with_languages("en-us;q=1,en-gb;q=0.9,en-*;q=0.8", ['en-us'], 'en-us')
|
62
|
+
responds_with_languages("en/us", ['en-us'], '')
|
63
|
+
end
|
64
|
+
end
|
data/wercker.yml
CHANGED
@@ -7,7 +7,7 @@ build:
|
|
7
7
|
steps:
|
8
8
|
# Uncomment this to force RVM to use a specific Ruby version
|
9
9
|
- rvm-use:
|
10
|
-
version: 2.1
|
10
|
+
version: 2.3.1
|
11
11
|
|
12
12
|
# A step that executes `bundle install` command
|
13
13
|
- bundle-install
|
@@ -24,4 +24,4 @@ build:
|
|
24
24
|
# Add more steps here:
|
25
25
|
- script:
|
26
26
|
name: rake
|
27
|
-
code: bundle exec rake
|
27
|
+
code: bundle exec rake
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: accept_headers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Chu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- spec/language_spec.rb
|
115
115
|
- spec/media_type/negotiator_spec.rb
|
116
116
|
- spec/media_type_spec.rb
|
117
|
+
- spec/middleware_spec.rb
|
117
118
|
- spec/spec_helper.rb
|
118
119
|
- spec/support/encodings/content-coding.csv
|
119
120
|
- spec/support/media_types/application.csv
|
@@ -137,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
138
|
requirements:
|
138
139
|
- - ">="
|
139
140
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
141
|
+
version: 2.2.0
|
141
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
143
|
requirements:
|
143
144
|
- - ">="
|
@@ -145,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
146
|
version: '0'
|
146
147
|
requirements: []
|
147
148
|
rubyforge_project:
|
148
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.5.2
|
149
150
|
signing_key:
|
150
151
|
specification_version: 4
|
151
152
|
summary: A ruby library that does content negotiation and parses and sorts http accept
|
@@ -157,6 +158,7 @@ test_files:
|
|
157
158
|
- spec/language_spec.rb
|
158
159
|
- spec/media_type/negotiator_spec.rb
|
159
160
|
- spec/media_type_spec.rb
|
161
|
+
- spec/middleware_spec.rb
|
160
162
|
- spec/spec_helper.rb
|
161
163
|
- spec/support/encodings/content-coding.csv
|
162
164
|
- spec/support/media_types/application.csv
|