rack-accept 0.2 → 0.3

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/.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rack-accept'
3
- s.version = '0.2'
3
+ s.version = '0.3'
4
4
  s.date = '2010-04-02'
5
5
 
6
6
  s.summary = 'HTTP Accept* for Ruby/Rack'
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/ }
20
20
 
21
21
  s.add_dependency('rack', '>= 0.4')
22
- s.add_development_dependency 'rake'
22
+ s.add_development_dependency('rake')
23
23
 
24
24
  s.has_rdoc = true
25
25
  s.rdoc_options = %w< --line-numbers --inline-source --title Rack::Accept --main Rack::Accept >
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.3 / April 3, 2010
2
+
3
+ * Enhanced Rack middleware component to be able to automatically send a 406
4
+ response when the request is not acceptable
5
+
1
6
  ## 0.2 / April 2, 2010
2
7
 
3
8
  * Moved all common header methods into Rack::Accept::Header module
data/README CHANGED
@@ -23,7 +23,7 @@ Using RubyGems:
23
23
  From a local copy:
24
24
 
25
25
  $ git clone git://github.com/mjijackson/rack-accept.git
26
- $ sudo rake install
26
+ $ rake package && sudo rake install
27
27
 
28
28
  Usage
29
29
  -----
@@ -37,7 +37,7 @@ middleware pipeline and access the Rack::Accept::Request object in the
37
37
 
38
38
  use Rack::Accept
39
39
 
40
- app = lambda {|env|
40
+ app = lambda do |env|
41
41
  accept = env['rack-accept.request']
42
42
  response = Rack::Response.new
43
43
 
@@ -50,22 +50,41 @@ middleware pipeline and access the Rack::Accept::Request object in the
50
50
  end
51
51
 
52
52
  response.finish
53
- }
53
+ end
54
54
 
55
55
  run app
56
56
 
57
+ Rack::Accept can also construct automatic 406 responses if you set up the types
58
+ of media, character sets, encoding, or languages your server is able to serve
59
+ ahead of time.
60
+
61
+ require 'rack/accept'
62
+
63
+ use(Rack::Accept) do |accept|
64
+ # We only ever serve content in English or Japanese from this site, so if
65
+ # the user doesn't accept either of these we will respond with a 406.
66
+ #
67
+ # Note: +accept+ is an instance of Rack::Accept::Context.
68
+ accept.languages = %w< en jp >
69
+ end
70
+
71
+ app = ...
72
+
73
+ run app
74
+
75
+ Note: You should probably think about this very carefully before you use
76
+ Rack::Accept in this way. Many user agents are careless about the types of
77
+ Accept headers they send, and depend on apps not being too picky. Instead of
78
+ automatically sending a 406, you should probably only send one when absolutely
79
+ necessary.
80
+
57
81
  Additionally, Rack::Accept may be used outside of a Rack context to provide
58
82
  any Ruby app the ability to construct and interpret Accept headers.
59
83
 
60
84
  require 'rack/accept'
61
85
 
62
86
  mtype = Rack::Accept::MediaType.new
63
- mtype.qvalues = {
64
- 'text/html' => 1,
65
- 'text/*' => 0.8,
66
- '*/*' => 0.5
67
- }
68
-
87
+ mtype.qvalues = { 'text/html' => 1, 'text/*' => 0.8, '*/*' => 0.5 }
69
88
  mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
70
89
 
71
90
  cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
@@ -74,7 +93,8 @@ any Ruby app the ability to construct and interpret Accept headers.
74
93
 
75
94
  The very last line in this example may look like a mistake to someone not
76
95
  familiar with the intricacies of the spec, but it's actually correct. It
77
- just puts emphasis on the convenience of using this library.
96
+ just puts emphasis on the convenience of using this library so you don't
97
+ have to worry about these kinds of details.
78
98
 
79
99
  Four-letter Words
80
100
  -----------------
