downspout 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.8
1
+ 0.2.9
@@ -48,22 +48,20 @@ module Downspout
48
48
  Utility method for validating a URL without initiating a download
49
49
  =end
50
50
  def self.viable_url?( url_string )
51
- $logger.info("downspout | supported_protocol? | URL : #{url_string} ")
52
-
53
- # remove user/password prefix if provided
54
- clean_url = self.extract_credentials_from_url!( url_string )
51
+ $logger.info("downspout | viable_url? | URL : #{url_string} ")
55
52
 
56
53
  begin
54
+ # remove user/password prefix if provided
55
+ clean_url = self.extract_credentials_from_url!( url_string )
56
+
57
57
  uri = URI.parse( clean_url )
58
58
  rescue URI::InvalidURIError
59
- $logger.warn("downspout | supported_protocol? | The format of the url is not valid : #{url_string}")
59
+ $logger.warn("downspout | viable_url? | The format of the url is not valid : #{url_string}")
60
60
  return false
61
61
  end
62
62
 
63
63
  return false unless self.supported_protocol?( uri.scheme )
64
64
 
65
- # TODO : do more in-depth checks on URL validity
66
-
67
65
  return true
68
66
  end
69
67
 
@@ -104,24 +102,28 @@ module Downspout
104
102
  end
105
103
 
106
104
  def self.extract_credentials_from_url!( some_url )
107
- the_uri = URI.parse( some_url )
108
105
 
109
- if the_uri.userinfo.nil? then
110
- return some_url
106
+ begin
107
+ some_uri = URI::parse( some_url )
108
+ rescue NoMethodError => e
109
+ # convert to Invalid URI as that's the more pertinent issue
110
+ raise URI::InvalidURIError, e.to_s
111
111
  end
112
112
 
113
- begin
114
- Downspout::Config.add_credential( :scheme => the_uri.scheme,
115
- :host => the_uri.host,
116
- :user_name => the_uri.user,
117
- :pass_word => the_uri.password
118
- )
119
- ensure
120
- the_uri.user = nil
121
- the_uri.password = nil
113
+ cred = Downspout::Credential.create_from_uri( some_uri )
114
+
115
+ if cred.nil? then
116
+ return some_url
122
117
  end
123
-
124
- return the_uri.to_s
118
+
119
+ Downspout::Config.add_credential( cred )
120
+
121
+ # zero out the user info
122
+ some_uri.user = nil
123
+ some_uri.password = nil
124
+
125
+ # return sanitized URL string
126
+ return some_uri.to_s
125
127
  end
126
128
 
127
129
  end
@@ -83,14 +83,21 @@ module Downspout
83
83
  end
84
84
 
85
85
  def self.add_credential( options = nil )
86
- return nil unless options && options.respond_to?(:keys)
87
- options = {:scheme => 'ftp'}.merge!( options )
86
+ return nil unless options
88
87
 
89
- c = Credential.new( options )
88
+ if (options.class == Downspout::Credential) then
89
+ c = options
90
+ else
91
+ return nil unless options.respond_to?(:keys)
92
+
93
+ options = {:scheme => 'ftp'}.merge!( options ) # defaults to FTP
90
94
 
95
+ c = Credential.new( options )
96
+ end
97
+
91
98
  $logger.debug("downspout | config | add_credential | #{c.host}, #{c.user_name}, #{c.scheme} ")
92
99
 
93
- @@credentials << c
100
+ @@credentials << c
94
101
 
95
102
  return c
96
103
  end
@@ -15,6 +15,36 @@ module Downspout
15
15
  end
16
16
  end
17
17
 
18
+ def self.create_from_url( some_url )
19
+ cred_hash = {}
20
+
21
+ begin
22
+ some_uri = URI::parse( some_url )
23
+ rescue NoMethodError => e
24
+ # convert to Invalid URI as that's the more pertinent issue
25
+ raise URI::InvalidURIError, e.to_s
26
+ end
27
+
28
+ return Credential.create_from_uri( some_uri )
29
+ end
30
+
31
+ def self.create_from_uri( some_uri )
32
+
33
+ if some_uri.userinfo.nil? then
34
+ return nil
35
+ end
36
+
37
+ cred_hash = {}
38
+ cred_hash[:scheme] = some_uri.scheme
39
+ cred_hash[:host] = some_uri.host
40
+ cred_hash[:port] = some_uri.port
41
+ cred_hash[:user_name] = some_uri.user
42
+ cred_hash[:pass_word] = some_uri.password
43
+
44
+ cred = Credential.new( cred_hash )
45
+
46
+ return cred
47
+ end
18
48
  end
