cfoundry 0.7.0.rc3 → 0.7.0.rc4

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.
@@ -12,8 +12,8 @@ module CFoundry
12
12
  attr_reader :rest_client
13
13
 
14
14
  def_delegators :rest_client, :target, :target=, :token,
15
- :proxy, :proxy=, :trace, :backtrace, :backtrace=,
16
- :log, :log=
15
+ :trace, :backtrace, :backtrace=, :log, :log=,
16
+ :http_proxy, :http_proxy=, :https_proxy, :https_proxy=
17
17
 
18
18
  def initialize(target = "https://api.cloudfoundry.com", token = nil)
19
19
  @rest_client = CFoundry::RestClient.new(target, token)
@@ -6,6 +6,29 @@ require "fileutils"
6
6
 
7
7
  module CFoundry
8
8
  class RestClient
9
+ class HTTPFactory
10
+ def self.create(uri, http_proxy, https_proxy)
11
+ scheme = uri.scheme
12
+ proxy_to_use = (scheme == "http" ? http_proxy : https_proxy)
13
+
14
+ if proxy_to_use
15
+ proxy_uri = URI.parse(proxy_to_use)
16
+ proxy_user, proxy_pass = proxy_uri.userinfo.split(/:/) if proxy_uri.userinfo
17
+ http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass).
18
+ new(uri.host, uri.port)
19
+ else
20
+ http = Net::HTTP.new(uri.host, uri.port)
21
+ end
22
+
23
+ if scheme == "https"
24
+ http.use_ssl = true
25
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
26
+ end
27
+
28
+ return http
29
+ end
30
+ end
31
+
9
32
  include CFoundry::TraceHelpers
10
33
 
11
34
  LOG_LENGTH = 10
@@ -24,7 +47,9 @@ module CFoundry
24
47
 
25
48
  attr_reader :target
26
49
 
27
- attr_accessor :trace, :backtrace, :log, :request_id, :token, :target, :proxy
50
+ attr_accessor :trace, :backtrace, :log,
51
+ :request_id, :token, :target,
52
+ :http_proxy, :https_proxy
28
53
 
29
54
  def initialize(target, token = nil)
30
55
  @target = target
@@ -49,7 +74,6 @@ module CFoundry
49
74
 
50
75
  headers["X-Request-Id"] = @request_id if @request_id
51
76
  headers["Authorization"] = @token.auth_header if @token
52
- headers["Proxy-User"] = @proxy if @proxy
53
77
 
54
78
  if accept_type = mimetype(options[:accept])
55
79
  headers["Accept"] = accept_type
@@ -118,17 +142,11 @@ module CFoundry
118
142
 
119
143
  add_headers(request, headers)
120
144
 
121
- # TODO: test http proxies
122
- http = Net::HTTP.new(uri.host, uri.port)
145
+ http = HTTPFactory.create(uri, http_proxy, https_proxy)
123
146
 
124
147
  # TODO remove this when staging returns streaming responses
125
148
  http.read_timeout = 300
126
149
 
127
- if uri.is_a?(URI::HTTPS)
128
- http.use_ssl = true
129
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
130
- end
131
-
132
150
  before = Time.now
133
151
  http.start do
134
152
  response = http.request(request)
@@ -1,4 +1,5 @@
1
1
  require File.expand_path("../../concerns/login_helpers", __FILE__)
2
+ require "forwardable"
2
3
 
3
4
  module CFoundry::V2
4
5
  # The primary API entrypoint. Wraps a BaseClient to provide nicer return
@@ -6,6 +7,7 @@ module CFoundry::V2
6
7
  # are the only two internal states.
7
8
  class Client
8
9
  include ClientMethods, CFoundry::LoginHelpers
10
+ extend Forwardable
9
11
 
10
12
  # Internal BaseClient instance. Normally won't be touching this.
11
13
  attr_reader :base
@@ -16,6 +18,8 @@ module CFoundry::V2
16
18
  # [Space] Currently targeted space.
17
19
  attr_accessor :current_space
18
20
 
21
+ def_delegators :@base, :target, :token, :token=, :http_proxy, :http_proxy=,
22
+ :https_proxy, :https_proxy=, :trace, :trace=, :log, :log=, :info
19
23
 
20
24
  # Create a new Client for interfacing with the given target.
21
25
  #
