faraday-conductivity 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +119 -0
- data/Rakefile +4 -0
- data/faraday-conductivity.gemspec +25 -0
- data/lib/faraday/conductivity/extended_logging.rb +71 -0
- data/lib/faraday/conductivity/request_id.rb +19 -0
- data/lib/faraday/conductivity/request_id_filter.rb +11 -0
- data/lib/faraday/conductivity/user_agent.rb +26 -0
- data/lib/faraday/conductivity/version.rb +5 -0
- data/lib/faraday/conductivity.rb +16 -0
- data/spec/faraday/conductivity_spec.rb +61 -0
- data/spec/spec_helper.rb +2 -0
- metadata +127 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 iain
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# Faraday::Conductivity
|
2
|
+
|
3
|
+
Extra Faraday Middleware! Geared towards a service oriented architecture.
|
4
|
+
|
5
|
+
Here is an overview of my favorite stack. More information about each
|
6
|
+
middleware is below.
|
7
|
+
|
8
|
+
``` ruby
|
9
|
+
APP_VERSION = IO.popen(["git", "rev-parse", "HEAD", :chdir => Rails.root]).read.chomp
|
10
|
+
|
11
|
+
connection = Faraday.new(url: "http://widgets.yourapp.com") do |faraday|
|
12
|
+
|
13
|
+
# provided by Faraday itself
|
14
|
+
faraday.token_auth "secret"
|
15
|
+
|
16
|
+
# provided by this gem
|
17
|
+
faraday.use :extended_logging, logger: Rails.logger
|
18
|
+
|
19
|
+
# provided by Faraday
|
20
|
+
faraday.request :multipart
|
21
|
+
faraday.request :url_encoded
|
22
|
+
|
23
|
+
# provided by this gem
|
24
|
+
faraday.request :user_agent, app: "MarketingSite", version: APP_VERSION
|
25
|
+
faraday.request :request_id
|
26
|
+
|
27
|
+
# provided by faraday_middleware
|
28
|
+
faraday.response :json, content_type: /\bjson$/
|
29
|
+
|
30
|
+
faraday.adapter Faraday.default_adapter
|
31
|
+
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
You should also take a look at
|
36
|
+
[faraday_middleware](https://github.com/lostisland/faraday_middleware).
|
37
|
+
|
38
|
+
More middleware to come!
|
39
|
+
|
40
|
+
## Installation
|
41
|
+
|
42
|
+
Add this line to your application's Gemfile:
|
43
|
+
|
44
|
+
gem 'faraday-conductivity'
|
45
|
+
|
46
|
+
And then execute:
|
47
|
+
|
48
|
+
$ bundle
|
49
|
+
|
50
|
+
Or install it yourself as:
|
51
|
+
|
52
|
+
$ gem install faraday-conductivity
|
53
|
+
|
54
|
+
## Usage
|
55
|
+
|
56
|
+
Here is an overview of the middleware included in this gem.
|
57
|
+
|
58
|
+
### Extended Logging
|
59
|
+
|
60
|
+
Provides pretty logging, allowing you to inspect every detail of the request
|
61
|
+
and response.
|
62
|
+
|
63
|
+
``` ruby
|
64
|
+
connection = Faraday.new(url: "http://widgets.yourapp.com") do |faraday|
|
65
|
+
faraday.use :extended_logging, logger: Rails.logger
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
### RequestID
|
70
|
+
|
71
|
+
Pass on a request ID from your frontend applications to your backend services.
|
72
|
+
This allows for tracking requests over multiple services. Use this in
|
73
|
+
combination with something like the Rails tagged logger and you'll always know
|
74
|
+
what triggered something to happen in your application.
|
75
|
+
|
76
|
+
It works by trying to find the request id in `Thread.current[:request_id]` and
|
77
|
+
setting the `X-Request-Id` header.
|
78
|
+
|
79
|
+
``` ruby
|
80
|
+
connection = Faraday.new(url: "http://widgets.yourapp.com") do |faraday|
|
81
|
+
faraday.request :request_id
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
In order for this to work, you need to make the Request ID globally available.
|
86
|
+
To do this in Rails:
|
87
|
+
|
88
|
+
``` ruby
|
89
|
+
class Application < ActionController::Base
|
90
|
+
before_filter Faraday::Conductivity::RequestIdFilter
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
It's a hack, but it works really well.
|
95
|
+
|
96
|
+
### User Agent
|
97
|
+
|
98
|
+
Which application, on which server, made this request? With this middleware you
|
99
|
+
know! It sets the User-Agent string based on the user, pid and hostname.
|
100
|
+
|
101
|
+
``` ruby
|
102
|
+
connection = Faraday.new(url: "http://widgets.yourapp.com") do |faraday|
|
103
|
+
faraday.request :user_agent, app: "MarketingSite", version: "1.1"
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
The User-Agent will looks like this on my machine:
|
108
|
+
|
109
|
+
```
|
110
|
+
MarketingSite/1.1 (iain.local; iain; 30360) ruby/1.9.3 (327; x86_64-darwin12.2.0)
|
111
|
+
```
|
112
|
+
|
113
|
+
## Contributing
|
114
|
+
|
115
|
+
1. Fork it
|
116
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
117
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
118
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
119
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'faraday/conductivity/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "faraday-conductivity"
|
8
|
+
gem.version = Faraday::Conductivity::VERSION
|
9
|
+
gem.authors = ["iain"]
|
10
|
+
gem.email = ["iain@iain.nl"]
|
11
|
+
gem.description = %q{Extra Faraday middleware, geared towards a service oriented architecture.}
|
12
|
+
gem.summary = %q{Extra Faraday middleware, geared towards a service oriented architecture.}
|
13
|
+
gem.homepage = "https://github.com/yourkarma/faraday-conductivity"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_dependency "faraday", "~> 0.8"
|
22
|
+
gem.add_development_dependency "rake"
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "pry"
|
25
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
module Conductivity
|
5
|
+
class ExtendedLogging < Faraday::Middleware
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
9
|
+
|
10
|
+
def initialize(app, options = {})
|
11
|
+
@app = app
|
12
|
+
@logger = options.fetch(:logger) {
|
13
|
+
require 'logger'
|
14
|
+
::Logger.new($stderr)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
start_time = Time.now
|
20
|
+
info { request_info(env) }
|
21
|
+
debug { request_debug(env) }
|
22
|
+
@app.call(env).on_complete do
|
23
|
+
end_time = Time.now
|
24
|
+
response_time = end_time - start_time
|
25
|
+
info { response_info(env, response_time) }
|
26
|
+
debug { response_debug(env) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def request_info(env)
|
33
|
+
"Started #{env[:method].to_s.upcase} request to: #{env[:url]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def response_info(env, response_time)
|
37
|
+
"Response from #{env[:url]}; Status: #{env[:status]}; Time: %.1fms" % (response_time * 1_000.0)
|
38
|
+
end
|
39
|
+
|
40
|
+
def request_debug(env)
|
41
|
+
<<-MESSAGE
|
42
|
+
Request Headers:
|
43
|
+
----------------
|
44
|
+
#{format_headers env[:request_headers]}
|
45
|
+
|
46
|
+
Request Body:
|
47
|
+
-------------
|
48
|
+
#{env[:body]}
|
49
|
+
MESSAGE
|
50
|
+
end
|
51
|
+
|
52
|
+
def response_debug(env)
|
53
|
+
<<-MESSAGE
|
54
|
+
Response Headers:
|
55
|
+
-----------------
|
56
|
+
#{format_headers env[:response_headers]}
|
57
|
+
|
58
|
+
Response Body:
|
59
|
+
--------------
|
60
|
+
#{env[:body]}
|
61
|
+
MESSAGE
|
62
|
+
end
|
63
|
+
|
64
|
+
def format_headers(headers)
|
65
|
+
length = headers.map {|k,v| k.to_s.size }.max
|
66
|
+
headers.map { |name, value| "#{name.to_s.ljust(length)} : #{value.inspect}" }.join("\n")
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Faraday
|
2
|
+
module Conductivity
|
3
|
+
class RequestId < Faraday::Middleware
|
4
|
+
|
5
|
+
def initialize(app)
|
6
|
+
super(app)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
request_id = Thread.current[:request_id]
|
11
|
+
if request_id
|
12
|
+
env[:request_headers]['X-Request-Id'] ||= request_id
|
13
|
+
end
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "etc"
|
2
|
+
require "socket"
|
3
|
+
require "thread"
|
4
|
+
|
5
|
+
module Faraday
|
6
|
+
module Conductivity
|
7
|
+
class UserAgent < Faraday::Middleware
|
8
|
+
|
9
|
+
def initialize(app, options = {})
|
10
|
+
super(app)
|
11
|
+
@name = options.fetch(:app) { "Faraday" }
|
12
|
+
@version = options.fetch(:version) { "0.0" }
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
login = Etc.getlogin
|
17
|
+
hostname = Socket.gethostname
|
18
|
+
pid = Process.pid
|
19
|
+
user_agent = "#{@name}/#{@version} (#{hostname}; #{login}; #{pid}) #{RUBY_ENGINE}/#{RUBY_VERSION} (#{RUBY_PATCHLEVEL}; #{RUBY_PLATFORM})"
|
20
|
+
env[:request_headers]['User-Agent'] ||= user_agent
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "faraday"
|
2
|
+
|
3
|
+
require "faraday/conductivity/version"
|
4
|
+
require "faraday/conductivity/request_id"
|
5
|
+
require "faraday/conductivity/request_id_filter"
|
6
|
+
require "faraday/conductivity/user_agent"
|
7
|
+
require "faraday/conductivity/extended_logging"
|
8
|
+
|
9
|
+
module Faraday
|
10
|
+
module Conductivity
|
11
|
+
end
|
12
|
+
register_middleware :middleware, :extended_logging => Faraday::Conductivity::ExtendedLogging
|
13
|
+
register_middleware :request, :user_agent => Faraday::Conductivity::UserAgent
|
14
|
+
register_middleware :request, :request_id => Faraday::Conductivity::RequestId
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "faraday/conductivity"
|
3
|
+
require "faraday_middleware"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
# I'm sorry about the state of this test file.
|
7
|
+
# This will be cleaned up, I promise.
|
8
|
+
|
9
|
+
describe Faraday::Conductivity do
|
10
|
+
|
11
|
+
it 'should have a version number' do
|
12
|
+
Faraday::Conductivity::VERSION.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
example "user_agent" do
|
16
|
+
connection = Faraday.new(url: "http://widgets.yourapp.com") do |faraday|
|
17
|
+
faraday.request :user_agent, app: "MarketingSite", version: "1.1"
|
18
|
+
end
|
19
|
+
request = connection.get("/foobar")
|
20
|
+
request.env[:request_headers]["User-Agent"].should match %r(^MarketingSite/1.1 \([^\s]+; [^\s]+; \d+\) ruby/1.9.3)
|
21
|
+
end
|
22
|
+
|
23
|
+
example "extended_logging" do
|
24
|
+
io = StringIO.new
|
25
|
+
dummy_logger = Logger.new(io)
|
26
|
+
request_with do |faraday|
|
27
|
+
faraday.use :extended_logging, logger: dummy_logger
|
28
|
+
end
|
29
|
+
io.rewind
|
30
|
+
logged = io.read
|
31
|
+
logged.should include "Started GET request"
|
32
|
+
logged.should include "http://example.org/test"
|
33
|
+
logged.should include "the dummy response"
|
34
|
+
logged.should include "the request body"
|
35
|
+
logged.should include "X-Response-Header"
|
36
|
+
logged.should include "header-value"
|
37
|
+
# puts logged
|
38
|
+
end
|
39
|
+
|
40
|
+
example "request id" do
|
41
|
+
Thread.current[:request_id] = "my-request-id"
|
42
|
+
response = request_with do |faraday|
|
43
|
+
faraday.request :request_id
|
44
|
+
end
|
45
|
+
response.env[:request_headers]["X-Request-Id"].should eq "my-request-id"
|
46
|
+
end
|
47
|
+
|
48
|
+
def request_with
|
49
|
+
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
50
|
+
stub.get('/test') { |env| [200, {"X-Response-Header" => "header-value"}, {foo:"the dummy response"}.to_json] }
|
51
|
+
end
|
52
|
+
connection = Faraday.new(url: "http://example.org/") do |faraday|
|
53
|
+
yield faraday
|
54
|
+
faraday.adapter :test, stubs
|
55
|
+
end
|
56
|
+
connection.get("/test") do |req|
|
57
|
+
req.body = "the request body"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faraday-conductivity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- iain
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.8'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Extra Faraday middleware, geared towards a service oriented architecture.
|
79
|
+
email:
|
80
|
+
- iain@iain.nl
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .rspec
|
87
|
+
- Gemfile
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- faraday-conductivity.gemspec
|
92
|
+
- lib/faraday/conductivity.rb
|
93
|
+
- lib/faraday/conductivity/extended_logging.rb
|
94
|
+
- lib/faraday/conductivity/request_id.rb
|
95
|
+
- lib/faraday/conductivity/request_id_filter.rb
|
96
|
+
- lib/faraday/conductivity/user_agent.rb
|
97
|
+
- lib/faraday/conductivity/version.rb
|
98
|
+
- spec/faraday/conductivity_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
homepage: https://github.com/yourkarma/faraday-conductivity
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 1.8.23
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: Extra Faraday middleware, geared towards a service oriented architecture.
|
125
|
+
test_files:
|
126
|
+
- spec/faraday/conductivity_spec.rb
|
127
|
+
- spec/spec_helper.rb
|