19
49
 
20
50
  end
@@ -167,13 +167,23 @@ module Downspout
167
167
 
168
168
  # look up the credentials for this host
169
169
  cred = Downspout::Config.credentials.select{|c| c.scheme == 'ftp' }.select{ |c| c.host == @uri.host }.first
170
+
170
171
  if cred.nil? then
171
- $logger.warn("downspout | downloader | net_ftp_download | No credentials found for '#{@uri.host}'.")
172
- # proceed anyway - slight possibility it's an un-authorized FTP account...
172
+ $logger.warn("downspout | downloader | net_ftp_download | No established credentials found for '#{@uri.host}'.")
173
+
174
+ # attempt to extract credential from the URL
175
+ cred = Downspout::Credential.create_from_url( @url )
173
176
  else
174
177
  $logger.debug("downspout | downloader | net_ftp_download | Loaded credentials for #{cred.host} ...")
175
178
  end
176
179
 
180
+ if cred.nil? then
181
+ $logger.warn("downspout | downloader | net_ftp_download | No embedded credentials found in URL.")
182
+ # proceed anyway - slight possibility it's an un-authorized FTP account...
183
+ else
184
+ $logger.warn("downspout | downloader | net_ftp_download | Using embedded credentials found in URL with user: #{cred.user_name}.")
185
+ end
186
+
177
187
  begin
178
188
  ftp = Net::FTP.open( @uri.host ) do |ftp|
179
189
  ftp.login( cred.user_name, cred.pass_word ) unless cred.nil?
@@ -240,7 +250,12 @@ module Downspout
240
250
  raise Downspout::ExcessiveRedirects, 'HTTP redirect too deep'
241
251
  end
242
252
 
243
- u = URI.parse( url_str )
253
+ begin
254
+ u = URI.parse( url_str )
255
+ rescue NoMethodError => e
256
+ # convert to Invalid URI as that's the more pertinent issue
257
+ raise URI::InvalidURIError, e.to_s
258
+ end
244
259
 
245
260
  http = Net::HTTP.new( u.host, u.port )
246
261
 
@@ -4,51 +4,12 @@ class FocusedTest < Test::Unit::TestCase
4
4
  context "Downspout" do
5
5
  context "Focus" do
6
6
  setup do
7
- @expected_url = "https://download.github.com/rails-rails-v2.3.11-0-gb0c3d45.tar.gz"
8
- @header_str = "HTTP/1.1 302 Found
9
- Server: nginx/0.7.67
10
- Date: Mon, 18 Apr 2011 01:53:16 GMT
11
- Content-Type: text/html; charset=utf-8
12
- Connection: keep-alive
13
- Status: 302 Found
14
- Location: https://nodeload.github.com/rails/rails/tarball/v2.3.11
15
- X-Runtime: 3ms
16
- Content-Length: 121
17
- Set-Cookie: _gh_sess=BAh7BzoRbG9jYWxlX2d1ZXNzMCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--719def2ab2d99283383e374327fcdbb716c45c12; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly
18
- Cache-Control: no-cache
19
- Strict-Transport-Security: max-age=2592000
20
-
21
- HTTP/1.1 302 Moved Temporarily
22
- Server: nginx/0.7.67
23
- Date: Mon, 18 Apr 2011 01:53:17 GMT
24
- Transfer-Encoding: chunked
25
- Connection: keep-alive
26
- Location: https://download.github.com/rails-rails-v2.3.11-0-gb0c3d45.tar.gz
27
-
28
- HTTP/1.1 200 OK
29
- Server: nginx/0.7.67
30
- Date: Mon, 18 Apr 2011 01:53:17 GMT
31
- Content-Type: application/octet-stream
32
- Content-Length: 3416081
33
- Last-Modified: Mon, 18 Apr 2011 01:45:25 GMT
34
- Connection: keep-alive
35
- Accept-Ranges: bytes"
7
+ @test_string = "foo"
36
8
  end