@@ -28,58 +32,6 @@ module CFoundry::V2
28
32
  2
29
33
  end
30
34
 
31
- # The current target URL of the client.
32
- def target
33
- @base.target
34
- end
35
-
36
- # Current authentication token.
37
- def token
38
- @base.token
39
- end
40
-
41
- # Set the authentication token.
42
- def token=(token)
43
- @base.token = token
44
- end
45
-
46
- # Current proxy user. Usually nil.
47
- def proxy
48
- @base.proxy
49
- end
50
-
51
- # Set the proxy user for the client. Must be authorized as an
52
- # administrator for this to have any effect.
53
- def proxy=(email)
54
- @base.proxy = email
55
- end
56
-
57
- # Is the client tracing API requests?
58
- def trace
59
- @base.trace
60
- end
61
-
62
- # Set the tracing flag; if true, API requests and responses will be
63
- # printed out.
64
- def trace=(bool)
65
- @base.trace = bool
66
- end
67
-
68
- # The current log. See +log=+.
69
- def log
70
- @base.log
71
- end
72
-
73
- # Set the logging mode. Mode can be one of:
74
- #
75
- # [+String+] Name of a file to log the last 10 requests to.
76
- # [+Array+] Array to append with log data (a Hash).
77
- # [+IO+] An IO object to write to.
78
- # [+false+] No logging.
79
- def log=(mode)
80
- @base.log = mode
81
- end
82
-
83
35
  # The currently authenticated user.
84
36
  def current_user
85
37
  return unless token
@@ -92,11 +44,6 @@ module CFoundry::V2
92
44
  end
93
45
  end
94
46
 
95
- # Cloud metadata
96
- def info
97
- @base.info
98
- end
99
-
100
47
  def login(username, password)
101
48
  @current_organization = nil
102
49
  @current_space = nil
@@ -1,4 +1,4 @@
1
1
  module CFoundry # :nodoc:
2
2
  # CFoundry library version number.
3
- VERSION = "0.7.0.rc3".freeze
3
+ VERSION = "0.7.0.rc4".freeze
4
4
  end
@@ -8,11 +8,11 @@ describe CFoundry::RestClient do
8
8
  describe '#request' do
9
9
  let(:path) { "some-path" }
10
10
  let(:url) { "#{target}/#{path}" }
11
- let(:method) { "GET" }
11
+ let(:verb) { "GET" }
12
12
  let(:options) { {} }
13
13
 
14
- def check_request(method = :get, &block)
15
- request_stub = stub_request(method, url).to_return do |req|
14
+ def check_request(verb = :get, &block)
15
+ request_stub = stub_request(verb, url).to_return do |req|
16
16
  block.call(req)
17
17
  {}
18
18
  end
@@ -20,10 +20,10 @@ describe CFoundry::RestClient do
20
20
  expect(request_stub).to have_been_requested
21
21
  end
22
22
 
23
- subject { rest_client.request(method, path, options) }
23
+ subject { rest_client.request(verb, path, options) }
24
24
 
25
25
  describe 'headers' do
26
- %w[Authorization Proxy-User X-Request-Id Content-Type].each do |header_name|
26
+ %w[Authorization X-Request-Id Content-Type].each do |header_name|
27
27
  it "should not include the #{header_name} by default" do
28
28
  check_request do |req|
29
29
  expect(req.headers).not_to have_key(header_name)
@@ -65,8 +65,8 @@ describe CFoundry::RestClient do
65
65
  end
66
66
 
67
67
  context "when the payload is a hash (i.e. multipart upload)" do
68
- let(:method) { "PUT" }
69
- let(:options) { { :payload => { "key" => "value" } } }
68
+ let(:verb) { "PUT" }
69
+ let(:options) { {:payload => {"key" => "value"}} }
70
70
 
71
71
  it 'includes a nonzero content length' do
72
72
  check_request(:put) do |req|
@@ -78,7 +78,7 @@ describe CFoundry::RestClient do
78
78
 
79
79
  context "when params are passed" do
80
80
  context "when params is an empty hash" do
81
- let(:options) { { :params => {} } }
81
+ let(:options) { {:params => {}} }
82
82
 
83
83
  it "does not add a query string delimiter (the question mark)" do
84
84
  request_stub = stub_request(:get, "https://api.cloudfoundry.com/some-path")