@@ -13,16 +13,16 @@
13
13
  <div id="header">
14
14
  <h1>rack-accept</h1>
15
15
  <ul>
16
- <li><a href="license.html">License</a></li>
17
16
  <li><a href="api/index.html">API</a></li>
18
17
  <li><a href="http://github.com/mjijackson/rack-accept/issues">Bugs</a></li>
19
18
  <li><a href="http://github.com/mjijackson/rack-accept">Code</a></li>
19
+ <li><a href="usage.html">Usage</a></li>
20
20
  <li><a href="index.html">Home</a></li>
21
21
  </ul>
22
22
  </div>
23
23
  <div id="content"><%= content %></div>
24
24
  <div id="footer">
25
- <p class="rights">Copyright &copy; 2010 <a href="http://mjijackson.com/about" rel="me author">Michael J. I. Jackson</a></p>
25
+ <p><a href="license.html" rel="license">Copyright</a> &copy; 2010 <a href="http://mjijackson.com/about" rel="me author">Michael J. I. Jackson</a></p>
26
26
  </div>
27
27
  </div>
28
28
  </body>
data/doc/assets/style.css CHANGED
@@ -38,7 +38,17 @@ code {
38
38
  }
39
39
  pre {
40
40
  background-color: #FDFDFD;
41
- padding-left: 6px;
41
+ padding: 4px 0 4px 6px;
42
+ line-height: 1.2;
43
+ }
44
+ strong {
45
+ font-weight: bold;
46
+ }
47
+ ::selection {
48
+ background: rgba(200,200,200,0.5);
49
+ }
50
+ ::-moz-selection {
51
+ background: rgba(200,200,200,0.5);
42
52
  }
43
53
  #wrapper {
44
54
  position: relative;
data/doc/index.markdown CHANGED
@@ -21,58 +21,7 @@ Using [RubyGems][rubygems]:
21
21
  From a local copy:
22
22
 
23
23
  $ git clone git://github.com/mjijackson/rack-accept.git
24
- $ sudo rake install
25
-
26
- Usage
27
- -----
28
-
29
- Rack::Accept implements the Rack middleware interface and may be used with any
30
- Rack-based application. Simply insert the Rack::Accept module in your Rack
31
- middleware pipeline and access the [Rack::Accept::Request][req] object in the
32
- "rack-accept.request" environment key, as in the following example:
33
-
34
- require 'rack/accept'
35
-
36
- use Rack::Accept
37
-
38
- app = lambda {|env|
39
- accept = env['rack-accept.request']
40
- response = Rack::Response.new
41
-
42
- if accept.media_type?('text/html')
43
- response['Content-Type'] = 'text/html'
44
- response.write "<p>Hello. You accept text/html!</p>"
45
- else
46
- response['Content-Type'] = 'text/plain'
47
- response.write "Apparently you don't accept text/html. Too bad."
48
- end
49
-
50
- response.finish
51
- }
52
-
53
- run app
54
-
55
- Additionally, Rack::Accept may be used outside of a Rack context to provide
56
- any Ruby app the ability to construct and interpret Accept headers.
57
-
58
- require 'rack/accept'
59
-
60
- mtype = Rack::Accept::MediaType.new
61
- mtype.qvalues = {
62
- 'text/html' => 1,
63
- 'text/*' => 0.8,
64
- '*/*' => 0.5
65
- }
66
-
67
- mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
68
-
69
- cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
70
- cset.best_of(%w< iso-8859-5 unicode-1-1 >) # => "unicode-1-1"
71
- cset.accept?('iso-8859-1') # => true
72
-
73
- The very last line in this example may look like a mistake to someone not
74
- familiar with the intricacies of [the spec][sec14-3], but it's actually
75
- correct. It just puts emphasis on the convenience of using this library.
24
+ $ rake package && sudo rake install
76
25
 