37
9
 
38
- should "grep last location header" do
39
- last_location = @header_str.scan(/Location\:\s?(.*)\W/).last.first
40
-
41
- assert_equal @expected_url, last_location
10
+ should "behave properly" do
11
+ assert_equal @test_string, "foo"
42
12
  end
43
-
44
- should "match last_location method" do
45
- @obj = Downspout::Downloader.new( :url => "http://bad.url/path" )
46
- last_location = @obj.send('curb_last_location', @header_str )
47
-
48
- assert_equal String, last_location.class
49
- assert_equal @expected_url, last_location
50
- end
51
-
52
13
  end
53
14
  end
54
15
  end
@@ -114,11 +114,27 @@ class DownspoutTest < Test::Unit::TestCase
114
114
  end
115
115
 
116
116
  should "be accepted with FTP protocol containing user & password" do
117
+ num = Downspout::Config.credentials.size
118
+
117
119
  assert Downspout.viable_url?( "ftp://uzer:passw0rd@host.domain.tld/resource/file.format" )
120
+
121
+ assert_equal num + 1, Downspout::Config.credentials.size
122
+
123
+ assert_equal 'host.domain.tld', Downspout::Config.credentials.last.host
118
124
  end
119
125
 
120
126
  end
121
127
  end
122
128
 
129
+ should "clean URLs with user & password via extract credentials" do
130
+ test_url = "ftp://uzer:passw0rd@host.domain.tld/resource/file.format"
131
+
132
+ new_url = Downspout.extract_credentials_from_url!( test_url )
133
+
134
+ assert !(new_url == test_url)
135
+ assert_equal URI::parse( test_url ).host, URI::parse( new_url ).host
136
+ assert_equal URI::parse( test_url ).path, URI::parse( new_url ).path
137
+ end
138
+
123
139
  end
124
140
  end
@@ -4,28 +4,75 @@ class CredentialTest < Test::Unit::TestCase
4
4
  context "Downspout" do
5
5
  context "Credential" do
6
6
 
7
- should "respond to scheme" do
8
- assert Downspout::Credential.new.respond_to?(:scheme)
7
+ context "object" do
8
+
9
+ should "respond to scheme" do
10
+ assert Downspout::Credential.new.respond_to?(:scheme)
11
+ end
12
+
13
+ should "respond to host" do
14
+ assert Downspout::Credential.new.respond_to?(:host)
15
+ end
16
+
17
+ should "respond to port" do
18
+ assert Downspout::Credential.new.respond_to?(:port)
19
+ end
20
+
21
+ should "respond to user_name" do
22
+ assert Downspout::Credential.new.respond_to?(:user_name)
23
+ end
24
+
25
+ should "respond to pass_word" do
26
+ assert Downspout::Credential.new.respond_to?(:pass_word)
27
+ end
28
+
9
29
  end
10
30
 
11
- should "respond to host" do
12
- assert Downspout::Credential.new.respond_to?(:host)
13
- end
14
-
15
- should "respond to port" do
16
- assert Downspout::Credential.new.respond_to?(:port)
17
- end
18
31
 
