artifice-excon 0.1.0
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/lib/artifice/excon.rb +120 -0
- metadata +46 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
module Artifice
|
2
|
+
module Excon
|
3
|
+
EXCON_CONNETION = ::Excon::Connection
|
4
|
+
|
5
|
+
# Activate an endpoint for a specific host. The host has both scheme and
|
6
|
+
# port omitted.
|
7
|
+
#
|
8
|
+
# activate_for('google.com', rack_endpoint)
|
9
|
+
def self.activate_for(host, endpoint)
|
10
|
+
Excon::Connection.endpoints[host] = endpoint
|
11
|
+
|
12
|
+
# activate only after the first stub is added
|
13
|
+
replace_connection(Artifice::Excon::Connection) \
|
14
|
+
if Excon::Connection.endpoints.count == 1
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
begin
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
deactivate_for(host)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Deactivate an endpoint for a specific host.
|
26
|
+
def self.deactivate_for(host)
|
27
|
+
Excon::Connection.endpoints.delete(host)
|
28
|
+
|
29
|
+
# deactivate fully after the last stub is gone
|
30
|
+
replace_connection(EXCON_CONNECTION) \
|
31
|
+
if Excon::Connection.endpoints.count == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Activate a default endpoint to which all requests will be routed (unless
|
35
|
+
# a more specific host endpoint is active).
|
36
|
+
def self.activate_with(endpoint, &block)
|
37
|
+
activate_for(:default, endpoint, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Deactivate all endpoints including the default and all host-specific
|
41
|
+
# endpoints as well.
|
42
|
+
def self.deactivate
|
43
|
+
Excon::Connection.endpoints.clear
|
44
|
+
replace_connection(EXCON_CONNECTION)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def self.replace_connection(value)
|
50
|
+
::Excon.class_eval do
|
51
|
+
remove_const(:Connection)
|
52
|
+
const_set(:Connection, value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This is an internal object that can receive Rack requests
|
57
|
+
# to the application using the Rack::Test API
|
58
|
+
class RackRequest
|
59
|
+
include Rack::Test::Methods
|
60
|
+
attr_reader :app
|
61
|
+
|
62
|
+
def initialize(app)
|
63
|
+
@app = app
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Connection < ::Excon::Connection
|
68
|
+
class << self
|
69
|
+
def endpoints
|
70
|
+
@endpoints ||= {}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def request_kernel(params)
|
75
|
+
endpoint = self.class.endpoints[params[:host]] ||
|
76
|
+
self.class.endpoints[:default]
|
77
|
+
return super unless endpoint
|
78
|
+
|
79
|
+
rack_request = RackRequest.new(endpoint)
|
80
|
+
|
81
|
+
params[:headers].each do |header, value|
|
82
|
+
rack_request.header(header, value)
|
83
|
+
end if params[:headers]
|
84
|
+
|
85
|
+
request = "#{params[:scheme]}://#{params[:host]}:#{params[:port]}"
|
86
|
+
request << params[:path]
|
87
|
+
request << query_string(params[:query])
|
88
|
+
|
89
|
+
response = rack_request.request(request,
|
90
|
+
{ :method => params[:method], :input => params[:body] })
|
91
|
+
|
92
|
+
::Excon::Response.new(:body => response.body,
|
93
|
+
:headers => response.headers, :status => response.status)
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def query_string(query)
|
99
|
+
query_string = ""
|
100
|
+
case query
|
101
|
+
when String
|
102
|
+
query_string << '?' << query
|
103
|
+
when Hash
|
104
|
+
query_string << '?'
|
105
|
+
query.each do |key, values|
|
106
|
+
if values.nil?
|
107
|
+
query_string << key.to_s << '&'
|
108
|
+
else
|
109
|
+
[*values].each do |value|
|
110
|
+
query_string << key.to_s << '=' << CGI.escape(value.to_s) << '&'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
query_string.chop! # remove trailing '&'
|
115
|
+
end
|
116
|
+
query_string
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: artifice-excon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brandur
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-10 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: brandur@mutelight.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/artifice/excon.rb
|
21
|
+
homepage: https://github.com/brandur/artifice-excon
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 1.8.23
|
43
|
+
signing_key:
|
44
|
+
specification_version: 3
|
45
|
+
summary: A version of Wycat's Artifice for use with Excon.
|
46
|
+
test_files: []
|