@@ -88,7 +88,7 @@ describe CFoundry::RestClient do
88
88
  end
89
89
 
90
90
  context "when params has values" do
91
- let(:options) { { :params => { "key" => "value" } } }
91
+ let(:options) { {:params => {"key" => "value"}} }
92
92
 
93
93
  it "appends a query string and delimiter" do
94
94
  request_stub = stub_request(:get, "https://api.cloudfoundry.com/some-path?key=value")
@@ -119,16 +119,6 @@ describe CFoundry::RestClient do
119
119
  end
120
120
  end
121
121
 
122
- context 'and the proxy is set' do
123
- before { rest_client.instance_variable_set(:@proxy, "some proxy") }
124
-
125
- it 'should include X-Request-Id in the header' do
126
- check_request do |req|
127
- expect(req.headers["Proxy-User"]).to eq "some proxy"
128
- end
129
- end
130
- end
131
-
132
122
  context 'and the content is passed in' do
133
123
  let(:options) { {:content => "text/xml"} }
134
124
 
@@ -149,7 +139,7 @@ describe CFoundry::RestClient do
149
139
  end
150
140
 
151
141
  context 'and it overrides an existing one' do
152
- let(:options) { { :content => "text/xml", :headers => { "Content-Type" => "text/html" } } }
142
+ let(:options) { {:content => "text/xml", :headers => {"Content-Type" => "text/html"}} }
153
143
 
154
144
  it 'uses the custom header' do
155
145
  check_request do |req|
@@ -191,7 +181,7 @@ describe CFoundry::RestClient do
191
181
  before do
192
182
  stub_request(:get, url).to_return({
193
183
  :status => 201,
194
- :headers => { "Content-Type" => "application/json"},
184
+ :headers => {"Content-Type" => "application/json"},
195
185
  :body => '{ "foo": 1 }'
196
186
  })
197
187
  end
@@ -202,11 +192,11 @@ describe CFoundry::RestClient do
202
192
  end
203
193
 
204
194
  describe "the returned request hash" do
205
- it "returns a hash of :headers, :url, :body and :method" do
195
+ it "returns a hash of :headers, :url, :body and :verb" do
206
196
  expect(subject[0]).to eq({
207
197
  :url => url,
208
198
  :method => "GET",
209
- :headers => { "Content-Length" => 0 },
199
+ :headers => {"Content-Length" => 0},
210
200
  :body => nil
211
201
  })
212
202
  end
@@ -216,7 +206,7 @@ describe CFoundry::RestClient do
216
206
  it "returns a hash of :headers, :status, :body" do
217
207
  expect(subject[1]).to eq({
218
208
  :status => "201",
219
- :headers => { "content-type" => "application/json"},
209
+ :headers => {"content-type" => "application/json"},
220
210
  :body => '{ "foo": 1 }'
221
211
  })
222
212
  end
@@ -264,12 +254,12 @@ describe CFoundry::RestClient do
264
254
  describe 'trace' do
265
255
  before do
266
256
  rest_client.trace = true
267
- stub_request(:get, url).to_return(:status => 200, :headers => { "content-type" => "application/json" }, :body => '{"some": "json"}')
257
+ stub_request(:get, url).to_return(:status => 200, :headers => {"content-type" => "application/json"}, :body => '{"some": "json"}')
268
258
  end
269
259
 
270
260
  it "prints the request and the response" do
271
- mock(rest_client).print_request({:headers=>{"Content-Length"=>0}, :url=>"https://api.cloudfoundry.com/some-path", :method=>"GET", :body=>nil})
272
- mock(rest_client).print_response({ :status => "200", :headers => { "content-type" => "application/json" }, :body => '{"some": "json"}' })
261
+ mock(rest_client).print_request({:headers => {"Content-Length" => 0}, :url => "https://api.cloudfoundry.com/some-path", :method => "GET", :body => nil})
262
+ mock(rest_client).print_response({:status => "200", :headers => {"content-type" => "application/json"}, :body => '{"some": "json"}'})
273
263
  subject
274
264
  end
275
265
  end
@@ -278,7 +268,7 @@ describe CFoundry::RestClient do
278
268
  before do