19
- should "respond to user_name" do
20
- assert Downspout::Credential.new.respond_to?(:user_name)
32
+ context "created from URL" do
33
+
34
+ should "return nil if no credential extractable from otherwise valid URL" do
35
+ @my_url = "ftp://ftp-test.domain.tld/path/2011-04-01_13-42-52/file.ext"
36
+
37
+ @no_cred = Downspout::Credential.create_from_url( @my_url )
38
+
39
+ assert_nil @no_cred
40
+ end
41
+
42
+ should "create credential from URL with embedded info" do
43
+ @my_url = "ftp://test-name:test-secret@ftp-test.domain.tld/path/2011-04-01_13-42-52/file.ext"
44
+
45
+ @my_cred = Downspout::Credential.create_from_url( @my_url )
46
+
47
+ assert_not_nil @my_cred
48
+
49
+ assert_equal Downspout::Credential, @my_cred.class
50
+
51
+ assert_equal 'ftp', @my_cred.scheme
52
+ assert_equal 'ftp-test.domain.tld', @my_cred.host
53
+ assert_equal 21, @my_cred.port
54
+ assert_equal 'test-name', @my_cred.user_name
55
+ assert_equal 'test-secret', @my_cred.pass_word
56
+ end
57
+
58
+ should "raise error when parsing invalid URL [partially encoded]" do
59
+ @bad_url = "ftp:%20%20test-name:test-secret@ftp-test.domain.tld/path/2011-04-01_13-42-52/file.ext"
60
+
61
+ assert_raise URI::InvalidURIError do
62
+ @bad_cred = Downspout::Credential.create_from_url( @bad_url )
63
+ end
64
+ end
65
+
66
+ should "raise error when parsing invalid URL [inserted space]" do
67
+ @bad_url = "ft p://test-name:test-secret@ftp-test.domain.tld/path/2011-04-01_13-42-52/file.ext"
68
+
69
+ assert_raise URI::InvalidURIError do
70
+ @bad_cred = Downspout::Credential.create_from_url( @bad_url )
71
+ end
72
+ end
73
+
21
74
  end
22
-
23
- should "respond to pass_word" do
24
- assert Downspout::Credential.new.respond_to?(:pass_word)
25
- end
26
-
27
75
  end
28
-
29
76
  end
30
77
 
31
78
  end
@@ -243,4 +243,51 @@ class DownloaderTest < Test::Unit::TestCase
243
243
 
244
244
  end
245
245
 
246
+ context "last location for curb redirects" do
247
+ setup do
248
+ @expected_url = "https://download.github.com/rails-rails-v2.3.11-0-gb0c3d45.tar.gz"
249
+ @header_str = "HTTP/1.1 302 Found
250
+ Server: nginx/0.7.67
251
+ Date: Mon, 18 Apr 2011 01:53:16 GMT
252
+ Content-Type: text/html; charset=utf-8
253
+ Connection: keep-alive
254
+ Status: 302 Found
255
+ Location: https://nodeload.github.com/rails/rails/tarball/v2.3.11
256
+ X-Runtime: 3ms
257
+ Content-Length: 121
258
+ Cache-Control: no-cache
259
+ Strict-Transport-Security: max-age=2592000
260
+
261
+ HTTP/1.1 302 Moved Temporarily
262
+ Server: nginx/0.7.67
263
+ Date: Mon, 18 Apr 2011 01:53:17 GMT
264
+ Transfer-Encoding: chunked
265
+ Connection: keep-alive
266
+ Location: https://download.github.com/rails-rails-v2.3.11-0-gb0c3d45.tar.gz
267
+
268
+ HTTP/1.1 200 OK
269
+ Server: nginx/0.7.67
270
+ Date: Mon, 18 Apr 2011 01:53:17 GMT
271
+ Content-Type: application/octet-stream
272
+ Content-Length: 3416081
273
+ Last-Modified: Mon, 18 Apr 2011 01:45:25 GMT
274
+ Connection: keep-alive
275
+ Accept-Ranges: bytes"
276
+ end
277
+
278
+ should "grep last location header" do
279
+ last_location = @header_str.scan(/Location\:\s?(.*)\W/).last.first
280
+
281
+ assert_equal @expected_url, last_location
282
+ end
283
+
284
+ should "match last_location method" do
285
+ @obj = Downspout::Downloader.new( :url => "http://bad.url/path" )
286
+ last_location = @obj.send('curb_last_location', @header_str )
287
+
288
+ assert_equal String, last_location.class
289
+ assert_equal @expected_url, last_location
290
+ end
291
+ end
292
+
246
293
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: downspout
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 8
10
- version: 0.2.8
9
+ - 9
10
+ version: 0.2.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Phi.Sanders
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-17 00:00:00 -04:00
18
+ date: 2011-04-27 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency