Skip to content

Commit

Permalink
Merge pull request lostisland#17 from pengwynn/next
Browse files Browse the repository at this point in the history
Refactoring & faraday-stack merge
  • Loading branch information
sferik committed Jan 19, 2012
2 parents cfbb9e2 + 9c3f2a4 commit 1d7510d
Show file tree
Hide file tree
Showing 40 changed files with 1,078 additions and 261 deletions.
1 change: 0 additions & 1 deletion .rspec
@@ -1,3 +1,2 @@
--color
--format=nested
--backtrace
6 changes: 3 additions & 3 deletions Gemfile
@@ -1,7 +1,7 @@
source 'http://rubygems.org'

platforms :jruby do
gem "jruby-openssl", "~> 0.7"
end
gem 'simplecov' unless ENV['CI']
gem 'json', :platforms => [:ruby_18, :jruby]
gem 'jruby-openssl', '~> 0.7', :platforms => :jruby

gemspec
11 changes: 9 additions & 2 deletions Rakefile
@@ -1,10 +1,17 @@
#!/usr/bin/env rake

task :default => [:enable_coverage, :spec, :test]

require 'bundler'
Bundler::GemHelper.install_tasks

require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)

task :test => :spec
task :default => :spec
task :enable_coverage do
ENV['COVERAGE'] = 'yes' unless ENV['CI']
end

task :test do
sh 'ruby', '-Ilib', 'spec/caching_test.rb'
end
5 changes: 2 additions & 3 deletions faraday_middleware.gemspec
@@ -1,15 +1,14 @@
require File.expand_path('../lib/faraday_middleware/version', __FILE__)

Gem::Specification.new do |gem|
gem.add_dependency 'faraday', '~> 0.7.4'
gem.add_development_dependency 'multi_json', '~> 1.0'
gem.add_dependency 'faraday', ['>= 0.7.4', '< 0.9']
gem.add_development_dependency 'multi_xml', '~> 0.2'
gem.add_development_dependency 'oauth2', '~> 0.5.0'
gem.add_development_dependency 'rake', '~> 0.9'
gem.add_development_dependency 'rash', '~> 0.3'
gem.add_development_dependency 'rspec', '~> 2.6'
gem.add_development_dependency 'simple_oauth', '~> 0.1'
gem.add_development_dependency 'simplecov', '~> 0.4'
gem.add_development_dependency 'rack-cache', '~> 1.1'
gem.authors = ["Erik Michaels-Ober", "Wynn Netherland"]
gem.description = %q{Various middleware for Faraday}
gem.email = ['sferik@gmail.com', 'wynn.netherland@gmail.com']
Expand Down
24 changes: 0 additions & 24 deletions lib/faraday/request/oauth2.rb

This file was deleted.

20 changes: 0 additions & 20 deletions lib/faraday/response/parse_json.rb

This file was deleted.

10 changes: 0 additions & 10 deletions lib/faraday/response/parse_marshal.rb

This file was deleted.

11 changes: 0 additions & 11 deletions lib/faraday/response/parse_xml.rb

This file was deleted.

11 changes: 0 additions & 11 deletions lib/faraday/response/parse_yaml.rb

This file was deleted.

9 changes: 0 additions & 9 deletions lib/faraday/response/rashify.rb

This file was deleted.

62 changes: 51 additions & 11 deletions lib/faraday_middleware.rb
@@ -1,15 +1,55 @@
require 'faraday'

class Faraday::Request
autoload :OAuth, 'faraday/request/oauth'
autoload :OAuth2, 'faraday/request/oauth2'
end
module FaradayMiddleware
class << self
middleware = {
:OAuth => 'request/oauth',
:OAuth2 => 'request/oauth2',
:EncodeJson => 'request/encode_json',
:Mashify => 'response/mashify',
:Rashify => 'response/rashify',
:ParseJson => 'response/parse_json',
:ParseXml => 'response/parse_xml',
:ParseMarshal => 'response/parse_marshal',
:ParseYaml => 'response/parse_yaml',
:Caching => 'response/caching',
:RackCompatible => 'rack_compatible',
:FollowRedirects => 'response/follow_redirects',
:Instrumentation => 'instrumentation'
}

# autoload without the autoload
define_method(:const_missing) { |const|
if middleware.member? const
require "faraday_middleware/#{middleware[const]}"
raise NameError, "missing #{const} middleware" unless const_defined? const
const_get const
else
super
end
}
end

if Faraday.respond_to? :register_middleware
Faraday.register_middleware :request,
:oauth => lambda { OAuth },
:oauth2 => lambda { OAuth2 },
:json => lambda { EncodeJson }

class Faraday::Response
autoload :Mashify, 'faraday/response/mashify'
autoload :ParseJson, 'faraday/response/parse_json'
autoload :ParseMarshal, 'faraday/response/parse_marshal'
autoload :ParseXml, 'faraday/response/parse_xml'
autoload :ParseYaml, 'faraday/response/parse_yaml'
autoload :Rashify, 'faraday/response/rashify'
Faraday.register_middleware :response,
:mashify => lambda { Mashify },
:rashify => lambda { Rashify },
:json => lambda { ParseJson },
:json_fix => lambda { ParseJson::MimeTypeFix },
:xml => lambda { ParseXml },
:marshal => lambda { ParseMarshal },
:yaml => lambda { ParseYaml },
:caching => lambda { Caching },
:follow_redirects => lambda { FollowRedirects }