77
26
  [rfc]: http://www.w3.org/Protocols/rfc2616/rfc2616.html
78
27
  [sec14]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
@@ -83,4 +32,3 @@ correct. It just puts emphasis on the convenience of using this library.
83
32
  [rack]: http://rack.rubyforge.org/
84
33
  [test]: http://github.com/mjijackson/rack-accept/tree/master/test/
85
34
  [rubygems]: http://rubygems.org/
86
- [req]: api/classes/Rack/Accept/Request.html
data/doc/license.markdown CHANGED
@@ -1,3 +1,6 @@
1
+ License
2
+ -------
3
+
1
4
  Copyright 2010 Michael J. I. Jackson
2
5
 
3
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -0,0 +1,74 @@
1
+ Usage
2
+ -----
3
+
4
+ Rack::Accept implements the Rack middleware interface and may be used with any
5
+ Rack-based application. Simply insert the Rack::Accept module in your Rack
6
+ middleware pipeline and access the [Rack::Accept::Request][req] object in the
7
+ "rack-accept.request" environment key, as in the following example:
8
+
9
+ require 'rack/accept'
10
+
11
+ use Rack::Accept
12
+
13
+ app = lambda do |env|
14
+ accept = env['rack-accept.request']
15
+ response = Rack::Response.new
16
+
17
+ if accept.media_type?('text/html')
18
+ response['Content-Type'] = 'text/html'
19
+ response.write "<p>Hello. You accept text/html!</p>"
20
+ else
21
+ response['Content-Type'] = 'text/plain'
22
+ response.write "Apparently you don't accept text/html. Too bad."
23
+ end
24
+
25
+ response.finish
26
+ end
27
+
28
+ run app
29
+
30
+ Rack::Accept can also construct a [406][406] response automatically if you set
31
+ up the types of media, character sets, encoding, or languages your server is
32
+ able to serve ahead of time.
33
+
34
+ require 'rack/accept'
35
+
36
+ use(Rack::Accept) do |accept|
37
+ # We only ever serve content in English or Japanese from this site, so if
38
+ # the user doesn't accept either of these we will respond with a 406.
39
+ #
40
+ # Note: +accept+ is an instance of Rack::Accept::Context.
41
+ accept.languages = %w< en jp >
42
+ end
43
+
44
+ app = ...
45
+
46
+ run app
47
+
48
+ __Note:__ You should probably think about this very carefully before you use
49
+ Rack::Accept in this way. Many user agents are careless about the types of
50
+ Accept headers they send, and depend on apps not being too picky. Instead of
51
+ automatically sending a 406, you should probably only send one when absolutely
52
+ necessary.
53
+
54
+ Additionally, Rack::Accept may be used outside of a Rack context to provide
55
+ any Ruby app the ability to construct and interpret Accept headers.
56
+
57
+ require 'rack/accept'
58
+
59
+ mtype = Rack::Accept::MediaType.new
60
+ mtype.qvalues = { 'text/html' => 1, 'text/*' => 0.8, '*/*' => 0.5 }
61
+ mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
62
+
63
+ cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
64
+ cset.best_of(%w< iso-8859-5 unicode-1-1 >) # => "unicode-1-1"
65
+ cset.accept?('iso-8859-1') # => true
66
+
67
+ The very last line in this example may look like a mistake to someone not
68
+ familiar with the intricacies of [the spec][sec14-3], but it's actually
69
+ correct. It just puts emphasis on the convenience of using this library so you
70
+ don't have to worry about these kinds of details.
71
+
72
+ [req]: api/classes/Rack/Accept/Request.html
73
+ [406]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7
74
+ [sec14-3]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
data/lib/rack/accept.rb CHANGED
@@ -3,7 +3,7 @@ require 'rack'
3
3
  module Rack::Accept
4
4
 
5
5
  # The current version of rack-accept.
6
- VERSION = [0, 2]
6
+ VERSION = [0, 3]
7
7
 
