net-http-uploadprogress 1.0.0 → 2.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dfca04e2958f5d9e546ee58349ce09b74c0e7eee
4
+ data.tar.gz: cfd40ef1a395ef7b083b011dbd6aaf9d244eada0
5
+ SHA512:
6
+ metadata.gz: 5c70ed1e96f4785be5df32f1e35e6940c63c41e37bd0fead8907aaf4702e4c98e7518b27dd70da3d48747f3f8f7744c3e2d70b6c5b9e26470172d24b723531f8
7
+ data.tar.gz: a55755082262ba51b9b86fb3e47813be53eb2bd900ffcb1171086b4747e5a67b00e62c66868865846dd619fe733c22ba31c0fc3d2fd0fe0cbc68bb660e3f4b45
data/.gitignore CHANGED
@@ -1,4 +1,20 @@
1
+ .DS_Store
1
2
  *.gem
3
+ *.rbc
2
4
  .bundle
5
+ .config
6
+ coverage
7
+ InstalledFiles
8
+ lib/bundler/man
3
9
  Gemfile.lock
4
- pkg/*
10
+ pkg
11
+ rdoc
12
+ spec/reports
13
+ test/tmp
14
+ test/version_tmp
15
+ tmp
16
+
17
+ # YARD artifacts
18
+ .yardoc
19
+ _yardoc
20
+ doc/
@@ -0,0 +1,36 @@
1
+ # net-http-uploadprogress.gem
2
+
3
+ Get the file uploading progress.
4
+
5
+ ## Installation
6
+
7
+ gem install net-http-uploadprogress
8
+
9
+ ## Examples
10
+
11
+ ```ruby
12
+ require 'net/http/uploadprogress'
13
+
14
+ # API style upload
15
+ File.open('path/to.file', 'rb') do |io|
16
+ http = Net::HTTP.new(host, port)
17
+ req = Net::HTTP::Post.new('/')
18
+ req.content_length = io.size
19
+ req.body_stream = io
20
+ Net::HTTP::UploadProgress.new(req) do |progress|
21
+ puts "uploaded so far: #{ progress.upload_size }"
22
+ end
23
+ res = http.request(req)
24
+ end
25
+
26
+ # Form input type="file" style upload
27
+ File.open('path/to.file', 'rb') do |io|
28
+ http = Net::HTTP.new(host, port)
29
+ req = Net::HTTP::Post.new('/')
30
+ req.set_form({'file_form_field_name' => io}, 'multipart/form-data')
31
+ Net::HTTP::UploadProgress.new(req) do |progress|
32
+ puts "uploaded so far: #{ progress.upload_size }"
33
+ end
34
+ res = http.request(req)
35
+ end
36
+ ```
@@ -1,52 +1,42 @@
1
1
  require 'net/http'
2
- require 'net/https'
2
+ require 'tempfile'
3
+ require 'securerandom'
3
4
 
4
- module Net
5
- class HTTP
6
- def begin_transport(req)
7
- if @socket.closed?
8
- req.reset_upload_size
9
- connect
10
- end
11
- if not req.response_body_permitted? and @close_on_empty_response
12
- req['connection'] ||= 'close'
13
- end
14
- req['host'] ||= addr_port()
15
- end
16
- end
17
-
18
- class HTTPGenericRequest
19
- def reset_upload_size
20
- @upload_size = 0
21
- end
5
+ class Net::HTTP::UploadProgress
6
+ attr_reader :upload_size
22
7
 
23
- def upload_size
24
- @upload_size = 0 if @upload_size.nil?
25
- @upload_size
8
+ def initialize(req, &block)
9
+ @req = req
10
+ @callback = block
11
+ @upload_size = 0
12
+ if req.body_stream
13
+ @io = req.body_stream
14
+ req.body_stream = self
15
+ elsif req.instance_variable_get(:@body_data)
16
+ raise NotImplementedError if req.chunked?
17
+ raise NotImplementedError if /\Amultipart\/form-data\z/i !~ req.content_type
18
+ opt = req.instance_variable_get(:@form_option).dup
19
+ opt[:boundary] ||= SecureRandom.urlsafe_base64(40)
20
+ req.set_content_type(req.content_type, boundary: opt[:boundary])
21
+ file = Tempfile.new('multipart')
22
+ file.binmode
23
+ req.send(:encode_multipart_form_data, file, req.instance_variable_get(:@body_data), opt)
24
+ file.rewind
25
+ req.content_length = file.size
26
+ @io = file
27
+ req.body_stream = self
28
+ else
29
+ raise NotImplementedError
26
30
  end
31
+ end
27
32
 
28
- private
29
-
30
- def send_request_with_body_stream(sock, ver, path, f)
31
- unless content_length() or chunked?
32
- raise ArgumentError,
33
- "Content-Length not given and Transfer-Encoding is not `chunked'"
34
- end
35
- @upload_size = 0 if @upload_size.nil?
36
- supply_default_content_type
37
- write_header sock, ver, path
38
- if chunked?
39
- while s = f.read(1024)
40
- @upload_size += s.length
41
- sock.write(sprintf("%x\r\n", s.length) << s << "\r\n")
42
- end
43
- sock.write "0\r\n\r\n"
44
- else
45
- while s = f.read(1024)
46
- @upload_size += s.length
47
- sock.write s
48
- end
49
- end
33
+ def readpartial(maxlen, outbuf)
34
+ begin
35
+ str = @io.readpartial(maxlen, outbuf)
36
+ ensure
37
+ @callback.call(self) unless @upload_size.zero?
50
38
  end
39
+ @upload_size += str.length
40
+ str
51
41
  end
52
42
  end
@@ -1,3 +1,3 @@
1
1
  module NetHttpUploadprogress
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -5,20 +5,17 @@ require "version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "net-http-uploadprogress"
7
7
  s.version = NetHttpUploadprogress::VERSION
8
- s.authors = ["SKAhack"]
9
- s.email = ["m@skahack.com"]
8
+ s.authors = ["SKAhack", "Vais Salikhov"]
9
+ s.email = ["m@skahack.com", "vsalikhov@gmail.com"]
10
10
  s.homepage = "https://github.com/SKAhack/net-http-uploadprogress"
11
11
  s.summary = %q{Get the file uploading progress.}
12
12
  s.description = %q{Get the file uploading progress.}
13
13
 
14
- s.rubyforge_project = "net-http-uploadprogress"
15
-
16
14
  s.files = `git ls-files`.split("\n")
17
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
17
  s.require_paths = ["lib"]
20
18
 
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
19
+ s.required_ruby_version = '~> 2.0'
20
+ s.add_development_dependency "minitest"
24
21
  end
@@ -0,0 +1,138 @@
1
+ # To run this test execute:
2
+ # $ bundle exec ruby spec/uploadprogress_spec.rb
3
+
4
+ require 'minitest/autorun'
5
+ require 'webrick'
6
+ require 'stringio'
7
+
8
+ require 'net/http/uploadprogress'
9
+
10
+ RUBY_IO_COPY_STREAM_BUFLEN = 16 * 1024
11
+ # See io.c
12
+ # static VALUE copy_stream_fallback_body(VALUE arg)
13
+ # ...
14
+ # const int buflen = 16*1024;
15
+ # ...
16
+ # https://github.com/ruby/ruby/blob/trunk/io.c#L10414
17
+
18
+
19
+ server = WEBrick::HTTPServer.new({
20
+ :BindAddress => '127.0.0.1',
21
+ :Port => 0,
22
+ :Logger => WEBrick::Log.new([], WEBrick::BasicLog::WARN),
23
+ :AccessLog => [],
24
+ :ServerType => Thread
25
+ })
26
+
27
+ server.mount_proc('/echo') do |req, res|
28
+ res.body = req.body
29
+ end
30
+
31
+ server.mount_proc('/file') do |req, res|
32
+ res.body = req.query['file']
33
+ end
34
+
35
+ server.start
36
+
37
+ describe 'Upload' do
38
+ [{
39
+ description: "smaller than buflen",
40
+ content_length: RUBY_IO_COPY_STREAM_BUFLEN - 1,
41
+ times_called: 1
42
+ }, {
43
+ description: "equal to buflen",
44
+ content_length: RUBY_IO_COPY_STREAM_BUFLEN,
45
+ times_called: 1
46
+ }, {
47
+ description: "larger than buflen",
48
+ content_length: RUBY_IO_COPY_STREAM_BUFLEN + 1,
49
+ times_called: 2
50
+ }, {
51
+ description: "exactly 2x larger than buflen",
52
+ content_length: RUBY_IO_COPY_STREAM_BUFLEN * 2,
53
+ times_called: 2
54
+ }, {
55
+ description: "more than 2x larger than buflen",
56
+ content_length: RUBY_IO_COPY_STREAM_BUFLEN * 2 + 1,
57
+ times_called: 3
58
+ }].each do |upload|
59
+
60
+ describe upload[:description] do
61
+ http = Net::HTTP.new(server[:BindAddress], server[:Port])
62
+ content = 'a' * upload[:content_length]
63
+ req = Net::HTTP::Post.new('/echo')
64
+ req.content_length = upload[:content_length]
65
+ req.body_stream = StringIO.new(content)
66
+
67
+ times_called = 0
68
+ upload_size = 0
69
+
70
+ Net::HTTP::UploadProgress.new(req) do |progress|
71
+ times_called += 1
72
+ upload_size += progress.upload_size - upload_size
73
+ end
74
+
75
+ res = http.request(req)
76
+
77
+ it 'correctly transmits data to the server' do
78
+ assert_equal(content, res.body)
79
+ end
80
+
81
+ it 'updates progress expected number of times' do
82
+ assert_equal(upload[:times_called], times_called)
83
+ end
84
+
85
+ it 'updates progress with correct upload size' do
86
+ assert_equal(upload[:content_length], upload_size)
87
+ end
88
+ end
89
+ end
90
+
91
+ describe 'file' do
92
+ http = Net::HTTP.new(server[:BindAddress], server[:Port])
93
+ req = Net::HTTP::Post.new('/file')
94
+
95
+ content = 'hello'
96
+
97
+ file = Tempfile.new('uploadprogress_spec')
98
+ file.binmode
99
+ file << content
100
+ file.rewind
101
+
102
+ req.set_form({'file' => file}, 'multipart/form-data', boundary: 'UfpmKZyktEWfuJidfSVW_Ss-HV5f-mbma0uQchAVbCJFxhKnYOcaTA')
103
+
104
+ multipart_content = [
105
+ '--UfpmKZyktEWfuJidfSVW_Ss-HV5f-mbma0uQchAVbCJFxhKnYOcaTA',
106
+ 'Content-Disposition: form-data; name="file"; filename="<filename>"',
107
+ 'Content-Type: application/octet-stream',
108
+ '',
109
+ 'hello',
110
+ '--UfpmKZyktEWfuJidfSVW_Ss-HV5f-mbma0uQchAVbCJFxhKnYOcaTA--',
111
+ ''
112
+ ].join("\r\n").sub('<filename>', File.basename(file.path))
113
+
114
+ times_called = 0
115
+ upload_size = 0
116
+
117
+ Net::HTTP::UploadProgress.new(req) do |progress|
118
+ times_called += 1
119
+ upload_size += progress.upload_size - upload_size
120
+ end
121
+
122
+ res = http.request(req)
123
+
124
+ file.close!
125
+
126
+ it 'correctly transmits data to the server' do
127
+ assert_equal(content, res.body)
128
+ end
129
+
130
+ it 'updates progress expected number of times' do
131
+ assert_equal(1, times_called)
132
+ end
133
+
134
+ it 'updates progress with correct upload size' do
135
+ assert_equal(multipart_content.length, upload_size)
136
+ end
137
+ end
138
+ end
metadata CHANGED
@@ -1,51 +1,68 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-http-uploadprogress
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
5
- prerelease:
4
+ version: 2.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - SKAhack
8
+ - Vais Salikhov
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-25 00:00:00.000000000Z
13
- dependencies: []
12
+ date: 2015-01-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  description: Get the file uploading progress.
15
29
  email:
16
30
  - m@skahack.com
31
+ - vsalikhov@gmail.com
17
32
  executables: []
18
33
  extensions: []
19
34
  extra_rdoc_files: []
20
35
  files:
21
36
  - .gitignore
22
37
  - Gemfile
38
+ - README.md
23
39
  - Rakefile
24
40
  - lib/net/http/uploadprogress.rb
25
41
  - lib/version.rb
26
42
  - net-http-uploadprogress.gemspec
43
+ - spec/uploadprogress_spec.rb
27
44
  homepage: https://github.com/SKAhack/net-http-uploadprogress
28
45
  licenses: []
46
+ metadata: {}
29
47
  post_install_message:
30
48
  rdoc_options: []
31
49
  require_paths:
32
50
  - lib
33
51
  required_ruby_version: !ruby/object:Gem::Requirement
34
- none: false
35
52
  requirements:
36
- - - ! '>='
53
+ - - ~>
37
54
  - !ruby/object:Gem::Version
38
- version: '0'
55
+ version: '2.0'
39
56
  required_rubygems_version: !ruby/object:Gem::Requirement
40
- none: false
41
57
  requirements:
42
- - - ! '>='
58
+ - - '>='
43
59
  - !ruby/object:Gem::Version
44
60
  version: '0'
45
61
  requirements: []
46
- rubyforge_project: net-http-uploadprogress
47
- rubygems_version: 1.8.6
62
+ rubyforge_project:
63
+ rubygems_version: 2.0.2
48
64
  signing_key:
49
- specification_version: 3
65
+ specification_version: 4
50
66
  summary: Get the file uploading progress.
51
- test_files: []
67
+ test_files:
68
+ - spec/uploadprogress_spec.rb