umanni-multipart-post 0.0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ Manifest
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in orkut.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2010-2011 Amit Kumar <toamitkumar@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1 @@
1
+ Copyright (c) 2010 (Amit Kumar), released under the MIT license
data/README.rdoc ADDED
@@ -0,0 +1,60 @@
1
+ = umanni-multipart-post
2
+
3
+ Umanni FORK, for toamitkumar/ruby-multipart-post
4
+
5
+ * http://github.com/umanni/ruby-multipart-post
6
+
7
+ == DESCRIPTION
8
+
9
+ Multipart form post thru Ruby script, headers content-type and content-length properly set
10
+
11
+ == SYNOPSIS
12
+
13
+ require 'ruby-multipart-post'
14
+
15
+ params = {
16
+ "param_0" => "value_0", "param_1" => "value_1",
17
+ "file_0" => FileUploadIO.new(path_to_file, file_content_type),
18
+ "file_1" => FileUploadIO.new(path_to_file, file_content_type)
19
+ }
20
+ #file_content_type is the file content_type eg: "image/jpeg"
21
+ #it now supports https url as well
22
+
23
+ multipart_post = MultiPart::Post.new(params) # MultiPart::Post.new(params, some_extra_headers, content_type)
24
+ multipart_post.submit(to_url) # multipart_post.submit(to_url, query_string)
25
+
26
+ == REQUIREMENTS
27
+
28
+ None
29
+
30
+ == Ruby Version compatibility
31
+ Tested against -> REE, Ruby MRI (1.8.x, 1.9.2)
32
+
33
+ == INSTALL
34
+
35
+ gem install umanni-multipart-post
36
+
37
+ == LICENSE:
38
+
39
+ (The MIT License)
40
+
41
+ Copyright (c) 2010-2011 Amit Kumar <toamitkumar@gmail.com>
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining
44
+ a copy of this software and associated documentation files (the
45
+ 'Software'), to deal in the Software without restriction, including
46
+ without limitation the rights to use, copy, modify, merge, publish,
47
+ distribute, sublicense, and/or sell copies of the Software, and to
48
+ permit persons to whom the Software is furnished to do so, subject to
49
+ the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be
52
+ included in all copies or substantial portions of the Software.
53
+
54
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
55
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
56
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
57
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
58
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
59
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
60
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => [:spec]
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,20 @@
1
+ module FileUploadIO
2
+ def self.new(file_path, content_type)
3
+ raise ArgumentError, "File content type required" unless content_type
4
+ file_io = File.open(file_path, "rb")
5
+ file_io.instance_eval(<<-EOS, __FILE__, __LINE__)
6
+ def content_type
7
+ "#{content_type}"
8
+ end
9
+
10
+ def file_name
11
+ "#{File.basename(file_path)}"
12
+ end
13
+
14
+ def file_size
15
+ "#{File.size(file_path)}".to_i
16
+ end
17
+ EOS
18
+ file_io
19
+ end
20
+ end
@@ -0,0 +1,53 @@
1
+ require 'net/http'
2
+ require "parts"
3
+ require "stream"
4
+
5
+ module MultiPart
6
+ class Post
7
+ def initialize(post_params, request_headers={})
8
+ @parts, @streams = [], []
9
+ construct_post_params(post_params)
10
+ @request_headers = request_headers
11
+ end
12
+
13
+ def construct_post_params(post_params)
14
+ post_params.each_pair do |key, val|
15
+ if(val.respond_to?(:content_type)) #construct file part
16
+ @parts << Parts::StringParam.new( "--" + multi_part_boundary + "\r\n" + \
17
+ "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.file_name}\"\r\n" + \
18
+ "Content-Type: #{val.content_type}\r\n\r\n"
19
+ )
20
+ @streams << val
21
+ @parts << Parts::StreamParam.new(val, val.file_size)
22
+ else #construct string part param
23
+ @parts << Parts::StringParam.new("--#{multi_part_boundary}\r\n" + "Content-Disposition: form-data; name=\"#{key}\"\r\n" + "\r\n" + "#{val}\r\n")
24
+ end
25
+ end
26
+ @parts << Parts::StringParam.new( "\r\n--" + multi_part_boundary + "--\r\n" )
27
+ end
28
+
29
+ def multi_part_boundary
30
+ @boundary ||= 'END_OF_PART'
31
+ end
32
+
33
+ def submit(to_url, query_string=nil, content_type='multipart/form-data')
34
+ post_stream = Stream::MultiPart.new(@parts)
35
+ url = URI.parse( to_url )
36
+ post_url_with_query_string = "#{url.path}"
37
+ post_url_with_query_string = "#{post_url_with_query_string}?#{query_string}" unless(query_string.nil?)
38
+ req = Net::HTTP::Post.new(post_url_with_query_string, @request_headers)
39
+ req.content_length = post_stream.size
40
+ req.content_type = "#{content_type}; boundary=#{multi_part_boundary}"
41
+ req.body_stream = post_stream
42
+ http_handle = Net::HTTP.new(url.host, url.port)
43
+ http_handle.use_ssl = true if(url.scheme == "https")
44
+ res = http_handle.start {|http| http.request(req)}
45
+
46
+ #close all the open hooks to the file on file-system
47
+ @streams.each do |local_stream|
48
+ local_stream.close();
49
+ end
50
+ res
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,29 @@
1
+ module Parts
2
+ class StreamParam
3
+ def initialize(stream, size)
4
+ @stream, @size = stream, size
5
+ end
6
+
7
+ def size
8
+ @size
9
+ end
10
+
11
+ def read(offset, how_much)
12
+ @stream.read(how_much)
13
+ end
14
+ end
15
+
16
+ class StringParam
17
+ def initialize (str)
18
+ @str = str
19
+ end
20
+
21
+ def size
22
+ @str.length
23
+ end
24
+
25
+ def read (offset, how_much)
26
+ @str[offset, how_much]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ module Stream
2
+ class MultiPart
3
+ def initialize(parts)
4
+ @parts = parts
5
+ @part_no = 0
6
+ @part_offset = 0
7
+ end
8
+
9
+ def size
10
+ total = 0
11
+ @parts.each do |part|
12
+ total += part.size
13
+ end
14
+ total
15
+ end
16
+
17
+ def read (how_much)
18
+ return nil if @part_no >= @parts.size
19
+
20
+ how_much_current_part = @parts[@part_no].size - @part_offset
21
+
22
+ how_much_current_part = if how_much_current_part > how_much
23
+ how_much
24
+ else
25
+ how_much_current_part
26
+ end
27
+
28
+ how_much_next_part = how_much - how_much_current_part
29
+ current_part = @parts[@part_no].read(@part_offset, how_much_current_part )
30
+
31
+ if how_much_next_part > 0
32
+ @part_no += 1
33
+ @part_offset = 0
34
+ next_part = read( how_much_next_part )
35
+ current_part + if next_part
36
+ next_part
37
+ else
38
+ ''
39
+ end
40
+ else
41
+ @part_offset += how_much_current_part
42
+ current_part
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ module MultiPart
2
+ class Version
3
+
4
+ def self.major
5
+ 0
6
+ end
7
+
8
+ def self.minor
9
+ 0
10
+ end
11
+
12
+ def self.patch
13
+ 0
14
+ end
15
+
16
+ def self.pre
17
+ 1 #nil
18
+ end
19
+
20
+ def self.to_s
21
+ [major, minor, patch, pre].compact.join('.')
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,2 @@
1
+ require 'multi_part/multi_part_post'
2
+ require 'multi_part/file_upload_io'
@@ -0,0 +1,30 @@
1
+ require "test/unit"
2
+ require File.expand_path(File.dirname(__FILE__)) + "/../lib/multi_part/file_upload_io"
3
+
4
+ class FileUploadIOTest < Test::Unit::TestCase
5
+ def setup
6
+ @file_io = FileUploadIO.new("files/file_0.txt", "text/plain")
7
+ end
8
+
9
+ def teardown
10
+ @file_io.close
11
+ end
12
+
13
+ def test_should_raise_when_content_type_not_specified
14
+ assert_raises ArgumentError do
15
+ FileUploadIO.new("files/file_0.txt")
16
+ end
17
+ end
18
+
19
+ def test_should_have_content_type
20
+ assert_equal("text/plain", @file_io.content_type)
21
+ end
22
+
23
+ def test_should_have_file_name
24
+ assert_equal("file_0.txt", @file_io.file_name)
25
+ end
26
+
27
+ def test_should_have_file_size
28
+ assert_equal(41, @file_io.file_size)
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ Text
2
+ here
3
+ to
4
+ be
5
+ tested
6
+ for
7
+ File
8
+ IO
@@ -0,0 +1,29 @@
1
+ require "test/unit"
2
+ require File.expand_path(File.dirname(__FILE__)) + "/../lib/multi_part/parts"
3
+
4
+ class PartsTest < Test::Unit::TestCase
5
+ def setup
6
+ @string_part = Parts::StringParam.new("Test String")
7
+ @file_part = Parts::StreamParam.new(File.new("files/file_0.txt"), 41)
8
+ end
9
+
10
+ def teardown
11
+ # Do nothing
12
+ end
13
+
14
+ def test_string_part_should_have_size
15
+ assert_equal(11, @string_part.size)
16
+ end
17
+
18
+ def test_should_read_string_part_by_offset
19
+ assert_equal("St", @string_part.read(5, 2))
20
+ end
21
+
22
+ def test_file_part_should_have_size
23
+ assert_equal(41, @file_part.size)
24
+ end
25
+
26
+ def test_should_read_file_part
27
+ assert_equal("Text\r\nhere", @file_part.read(5, 10))
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "multi_part/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'umanni-multipart-post'
7
+ s.version = MultiPart::Version.to_s
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Amit Kumar', 'Umanni']
10
+ s.email = ['toamitkumar@gmail.com', 'contato@umanni.com']
11
+ s.homepage = 'https://github.com/umanni/ruby-multipart-post'
12
+ s.summary = %q{Ruby MultiPart Post}
13
+ s.description = %q{Multipart form post thru Ruby script, headers content-type and content-length properly set}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: umanni-multipart-post
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Amit Kumar
9
+ - Umanni
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-11-24 00:00:00.000000000Z
14
+ dependencies: []
15
+ description: Multipart form post thru Ruby script, headers content-type and content-length
16
+ properly set
17
+ email:
18
+ - toamitkumar@gmail.com
19
+ - contato@umanni.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - LICENSE
29
+ - README
30
+ - README.rdoc
31
+ - Rakefile
32
+ - lib/multi_part/file_upload_io.rb
33
+ - lib/multi_part/multi_part_post.rb
34
+ - lib/multi_part/parts.rb
35
+ - lib/multi_part/stream.rb
36
+ - lib/multi_part/version.rb
37
+ - lib/ruby-multipart-post.rb
38
+ - test/file_upload_io_test.rb
39
+ - test/files/file_0.txt
40
+ - test/parts_test.rb
41
+ - umanni-multipart-post.gemspec
42
+ homepage: https://github.com/umanni/ruby-multipart-post
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.11
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Ruby MultiPart Post
66
+ test_files: []