Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions lib/grape/middleware/globals.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# This Middleware is not loaded by grape by default.
# If you intend to use it you must first:
# require 'grape/middleware/globals'
# See the spec for examples.
#
require 'grape/middleware/base'

module Grape
module Middleware
class Globals < Base
# NOTE: If you have Grape mounted as a Rack endpoint in a Rails stack action dispatch may have moved the params
# If your params are not showing up,
# then you may need to override this method and
# have it load params from @env['action_dispatch.request.request_parameters'] instead of request.params
def before
@env['grape.request'] = Grape::Request.new(@env)
request = Grape::Request.new(@env)
@env['grape.request.headers'] = request.headers
@env['grape.request.params'] = request.params if @env['rack.input']
@env['grape.request.params'] = request.params
end
end
end
Expand Down
73 changes: 73 additions & 0 deletions lib/grape/middleware/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# This Middleware is not loaded by grape by default.
# If you intend to use it you must first:
# require 'grape/middleware/logger'
# See the spec for examples.
#
require 'grape/middleware/globals'

module Grape
module Middleware
class Logger < Globals
def before
super
logger.info "[api] Requested#{request_log}" unless request_log.nil? || request_log.empty?
logger.info "[api] HEADERS: #{@env['grape.request.headers']}" unless @env['grape.request.headers'].nil? || @env['grape.request.headers'].empty?
logger.info "[api] PARAMS: #{@env['grape.request.params']}" unless @env['grape.request.params'].nil? || @env['grape.request.params'].empty?
end

# Example of what you might do in a subclass in an after hook:
# def after
# response_body = JSON.parse(response.body.first)
# if response_body.is_a?(Hash)
# logger.debug "[api] RespType: #{response_body['response_type']}" unless response_body['response_type'].blank?
# logger.debug "[api] Response: #{response_body['response']}" unless response_body['response'].blank?
# logger.debug "[api] Backtrace:\n#{response_body['backtrace'].join("\n")}" if response_body['backtrace'] && response_body['backtrace'].any?
# end
# super
# end

private

# Override in a subclass to customize the logger (not affected by setting the logger helper in Grape::API)
# def logger
# @logger ||= Rails.logger # as an example
# end
def logger
@logger ||= Logger.new(STDOUT)
end

def request_log
@request_log ||= begin
res = ''
res << " #{request_log_data}" unless request_log_data.nil? || request_log_data.empty?
res
end
end

def request_log_data
rld = {}

x_org = env['HTTP_X_ORGANIZATION']

rld[:user_id] = current_user.id if current_user
rld[:x_organization] = x_org if x_org

rld
end

# Override this method in a subclass and mount the subclass
# For example with Devise & Warden:
# def current_user
# @warden_user_for_log ||= begin
# woo = env['warden'].instance_variable_get(:'@users')
# woo[:user] if woo
# end
# end
# Also if Warden is later in your Rack Middleware stack
# then you can only render the current user data in the after hook, not the before hook.
def current_user
false
end
end
end
end
35 changes: 35 additions & 0 deletions spec/grape/middleware/globals_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'spec_helper'
require 'grape/middleware/globals'

describe Grape::Middleware::Globals do
let(:app) { lambda { |env| [200, env, 'Howdy Doody'] } }
subject { Grape::Middleware::Globals.new(app, {}) }

context 'with params' do
it 'sets the params based on the params' do
env = Rack::MockRequest.env_for('/awesome', params: { 'swank' => 'bank' })
expect(subject.call(env)[1]['grape.request.params']).to eq('swank' => 'bank')
expect(subject.call(env)[1]['grape.request.headers']).to eq({})
end
end

context 'with headers' do
it 'sets the headers based on the headers' do
env = Rack::MockRequest.env_for('/awesome', params: {})
env['HTTP_MONKEY'] = 'I_BANANA'

expect(subject.call(env)[1]['grape.request.params']).to eq({})
expect(subject.call(env)[1]['grape.request.headers']).to eq('Monkey' => 'I_BANANA')
end
end

context 'with headers and params' do
it 'sets the headers based on the headers' do
env = Rack::MockRequest.env_for('/awesome', params: { 'grapes' => 'wrath' })
env['HTTP_MONKEY'] = 'I_BANANA'

expect(subject.call(env)[1]['grape.request.params']).to eq('grapes' => 'wrath')
expect(subject.call(env)[1]['grape.request.headers']).to eq('Monkey' => 'I_BANANA')
end
end
end