cfoundry 0.7.0.rc3 → 0.7.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: