pinch 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/Rakefile +1 -1
  2. data/lib/pinch.rb +51 -38
  3. data/spec/pinch_spec.rb +48 -26
  4. metadata +56 -31
data/Rakefile CHANGED
@@ -5,5 +5,5 @@ task :default => :test
5
5
  Rake::TestTask.new(:test) do |t|
6
6
  t.test_files = FileList['spec/*_spec.rb']
7
7
  t.ruby_opts = ['-rubygems'] if defined? Gem
8
- t.ruby_opts << '-I. -w'
8
+ t.ruby_opts << '-I.'
9
9
  end
data/lib/pinch.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # encoding: utf-8
2
- require 'net/http'
2
+ require 'net/https'
3
3
  require 'zlib'
4
4
 
5
5
  # @author Peter Hellberg
6
6
  # @author Edward Patel
7
7
  class Pinch
8
- VERSION = "0.0.7"
8
+ VERSION = "0.0.8"
9
9
 
10
10
  attr_reader :uri
11
11
 
@@ -82,38 +82,32 @@ private
82
82
 
83
83
  raise Errno::ENOENT if file_headers[file_name].nil?
84
84
 
85
- req = Net::HTTP::Get.new(uri.path)
86
85
  padding = 16
87
86
 
88
- req.set_range(file_headers[file_name][16],
89
- 30 +
90
- file_headers[file_name][16] +
91
- file_headers[file_name][8] +
92
- file_headers[file_name][10] +
93
- file_headers[file_name][11] +
94
- file_headers[file_name][12] +
95
- padding)
96
-
97
- res = Net::HTTP.start(uri.host, uri.port) do |http|
98
- http.request(req)
99
- end
87
+ offset_start = file_headers[file_name][16]
88
+ offset_end = 30 + padding +
89
+ file_headers[file_name][16] +
90
+ file_headers[file_name][8] +
91
+ file_headers[file_name][10] +
92
+ file_headers[file_name][11] +
93
+ file_headers[file_name][12]
100
94
 
95
+ response = fetch_data(offset_start, offset_end)
101
96
 
102
- local_file_header = res.body.unpack('VvvvvvVVVvv')
103
- file_data = res.body[30+local_file_header[9]+local_file_header[10]..-1]
97
+ local_file_header = response.body.unpack('VvvvvvVVVvv')
98
+ file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
104
99
 
105
100
  if local_file_header[3] == 0
106
101
  # Uncompressed file
107
102
  offset = 30+local_file_header[9]+local_file_header[10]
108
- res.body[offset..(offset+local_file_header[8]-1)]
103
+ response.body[offset..(offset+local_file_header[8]-1)]
109
104
  else
110
105
  # Compressed file
111
- file_data = res.body[30+local_file_header[9]+local_file_header[10]..-1]
106
+ file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
112
107
  Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(file_data)
113
108
  end
114
109
  end
115
110
 
116
-
117
111
  def file_headers
118
112
  @file_headers ||= begin
119
113
  raise RuntimeError, "Couldn’t find the central directory." if central_directory.nil?
@@ -155,19 +149,15 @@ private
155
149
  #16 uint32 relativeOffsetOfLocalFileHeader
156
150
 
157
151
  @central_directory ||= begin
158
- req = Net::HTTP::Get.new(uri.path)
159
- req.set_range(end_of_central_directory_record[5],
160
- end_of_central_directory_record[5] +
161
- end_of_central_directory_record[4])
152
+ offset_start = end_of_central_directory_record[5]
153
+ offset_end = end_of_central_directory_record[5] + end_of_central_directory_record[4]
162
154
 
163
- res = Net::HTTP.start(uri.host, uri.port) { |http|
164
- http.request(req)
165
- }
155
+ response = fetch_data(offset_start, offset_end)
166
156
 
167
- if [200, 206].include?(res.code)
168
- raise RuntimeError, "Couldn’t find the ZIP file (HTTP: #{res.code})"
157
+ if [200, 206].include?(response.code)
158
+ raise RuntimeError, "Couldn’t find the ZIP file (HTTP: #{response.code})"
169
159
  else
170
- res.body
160
+ response.body
171
161
  end
172
162
  end
173
163
  end
@@ -183,27 +173,50 @@ private
183
173
 
184
174
  @end_of_central_directory_record ||= begin
185
175
  # Retrieve a 4k of data from the end of the zip file
186
- request = Net::HTTP::Get.new(uri.path)
187
- offset = content_length >= 4096 ? content_length-4096 : 0
176
+ offset = content_length >= 4096 ? content_length-4096 : 0
188
177
 
189
- request.set_range(offset, content_length)
190
-
191
- response = Net::HTTP.start(uri.host, uri.port) do |http|
192
- http.request(request)
193
- end
178
+ response = fetch_data(offset, content_length)
194
179
 
