Class: Versionist::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/versionist/middleware.rb

Overview

When your routes don’t include an explicit format in the URL (i.e. ‘match ’foos.(:format)‘ => foos#index`), Rails inspects the Accept header to determine the requested format. Since an Accept header can have multiple values, Rails uses the first one present to determine the format. If your custom version header happens to be the first value in the Accept header, it would incorrectly be interpretted as the format. This middleware moves your custom version header (if found) to the end of the Accept header so as to not interfere with this format logic in Rails.

Constant Summary collapse

ACCEPT =
"Accept"
HTTP_ACCEPT =
"HTTP_ACCEPT"

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Middleware

Returns a new instance of Middleware.



12
13
14
# File 'lib/versionist/middleware.rb', line 12

def initialize(app)
  @app = app
end

Instance Method Details

#_call(env) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/versionist/middleware.rb', line 20

def _call(env)
  request = ::Rack::Request.new(env)
  potential_matches = Versionist.configuration.header_versions.select {|hv| hv.config[:header][:name] == ACCEPT && env[HTTP_ACCEPT].try(:include?, hv.config[:header][:value])}
  if !potential_matches.empty?
    strategy = potential_matches.max {|a,b| a.config[:header][:value].length <=> b.config[:header][:value].length}
  end
  if !strategy.nil?
    entries = env[HTTP_ACCEPT].split(',')
    index = -1
    entries.each_with_index do |e, i|
      e.strip!
      index = i if e == strategy.config[:header][:value]
    end
    if (index != -1)
      version = entries.delete_at(index)
      entries << version
    end
    env[HTTP_ACCEPT] = entries.join(", ")
  end
  @app.call(env)
end

#call(env) ⇒ Object



16
17
18
# File 'lib/versionist/middleware.rb', line 16

def call(env)
  dup._call(env)
end