markdillon-restclient 1.0 → 1.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/lib/restclient/mixin/response.rb +43 -0
- data/lib/restclient/multipart.rb +88 -0
- data/restclient.gemspec +2 -1
- metadata +3 -1
@@ -0,0 +1,43 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Mixin
|
3
|
+
module Response
|
4
|
+
attr_reader :net_http_res
|
5
|
+
|
6
|
+
# HTTP status code, always 200 since RestClient throws exceptions for
|
7
|
+
# other codes.
|
8
|
+
def code
|
9
|
+
@code ||= @net_http_res.code.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
# A hash of the headers, beautified with symbols and underscores.
|
13
|
+
# e.g. "Content-type" will become :content_type.
|
14
|
+
def headers
|
15
|
+
@headers ||= self.class.beautify_headers(@net_http_res.to_hash)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Hash of cookies extracted from response headers
|
19
|
+
def cookies
|
20
|
+
@cookies ||= (self.headers[:set_cookie] || "").split('; ').inject({}) do |out, raw_c|
|
21
|
+
key, val = raw_c.split('=')
|
22
|
+
unless %w(expires domain path secure).member?(key)
|
23
|
+
out[key] = val
|
24
|
+
end
|
25
|
+
out
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.included(receiver)
|
30
|
+
receiver.extend(RestClient::Mixin::Response::ClassMethods)
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
def beautify_headers(headers)
|
35
|
+
headers.inject({}) do |out, (key, value)|
|
36
|
+
out[key.gsub(/-/, '_').to_sym] = value.first
|
37
|
+
out
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class Base
|
2
|
+
def initialize(params)
|
3
|
+
build_stream(params)
|
4
|
+
end
|
5
|
+
|
6
|
+
def build_stream(params)
|
7
|
+
@stream = StringIO.new(params)
|
8
|
+
@stream.seek(0)
|
9
|
+
end
|
10
|
+
|
11
|
+
def read(bytes=nil)
|
12
|
+
@stream.read(bytes)
|
13
|
+
end
|
14
|
+
alias :to_s :read
|
15
|
+
|
16
|
+
def escape(v)
|
17
|
+
URI.escape(v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def headers
|
21
|
+
{ 'Content-Length' => size.to_s }
|
22
|
+
end
|
23
|
+
|
24
|
+
def size
|
25
|
+
@stream.size
|
26
|
+
end
|
27
|
+
alias :length :size
|
28
|
+
|
29
|
+
def close
|
30
|
+
@stream.close
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Multipart < Base
|
35
|
+
EOL = "\r\n"
|
36
|
+
|
37
|
+
def build_stream(params)
|
38
|
+
b = "--#{boundary}"
|
39
|
+
|
40
|
+
@stream = Tempfile.new("RESTClient.Stream.#{rand(1000)}")
|
41
|
+
@stream.write(b)
|
42
|
+
params.each do |k,v|
|
43
|
+
@stream.write(EOL)
|
44
|
+
if v.respond_to?(:read) && v.respond_to?(:path)
|
45
|
+
create_file_field(@stream, k,v)
|
46
|
+
else
|
47
|
+
create_regular_field(@stream, k,v)
|
48
|
+
end
|
49
|
+
@stream.write(EOL + b)
|
50
|
+
end
|
51
|
+
@stream.write('--')
|
52
|
+
@stream.write(EOL)
|
53
|
+
@stream.seek(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_regular_field(s, k, v)
|
57
|
+
s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"")
|
58
|
+
s.write(EOL)
|
59
|
+
s.write(EOL)
|
60
|
+
s.write(v)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_file_field(s, k, v, content_type = nil)
|
64
|
+
begin
|
65
|
+
content_type ||= `file -b --mime #{v.path}`.gsub(/\n/, '')
|
66
|
+
s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"; filename=\"#{v.path}\"#{EOL}")
|
67
|
+
s.write("Content-Type: #{content_type}#{EOL}")
|
68
|
+
s.write(EOL)
|
69
|
+
while data = v.read(8124)
|
70
|
+
s.write(data)
|
71
|
+
end
|
72
|
+
ensure
|
73
|
+
v.close
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def boundary
|
78
|
+
@boundary ||= rand(1_000_000).to_s
|
79
|
+
end
|
80
|
+
|
81
|
+
def headers
|
82
|
+
super.merge({:content_type => %Q{multipart/form-data; boundary="#{boundary}"}})
|
83
|
+
end
|
84
|
+
|
85
|
+
def close
|
86
|
+
@stream.close
|
87
|
+
end
|
88
|
+
end
|
data/restclient.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "restclient"
|
3
|
-
s.version = "1.
|
3
|
+
s.version = "1.1"
|
4
4
|
s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
|
5
5
|
s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
|
6
6
|
s.author = "Adam Wiggins"
|
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
lib/restclient.rb
|
13
13
|
lib/restclient/request.rb lib/restclient/response.rb
|
14
14
|
lib/restclient/exceptions.rb lib/restclient/resource.rb
|
15
|
+
lib/restclient/multipart.rb lib/restclient/mixin/response.rb
|
15
16
|
spec/base.rb spec/request_spec.rb spec/response_spec.rb
|
16
17
|
spec/exceptions_spec.rb spec/resource_spec.rb spec/restclient_spec.rb
|
17
18
|
bin/restclient)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdillon-restclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.1"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -30,6 +30,8 @@ files:
|
|
30
30
|
- lib/restclient/response.rb
|
31
31
|
- lib/restclient/exceptions.rb
|
32
32
|
- lib/restclient/resource.rb
|
33
|
+
- lib/restclient/multipart.rb
|
34
|
+
- lib/restclient/mixin/response.rb
|
33
35
|
- spec/base.rb
|
34
36
|
- spec/request_spec.rb
|
35
37
|
- spec/response_spec.rb
|