http2 0.0.24 → 0.0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/Gemfile.lock +25 -19
- data/README.md +1 -0
- data/VERSION +1 -1
- data/http2.gemspec +16 -8
- data/include/connection.rb +142 -0
- data/include/get_request.rb +34 -0
- data/include/post_data_generator.rb +62 -0
- data/include/post_multipart_request.rb +113 -0
- data/include/post_request.rb +71 -0
- data/include/response.rb +17 -45
- data/include/response_reader.rb +101 -97
- data/include/url_builder.rb +58 -0
- data/lib/http2.rb +52 -315
- data/spec/http2/post_data_generator_spec.rb +24 -0
- data/spec/http2/url_builder_spec.rb +17 -0
- data/spec/http2_spec.rb +18 -24
- data/spec/spec_helper.rb +3 -1
- metadata +25 -18
- data/include/post_multipart_helper.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a747caea21ace1b6e3aea354a4d9e9ffe437dc08
|
4
|
+
data.tar.gz: 4cd7db8fbe2d498efcf28fdfad1cba6d9388c491
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ed8bec6e8c5abaa859799a1cb378189eac83e13fccd947c736555a249d6b1de291da4b1beb65df1fba46982023c757a9374ae287f70b7a7ee1808f26f211c04
|
7
|
+
data.tar.gz: e36e5e10eb01b93e219b5912de26c9b049605c55628770e356c9d34faa11c37cfc74c28feb0d4efa0b8212729cc82424497596faa58afa4b9b7628a3f507e353
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -3,38 +3,43 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
addressable (2.3.6)
|
5
5
|
builder (3.2.2)
|
6
|
-
codeclimate-test-reporter (0.
|
6
|
+
codeclimate-test-reporter (0.4.0)
|
7
7
|
simplecov (>= 0.7.1, < 1.0.0)
|
8
|
+
descendants_tracker (0.0.4)
|
9
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
8
10
|
diff-lcs (1.1.3)
|
9
11
|
docile (1.1.5)
|
10
|
-
faraday (0.
|
11
|
-
multipart-post (
|
12
|
-
git (1.2.
|
13
|
-
github_api (0.
|
14
|
-
addressable
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
faraday (0.9.0)
|
13
|
+
multipart-post (>= 1.2, < 3)
|
14
|
+
git (1.2.8)
|
15
|
+
github_api (0.12.0)
|
16
|
+
addressable (~> 2.3)
|
17
|
+
descendants_tracker (~> 0.0.4)
|
18
|
+
faraday (~> 0.8, < 0.10)
|
19
|
+
hashie (>= 3.2)
|
20
|
+
multi_json (>= 1.7.5, < 2.0)
|
21
|
+
nokogiri (~> 1.6.3)
|
19
22
|
oauth2
|
20
|
-
hashie (2.
|
23
|
+
hashie (3.2.0)
|
21
24
|
highline (1.6.21)
|
22
|
-
jeweler (
|
25
|
+
jeweler (2.0.1)
|
23
26
|
builder
|
24
|
-
bundler (
|
27
|
+
bundler (>= 1.0)
|
25
28
|
git (>= 1.2.5)
|
26
|
-
github_api
|
29
|
+
github_api
|
27
30
|
highline (>= 1.6.15)
|
28
|
-
nokogiri (
|
31
|
+
nokogiri (>= 1.5.10)
|
29
32
|
rake
|
30
33
|
rdoc
|
31
34
|
json (1.8.1)
|
32
35
|
jwt (1.0.0)
|
36
|
+
mini_portile (0.6.0)
|
33
37
|
multi_json (1.10.1)
|
34
38
|
multi_xml (0.5.5)
|
35
|
-
multipart-post (
|
36
|
-
nokogiri (1.
|
37
|
-
|
39
|
+
multipart-post (2.0.0)
|
40
|
+
nokogiri (1.6.3.1)
|
41
|
+
mini_portile (= 0.6.0)
|
42
|
+
oauth2 (1.0.0)
|
38
43
|
faraday (>= 0.8, < 0.10)
|
39
44
|
jwt (~> 1.0)
|
40
45
|
multi_json (~> 1.3)
|
@@ -52,12 +57,13 @@ GEM
|
|
52
57
|
rspec-expectations (2.8.0)
|
53
58
|
diff-lcs (~> 1.1.2)
|
54
59
|
rspec-mocks (2.8.0)
|
55
|
-
simplecov (0.
|
60
|
+
simplecov (0.9.0)
|
56
61
|
docile (~> 1.1.0)
|
57
62
|
multi_json
|
58
63
|
simplecov-html (~> 0.8.0)
|
59
64
|
simplecov-html (0.8.0)
|
60
65
|
string-cases (0.0.0)
|
66
|
+
thread_safe (0.3.4)
|
61
67
|
|
62
68
|
PLATFORMS
|
63
69
|
ruby
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://api.shippable.com/projects/53bd3eef2e23bdcb03c0df9e/badge/master)](https://www.shippable.com/projects/53bd3eef2e23bdcb03c0df9e)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/kaspernj/http2.png)](https://codeclimate.com/github/kaspernj/http2)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/kaspernj/http2/coverage.png)](https://codeclimate.com/github/kaspernj/http2)
|
5
6
|
|
6
7
|
Example of usage:
|
7
8
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.25
|
data/http2.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: http2 0.0.25 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "http2"
|
8
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.25"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-08-04"
|
13
15
|
s.description = "A lightweight framework for doing http-connections in Ruby. Supports cookies, keep-alive, compressing and much more."
|
14
16
|
s.email = "k@spernj.org"
|
15
17
|
s.extra_rdoc_files = [
|
@@ -26,20 +28,26 @@ Gem::Specification.new do |s|
|
|
26
28
|
"Rakefile",
|
27
29
|
"VERSION",
|
28
30
|
"http2.gemspec",
|
31
|
+
"include/connection.rb",
|
29
32
|
"include/errors.rb",
|
30
|
-
"include/
|
33
|
+
"include/get_request.rb",
|
34
|
+
"include/post_data_generator.rb",
|
35
|
+
"include/post_multipart_request.rb",
|
36
|
+
"include/post_request.rb",
|
31
37
|
"include/response.rb",
|
32
38
|
"include/response_reader.rb",
|
39
|
+
"include/url_builder.rb",
|
33
40
|
"include/utils.rb",
|
34
41
|
"lib/http2.rb",
|
35
42
|
"shippable.yml",
|
43
|
+
"spec/http2/post_data_generator_spec.rb",
|
44
|
+
"spec/http2/url_builder_spec.rb",
|
36
45
|
"spec/http2_spec.rb",
|
37
46
|
"spec/spec_helper.rb"
|
38
47
|
]
|
39
48
|
s.homepage = "http://github.com/kaspernj/http2"
|
40
49
|
s.licenses = ["MIT"]
|
41
|
-
s.
|
42
|
-
s.rubygems_version = "2.0.14"
|
50
|
+
s.rubygems_version = "2.4.0"
|
43
51
|
s.summary = "A lightweight framework for doing http-connections in Ruby. Supports cookies, keep-alive, compressing and much more."
|
44
52
|
|
45
53
|
if s.respond_to? :specification_version then
|
@@ -50,20 +58,20 @@ Gem::Specification.new do |s|
|
|
50
58
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
51
59
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
52
60
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
53
|
-
s.add_development_dependency(%q<jeweler>, ["
|
61
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.8.4"])
|
54
62
|
else
|
55
63
|
s.add_dependency(%q<string-cases>, [">= 0"])
|
56
64
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
57
65
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
58
66
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
59
|
-
s.add_dependency(%q<jeweler>, ["
|
67
|
+
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
60
68
|
end
|
61
69
|
else
|
62
70
|
s.add_dependency(%q<string-cases>, [">= 0"])
|
63
71
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
64
72
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
65
73
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
66
|
-
s.add_dependency(%q<jeweler>, ["
|
74
|
+
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
@@ -0,0 +1,142 @@
|
|
1
|
+
class Http2::Connection
|
2
|
+
def initialize(http2)
|
3
|
+
@http2, @debug, @args = http2, http2.debug, http2.args
|
4
|
+
reconnect
|
5
|
+
end
|
6
|
+
|
7
|
+
def destroy
|
8
|
+
@sock.close if @sock and !@sock.closed?
|
9
|
+
@sock = nil
|
10
|
+
|
11
|
+
@sock_plain.close if @sock_plain and !@sock_plain.closed?
|
12
|
+
@sock_plain = nil
|
13
|
+
|
14
|
+
@sock_ssl.close if @sock_ssl and !@sock_ssl.closed?
|
15
|
+
@sock_ssl = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def gets
|
19
|
+
@sock.gets
|
20
|
+
end
|
21
|
+
|
22
|
+
def read(length)
|
23
|
+
@sock.read(length)
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
@sock.close
|
28
|
+
end
|
29
|
+
|
30
|
+
def closed?
|
31
|
+
@sock.closed?
|
32
|
+
end
|
33
|
+
|
34
|
+
def sock_write(str)
|
35
|
+
str = str.to_s
|
36
|
+
return if str.empty?
|
37
|
+
count = @sock.write(str)
|
38
|
+
raise "Couldnt write to socket: '#{count}', '#{str}'." if count <= 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def sock_puts(str)
|
42
|
+
sock_write("#{str}#{@nl}")
|
43
|
+
end
|
44
|
+
|
45
|
+
# Tries to write a string to the socket. If it fails it reconnects and tries again.
|
46
|
+
def write(str)
|
47
|
+
reconnect unless socket_working?
|
48
|
+
|
49
|
+
begin
|
50
|
+
raise Errno::EPIPE, "The socket is closed." if !@sock || @sock.closed?
|
51
|
+
sock_write(str)
|
52
|
+
rescue Errno::EPIPE #this can also be thrown by puts.
|
53
|
+
reconnect
|
54
|
+
sock_write(str)
|
55
|
+
end
|
56
|
+
|
57
|
+
@request_last = Time.now
|
58
|
+
end
|
59
|
+
|
60
|
+
# Reconnects to the host.
|
61
|
+
def reconnect
|
62
|
+
puts "Http2: Reconnect." if @debug
|
63
|
+
|
64
|
+
#Open connection.
|
65
|
+
if @args[:proxy] && @args[:ssl]
|
66
|
+
connect_proxy_ssl
|
67
|
+
elsif @args[:proxy]
|
68
|
+
connect_proxy
|
69
|
+
else
|
70
|
+
print "Http2: Opening socket connection to '#{@args[:host]}:#{@args[:port]}'.\n" if @debug
|
71
|
+
@sock_plain = TCPSocket.new(@args[:host], @args[:port].to_i)
|
72
|
+
end
|
73
|
+
|
74
|
+
if @args[:ssl]
|
75
|
+
apply_ssl
|
76
|
+
else
|
77
|
+
@sock = @sock_plain
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns boolean based on the if the object is connected and the socket is working.
|
82
|
+
#===Examples
|
83
|
+
# puts "Socket is working." if http.socket_working?
|
84
|
+
def socket_working?
|
85
|
+
return false if !@sock or @sock.closed?
|
86
|
+
|
87
|
+
if @keepalive_timeout && @request_last
|
88
|
+
between = Time.now.to_i - @request_last.to_i
|
89
|
+
if between >= @keepalive_timeout
|
90
|
+
puts "Http2: We are over the keepalive-wait - returning false for socket_working?." if @debug
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
|
98
|
+
# Closes the current connection if any.
|
99
|
+
def close
|
100
|
+
@sock.close if @sock && !@sock.closed?
|
101
|
+
@sock_ssl.close if @sock_ssl && !@sock_ssl.closed?
|
102
|
+
@sock_plain.close if @sock_plain && !@sock_plain.closed?
|
103
|
+
end
|
104
|
+
|
105
|
+
def connect_proxy_ssl
|
106
|
+
puts "Http2: Initializing proxy stuff." if @debug
|
107
|
+
@sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port])
|
108
|
+
|
109
|
+
@sock_plain.write("CONNECT #{@args[:host]}:#{@args[:port]} HTTP/1.0#{@nl}")
|
110
|
+
@sock_plain.write("User-Agent: #{@uagent}#{@nl}")
|
111
|
+
|
112
|
+
if @args[:proxy][:user] && @args[:proxy][:passwd]
|
113
|
+
credential = ["#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}"].pack("m")
|
114
|
+
credential.delete!("\r\n")
|
115
|
+
@sock_plain.write("Proxy-Authorization: Basic #{credential}#{@nl}")
|
116
|
+
end
|
117
|
+
|
118
|
+
@sock_plain.write(@nl)
|
119
|
+
|
120
|
+
res = @sock_plain.gets
|
121
|
+
raise res if res.to_s.downcase != "http/1.0 200 connection established#{@nl}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def connect_proxy
|
125
|
+
puts "Http2: Opening socket connection to '#{@args[:host]}:#{@args[:port]}' through proxy '#{@args[:proxy][:host]}:#{@args[:proxy][:port]}'." if @debug
|
126
|
+
@sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port].to_i)
|
127
|
+
end
|
128
|
+
|
129
|
+
def apply_ssl
|
130
|
+
puts "Http2: Initializing SSL." if @debug
|
131
|
+
require "openssl" unless ::Kernel.const_defined?(:OpenSSL)
|
132
|
+
|
133
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
134
|
+
#ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
135
|
+
|
136
|
+
@sock_ssl = OpenSSL::SSL::SSLSocket.new(@sock_plain, ssl_context)
|
137
|
+
@sock_ssl.sync_close = true
|
138
|
+
@sock_ssl.connect
|
139
|
+
|
140
|
+
@sock = @sock_ssl
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Http2::GetRequest
|
2
|
+
def initialize(http2, args)
|
3
|
+
@http2, @args, @debug, @nl = http2, http2.parse_args(args), http2.debug, http2.nl
|
4
|
+
end
|
5
|
+
|
6
|
+
def execute
|
7
|
+
@http2.mutex.synchronize do
|
8
|
+
puts "Http2: Writing headers: #{header_string}" if @debug
|
9
|
+
@http2.connection.write(header_string)
|
10
|
+
|
11
|
+
puts "Http2: Reading response." if @debug
|
12
|
+
resp = @http2.read_response(@args)
|
13
|
+
|
14
|
+
puts "Http2: Done with get request." if @debug
|
15
|
+
return resp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def method
|
22
|
+
if @args[:method]
|
23
|
+
@args[:method].to_s.upcase
|
24
|
+
else
|
25
|
+
"GET"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def header_string
|
30
|
+
header_str = "#{method} /#{@args[:url]} HTTP/1.1#{@nl}"
|
31
|
+
header_str << @http2.header_str(@http2.default_headers(@args), @args)
|
32
|
+
header_str << @nl
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Http2::PostDataGenerator
|
2
|
+
def initialize(pdata, args = {})
|
3
|
+
@pdata, @args = pdata, args
|
4
|
+
end
|
5
|
+
|
6
|
+
def generate
|
7
|
+
praw = ""
|
8
|
+
|
9
|
+
if @pdata.is_a?(Hash)
|
10
|
+
praw << generate_for_hash(@pdata)
|
11
|
+
elsif @pdata.is_a?(Array)
|
12
|
+
praw << generate_for_array(@pdata)
|
13
|
+
else
|
14
|
+
return @pdata.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
return praw
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def generate_for_hash(hash)
|
23
|
+
praw = ""
|
24
|
+
|
25
|
+
@pdata.each do |key, val|
|
26
|
+
praw << "&" if praw != ""
|
27
|
+
key = "#{@args[:orig_key]}[#{key}]" if @args[:orig_key]
|
28
|
+
praw << generate_key_value(key, val)
|
29
|
+
end
|
30
|
+
|
31
|
+
praw
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_for_array(array)
|
35
|
+
praw = ""
|
36
|
+
|
37
|
+
count = 0
|
38
|
+
@pdata.each do |val|
|
39
|
+
praw << "&" if praw != ""
|
40
|
+
|
41
|
+
if @args[:orig_key]
|
42
|
+
key = "#{@args[:orig_key]}[#{count}]"
|
43
|
+
else
|
44
|
+
key = count
|
45
|
+
end
|
46
|
+
|
47
|
+
praw << generate_key_value(key, val)
|
48
|
+
count += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
praw
|
52
|
+
end
|
53
|
+
|
54
|
+
def generate_key_value(key, value)
|
55
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
56
|
+
return ::Http2::PostDataGenerator.new(value, :orig_key => key).generate
|
57
|
+
else
|
58
|
+
data = ::Http2::PostDataGenerator.new(value).generate
|
59
|
+
return "#{Http2::Utils.urlenc(key)}=#{Http2::Utils.urlenc(data)}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "tempfile"
|
2
|
+
|
3
|
+
class Http2::PostMultipartRequest
|
4
|
+
def initialize(http2, *args)
|
5
|
+
@http2, @nl, @args = http2, http2.nl, http2.parse_args(*args)
|
6
|
+
@phash = @args[:post].clone
|
7
|
+
@http2.autostate_set_on_post_hash(phash) if @http2.autostate
|
8
|
+
@boundary = rand(36**50).to_s(36)
|
9
|
+
@conn = @http2.connection
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
generate_raw(@phash) do |helper, praw|
|
14
|
+
puts "Http2: Header string: #{header_string}" if @debug
|
15
|
+
|
16
|
+
@http2.mutex.synchronize do
|
17
|
+
@conn.write(header_string(praw))
|
18
|
+
|
19
|
+
praw.rewind
|
20
|
+
praw.each_line do |data|
|
21
|
+
@conn.sock_write(data)
|
22
|
+
end
|
23
|
+
|
24
|
+
return @http2.read_response(@args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def header_string(praw)
|
32
|
+
header_str = "POST /#{@args[:url]} HTTP/1.1#{@nl}"
|
33
|
+
header_str << @http2.header_str(@http2.default_headers(@args).merge(
|
34
|
+
"Content-Type" => "multipart/form-data; boundary=#{@boundary}",
|
35
|
+
"Content-Length" => praw.size
|
36
|
+
), @args)
|
37
|
+
header_str << @nl
|
38
|
+
|
39
|
+
return header_str
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_raw(phash)
|
43
|
+
Tempfile.open("http2_post_multipart_tmp_#{@boundary}") do |praw|
|
44
|
+
phash.each do |key, val|
|
45
|
+
add_headers(praw, key, val)
|
46
|
+
add_body(praw, val)
|
47
|
+
end
|
48
|
+
|
49
|
+
praw << "--#{@boundary}--"
|
50
|
+
|
51
|
+
yield self, praw
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def read_file(path, praw)
|
56
|
+
File.open(path, "r") do |fp|
|
57
|
+
begin
|
58
|
+
while data = fp.sysread(4096)
|
59
|
+
praw << data
|
60
|
+
end
|
61
|
+
rescue EOFError
|
62
|
+
# Happens when done.
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def parse_temp_file(key, val, praw)
|
68
|
+
praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.original_filename}\";#{@nl}"
|
69
|
+
praw << "Content-Length: #{val.to_s.bytesize}#{@nl}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_file(key, val, praw)
|
73
|
+
praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val[:filename]}\";#{@nl}"
|
74
|
+
|
75
|
+
if val[:content]
|
76
|
+
praw << "Content-Length: #{val[:content].to_s.bytesize}#{@nl}"
|
77
|
+
elsif val[:fpath]
|
78
|
+
praw << "Content-Length: #{File.size(val[:fpath])}#{@nl}"
|
79
|
+
else
|
80
|
+
raise "Could not figure out where to get content from."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_headers(praw, key, val)
|
85
|
+
praw << "--#{@boundary}#{@nl}"
|
86
|
+
|
87
|
+
if val.is_a?(Tempfile) && val.respond_to?(:original_filename)
|
88
|
+
parse_temp_file(key, val, praw)
|
89
|
+
elsif val.is_a?(Hash) && val[:filename]
|
90
|
+
parse_file(key, val, praw)
|
91
|
+
else
|
92
|
+
praw << "Content-Disposition: form-data; name=\"#{key}\";#{@nl}"
|
93
|
+
praw << "Content-Length: #{val.to_s.bytesize}#{@nl}"
|
94
|
+
end
|
95
|
+
|
96
|
+
praw << "Content-Type: text/plain#{@nl}"
|
97
|
+
praw << @nl
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_body(praw, val)
|
101
|
+
if val.class.name.to_s == "StringIO"
|
102
|
+
praw << val.read
|
103
|
+
elsif val.is_a?(Hash) && val[:content]
|
104
|
+
praw << val[:content].to_s
|
105
|
+
elsif val.is_a?(Hash) && val[:fpath]
|
106
|
+
read_file(val[:fpath], praw)
|
107
|
+
else
|
108
|
+
praw << val.to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
praw << @nl
|
112
|
+
end
|
113
|
+
end
|