pinch 0.0.7 → 0.0.8

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.
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