raca 0.4.2 → 0.4.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 708a253f4ed2a4a4698ad10a9bdf324d7ce10621
4
- data.tar.gz: 4a2b677bfd024e010b5c65f3d4e33e910f60c843
3
+ metadata.gz: afe99d603e6ba54f7b49a0647a5b41fc200a48cd
4
+ data.tar.gz: e27360551bbe68b0e280956b6b5120043ede60ed
5
5
  SHA512:
6
- metadata.gz: 9bb93f27145cc61c1c07978b412015b6258ed1134c6fe21f8b61bb2a5f036b8fd3f9a96e3323c85ebaefe2460d30aca8c8f1ad72fa8ae1ab21b3d82f91a35c99
7
- data.tar.gz: c5ec178d8f6468a1020d6478ebc73e5611e193eae83fe1c2e27f022f4e70058501fe32f5197402e659215a11ebc37e03920fc2475f3293108540b5f788f6cd25
6
+ metadata.gz: 24db05708c37b8fa0d2c0a49bfd19d1a75c8609a9c3c5e7fad889fbee0ccec8bfac8bcc5bdf1cae60be8bb28db4d3e9997afaeeada507e894fbc7492e7902aa8
7
+ data.tar.gz: ede623eb08d1fcb150d23231f853eee503c5401dedbbd7ae8cbbc813f8f3461c044d3ca6313cd8b71c8d86ddfc320b54b6a34bd2f289be87e517068f14d4ddc0
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ v0.4.3 (12th September 2015)
2
+ * Use less memory when uploading large files (> 5Gb) to cloud files
3
+ * Allow a pre-computed ETag header to be provided when uploading to cloud files
4
+
1
5
  v0.4.2 (19th July 2015)
2
6
  * Large files (> 5Gb) that are uploaded to cloud files are broken into 4Gb
3
7
  chunks instead of 100Mb.
@@ -1,6 +1,7 @@
1
1
  require 'digest/md5'
2
2
  require 'openssl'
3
3
  require 'uri'
4
+ require 'raca/windowed_io'
4
5
 
5
6
  module Raca
6
7
 
@@ -32,15 +33,14 @@ module Raca
32
33
  # manually specify content type, content disposition, CORS headers, etc.
33
34
  #
34
35
  def upload(key, data_or_path, headers = {})
35
- case data_or_path
36
- when StringIO, File
36
+ if data_or_path.respond_to?(:read) && data_or_path.respond_to?(:size)
37
37
  upload_io(key, data_or_path, data_or_path.size, headers)
38
- when String
39
- File.open(data_or_path, "rb") do |io|
38
+ elsif !File.file?(data_or_path.to_s)
39
+ raise ArgumentError, "data_or_path must be an IO with data or filename string"
40
+ else
41
+ File.open(data_or_path.to_s, "rb") do |io|
40
42
  upload_io(key, io, io.stat.size, headers)
41
43
  end
42
- else
43
- raise ArgumentError, "data_or_path must be an IO with data or filename string"
44
44
  end
45
45
  end
46
46
 
@@ -276,7 +276,7 @@ module Raca
276
276
  if io.respond_to?(:path)
277
277
  headers['Content-Type'] ||= extension_content_type(io.path)
278
278
  end
279
- headers['ETag'] = md5_io(io)
279
+ headers['ETag'] ||= md5_io(io)
280
280
  headers['Content-Type'] ||= "application/octet-stream"
281
281
  if content_type_needs_cors(key)
282
282
  headers['Access-Control-Allow-Origin'] = "*"
@@ -292,9 +292,8 @@ module Raca
292
292
  while segments.size < segment_count
293
293
  start_pos = 0 + (LARGE_FILE_SEGMENT_SIZE * segments.size)
294
294
  segment_key = "%s.%03d" % [key, segments.size]
295
- io.seek(start_pos)
296
- segment_io = StringIO.new(io.read(LARGE_FILE_SEGMENT_SIZE))
297
- etag = upload_io_standard(segment_key, segment_io, segment_io.size, headers)
295
+ segment_io = WindowedIO.new(io, start_pos, LARGE_FILE_SEGMENT_SIZE)
296
+ etag = upload_io_standard(segment_key, segment_io, segment_io.size, headers.reject { |k,_v| k == "ETag"})
298
297
  segments << {path: "#{@container_name}/#{segment_key}", etag: etag, size_bytes: segment_io.size}
299
298
  end
300
299
  full_path = File.join(container_path, Raca::Util.url_encode(key)) + "?multipart-manifest=put"
@@ -0,0 +1,72 @@
1
+ module Raca
2
+
3
+ # Wrap an IO object and expose only a partial subset of the underlying data
4
+ # in an IO-ish interface. Calling code will have access to the window of data
5
+ # starting at 'offset' and the following 'length' bytes.
6
+ #
7
+ # This doesn't implement the entire IO contract, just enough to make it work
8
+ # when handed to Net::HTTP as a request body.
9
+ #
10
+ class WindowedIO
11
+ def initialize(io, offset, length)
12
+ @io = io
13
+ @offset = offset
14
+ if @offset + length > @io.size
15
+ @length = @io.size - offset
16
+ else
17
+ @length = length
18
+ end
19
+ @io.seek(@offset)
20
+ end
21
+
22
+ def eof?
23
+ @io.pos >= @offset + @length
24
+ end
25
+
26
+ def pos
27
+ @io.pos - @offset
28
+ end
29
+
30
+ def seek(to)
31
+ if to <= 0
32
+ @io.seek(@offset)
33
+ elsif to >= @length
34
+ @io.seek(@offset + @length)
35
+ else
36
+ @io.seek(@offset + to)
37
+ end
38
+ end
39
+
40
+ def size
41
+ @length
42
+ end
43
+
44
+ def each(bytes, &block)
45
+ loop do
46
+ line = read(bytes)
47
+ break if line.nil? || line == ""
48
+ yield line
49
+ end
50
+ end
51
+
52
+ def read(bytes = 1024)
53
+ @io.read(capped_bytes_to_read(bytes))
54
+ end
55
+
56
+ def readpartial(bytes = 1024, outbuf = nil)
57
+ raise EOFError.new("end of file reached") if eof?
58
+ bytes = capped_bytes_to_read(bytes)
59
+ @io.readpartial(bytes, outbuf)
60
+ end
61
+
62
+ private
63
+
64
+ def capped_bytes_to_read(bytes)
65
+ if pos + bytes > @length
66
+ size - pos
67
+ else
68
+ bytes
69
+ end
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Healy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-19 00:00:00.000000000 Z
11
+ date: 2015-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: webmock
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '1.20'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "<"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1.20'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: ir_b
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +102,7 @@ files:
102
102
  - lib/raca/user.rb
103
103
  - lib/raca/users.rb
104
104
  - lib/raca/util.rb
105
+ - lib/raca/windowed_io.rb
105
106
  homepage: http://github.com/conversation/raca
106
107
  licenses:
107
108
  - MIT
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
126
  version: '0'
126
127
  requirements: []
127
128
  rubyforge_project:
128
- rubygems_version: 2.4.5
129
+ rubygems_version: 2.4.5.1
129
130
  signing_key:
130
131
  specification_version: 4
131
132
  summary: A simple wrapper for the Rackspace Cloud API with no dependencies