Class: Utopia::Controller::Respond::Responder

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/controller/respond.rb

Constant Summary collapse

HTTP_ACCEPT =
'HTTP_ACCEPT'.freeze
NOT_ACCEPTABLE_RESPONSE =
[406, {}, []].freeze

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Responder

Returns a new instance of Responder.



92
93
94
95
# File 'lib/utopia/controller/respond.rb', line 92

def initialize
  @converters = HTTP::Accept::MediaTypes::Map.new
  @otherwise = nil
end

Instance Method Details

#browser_preferred_media_types(env) ⇒ Object

Parse the list of browser preferred content types and return ordered by priority.



105
106
107
108
109
110
111
# File 'lib/utopia/controller/respond.rb', line 105

def browser_preferred_media_types(env)
  if accept_content_types = env[HTTP_ACCEPT]
    HTTP::Accept::MediaTypes.parse(accept_content_types)
  else
    return []
  end
end

#call(context, request, path, response) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/utopia/controller/respond.rb', line 133

def call(context, request, path, response)
  media_types = browser_preferred_media_types(request.env)
  
  converter, media_range = @converters.for(media_types)
  
  if converter
    converter.call(context, response, media_range)
  else
    not_acceptable_response(context, response)
  end
end

#freeze ⇒ Object



97
98
99
100
101
102
# File 'lib/utopia/controller/respond.rb', line 97

def freeze
  @converters.freeze
  @otherwise.freeze
  
  super
end

#not_acceptable_response(context, response) ⇒ Object

Generate a not acceptable response which unless customised with otherwise, will result in a generic 406 Not Acceptable response.



146
147
148
149
150
151
152
# File 'lib/utopia/controller/respond.rb', line 146

def not_acceptable_response(context, response)
  if @otherwise
    context.instance_exec(response, &@otherwise)
  else
    NOT_ACCEPTABLE_RESPONSE
  end
end

#otherwise(&block) ⇒ Object

If the content type could not be matched, invoke the provided block and use it's result as the response.



124
125
126
# File 'lib/utopia/controller/respond.rb', line 124

def otherwise(&block)
  @otherwise = block
end

#otherwise_passthrough ⇒ Object

If the content type could not be matched, ignore it and don't use the result of the controller layer.



129
130
131
# File 'lib/utopia/controller/respond.rb', line 129

def otherwise_passthrough
  @otherwise = proc { nil }
end

#with(content_type, &block) ⇒ Object

Add a converter for the specified content type. Call the block with the response content if the request accepts the specified content_type.



114
115
116
# File 'lib/utopia/controller/respond.rb', line 114

def with(content_type, &block)
  @converters << Converter::Callback.new(content_type, block)
end

#with_json ⇒ Object

Add a converter for JSON when requests accept 'application/json'



119
120
121
# File 'lib/utopia/controller/respond.rb', line 119

def with_json
  @converters << Converter::ToJSON
end