Faraday.register_middleware \
:instrumentation => lambda { Instrumentation }
end
end

require 'faraday_middleware/backwards_compatibility'
20 changes: 20 additions & 0 deletions lib/faraday_middleware/addressable_patch.rb
@@ -0,0 +1,20 @@
require 'addressable/uri'

# feature-detect the bug
unless Addressable::URI.parse('/?a=1&b=2') === '/?b=2&a=1'
# fix `normalized_query` by sorting query key-value pairs
# (rejected: https://github.com/sporkmonger/addressable/issues/28)
class Addressable::URI
alias normalized_query_without_ordering_fix normalized_query

def normalized_query
fresh = @normalized_query.nil?
query = normalized_query_without_ordering_fix
if query && fresh
@normalized_query = query.split('&', -1).sort_by {|q| q[0..(q.index('=')||-1)] }.join('&')
else
query
end
end
end
end
30 changes: 30 additions & 0 deletions lib/faraday_middleware/backwards_compatibility.rb
@@ -0,0 +1,30 @@
deprecation_warning = lambda { |old, new, trace|
warn "Deprecation warning: #{old} is deprecated; use #{new}"
warn trace[0,10].join("\n") if $DEBUG
}

Faraday::Request.extend Module.new {
legacy = [:OAuth, :OAuth2]
define_method(:const_missing) { |const|
if legacy.include? const
klass = FaradayMiddleware.const_get(const)
deprecation_warning.call "Faraday::Request::#{const}", klass.name, caller
const_set const, klass
else
super
end
}
}

Faraday::Response.extend Module.new {
legacy = [:Mashify, :Rashify, :ParseJson, :ParseMarshal, :ParseXml, :ParseYaml]
define_method(:const_missing) { |const|
if legacy.include? const
klass = FaradayMiddleware.const_get(const)
deprecation_warning.call "Faraday::Response::#{const}", klass.name, caller
const_set const, klass
else
super
end
}
}
30 changes: 30 additions & 0 deletions lib/faraday_middleware/instrumentation.rb
@@ -0,0 +1,30 @@
require 'faraday'

module FaradayMiddleware
# Public: Instruments requests using Active Support.
#
# Measures time spent only for synchronous requests.
#
# Examples
#
# ActiveSupport::Notifications.subscribe('request.faraday') do |name, start_time, end_time, _, env|
# url = env[:url]
# http_method = env[:method].to_s.upcase
# duration = end_time - start_time
# $stderr.puts '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration]
# end
class Instrumentation < Faraday::Middleware
dependency 'active_support/notifications'

def initialize(app, options = {})
super(app)
@name = options.fetch(:name, 'request.faraday')
end

def call(env)
ActiveSupport::Notifications.instrument(@name, env) do
@app.call(env)
end
end
end
end
76 changes: 76 additions & 0 deletions lib/faraday_middleware/rack_compatible.rb
@@ -0,0 +1,76 @@
require 'stringio'

module FaradayMiddleware
# Wraps a handler originally written for Rack to make it compatible with Faraday.
#
# Experimental. Only handles changes in request headers.
class RackCompatible
def initialize(app, rack_handler, *args)
# tiny middleware that decomposes a Faraday::Response to standard Rack
# array: [status, headers, body]
compatible_app = lambda do |env|
restore_env(env)
response = app.call(env)
[response.status, response.headers, Array(response.body)]
end
@rack = rack_handler.new(compatible_app, *args)
end

def call(env)
prepare_env(env)
rack_response = @rack.call(env)
finalize_response(env, rack_response)
end

NonPrefixedHeaders = %w[CONTENT_LENGTH CONTENT_TYPE]

# faraday to rack-compatible
def prepare_env(env)
env[:request_headers].each do |name, value|
name = name.upcase.tr('-', '_')
name = "HTTP_#{name}" unless NonPrefixedHeaders.include? name
env[name] = value
end

url = env[:url]
env['rack.url_scheme'] = url.scheme
env['PATH_INFO'] = url.path
env['SERVER_PORT'] = url.respond_to?(:inferred_port) ? url.inferred_port : url.port
env['QUERY_STRING'] = url.query
env['REQUEST_METHOD'] = env[:method].to_s.upcase

env['rack.errors'] ||= StringIO.new

env
end

# rack to faraday-compatible
def restore_env(env)
headers = env[:request_headers]
headers.clear

env.each do |name, value|
next unless String === name
if NonPrefixedHeaders.include? name or name.index('HTTP_') == 0
name = name.sub(/^HTTP_/, '').downcase.tr('_', '-')
headers[name] = value
end
end

env[:method] = env['REQUEST_METHOD'].downcase.to_sym
env
end

def finalize_response(env, rack_response)
status, headers, body = rack_response
body = body.inject('') { |str, part| str << part }
headers = Faraday::Utils::Headers.new(headers) unless Faraday::Utils::Headers === headers

response_env = { :status => status, :body => body, :response_headers => headers }

env[:response] ||= Faraday::Response.new({})
env[:response].env.update(response_env)
env[:response]
end
end
end

0 comments on commit 1d7510d

Please sign in to comment.