8
8
  # Returns the current version of rack-accept as a string.
9
9
  def self.version
@@ -22,5 +22,6 @@ module Rack::Accept
22
22
  autoload :Language, 'rack/accept/language'
23
23
  autoload :MediaType, 'rack/accept/media_type'
24
24
  autoload :Request, 'rack/accept/request'
25
+ autoload :Response, 'rack/accept/response'
25
26
 
26
27
  end
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Charset'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +charset+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +charset+.
20
19
  def qvalue(charset)
21
20
  m = matches(charset)
22
21
  if m.empty?
@@ -26,8 +25,8 @@ module Rack::Accept
26
25
  end
27
26
  end
28
27
 
29
- # Returns an array of character sets from the original header that match
30
- # the given +charset+, ordered by precedence.
28
+ # Returns an array of character sets from this header that match the given
29
+ # +charset+, ordered by precedence.
31
30
  def matches(charset)
32
31
  values.select {|v|
33
32
  v == charset || v == '*'
@@ -3,18 +3,67 @@ module Rack::Accept
3
3
  # Implements the Rack middleware interface.
4
4
  class Context
5
5
 
6
+ # This error is raised when the server is not able to provide an acceptable
7
+ # response.
8
+ class AcceptError < StandardError; end
9
+
6
10
  attr_reader :app
7
11
 
8
12
  def initialize(app)
9
13
  @app = app
14
+ @checks = {}
15
+ @check_headers = []
10
16
  yield self if block_given?
11
17
  end
12
18
 
13
19
  # Inserts a new Rack::Accept::Request object into the environment before
14
20
  # handing the request to the app immediately downstream.
15
21
  def call(env)
16
- env['rack-accept.request'] ||= Request.new(env)
22
+ request = env['rack-accept.request'] ||= Request.new(env)
23
+ check!(request) unless @checks.empty?
17
24
  @app.call(env)
25
+ rescue AcceptError
26
+ response = Response.new
27
+ response.not_acceptable!
28
+ response.finish
29
+ end
30
+
31
+ # Defines the types of media this server is able to serve.
32
+ def media_types=(media_types)
33
+ add_check(:media_type, media_types)
34
+ end
35
+
36
+ # Defines the character sets this server is able to serve.
37
+ def charsets=(charsets)
38
+ add_check(:charset, charsets)
39
+ end
40
+
41
+ # Defines the types of encodings this server is able to serve.
42
+ def encodings=(encodings)
43
+ add_check(:encoding, encodings)
44
+ end
45
+
46
+ # Defines the languages this server is able to serve.
47
+ def languages=(languages)
48
+ add_check(:language, languages)
49
+ end
50
+
51
+ private
52
+
53
+ def add_check(header_name, values)
54
+ @checks[header_name] ||= []
55
+ @checks[header_name].concat(values)
56
+ @check_headers << header_name unless @check_headers.include?(header_name)
57
+ end
58
+
59
+ # Raises an AcceptError if this server is not able to serve an acceptable
60
+ # response.
61
+ def check!(request)
62
+ @check_headers.each do |header_name|
63
+ values = @checks[header_name]
64
+ header = request.send(header_name)
65
+ raise AcceptError unless values.any? {|v| header.accept?(v) }
66
+ end
18
67
  end
19
68
 
20
69
  end
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Encoding'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +encoding+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +encoding+.
20
19
  def qvalue(encoding)
21
20
  m = matches(encoding)
22
21
  if m.empty?
@@ -26,8 +25,8 @@ module Rack::Accept
26
25
  end
27
26
  end
28
27
 
29
- # Returns an array of encodings from the original header that match
30
- # the given +encoding+, ordered by precedence.
28
+ # Returns an array of encodings from this header that match the given
29
+ # +encoding+, ordered by precedence.
31
30
  def matches(encoding)
32
31
  values.select {|v|
33
32
  v == encoding || v == '*'
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Language'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +language+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +language+.
20
19
  def qvalue(language)
21
20
  return 1 if @qvalues.empty?
22
21
  m = matches(language)
@@ -24,8 +23,8 @@ module Rack::Accept
24
23
  @qvalues[m.first]
25
24
  end
26
25
 
27
- # Returns an array of languages from the original header that match
28
- # the given +language+, ordered by precedence.
26
+ # Returns an array of languages from this header that match the given
27
+ # +language+, ordered by precedence.
29
28
  def matches(language)
30
29
  values.select {|v|
31
30
  v == language || v == '*' || (language.match(/^(.+?)-/) && v == $1)
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +media_type+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +media_type+.
20
19
  def qvalue(media_type)
21
20
  return 1 if @qvalues.empty?
22
21
  m = matches(media_type)
@@ -24,8 +23,8 @@ module Rack::Accept
24
23
  @qvalues[m.first]
25
24
  end
26
25
 
27
- # Returns an array of media types from the original header that match
28
- # the given +media_type+, ordered by precedence.
26
+ # Returns an array of media types from this header that match the given
27
+ # +media_type+, ordered by precedence.
29
28
  def matches(media_type)
30
29
  type, subtype, params = parse_media_type(media_type)
31
30
  values.select {|v|
@@ -1,14 +1,11 @@
1
+ require 'rack/request'
2
+
1
3
  module Rack::Accept
2
4
 
3
5
  # A container class for convenience methods when Rack::Accept is used on the
4
- # request level (as Rack middleware, for example). This class manages a
6
+ # request level as Rack middleware. Instances of this class also manage a
5
7
  # lightweight cache of various header instances to speed up execution.
6
- #
7
- # Request currently does not extend Rack::Request because that class
8
- # currently provides some limited functionality when it comes to determining
9
- # the proper encoding to use with a request and I didn't want to confuse
10
- # users.
11
- class Request
8
+ class Request < Rack::Request
12
9
 
13
10
  attr_reader :env
14
11
 
@@ -0,0 +1,21 @@
1
+ require 'rack/response'
2
+
3
+ module Rack::Accept
4
+
5
+ # The base class for responses issued by Rack::Accept.
6
+ class Response < Rack::Response
7
+
8
+ # Marks this response as being unacceptable and clears the response body.
9
+ #
10
+ # Note: The HTTP spec advises servers to respond with an "entity" that
11
+ # describes acceptable parameters, but it fails to go into detail about its
12
+ # implementation. Thus, it is up to the user of this library to create such
13
+ # an entity if one is desired.
14
+ def not_acceptable!
15
+ self.status = 406
16
+ self.body = []
17
+ header['Content-Length'] = '0'
18
+ end
19
+
20
+ end
21
+ end
data/test/charset_test.rb CHANGED
@@ -22,6 +22,9 @@ class CharsetTest < Test::Unit::TestCase
22
22
  c = C.new('iso-8859-1;q=0, *;q=0.5')
23
23
  assert_equal(0.5, c.qvalue('iso-8859-5'))
24
24
  assert_equal(0, c.qvalue('iso-8859-1'))
25
+
26
+ c = C.new('*;q=0')
27
+ assert_equal(0, c.qvalue('iso-8859-1'))
25
28
  end
26
29
 
27
30
  def test_matches
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ContextTest < Test::Unit::TestCase
4
+
5
+ def media_types; Proc.new {|c| c.media_types = %w< text/html > } end
6
+ def charsets; Proc.new {|c| c.charsets = %w< iso-8859-5 > } end
7
+ def encodings; Proc.new {|c| c.encodings = %w< gzip > } end
8
+ def languages; Proc.new {|c| c.languages = %w< en > } end
9
+
10
+ def test_empty
11
+ request
12
+ assert_equal(200, status)
13
+ end
14
+
15
+ def test_media_types
16
+ request('HTTP_ACCEPT' => 'text/html')
17
+ assert_equal(200, status)
18
+
19
+ request('HTTP_ACCEPT' => 'text/html', &media_types)
20
+ assert_equal(200, status)
21
+
22
+ request('HTTP_ACCEPT' => 'text/plain', &media_types)
23
+ assert_equal(406, status)
24
+ end
25
+
26
+ def test_charsets
27
+ request('HTTP_ACCEPT_CHARSET' => 'iso-8859-5')
28
+ assert_equal(200, status)
29
+
30
+ request('HTTP_ACCEPT_CHARSET' => 'iso-8859-5', &charsets)
31
+ assert_equal(200, status)
32
+
33
+ request('HTTP_ACCEPT_CHARSET' => 'unicode-1-1', &charsets)
34
+ assert_equal(406, status)
35
+ end
36
+
37
+ def test_encodings
38
+ request('HTTP_ACCEPT_ENCODING' => 'gzip')
39
+ assert_equal(200, status)
40
+
41
+ request('HTTP_ACCEPT_ENCODING' => 'gzip', &encodings)
42
+ assert_equal(200, status)
43
+
44
+ request('HTTP_ACCEPT_ENCODING' => 'compress', &encodings)
45
+ assert_equal(406, status)
46
+ end
47
+
48
+ def test_languages
49
+ request('HTTP_ACCEPT_LANGUAGE' => 'en')
50
+ assert_equal(200, status)
51
+
52
+ request('HTTP_ACCEPT_LANGUAGE' => 'en', &languages)
53
+ assert_equal(200, status)
54
+
55
+ request('HTTP_ACCEPT_LANGUAGE' => 'jp', &languages)
56
+ assert_equal(406, status)
57
+ end
58
+
59
+ end
data/test/helper.rb CHANGED
@@ -15,3 +15,24 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
15
15
 
16
16
  require 'test/unit'
17
17
  require 'rack/accept'
18
+
19
+ class Test::Unit::TestCase
20
+ attr_reader :context
21
+ attr_reader :response
22
+
23
+ def status
24
+ @response && @response.status
25
+ end
26
+
27
+ def request(env={}, method='GET', uri='/')
28
+ @context = Rack::Accept.new(fake_app)
29
+ yield @context if block_given?
30
+ mock_request = Rack::MockRequest.new(@context)
31
+ @response = mock_request.request(method.to_s.upcase, uri, env)
32
+ @response
33
+ end
34
+
35
+ def fake_app(status=200, headers={}, body=[])
36
+ lambda {|env| Rack::Response.new(body, status, headers).finish }
37
+ end
38
+ end
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- version: "0.2"
7
+ - 3
8
+ version: "0.3"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Michael J. I. Jackson
@@ -58,8 +58,10 @@ files:
58
58
  - lib/rack/accept/language.rb
59
59
  - lib/rack/accept/media_type.rb
60
60
  - lib/rack/accept/request.rb
61
+ - lib/rack/accept/response.rb
61
62
  - lib/rack/accept.rb
62
63
  - test/charset_test.rb
64
+ - test/context_test.rb
63
65
  - test/encoding_test.rb
64
66
  - test/header_test.rb
65
67
  - test/helper.rb
@@ -70,6 +72,7 @@ files:
70
72
  - doc/assets/style.css
71
73
  - doc/index.markdown
72
74
  - doc/license.markdown
75
+ - doc/usage.markdown
73
76
  - CHANGES
74
77
  - .gemspec
75
78
  - Rakefile
@@ -111,6 +114,7 @@ specification_version: 3
111
114
  summary: HTTP Accept* for Ruby/Rack
112
115
  test_files:
113
116
  - test/charset_test.rb
117
+ - test/context_test.rb
114
118
  - test/encoding_test.rb
115
119
  - test/header_test.rb
116
120
  - test/language_test.rb