279
269
  stub_request(:post, "https://api.cloudfoundry.com/apps").to_return(
280
270
  :status => 301,
281
- :headers => { "location" => "https://api.cloudfoundry.com/apps/some-guid" }
271
+ :headers => {"location" => "https://api.cloudfoundry.com/apps/some-guid"}
282
272
  )
283
273
  stub_request(:get, "https://api.cloudfoundry.com/apps/some-guid").to_return(
284
274
  :status => 200,
@@ -296,4 +286,86 @@ describe CFoundry::RestClient do
296
286
  end
297
287
  end
298
288
  end
289
+
290
+ describe CFoundry::RestClient::HTTPFactory do
291
+ describe ".create" do
292
+ let(:http_proxy) { '' }
293
+ let(:https_proxy) { '' }
294
+ let(:target_uri) { "http://cloudfoundry.com" }
295
+
296
+ subject { CFoundry::RestClient::HTTPFactory.create(URI.parse(target_uri), http_proxy, https_proxy) }
297
+
298
+ context "when no proxy URI is set" do
299
+ it "should return an instance of the plain Net:HTTP class" do
300
+ expect(subject).to be_instance_of(Net::HTTP)
301
+ expect(subject.use_ssl?).to be_false
302
+ expect(subject.proxy?).to_not be_true
303
+ end
304
+ end
305
+
306
+ context "when the target is an https URI" do
307
+ let(:target_uri) { "https://cloudfoundry.com" }
308
+ it "should return an instance of the plain Net:HTTP class with use_ssl" do
309
+ expect(subject).to be_instance_of(Net::HTTP)
310
+ expect(subject.use_ssl?).to be_true
311
+ expect(subject.proxy?).to_not be_true
312
+ end
313
+ end
314
+
315
+ context "when a http proxy URI without user/password is set " do
316
+ let(:http_proxy) { "http://exapmle.com:8080" }
317
+
318
+ it "should return an instance of the proxy class" do
319
+ expect(subject.proxy?).to be_true
320
+ expect(subject.proxy_address).to eql("exapmle.com")
321
+ expect(subject.proxy_port).to eql(8080)
322
+ end
323
+ end
324
+
325
+ context "when a http proxy URI with user/password is set " do
326
+ let(:http_proxy) { "http://user:pass@exapmle.com:8080" }
327
+
328
+ it "should return an instance of the proxy class" do
329
+ expect(subject.proxy?).to be_true
330
+ expect(subject.proxy_user).to eql("user")
331
+ expect(subject.proxy_pass).to eql("pass")
332
+ end
333
+ end
334
+
335
+ context "when a https proxy URI is set and the target is an https URI" do
336
+ let(:target_uri) { "https://cloudfoundry.com" }
337
+ let(:https_proxy) { "http://exapmle.com:8080" }
338
+
339
+ it "should return an instance of the proxy class" do
340
+ expect(subject.proxy?).to be_true
341
+ end
342
+ end
343
+
344
+ context "when a https proxy URI is set and the target is an http URI" do
345
+ let(:target_uri) { "http://cloudfoundry.com" }
346
+ let(:https_proxy) { "http://exapmle.com:8080" }
347
+
348
+ it "should return an instance of the plain Net:HTTP class" do
349
+ expect(subject.proxy?).to be_nil
350
+ end
351
+ end
352
+
353
+ context "when a http proxy URI is set and the target is an https URI" do
354
+ let(:target_uri) { "https://cloudfoundry.com" }
355
+ let(:http_proxy) { "http://exapmle.com:8080" }
356
+
357
+ it "should return an instance of the plain Net:HTTP class" do
358
+ expect(subject.proxy?).to be_nil
359
+ end
360
+ end
361
+
362
+ context "when an invalid proxy URI is set" do
363
+ let(:http_proxy) { "invalid URI" }
364
+
365
+ it "should raise an error" do
366
+ expect { subject }.to raise_error(URI::InvalidURIError)
367
+ end
368
+ end
369
+ end
370
+ end
299
371
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfoundry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.rc3
4
+ version: 0.7.0.rc4
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-04-16 00:00:00.000000000 Z
13
+ date: 2013-04-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multipart-post
@@ -337,7 +337,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
337
337
  version: '0'
338
338
  segments:
339
339
  - 0
340
- hash: 511819230791673008
340
+ hash: -1868647362048337805
341
341
  required_rubygems_version: !ruby/object:Gem::Requirement
342
342
  none: false
343
343
  requirements: