cf-uaa-lib 3.6.0 → 3.7.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.
- checksums.yaml +4 -4
- data/cf-uaa-lib.gemspec +1 -0
- data/lib/uaa/http.rb +45 -42
- data/lib/uaa/info.rb +0 -2
- data/lib/uaa/scim.rb +0 -2
- data/lib/uaa/token_coder.rb +19 -1
- data/lib/uaa/token_issuer.rb +0 -2
- data/lib/uaa/version.rb +1 -1
- data/spec/http_spec.rb +74 -55
- data/spec/info_spec.rb +36 -38
- data/spec/integration_spec.rb +173 -110
- data/spec/scim_spec.rb +75 -80
- data/spec/token_issuer_spec.rb +130 -135
- metadata +16 -3
- data/lib/uaa/proxy_options.rb +0 -30
data/spec/token_issuer_spec.rb
CHANGED
@@ -23,255 +23,250 @@ describe TokenIssuer do
|
|
23
23
|
|
24
24
|
before do
|
25
25
|
#Util.default_logger(:trace)
|
26
|
-
@issuer = TokenIssuer.new(
|
26
|
+
@issuer = TokenIssuer.new('http://test.uaa.target', 'test_client', 'test_secret', options)
|
27
27
|
end
|
28
28
|
|
29
29
|
subject { @issuer }
|
30
30
|
|
31
|
-
describe
|
31
|
+
describe 'initialize' do
|
32
32
|
let(:options) { {:http_proxy => 'http-proxy.com', :https_proxy => 'https-proxy.com', :skip_ssl_validation => true} }
|
33
33
|
|
34
|
-
it
|
35
|
-
subject.http_proxy.should == 'http-proxy.com'
|
36
|
-
subject.https_proxy.should == 'https-proxy.com'
|
37
|
-
end
|
38
|
-
|
39
|
-
it "sets skip_ssl_validation" do
|
34
|
+
it 'sets skip_ssl_validation' do
|
40
35
|
subject.skip_ssl_validation == true
|
41
36
|
end
|
42
37
|
end
|
43
38
|
|
44
|
-
context
|
39
|
+
context 'with client credentials grant' do
|
45
40
|
|
46
|
-
it
|
41
|
+
it 'gets a token with client credentials' do
|
47
42
|
subject.set_request_handler do |url, method, body, headers|
|
48
|
-
headers[
|
49
|
-
headers[
|
43
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
44
|
+
headers['accept'].should =~ /application\/json/
|
50
45
|
# TODO check basic auth header
|
51
|
-
url.should ==
|
46
|
+
url.should == 'http://test.uaa.target/oauth/token'
|
52
47
|
method.should == :post
|
53
|
-
reply = {:access_token =>
|
54
|
-
:scope =>
|
55
|
-
[200, Util.json(reply), {
|
48
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
49
|
+
:scope => 'logs.read', :expires_in => 98765}
|
50
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
56
51
|
end
|
57
|
-
token = subject.client_credentials_grant(
|
52
|
+
token = subject.client_credentials_grant('logs.read')
|
58
53
|
token.should be_an_instance_of TokenInfo
|
59
|
-
token.info[
|
60
|
-
token.info[
|
61
|
-
token.info[
|
62
|
-
token.info[
|
54
|
+
token.info['access_token'].should == 'test_access_token'
|
55
|
+
token.info['token_type'].should =~ /^bearer$/i
|
56
|
+
token.info['scope'].should == 'logs.read'
|
57
|
+
token.info['expires_in'].should == 98765
|
63
58
|
end
|
64
59
|
|
65
|
-
it
|
60
|
+
it 'gets all granted scopes if none specified' do
|
66
61
|
subject.set_request_handler do |url, method, body, headers|
|
67
|
-
reply = {:access_token =>
|
68
|
-
:scope =>
|
69
|
-
[200, Util.json(reply), {
|
62
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
63
|
+
:scope => 'openid logs.read', :expires_in => 98765}
|
64
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
70
65
|
end
|
71
66
|
token = subject.client_credentials_grant
|
72
|
-
Util.arglist(token.info[
|
67
|
+
Util.arglist(token.info['scope']).to_set.should == Util.arglist('openid logs.read').to_set
|
73
68
|
end
|
74
69
|
|
75
|
-
it
|
76
|
-
subject.set_request_handler { [200,
|
70
|
+
it 'raises a bad response error if response content type is not json' do
|
71
|
+
subject.set_request_handler { [200, 'not json', {'content-type' => 'text/html'}] }
|
77
72
|
expect {subject.client_credentials_grant}.to raise_exception BadResponse
|
78
73
|
end
|
79
74
|
|
80
|
-
it
|
81
|
-
subject.set_request_handler { [200,
|
75
|
+
it 'raises a bad response error if the response is not proper json' do
|
76
|
+
subject.set_request_handler { [200, 'bad json', {'content-type' => 'application/json'}] }
|
82
77
|
expect {subject.client_credentials_grant}.to raise_exception BadResponse
|
83
78
|
end
|
84
79
|
|
85
|
-
it
|
86
|
-
subject.set_request_handler { [400, '{"error":"invalid scope"}', {
|
87
|
-
expect {subject.client_credentials_grant(
|
80
|
+
it 'raises a target error if the response is 400 with valid oauth json error' do
|
81
|
+
subject.set_request_handler { [400, '{"error":"invalid scope"}', {'content-type' => 'application/json'}] }
|
82
|
+
expect {subject.client_credentials_grant('bad.scope')}.to raise_exception TargetError
|
88
83
|
end
|
89
84
|
end
|
90
85
|
|
91
|
-
context
|
86
|
+
context 'with owner password grant' do
|
92
87
|
|
93
|
-
it
|
88
|
+
it 'gets a token with owner password' do
|
94
89
|
subject.set_request_handler do |url, method, body, headers|
|
95
|
-
headers[
|
96
|
-
headers[
|
90
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
91
|
+
headers['accept'].should =~ /application\/json/
|
97
92
|
# TODO check basic auth header
|
98
|
-
url.should ==
|
93
|
+
url.should == 'http://test.uaa.target/oauth/token'
|
99
94
|
method.should == :post
|
100
|
-
reply = {:access_token =>
|
101
|
-
:scope =>
|
102
|
-
[200, Util.json(reply), {
|
95
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
96
|
+
:scope => 'openid', :expires_in => 98765}
|
97
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
103
98
|
end
|
104
|
-
token = subject.owner_password_grant(
|
99
|
+
token = subject.owner_password_grant('joe+admin', "?joe's%password$@ ", 'openid')
|
105
100
|
token.should be_an_instance_of TokenInfo
|
106
|
-
token.info[
|
107
|
-
token.info[
|
108
|
-
token.info[
|
109
|
-
token.info[
|
101
|
+
token.info['access_token'].should == 'test_access_token'
|
102
|
+
token.info['token_type'].should =~ /^bearer$/i
|
103
|
+
token.info['scope'].should == 'openid'
|
104
|
+
token.info['expires_in'].should == 98765
|
110
105
|
end
|
111
106
|
|
112
|
-
it
|
107
|
+
it 'gets a token with passcode' do
|
113
108
|
subject.set_request_handler do |url, method, body, headers|
|
114
|
-
headers[
|
115
|
-
headers[
|
109
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
110
|
+
headers['accept'].should =~ /application\/json/
|
116
111
|
# TODO check basic auth header
|
117
|
-
url.should ==
|
112
|
+
url.should == 'http://test.uaa.target/oauth/token'
|
118
113
|
body.should =~ /(^|&)passcode=12345($|&)/
|
119
114
|
body.should =~ /(^|&)grant_type=password($|&)/
|
120
115
|
method.should == :post
|
121
|
-
reply = {:access_token =>
|
122
|
-
:scope =>
|
123
|
-
[200, Util.json(reply), {
|
116
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
117
|
+
:scope => 'openid', :expires_in => 98765}
|
118
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
124
119
|
end
|
125
|
-
token = subject.passcode_grant(
|
120
|
+
token = subject.passcode_grant('12345')
|
126
121
|
token.should be_an_instance_of TokenInfo
|
127
|
-
token.info[
|
128
|
-
token.info[
|
129
|
-
token.info[
|
130
|
-
token.info[
|
122
|
+
token.info['access_token'].should == 'test_access_token'
|
123
|
+
token.info['token_type'].should =~ /^bearer$/i
|
124
|
+
token.info['scope'].should == 'openid'
|
125
|
+
token.info['expires_in'].should == 98765
|
131
126
|
end
|
132
127
|
|
133
128
|
end
|
134
129
|
|
135
|
-
describe
|
136
|
-
it
|
130
|
+
describe '#owner_password_credentials_grant' do
|
131
|
+
it 'gets a token grant type password' do
|
137
132
|
subject.set_request_handler do |url, method, body, headers|
|
138
|
-
headers[
|
139
|
-
headers[
|
140
|
-
url.should ==
|
133
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
134
|
+
headers['accept'].should =~ /application\/json/
|
135
|
+
url.should == 'http://test.uaa.target/oauth/token'
|
141
136
|
method.should == :post
|
142
|
-
body.split('&').should =~ [
|
143
|
-
reply = {:access_token =>
|
144
|
-
:scope =>
|
145
|
-
[200, Util.json(reply), {
|
137
|
+
body.split('&').should =~ ['passcode=fake-passcode', 'grant_type=password']
|
138
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
139
|
+
:scope => 'openid', :expires_in => 98765}
|
140
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
146
141
|
end
|
147
|
-
token = subject.owner_password_credentials_grant({passcode:
|
142
|
+
token = subject.owner_password_credentials_grant({passcode: 'fake-passcode'})
|
148
143
|
token.should be_an_instance_of TokenInfo
|
149
|
-
token.info[
|
150
|
-
token.info[
|
151
|
-
token.info[
|
152
|
-
token.info[
|
144
|
+
token.info['access_token'].should == 'test_access_token'
|
145
|
+
token.info['token_type'].should =~ /^bearer$/i
|
146
|
+
token.info['scope'].should == 'openid'
|
147
|
+
token.info['expires_in'].should == 98765
|
153
148
|
end
|
154
149
|
|
155
150
|
end
|
156
151
|
|
157
|
-
context
|
152
|
+
context 'with implicit grant' do
|
158
153
|
|
159
|
-
it
|
154
|
+
it 'gets the prompts for credentials used to authenticate implicit grant' do
|
160
155
|
subject.set_request_handler do |url, method, body, headers|
|
161
|
-
info = { :prompts => {:username => [
|
162
|
-
[200, Util.json(info), {
|
156
|
+
info = { :prompts => {:username => ['text', 'Username'], :password => ['password', 'Password']} }
|
157
|
+
[200, Util.json(info), {'content-type' => 'application/json'}]
|
163
158
|
end
|
164
159
|
result = subject.prompts
|
165
160
|
result.should_not be_empty
|
166
161
|
end
|
167
162
|
|
168
|
-
it
|
163
|
+
it 'raises a bad target error if no prompts are received' do
|
169
164
|
subject.set_request_handler do |url, method, body, headers|
|
170
|
-
[200, Util.json({}), {
|
165
|
+
[200, Util.json({}), {'content-type' => 'application/json'}]
|
171
166
|
end
|
172
167
|
expect { subject.prompts }.to raise_exception BadResponse
|
173
168
|
end
|
174
169
|
|
175
|
-
context
|
176
|
-
it
|
170
|
+
context '#implicit_grant_with_creds' do
|
171
|
+
it 'gets only an access token, no openid in scope' do
|
177
172
|
subject.set_request_handler do |url, method, body, headers|
|
178
|
-
headers[
|
179
|
-
headers[
|
180
|
-
url.should match
|
173
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
174
|
+
headers['accept'].should =~ /application\/json/
|
175
|
+
url.should match 'http://test.uaa.target/oauth/authorize'
|
181
176
|
(state = /state=([^&]+)/.match(url)[1]).should_not be_nil
|
182
177
|
method.should == :post
|
183
|
-
location =
|
184
|
-
|
178
|
+
location = 'https://uaa.cloudfoundry.com/redirect/test_client#' +
|
179
|
+
'access_token=test_access_token&token_type=bearer&' +
|
185
180
|
"expires_in=98765&scope=logs.read&state=#{state}"
|
186
|
-
[302, nil, {
|
181
|
+
[302, nil, {'content-type' => 'application/json', 'location' => location}]
|
187
182
|
end
|
188
183
|
|
189
|
-
expect(subject).to receive(:authorize_path_args).with(
|
190
|
-
subject.stub(:random_state).and_return(
|
191
|
-
subject.stub(:authorize_path_args).and_return(
|
184
|
+
expect(subject).to receive(:authorize_path_args).with('token', 'https://uaa.cloudfoundry.com/redirect/test_client', 'logs.read', anything)
|
185
|
+
subject.stub(:random_state).and_return('1234')
|
186
|
+
subject.stub(:authorize_path_args).and_return('/oauth/authorize?state=1234&scope=logs.read')
|
192
187
|
|
193
|
-
token = subject.implicit_grant_with_creds({:username =>
|
188
|
+
token = subject.implicit_grant_with_creds({:username => 'joe+admin', :password => "?joe's%password$@ "}, 'logs.read')
|
194
189
|
token.should be_an_instance_of TokenInfo
|
195
|
-
token.info[
|
196
|
-
token.info[
|
197
|
-
Util.arglist(token.info[
|
198
|
-
token.info[
|
190
|
+
token.info['access_token'].should == 'test_access_token'
|
191
|
+
token.info['token_type'].should =~ /^bearer$/i
|
192
|
+
Util.arglist(token.info['scope']).to_set.should == Util.arglist('logs.read').to_set
|
193
|
+
token.info['expires_in'].should == 98765
|
199
194
|
end
|
200
195
|
|
201
|
-
it
|
196
|
+
it 'also asks for an id_token if scope contains openid' do
|
202
197
|
subject.set_request_handler do |url, method, body, headers|
|
203
|
-
location =
|
204
|
-
|
205
|
-
|
206
|
-
[302, nil, {
|
198
|
+
location = 'https://uaa.cloudfoundry.com/redirect/test_client#' +
|
199
|
+
'access_token=test_access_token&id_token=test-id_token&token_type=bearer&' +
|
200
|
+
'expires_in=98765&scope=openid+logs.read&state=1234'
|
201
|
+
[302, nil, {'content-type' => 'application/json', 'location' => location}]
|
207
202
|
end
|
208
203
|
|
209
|
-
expect(subject).to receive(:authorize_path_args).with(
|
210
|
-
subject.stub(:random_state).and_return(
|
211
|
-
subject.implicit_grant_with_creds({:username =>
|
204
|
+
expect(subject).to receive(:authorize_path_args).with('token id_token', 'https://uaa.cloudfoundry.com/redirect/test_client', 'openid logs.read', anything)
|
205
|
+
subject.stub(:random_state).and_return('1234')
|
206
|
+
subject.implicit_grant_with_creds({:username => 'joe+admin', :password => "?joe's%password$@ "}, 'openid logs.read')
|
212
207
|
end
|
213
208
|
end
|
214
209
|
|
215
|
-
it
|
210
|
+
it 'rejects an access token with wrong state' do
|
216
211
|
subject.set_request_handler do |url, method, body, headers|
|
217
|
-
location =
|
218
|
-
|
219
|
-
|
220
|
-
[302, nil, {
|
212
|
+
location = 'https://uaa.cloudfoundry.com/redirect/test_client#' +
|
213
|
+
'access_token=test_access_token&token_type=bearer&' +
|
214
|
+
'expires_in=98765&scope=openid+logs.read&state=bad_state'
|
215
|
+
[302, nil, {'content-type' => 'application/json', 'location' => location}]
|
221
216
|
end
|
222
|
-
expect {token = subject.implicit_grant_with_creds(:username =>
|
217
|
+
expect {token = subject.implicit_grant_with_creds(:username => 'joe+admin',
|
223
218
|
:password => "?joe's%password$@ ")}.to raise_exception BadResponse
|
224
219
|
end
|
225
220
|
|
226
|
-
it
|
227
|
-
uri_parts = subject.implicit_uri(
|
221
|
+
it 'asks for an id_token with openid scope' do
|
222
|
+
uri_parts = subject.implicit_uri('http://call.back/uri_path', 'openid logs.read').split('?')
|
228
223
|
params = Util.decode_form(uri_parts[1])
|
229
|
-
params[
|
224
|
+
params['response_type'].should == 'token id_token'
|
230
225
|
end
|
231
226
|
|
232
227
|
it "only asks for token if scope isn't openid" do
|
233
|
-
uri_parts = subject.implicit_uri(
|
228
|
+
uri_parts = subject.implicit_uri('http://call.back/uri_path').split('?')
|
234
229
|
params = Util.decode_form(uri_parts[1])
|
235
|
-
params[
|
230
|
+
params['response_type'].should == 'token'
|
236
231
|
end
|
237
232
|
|
238
233
|
end
|
239
234
|
|
240
|
-
context
|
235
|
+
context 'with auth code grant' do
|
241
236
|
|
242
|
-
it
|
243
|
-
redir_uri =
|
244
|
-
uri_parts = subject.authcode_uri(redir_uri,
|
245
|
-
uri_parts[0].should ==
|
237
|
+
it 'gets the authcode uri to be sent to the user agent for an authcode' do
|
238
|
+
redir_uri = 'http://call.back/uri_path'
|
239
|
+
uri_parts = subject.authcode_uri(redir_uri, 'openid').split('?')
|
240
|
+
uri_parts[0].should == 'http://test.uaa.target/oauth/authorize'
|
246
241
|
params = Util.decode_form(uri_parts[1])
|
247
|
-
params[
|
248
|
-
params[
|
249
|
-
params[
|
250
|
-
params[
|
251
|
-
params[
|
242
|
+
params['response_type'].should == 'code'
|
243
|
+
params['client_id'].should == 'test_client'
|
244
|
+
params['scope'].should == 'openid'
|
245
|
+
params['redirect_uri'].should == redir_uri
|
246
|
+
params['state'].should_not be_nil
|
252
247
|
end
|
253
248
|
|
254
|
-
it
|
249
|
+
it 'gets an access token with an authorization code' do
|
255
250
|
subject.set_request_handler do |url, method, body, headers|
|
256
|
-
headers[
|
257
|
-
headers[
|
251
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
252
|
+
headers['accept'].should =~ /application\/json/
|
258
253
|
# TODO check basic auth header
|
259
|
-
url.should match
|
254
|
+
url.should match 'http://test.uaa.target/oauth/token'
|
260
255
|
method.should == :post
|
261
|
-
reply = {:access_token =>
|
262
|
-
:scope =>
|
263
|
-
[200, Util.json(reply), {
|
256
|
+
reply = {:access_token => 'test_access_token', :token_type => 'BEARER',
|
257
|
+
:scope => 'openid', :expires_in => 98765}
|
258
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
264
259
|
end
|
265
|
-
cburi =
|
260
|
+
cburi = 'http://call.back/uri_path'
|
266
261
|
redir_uri = subject.authcode_uri(cburi)
|
267
262
|
state = /state=([^&]+)/.match(redir_uri)[1]
|
268
263
|
reply_query = "state=#{state}&code=kz8%2F5gQZ2pc%3D"
|
269
264
|
token = subject.authcode_grant(redir_uri, reply_query)
|
270
265
|
token.should be_an_instance_of TokenInfo
|
271
|
-
token.info[
|
272
|
-
token.info[
|
273
|
-
token.info[
|
274
|
-
token.info[
|
266
|
+
token.info['access_token'].should == 'test_access_token'
|
267
|
+
token.info['token_type'].should =~ /^bearer$/i
|
268
|
+
token.info['scope'].should == 'openid'
|
269
|
+
token.info['expires_in'].should == 98765
|
275
270
|
end
|
276
271
|
|
277
272
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cf-uaa-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Syer
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2016-
|
15
|
+
date: 2016-12-15 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: multi_json
|
@@ -28,6 +28,20 @@ dependencies:
|
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: httpclient
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - "~>"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.8.2.4
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 2.8.2.4
|
31
45
|
- !ruby/object:Gem::Dependency
|
32
46
|
name: bundler
|
33
47
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,7 +168,6 @@ files:
|
|
154
168
|
- lib/uaa.rb
|
155
169
|
- lib/uaa/http.rb
|
156
170
|
- lib/uaa/info.rb
|
157
|
-
- lib/uaa/proxy_options.rb
|
158
171
|
- lib/uaa/scim.rb
|
159
172
|
- lib/uaa/token_coder.rb
|
160
173
|
- lib/uaa/token_issuer.rb
|
data/lib/uaa/proxy_options.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Cloud Foundry
|
3
|
-
# Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
|
4
|
-
#
|
5
|
-
# This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
6
|
-
# You may not use this product except in compliance with the License.
|
7
|
-
#
|
8
|
-
# This product includes a number of subcomponents with
|
9
|
-
# separate copyright notices and license terms. Your use of these
|
10
|
-
# subcomponents is subject to the terms and conditions of the
|
11
|
-
# subcomponent's license, as noted in the LICENSE file.
|
12
|
-
#++
|
13
|
-
|
14
|
-
module CF::UAA
|
15
|
-
module ProxyOptions
|
16
|
-
def proxy_options_for(uri)
|
17
|
-
ssl = uri.is_a?(URI::HTTPS)
|
18
|
-
proxy_to_use = (ssl ? https_proxy : http_proxy)
|
19
|
-
|
20
|
-
if proxy_to_use
|
21
|
-
proxy_to_use = "proto://#{proxy_to_use}" unless proxy_to_use =~ /:\/\//
|
22
|
-
proxy_uri = URI.parse(proxy_to_use)
|
23
|
-
proxy_user, proxy_password = proxy_uri.userinfo.split(/:/) if proxy_uri.userinfo
|
24
|
-
[proxy_uri.host, proxy_uri.port, proxy_user, proxy_password]
|
25
|
-
else
|
26
|
-
[]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|