Module: Artoo::Api::RouteHelpers::InstanceMethods

Defined in:
lib/artoo/api/route_helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.force_encoding(data, encoding = default_encoding) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
# File 'lib/artoo/api/route_helpers.rb', line 217

def self.force_encoding(data, encoding = default_encoding)
  return if data == settings || data.is_a?(Tempfile)
  if data.respond_to? :force_encoding
    data.force_encoding(encoding).encode!
  elsif data.respond_to? :each_value
    data.each_value { |v| force_encoding(v, encoding) }
  elsif data.respond_to? :each
    data.each { |v| force_encoding(v, encoding) }
  end
  data
end

Instance Method Details

#dispatch!(connection, req) ⇒ Object

Handle the request



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/artoo/api/route_helpers.rb', line 137

def dispatch!(connection, req)
  resp = catch(:halt) do
    try_static! connection, req
    route!      connection, req
  end

  return unless connection.response_state == :headers

  if resp && !resp.nil?
    status, body = resp

    begin
      if @is_static
        req.respond status, body
      else
        req.respond status, {'Content-Type' => 'application/json'}, body
      end
    rescue Errno::EAGAIN
      retry
    end
  else
    @error ||= "NOT FOUND"
    req.respond :not_found, {'Content-Type' => 'application/json'}, {error: @error}.to_json
    @error = nil
  end
end

#force_encoding(*args) ⇒ Object

Fixes encoding issues by

  • defaulting to UTF-8
  • casting params to Encoding.default_external

The latter might not be necessary if Rack handles it one day. Keep an eye on Rack's LH #100.



215
# File 'lib/artoo/api/route_helpers.rb', line 215

def force_encoding(*args) settings.force_encoding(*args) end

#halt(*response) ⇒ Object

Exit the current block, halts any further processing of the request, and returns the specified response.



166
167
168
169
# File 'lib/artoo/api/route_helpers.rb', line 166

def halt(*response)
  response = response.first if response.length == 1
  throw :halt, response
end

#route!(connection, req) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/artoo/api/route_helpers.rb', line 183

def route!(connection, req)
  if routes = self.class.routes[req.method]
    routes.each do |pattern, keys, conditions, block|
      route = req.url
      next unless match = pattern.match(route)
      values = match.captures.to_a.map { |v| URI.decode_www_form_component(v) if v }
      if values.any?
        params = {}
        keys.zip(values) { |k,v| Array === params[k] ? params[k] << v : params[k] = v if v }
        @params = params
      end

      @connection = connection
      @req = req

      begin
        body = block ? block[self, values] : yield(self, values)
        halt [:ok, body]
      rescue Exception => e
        p [:e, e]
      end
    end
  end
  nil
end

#try_static!(connection, req) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/artoo/api/route_helpers.rb', line 171

def try_static!(connection, req)
  fpath = req.url == '/' ? 'index.html' : req.url[1..-1]
  filepath = File.expand_path(fpath, self.class.static_path)
  if File.file?(filepath)
    # TODO: stream this?
    data = open(filepath).read
    @is_static = true
    halt :ok, data
  end
  @is_static = false
end