nestful 1.0.0.pre → 1.0.0.rc1
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/README.markdown +40 -26
- data/examples/resource.rb +24 -3
- data/lib/nestful/connection.rb +11 -40
- data/lib/nestful/exceptions.rb +1 -0
- data/lib/nestful/formats/json_format.rb +1 -1
- data/lib/nestful/helpers.rb +12 -28
- data/lib/nestful/request.rb +6 -12
- data/lib/nestful/resource.rb +52 -48
- data/lib/nestful/version.rb +1 -1
- data/lib/nestful.rb +3 -3
- metadata +2 -4
- data/VERSION +0 -1
- data/lib/nestful/formats/multipart_format.rb +0 -80
data/README.markdown
CHANGED
@@ -7,56 +7,70 @@ Nestful is a simple Ruby HTTP/REST client with a sane API.
|
|
7
7
|
## Features
|
8
8
|
|
9
9
|
* Simple API
|
10
|
-
* File buffering
|
11
|
-
* Before/Progress/After Callbacks
|
12
10
|
* JSON requests
|
13
|
-
* Multipart requests (file uploading)
|
14
11
|
* Resource API
|
15
12
|
* Proxy support
|
16
13
|
* SSL support
|
17
14
|
|
18
|
-
##
|
15
|
+
## API
|
16
|
+
|
17
|
+
### GET request
|
18
|
+
|
19
|
+
Nestful.get 'http://example.com' #=> "body"
|
20
|
+
|
21
|
+
### POST request
|
22
|
+
|
23
|
+
Nestful.post 'http://example.com', :foo => 'bar'
|
24
|
+
Nestful.post 'http://example.com', {:foo => 'bar'}, :format => :json
|
25
|
+
|
26
|
+
### Parameters
|
27
|
+
|
28
|
+
Nestful.get 'http://example.com', :nestled => {:vars => 1}
|
29
|
+
|
30
|
+
## Request
|
31
|
+
|
32
|
+
`Request` is the base class for making HTTP requests - everthing else is just an abstraction upon it.
|
33
|
+
|
34
|
+
Request.new(url, options = {})
|
19
35
|
|
20
|
-
Request options:
|
36
|
+
Valid `Request` options are:
|
21
37
|
|
22
38
|
* headers (hash)
|
23
39
|
* params (hash)
|
24
40
|
* method (:get/:post/:put/:delete/:head)
|
25
|
-
|
26
|
-
Connection options:
|
27
|
-
|
28
41
|
* proxy
|
29
42
|
* user
|
30
43
|
* password
|
31
|
-
* auth_type
|
44
|
+
* auth_type (:basic/:bearer)
|
32
45
|
* timeout
|
33
46
|
* ssl_options
|
34
47
|
|
35
|
-
##
|
36
|
-
|
37
|
-
### GET request
|
38
|
-
|
39
|
-
Nestful.get 'http://example.com' #=> "body"
|
40
|
-
|
41
|
-
### POST request
|
48
|
+
## Endpoint
|
42
49
|
|
43
|
-
|
44
|
-
Nestful.post 'http://example.com', :params => {:foo => 'bar'}, :format => :json
|
50
|
+
The `Endpoint` class provides a single object to work with restful services. The following example does a GET request to the URL; http://example.com/assets/1/
|
45
51
|
|
46
|
-
|
52
|
+
Nestful::Endpoint.new('http://example.com')['assets'][1].get
|
47
53
|
|
48
|
-
|
54
|
+
## Resource
|
49
55
|
|
50
|
-
|
56
|
+
If you're building a binding for a REST API, then you should consider using the `Resource` class.
|
51
57
|
|
52
|
-
|
58
|
+
class Charge < Nestful::Resource
|
59
|
+
url 'https://api.stripe.com/v1/charges'
|
53
60
|
|
54
|
-
|
61
|
+
def self.all
|
62
|
+
self.new(get)
|
63
|
+
end
|
55
64
|
|
56
|
-
|
65
|
+
def self.find(id)
|
66
|
+
self.new(get(id))
|
67
|
+
end
|
57
68
|
|
58
|
-
|
69
|
+
def refund
|
70
|
+
post(:refund)
|
71
|
+
end
|
72
|
+
end
|
59
73
|
|
60
74
|
## Credits
|
61
75
|
|
62
|
-
|
76
|
+
Parts of the connection code were taken from ActiveResource
|
data/examples/resource.rb
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
require 'nestful'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
# Example of using Stripe's API
|
4
|
+
|
5
|
+
class Base < Nestful::Resource
|
6
|
+
endpoint 'https://api.stripe.com'
|
7
|
+
options :auth_type => :bearer, :password => ENV['SECRET_KEY']
|
8
|
+
|
9
|
+
def self.all(*args)
|
10
|
+
# We have to delve into the response,
|
11
|
+
# as Stripe doesn't return arrays for
|
12
|
+
# list responses.
|
13
|
+
self.new(Base.new(get('', *args)).data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(id)
|
17
|
+
self.new(get(id))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Charge < Base
|
22
|
+
path '/v1/charges'
|
23
|
+
|
24
|
+
def refund
|
25
|
+
post(:refund)
|
26
|
+
end
|
6
27
|
end
|
data/lib/nestful/connection.rb
CHANGED
@@ -5,12 +5,12 @@ module Nestful
|
|
5
5
|
class Connection
|
6
6
|
UriParser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :endpoint, :auth_type, :timeout, :proxy, :ssl_options
|
9
9
|
|
10
|
-
# The +
|
10
|
+
# The +endpoint+ parameter is required and will set the +endpoint+
|
11
11
|
# attribute to the URI for the remote resource service.
|
12
|
-
def initialize(
|
13
|
-
self.
|
12
|
+
def initialize(endpoint, options = {})
|
13
|
+
self.endpoint = endpoint
|
14
14
|
|
15
15
|
options.each do |key, value|
|
16
16
|
self.send("#{key}=", value) unless value.nil?
|
@@ -18,8 +18,8 @@ module Nestful
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# Set URI for remote service.
|
21
|
-
def
|
22
|
-
@
|
21
|
+
def endpoint=(endpoint)
|
22
|
+
@endpoint = endpoint.is_a?(URI) ? endpoint : UriParser.parse(endpoint)
|
23
23
|
end
|
24
24
|
|
25
25
|
# Set the proxy for remote service.
|
@@ -51,37 +51,8 @@ module Nestful
|
|
51
51
|
|
52
52
|
# Makes a request to the remote service.
|
53
53
|
def request(method, path, *arguments)
|
54
|
-
|
55
|
-
|
56
|
-
headers = arguments.shift || {}
|
57
|
-
|
58
|
-
method = Net::HTTP.const_get(method.to_s.capitalize)
|
59
|
-
method = method.new(path)
|
60
|
-
|
61
|
-
if body
|
62
|
-
if body.respond_to?(:read)
|
63
|
-
method.body_stream = body
|
64
|
-
else
|
65
|
-
method.body = body
|
66
|
-
end
|
67
|
-
|
68
|
-
if body.respond_to?(:size)
|
69
|
-
headers['Content-Length'] ||= body.size
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
headers.each do |name, value|
|
74
|
-
next unless value
|
75
|
-
method.add_field(name, value)
|
76
|
-
end
|
77
|
-
|
78
|
-
http.start do |stream|
|
79
|
-
stream.request(method) do |rsp|
|
80
|
-
handle_response(rsp)
|
81
|
-
yield(rsp) if block_given?
|
82
|
-
rsp
|
83
|
-
end
|
84
|
-
end
|
54
|
+
response = http.send(method, path, *arguments)
|
55
|
+
handle_response(response)
|
85
56
|
|
86
57
|
rescue Timeout::Error => e
|
87
58
|
raise TimeoutError.new(e.message)
|
@@ -131,11 +102,11 @@ module Nestful
|
|
131
102
|
|
132
103
|
def new_http
|
133
104
|
if proxy
|
134
|
-
Net::HTTP.new(
|
105
|
+
Net::HTTP.new(endpoint.host, endpoint.port,
|
135
106
|
proxy.host, proxy.port,
|
136
107
|
proxy.user, proxy.password)
|
137
108
|
else
|
138
|
-
Net::HTTP.new(
|
109
|
+
Net::HTTP.new(endpoint.host, endpoint.port)
|
139
110
|
end
|
140
111
|
end
|
141
112
|
|
@@ -152,7 +123,7 @@ module Nestful
|
|
152
123
|
end
|
153
124
|
|
154
125
|
def apply_ssl_options(http)
|
155
|
-
return http unless
|
126
|
+
return http unless endpoint.is_a?(URI::HTTPS)
|
156
127
|
|
157
128
|
http.use_ssl = true
|
158
129
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
data/lib/nestful/exceptions.rb
CHANGED
@@ -11,6 +11,7 @@ module Nestful
|
|
11
11
|
message = "Failed."
|
12
12
|
message << " Response code = #{response.code}." if response.respond_to?(:code)
|
13
13
|
message << " Response message = #{response.message}." if response.respond_to?(:message)
|
14
|
+
message << " Response Body = #{response.body}." if response.respond_to?(:body)
|
14
15
|
message
|
15
16
|
end
|
16
17
|
end
|
data/lib/nestful/helpers.rb
CHANGED
@@ -2,40 +2,24 @@ require 'cgi'
|
|
2
2
|
|
3
3
|
module Nestful
|
4
4
|
module Helpers extend self
|
5
|
-
def
|
6
|
-
case
|
7
|
-
when Hash
|
8
|
-
|
9
|
-
|
10
|
-
when Array
|
11
|
-
prefix = "#{key}[]"
|
12
|
-
value.collect { |v| to_query(prefix, v) }.join('&')
|
13
|
-
|
5
|
+
def to_param(value, key = nil)
|
6
|
+
case value
|
7
|
+
when Hash then value.map { |k,v| to_param(v, append_key(key,k)) }.join('&')
|
8
|
+
when Array then value.map { |v| to_param(v, "#{key}[]") }.join('&')
|
9
|
+
when nil then ''
|
14
10
|
else
|
15
|
-
value
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_param(object, namespace = nil)
|
20
|
-
case object
|
21
|
-
when Hash
|
22
|
-
object.map do |key, value|
|
23
|
-
key = "#{namespace}[#{key}]" if namespace
|
24
|
-
to_query(key, value)
|
25
|
-
end.join('&')
|
26
|
-
|
27
|
-
when Array
|
28
|
-
object.each do |value|
|
29
|
-
to_param(value)
|
30
|
-
end.join('/')
|
31
|
-
|
32
|
-
else
|
33
|
-
value
|
11
|
+
"#{key}=#{CGI.escape(value.to_s)}"
|
34
12
|
end
|
35
13
|
end
|
36
14
|
|
37
15
|
def camelize(value)
|
38
16
|
value.to_s.split('_').map {|w| w.capitalize }.join
|
39
17
|
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def append_key(root_key, key)
|
22
|
+
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
|
23
|
+
end
|
40
24
|
end
|
41
25
|
end
|
data/lib/nestful/request.rb
CHANGED
@@ -35,13 +35,13 @@ module Nestful
|
|
35
35
|
def uri
|
36
36
|
return @uri if @uri
|
37
37
|
|
38
|
-
url = @url.match(
|
38
|
+
url = @url.match(/\Ahttps?:\/\//) ? @url : "http://#{@url}"
|
39
39
|
|
40
40
|
@uri = URI.parse(url)
|
41
|
-
@uri.path =
|
41
|
+
@uri.path = '/' if @uri.path.empty?
|
42
42
|
|
43
|
-
@uri.query.split(
|
44
|
-
key, value = res.split(
|
43
|
+
@uri.query.split('&').each do |res|
|
44
|
+
key, value = res.split('=')
|
45
45
|
@params[key] = value
|
46
46
|
end if @uri.query
|
47
47
|
|
@@ -53,16 +53,10 @@ module Nestful
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def execute
|
56
|
-
result = nil
|
57
|
-
|
58
56
|
if encoded?
|
59
|
-
connection.send(method, path, encoded, build_headers)
|
60
|
-
result = res
|
61
|
-
end
|
57
|
+
result = connection.send(method, path, encoded, build_headers)
|
62
58
|
else
|
63
|
-
connection.send(method, query_path, build_headers)
|
64
|
-
result = res
|
65
|
-
end
|
59
|
+
result = connection.send(method, query_path, build_headers)
|
66
60
|
end
|
67
61
|
|
68
62
|
Response.new(result)
|
data/lib/nestful/resource.rb
CHANGED
@@ -4,82 +4,93 @@ module Nestful
|
|
4
4
|
class Resource
|
5
5
|
def self.endpoint(value = nil)
|
6
6
|
@endpoint = value if value
|
7
|
-
@endpoint
|
7
|
+
return @endpoint if @endpoint
|
8
|
+
superclass.respond_to?(:endpoint) ? superclass.endpoint : nil
|
8
9
|
end
|
9
10
|
|
10
|
-
def self.
|
11
|
-
@
|
12
|
-
@
|
11
|
+
def self.path(value = nil)
|
12
|
+
@path = value if value
|
13
|
+
return @path if @path
|
14
|
+
superclass.respond_to?(:path) ? superclass.path : nil
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.options(value = nil)
|
16
18
|
@options = value if value
|
17
|
-
@options
|
19
|
+
return @options if @options
|
20
|
+
superclass.respond_to?(:options) ? superclass.options : nil
|
18
21
|
end
|
19
22
|
|
20
|
-
def self.
|
21
|
-
|
23
|
+
def self.url
|
24
|
+
URI.join(endpoint.to_s, path.to_s).to_s
|
22
25
|
end
|
23
26
|
|
24
|
-
def self.
|
25
|
-
|
27
|
+
def self.uri(*parts)
|
28
|
+
parts.unshift(path)
|
29
|
+
parts.unshift(endpoint)
|
30
|
+
URI.join(*parts.compact.map(&:to_s))
|
26
31
|
end
|
27
32
|
|
28
|
-
def self.
|
29
|
-
request(
|
33
|
+
def self.get(action = '', params = {}, options = {})
|
34
|
+
request(uri(action), options.merge(:method => :get, :params => params))
|
30
35
|
end
|
31
36
|
|
32
|
-
def self.
|
33
|
-
request(
|
37
|
+
def self.put(action = '', params = {}, options = {})
|
38
|
+
request(uri(action), options.merge(:method => :put, :params => params))
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.post(action = '', params = {}, options = {})
|
42
|
+
request(uri(action), options.merge(:method => :post, :params => params))
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.delete(action = '', params = {}, options = {})
|
46
|
+
request(uri(action), options.merge(:method => :delete, :params => params))
|
34
47
|
end
|
35
48
|
|
36
49
|
def self.request(url, options = {})
|
37
50
|
Request.new(url, self.options.merge(options)).execute
|
38
51
|
end
|
39
52
|
|
40
|
-
def self.all
|
41
|
-
self.new(get(
|
53
|
+
def self.all(*args)
|
54
|
+
self.new(get('', *args))
|
42
55
|
end
|
43
56
|
|
44
57
|
def self.find(id)
|
45
|
-
self.new(get(
|
58
|
+
self.new(get(id))
|
46
59
|
end
|
47
60
|
|
48
|
-
def self.new(attributes = {}
|
61
|
+
def self.new(attributes = {})
|
49
62
|
if attributes.is_a?(Array)
|
50
|
-
attributes.map {|set| super(set
|
63
|
+
attributes.map {|set| super(set) }
|
51
64
|
else
|
52
65
|
super
|
53
66
|
end
|
54
67
|
end
|
55
68
|
|
56
|
-
attr_reader :attributes
|
69
|
+
attr_reader :attributes
|
57
70
|
|
58
|
-
def initialize(attributes = {}
|
59
|
-
@attributes =
|
60
|
-
|
71
|
+
def initialize(attributes = {})
|
72
|
+
@attributes = {}
|
73
|
+
load(attributes)
|
61
74
|
end
|
62
75
|
|
63
|
-
def get(*args)
|
64
|
-
self.class.get(
|
76
|
+
def get(action = '', *args)
|
77
|
+
self.class.get(uri(action), *args)
|
65
78
|
end
|
66
79
|
|
67
|
-
def put(*args)
|
68
|
-
self.class.put(
|
80
|
+
def put(action = '', *args)
|
81
|
+
self.class.put(uri(action), *args)
|
69
82
|
end
|
70
83
|
|
71
|
-
def post(*args)
|
72
|
-
self.class.post(
|
84
|
+
def post(action = '', *args)
|
85
|
+
self.class.post(uri(action), *args)
|
73
86
|
end
|
74
87
|
|
75
|
-
def delete(*args)
|
76
|
-
self.class.delete(
|
88
|
+
def delete(action = '', *args)
|
89
|
+
self.class.delete(uri(action), *args)
|
77
90
|
end
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
def url
|
82
|
-
URI.join(self.class.url, self.id.to_s)
|
92
|
+
def uri(*parts)
|
93
|
+
self.class.uri(self.id, *parts)
|
83
94
|
end
|
84
95
|
|
85
96
|
def id #:nodoc:
|
@@ -99,7 +110,7 @@ module Nestful
|
|
99
110
|
end
|
100
111
|
|
101
112
|
def to_hash
|
102
|
-
|
113
|
+
attributes.dup
|
103
114
|
end
|
104
115
|
|
105
116
|
alias_method :as_json, :to_hash
|
@@ -108,6 +119,12 @@ module Nestful
|
|
108
119
|
as_json.to_json
|
109
120
|
end
|
110
121
|
|
122
|
+
def load(attributes = {})
|
123
|
+
attributes.to_hash.each do |key, value|
|
124
|
+
send("#{key}=", value)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
111
128
|
alias_method :respond_to_without_attributes?, :respond_to?
|
112
129
|
|
113
130
|
def respond_to?(method, include_priv = false)
|
@@ -123,19 +140,6 @@ module Nestful
|
|
123
140
|
|
124
141
|
protected
|
125
142
|
|
126
|
-
def indifferent_attributes(attributes)
|
127
|
-
attributes = indifferent_hash.merge(attributes)
|
128
|
-
attributes.each do |key, value|
|
129
|
-
next unless value.is_a?(Hash)
|
130
|
-
attributes[key] = indifferent_attributes(value)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
# Creates a Hash with indifferent access.
|
135
|
-
def indifferent_hash
|
136
|
-
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
137
|
-
end
|
138
|
-
|
139
143
|
def method_missing(method_symbol, *arguments) #:nodoc:
|
140
144
|
method_name = method_symbol.to_s
|
141
145
|
|
data/lib/nestful/version.rb
CHANGED
data/lib/nestful.rb
CHANGED
@@ -16,15 +16,15 @@ module Nestful
|
|
16
16
|
Endpoint[url].get(*args)
|
17
17
|
end
|
18
18
|
|
19
|
-
def post(url,
|
19
|
+
def post(url, *args)
|
20
20
|
Endpoint[url].post(*args)
|
21
21
|
end
|
22
22
|
|
23
|
-
def put(url,
|
23
|
+
def put(url, *args)
|
24
24
|
Endpoint[url].put(*args)
|
25
25
|
end
|
26
26
|
|
27
|
-
def delete(url,
|
27
|
+
def delete(url, *args)
|
28
28
|
Endpoint[url].delete(*args)
|
29
29
|
end
|
30
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nestful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -23,7 +23,6 @@ files:
|
|
23
23
|
- MIT-LICENSE
|
24
24
|
- README.markdown
|
25
25
|
- Rakefile
|
26
|
-
- VERSION
|
27
26
|
- examples/resource.rb
|
28
27
|
- lib/nestful.rb
|
29
28
|
- lib/nestful/.DS_Store
|
@@ -33,7 +32,6 @@ files:
|
|
33
32
|
- lib/nestful/formats.rb
|
34
33
|
- lib/nestful/formats/form_format.rb
|
35
34
|
- lib/nestful/formats/json_format.rb
|
36
|
-
- lib/nestful/formats/multipart_format.rb
|
37
35
|
- lib/nestful/helpers.rb
|
38
36
|
- lib/nestful/request.rb
|
39
37
|
- lib/nestful/resource.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.8
|
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
require 'tempfile'
|
3
|
-
|
4
|
-
module Nestful
|
5
|
-
module Formats
|
6
|
-
class MultipartFormat < Format
|
7
|
-
EOL = "\r\n"
|
8
|
-
|
9
|
-
attr_reader :boundary, :stream
|
10
|
-
|
11
|
-
def initialize(*args)
|
12
|
-
super
|
13
|
-
@boundary = SecureRandom.hex(10)
|
14
|
-
@stream = Tempfile.new("nf.#{rand(1000)}")
|
15
|
-
@stream.binmode
|
16
|
-
end
|
17
|
-
|
18
|
-
def mime_type
|
19
|
-
%Q{multipart/form-data; boundary=#{boundary}}
|
20
|
-
end
|
21
|
-
|
22
|
-
def encode(params, options = nil)
|
23
|
-
to_multipart(params)
|
24
|
-
stream.write("--" + boundary + "--" + EOL)
|
25
|
-
stream.flush
|
26
|
-
stream.rewind
|
27
|
-
stream
|
28
|
-
end
|
29
|
-
|
30
|
-
def decode(body)
|
31
|
-
body
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
def to_multipart(params, namespace = nil)
|
36
|
-
params.each do |key, value|
|
37
|
-
key = namespace ? "#{namespace}[#{key}]" : key
|
38
|
-
|
39
|
-
# Support nestled params
|
40
|
-
if value.is_a?(Hash)
|
41
|
-
to_multipart(value, key)
|
42
|
-
next
|
43
|
-
end
|
44
|
-
|
45
|
-
stream.write("--" + boundary + EOL)
|
46
|
-
|
47
|
-
if value.respond_to?(:read)
|
48
|
-
create_file_field(key, value)
|
49
|
-
else
|
50
|
-
create_field(key, value)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def create_file_field(key, value)
|
56
|
-
stream.write(%Q{Content-Disposition: form-data; name="#{key}"; filename="#{filename(value)}"} + EOL)
|
57
|
-
stream.write(%Q{Content-Type: application/octet-stream} + EOL)
|
58
|
-
stream.write(%Q{Content-Transfer-Encoding: binary} + EOL)
|
59
|
-
stream.write(EOL)
|
60
|
-
while data = value.read(8124)
|
61
|
-
stream.write(data)
|
62
|
-
end
|
63
|
-
stream.write(EOL)
|
64
|
-
end
|
65
|
-
|
66
|
-
def create_field(key, value)
|
67
|
-
stream.write(%Q{Content-Disposition: form-data; name="#{key}"} + EOL)
|
68
|
-
stream.write(EOL)
|
69
|
-
stream.write(value)
|
70
|
-
stream.write(EOL)
|
71
|
-
end
|
72
|
-
|
73
|
-
def filename(body)
|
74
|
-
return body.original_filename if body.respond_to?(:original_filename)
|
75
|
-
return File.basename(body.path) if body.respond_to?(:path)
|
76
|
-
'Unknown'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|