195
180
  # Unpack the body into a hex string
196
181
  hex = response.body.unpack("H*")[0]
197
182
 
198
183
  # Split on the end record signature, and unpack the last one
199
184
  [hex.split("504b0506").last].pack("H*").unpack("vvvvVVv")
185
+
186
+ # Skipping the hex unpack and splitting on
187
+ # PK\x05\x06 instead was for some reason slower.
200
188
  end
201
189
  end
202
190
 
191
+ ##
192
+ # Get range of data from URL
193
+ def fetch_data(offset_start, offset_end)
194
+ request = Net::HTTP::Get.new(@uri.request_uri)
195
+ request.set_range(offset_start, offset_end)
196
+
197
+ prepared_connection.request(request)
198
+ end
199
+
200
+ ##
203
201
  # Retrieve the content length of the file
204
202
  def content_length
205
- @content_length ||= Net::HTTP.start(@uri.host, @uri.port) { |http|
203
+ @content_length ||= prepared_connection.start { |http|
206
204
  http.head(@uri.path)
207
205
  }['Content-Length'].to_i
208
206
  end
207
+
208
+ ##
209
+ # Prepare the connection and GET request
210
+ def prepared_connection
211
+ @prepared_connection ||= begin
212
+ http = Net::HTTP.new(@uri.host, @uri.port)
213
+
214
+ if @uri.is_a?(URI::HTTPS)
215
+ http.use_ssl = true
216
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
217
+ end
218
+
219
+ http
220
+ end
221
+ end
209
222
  end
data/spec/pinch_spec.rb CHANGED
@@ -1,33 +1,40 @@
1
1
  require 'minitest/pride'
2
2
  require 'minitest/autorun'
3
3
  require 'minitest/spec'
4
+ require 'vcr'
5
+
6
+ VCR.config do |c|
7
+ c.allow_http_connections_when_no_cassette = true
8
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
9
+ c.stub_with :fakeweb
10
+ end
4
11
 
5
12
  require File.dirname(__FILE__) + '/../lib/pinch'
6
13
 
7
14
  describe Pinch do
8
15
  describe "when calling get on a compressed zip file" do
9
- before do
10
- @url = 'http://ftp.sunet.se/pub/lang/smalltalk/Squeak/current_stable/Squeak3.8-6665-full.zip'
11
- @file = 'ReadMe.txt'
12
- end
13
-
14
16
  it "should return the contents of the file" do
15
- data = Pinch.get @url, @file
16
- data.must_match(/Morphic graphics architecture/)
17
- data.size.must_equal 26431
17
+ VCR.use_cassette('squeak') do
18
+ @url = 'http://ftp.sunet.se/pub/lang/smalltalk/Squeak/current_stable/Squeak3.8-6665-full.zip'
19
+ @file = 'ReadMe.txt'
20
+
21
+ data = Pinch.get @url, @file
22
+ data.must_match(/Morphic graphics architecture/)
23
+ data.size.must_equal 26431
24
+ end
18
25
  end
19
26
  end
20
27
 
21
28
  describe "when calling get on a zip file that is not compressed" do
22
- before do
23
- @url = 'http://memention.com/ericjohnson-canabalt-ios-ef43b7d.zip'
24
- @file = 'ericjohnson-canabalt-ios-ef43b7d/README.TXT'
25
- end
26
-
27
29
  it "should return the contents of the file" do
28
- data = Pinch.get @url, @file
29
- data.must_match(/Daring Escape/)
30
- data.size.must_equal 2288
30
+ VCR.use_cassette('canabalt') do
31
+ @url = 'http://memention.com/ericjohnson-canabalt-ios-ef43b7d.zip'
32
+ @file = 'ericjohnson-canabalt-ios-ef43b7d/README.TXT'
33
+
34
+ data = Pinch.get @url, @file
35
+ data.must_match(/Daring Escape/)
36
+ data.size.must_equal 2288
37
+ end
31
38
  end
32
39
  end
33
40
 
@@ -35,27 +42,42 @@ describe Pinch do
35
42
  before do
36
43
  @url = 'http://peterhellberg.github.com/pinch/test.zip'
37
44
  @file = 'data.json'
45
+ @data = "{\"gem\":\"pinch\",\"authors\":[\"Peter Hellberg\",\"Edward Patel\"],\"github_url\":\"https://github.com/peterhellberg/pinch\"}\n"
38
46
  end
39
47
 
40
48
  it "should retrieve the contents of the file data.json" do
41
- data = Pinch.get @url, @file
42
- data.must_equal "{\"gem\":\"pinch\",\"authors\":[\"Peter Hellberg\",\"Edward Patel\"],\"github_url\":\"https://github.com/peterhellberg/pinch\"}\n"
43
- data.size.must_equal 114
49
+ VCR.use_cassette('test_zip') do
50
+ data = Pinch.get @url, @file
51
+ data.must_equal @data
52
+ data.size.must_equal 114
53
+ end
54
+ end
55
+
56
+ it "should retrieve the contents of the file data.json when passed a HTTPS url" do
57
+ VCR.use_cassette('ssl_test') do
58
+ @url = 'https://dl.dropbox.com/u/2230186/pinch_test.zip'
59
+
60
+ data = Pinch.get @url, @file
61
+ data.must_equal @data
62
+ data.size.must_equal 114
63
+ end
44
64
  end
45
65
 
46
66
  it "should contain three files" do
47
- Pinch.file_list(@url).size.must_equal 3
67
+ VCR.use_cassette('test_file_count') do
68
+ Pinch.file_list(@url).size.must_equal 3
69
+ end
48
70
  end
49
71
  end
50
72
 
51
73
  describe "#file_list" do
52
- before do
53
- @url = 'http://memention.com/ericjohnson-canabalt-ios-ef43b7d.zip'
54
- end
55
-
56
74
  it "should return a list with all the file names in the zip" do
57
- file_list = Pinch.file_list(@url)
58
- file_list.size.must_equal 491
75
+ VCR.use_cassette('file_list') do
76
+ @url = 'http://memention.com/ericjohnson-canabalt-ios-ef43b7d.zip'
77
+
78
+ file_list = Pinch.file_list(@url)
79
+ file_list.size.must_equal 491
80
+ end
59
81
  end
60
82
  end
61
83
  end
metadata CHANGED
@@ -1,38 +1,62 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pinch
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.7
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.0.8
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Peter Hellberg
9
9
  - Edward Patel
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-07-05 00:00:00.000000000 +02:00
13
+
14
+ date: 2011-07-07 00:00:00 +02:00
14
15
  default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
17
18
  name: minitest
18
- requirement: &2152860800 !ruby/object:Gem::Requirement
19
+ prerelease: false
20
+ requirement: &id001 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "0"
26
+ type: :development
27
+ version_requirements: *id001
28
+ - !ruby/object:Gem::Dependency
29
+ name: fakeweb
30
+ prerelease: false
31
+ requirement: &id002 !ruby/object:Gem::Requirement
19
32
  none: false
20
- requirements:
21
- - - ! '>='
22
- - !ruby/object:Gem::Version
23
- version: '0'
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: "0"
24
37
  type: :development
38
+ version_requirements: *id002
39
+ - !ruby/object:Gem::Dependency
40
+ name: vcr
25
41
  prerelease: false
26
- version_requirements: *2152860800
27
- description: Pinch makes it possible to download a specific file from within a ZIP
28
- file over HTTP 1.1.
42
+ requirement: &id003 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id003
50
+ description: Pinch makes it possible to download a specific file from within a ZIP file over HTTP 1.1.
29
51
  email: peter@c7.se
30
52
  executables: []
53
+
31
54
  extensions: []
32
- extra_rdoc_files:
55
+
56
+ extra_rdoc_files:
33
57
  - README.rdoc
34
58
  - MIT-LICENSE
35
- files:
59
+ files:
36
60
  - lib/pinch.rb
37
61
  - MIT-LICENSE
38
62
  - README.rdoc
@@ -40,34 +64,35 @@ files:
40
64
  - .gemtest
41
65
  - spec/pinch_spec.rb
42
66
  has_rdoc: true
43
- homepage: https://github.com/peterhellberg/pinch
44
- licenses:
67
+ homepage: http://peterhellberg.github.com/pinch/
68
+ licenses:
45
69
  - MIT-LICENSE
46
70
  post_install_message:
47
- rdoc_options:
71
+ rdoc_options:
48
72
  - --main
49
73
  - README.rdoc
50
74
  - --charset=UTF-8
51
- require_paths:
75
+ require_paths:
52
76
  - lib
53
77
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
78
+ required_ruby_version: !ruby/object:Gem::Requirement
55
79
  none: false
56
- requirements:
57
- - - ! '>='
58
- - !ruby/object:Gem::Version
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
59
83
  version: 1.8.7
60
- required_rubygems_version: !ruby/object:Gem::Requirement
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
85
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
66
90
  requirements: []
91
+
67
92
  rubyforge_project:
68
93
  rubygems_version: 1.6.2
69
94
  signing_key:
70
95
  specification_version: 3
71
96
  summary: Retrieve a file from inside a zip file, over the network!
72
- test_files:
97
+ test_files:
73
98
  - spec/pinch_spec.rb