rest-core 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b126115b38499438877d2c55fe68b14c3d9989bd
4
- data.tar.gz: 6ba8f157a2025d94fe326767dc36823d11585854
3
+ metadata.gz: 5cc0c6118d2d5169988871b31d9b5544e2f28f60
4
+ data.tar.gz: c73e366ba7c4cdbdec4a5a76528ed5d8df21aed4
5
5
  SHA512:
6
- metadata.gz: 14b1c0022f58a2af1a26bb0126159937b0540ee462bb6fe96db3fa777e0ba7cd14183e6ff8e051e45acc65c02708a69f51b31ad3371d0792e4124c2811029720
7
- data.tar.gz: 4a3e037e2b30b77c57e7b030c05322389c1a585766ba414d137ce790c8c3e0b1c141c281a1dd664d07e47150a1f9f2a963059e42ffdad91d63549afd07ce095f
6
+ metadata.gz: c175b2f84c14257fe189ae82bee8f1d3a2bd205ac4da36ab8b0b596ccfdf47253d05b8cb4940c4ebe47e770385ed282b6dfadf53db04a1fba67adc4975ae177e
7
+ data.tar.gz: 53cd1bed753213a3a27637ceb85acf9577504aaa48cf0b760c48c20a6cd35c87f96f8b8c2dc438b568adc8404d1b4c19066dbb5efc6c40871d5ea91e78cd43e5
data/CHANGES.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-core 2.1.1 -- 2013-05-21
4
+
5
+ ### Bugs fixes
6
+
7
+ * Fixed em-http-request support.
8
+
9
+ ### Enhancement
10
+
11
+ * [`Payload`] Now it is a class rather than a module.
12
+ * [`Paylaod`] Introduced `Payload.generate_with_headers`.
13
+ * [`Paylaod`] Give a `nil` if payload passing to `Payload.generate` should
14
+ not have any payload at all.
15
+
3
16
  ## rest-core 2.1.0 -- 2013-05-08
4
17
 
5
18
  ### Incompatible changes
data/Rakefile CHANGED
@@ -24,7 +24,7 @@ task 'gem:spec' do
24
24
  s.email = ['dev (XD) cardinalblue.com']
25
25
 
26
26
  s.post_install_message = <<-MARKDOWN
27
- # [rest-core] Incompatible changes for POST requests:
27
+ # [rest-core] Since 2.1.0, Incompatible changes for POST requests:
28
28
 
29
29
  * We no longer support Rails-like POST payload, like translating
30
30
  `{:foo => [1, 2]}` to `'foo[]=1&foo[]=2'`. It would now be translated to
@@ -20,41 +20,37 @@ class RestCore::EmHttpRequest
20
20
  FUTURE => future)
21
21
  end
22
22
 
23
- def close client, tmpfile
24
- (client.instance_variable_get(:@callbacks)||[]).clear
25
- (client.instance_variable_get(:@errbacks )||[]).clear
26
- client.close
27
- if tmpfile.respond_to?(:close!) # tempfile
28
- tmpfile.close!
29
- elsif tmpfile.respond_to?(:close) # regular IO
30
- tmpfile.close
31
- end
32
- end
33
-
34
23
  def request future, env
35
- payload = Payload.generate(env[REQUEST_PAYLOAD])
36
- tmpfile = payload2file(payload)
37
- args = if tmpfile.respond_to?(:path)
38
- {:file => tmpfile.path}
39
- else
40
- {:body => tmpfile}
41
- end
42
- client = ::EventMachine::HttpRequest.new(request_uri(env)).send(
43
- env[REQUEST_METHOD], args.merge(
44
- :head => payload.headers.merge(env[REQUEST_HEADERS])))
24
+ payload, headers = Payload.generate_with_headers(env[REQUEST_PAYLOAD],
25
+ env[REQUEST_HEADERS])
26
+ args = if payload.nil?
27
+ {}
28
+ else
29
+ tmpfile = payload2file(payload)
30
+ if tmpfile.respond_to?(:path)
31
+ {:file => tmpfile.path}
32
+ else
33
+ {:body => tmpfile}
34
+ end
35
+ end.merge(:head => headers)
36
+
37
+ client = ::EventMachine::HttpRequest.new(request_uri(env)).
38
+ send(env[REQUEST_METHOD], args)
45
39
 
46
40
  client.callback{
47
- close(client, tmpfile)
41
+ close_tmpfile(tmpfile)
48
42
  future.on_load(client.response,
49
43
  client.response_header.status,
50
44
  client.response_header)}
51
45
 
52
46
  client.errback{
53
- close(client, tmpfile)
47
+ close_client(client)
48
+ close_tmpfile(tmpfile)
54
49
  future.on_error(client.error)}
55
50
 
56
51
  env[TIMER].on_timeout{
57
- close(client, tmpfile)
52
+ close_client(client)
53
+ close_tmpfile(tmpfile)
58
54
  future.on_error(env[TIMER].error)
59
55
  } if env[TIMER]
60
56
  end
@@ -77,4 +73,18 @@ class RestCore::EmHttpRequest
77
73
  IO.copy_stream(io, tempfile)
78
74
  tempfile
79
75
  end
76
+
77
+ def close_client client
78
+ (client.instance_variable_get(:@callbacks)||[]).clear
79
+ (client.instance_variable_get(:@errbacks )||[]).clear
80
+ client.close
81
+ end
82
+
83
+ def close_tmpfile tmpfile
84
+ if tmpfile.respond_to?(:close!) # tempfile
85
+ tmpfile.close!
86
+ elsif tmpfile.respond_to?(:close) # regular IO
87
+ tmpfile.close
88
+ end
89
+ end
80
90
  end
@@ -10,29 +10,8 @@ class RestCore::RestClient
10
10
  def call env, &k
11
11
  future = Future::FutureThread.new(env, k, env[ASYNC])
12
12
 
13
- t = future.wrap{ # we can implement thread pool in the future
14
- begin
15
- payload = Payload.generate(env[REQUEST_PAYLOAD])
16
- headers = env[REQUEST_HEADERS].merge(payload.headers)
17
- res = ::RestClient::Request.execute(:method => env[REQUEST_METHOD],
18
- :url => request_uri(env) ,
19
- :payload => payload ,
20
- :headers => headers ,
21
- :max_redirects => 0)
22
- future.on_load(res.body, res.code, normalize_headers(res.raw_headers))
23
-
24
- rescue ::RestClient::Exception => e
25
- if res = e.response
26
- # we don't want to raise an exception for 404 requests
27
- future.on_load(res.body, res.code,
28
- normalize_headers(res.raw_headers))
29
- else
30
- future.on_error(e)
31
- end
32
- rescue Exception => e
33
- future.on_error(e)
34
- end
35
- }
13
+ # we can implement thread pool in the future
14
+ t = future.wrap{ request(future, env) }
36
15
 
37
16
  env[TIMER].on_timeout{
38
17
  t.kill
@@ -45,6 +24,27 @@ class RestCore::RestClient
45
24
  FUTURE => future)
46
25
  end
47
26
 
27
+ def request future, env
28
+ payload, headers = Payload.generate_with_headers(env[REQUEST_PAYLOAD],
29
+ env[REQUEST_HEADERS])
30
+ res = ::RestClient::Request.execute(:method => env[REQUEST_METHOD],
31
+ :url => request_uri(env) ,
32
+ :payload => payload ,
33
+ :headers => headers ,
34
+ :max_redirects => 0)
35
+ future.on_load(res.body, res.code, normalize_headers(res.raw_headers))
36
+
37
+ rescue ::RestClient::Exception => e
38
+ if res = e.response
39
+ # we don't want to raise an exception for 404 requests
40
+ future.on_load(res.body, res.code, normalize_headers(res.raw_headers))
41
+ else
42
+ future.on_error(e)
43
+ end
44
+ rescue Exception => e
45
+ future.on_error(e)
46
+ end
47
+
48
48
  def normalize_headers raw_headers
49
49
  raw_headers.inject({}){ |r, (k, v)|
50
50
  r[k.to_s.upcase.tr('-', '_')] = if v.kind_of?(Array) && v.size == 1
@@ -9,11 +9,19 @@ require 'stringio'
9
9
  require 'tempfile'
10
10
 
11
11
  module RestCore; end
12
- module RestCore::Payload
12
+ class RestCore::Payload
13
13
  include RestCore
14
- module_function
15
14
 
16
- def generate payload
15
+ def self.generate_with_headers payload, headers
16
+ h = if p = generate(payload)
17
+ p.headers.merge(headers)
18
+ else
19
+ headers
20
+ end
21
+ [p, h]
22
+ end
23
+
24
+ def self.generate payload
17
25
  if payload.respond_to?(:read)
18
26
  Streamed.new(payload)
19
27
 
@@ -21,7 +29,10 @@ module RestCore::Payload
21
29
  StreamedString.new(payload)
22
30
 
23
31
  elsif payload.kind_of?(Hash)
24
- if Middleware.contain_binary?(payload)
32
+ if payload.empty?
33
+ nil
34
+
35
+ elsif Middleware.contain_binary?(payload)
25
36
  Multipart.new(payload)
26
37
 
27
38
  else
@@ -34,34 +45,30 @@ module RestCore::Payload
34
45
  end
35
46
  end
36
47
 
37
- class Streamed
38
- def initialize payload
39
- @io = payload
40
- end
41
-
42
- attr_reader :io
43
- alias_method :to_io, :io
44
-
45
- def read bytes=nil
46
- io.read(bytes)
48
+ # Payload API
49
+ attr_reader :io
50
+ alias_method :to_io, :io
51
+
52
+ def initialize payload; @io = payload ; end
53
+ def read bytes=nil; io.read(bytes) ; end
54
+ def close ; io.close unless closed?; end
55
+ def closed? ; io.closed? ; end
56
+ def headers ; {} ; end
57
+
58
+ def size
59
+ if io.respond_to?(:size)
60
+ io.size
61
+ elsif io.respond_to?(:stat)
62
+ io.stat.size
63
+ else
64
+ 0
47
65
  end
66
+ end
48
67
 
68
+ class Streamed < Payload
49
69
  def headers
50
70
  {'Content-Length' => size.to_s}
51
71
  end
52
-
53
- def size
54
- if io.respond_to?(:size)
55
- io.size
56
- elsif io.respond_to?(:stat)
57
- io.stat.size
58
- else
59
- 0
60
- end
61
- end
62
-
63
- def close ; io.close unless closed?; end
64
- def closed?; io.closed? ; end
65
72
  end
66
73
 
67
74
  class StreamedString < Streamed
@@ -1,4 +1,4 @@
1
1
 
2
2
  module RestCore
3
- VERSION = '2.1.0'
3
+ VERSION = '2.1.1'
4
4
  end
data/rest-core.gemspec CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rest-core"
5
- s.version = "2.1.0"
5
+ s.version = "2.1.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = [
9
9
  "Cardinal Blue",
10
10
  "Lin Jen-Shin (godfat)"]
11
- s.date = "2013-05-08"
11
+ s.date = "2013-05-21"
12
12
  s.description = "Modular Ruby clients interface for REST APIs.\n\nThere has been an explosion in the number of REST APIs available today.\nTo address the need for a way to access these APIs easily and elegantly,\nwe have developed rest-core, which consists of composable middleware\nthat allows you to build a REST client for any REST API. Or in the case of\ncommon APIs such as Facebook, Github, and Twitter, you can simply use the\ndedicated clients provided by [rest-more][].\n\n[rest-more]: https://github.com/cardinalblue/rest-more"
13
13
  s.email = ["dev (XD) cardinalblue.com"]
14
14
  s.files = [
@@ -97,7 +97,7 @@ Gem::Specification.new do |s|
97
97
  "test/test_wrapper.rb"]
98
98
  s.homepage = "https://github.com/cardinalblue/rest-core"
99
99
  s.licenses = ["Apache License 2.0"]
100
- s.post_install_message = "# [rest-core] Incompatible changes for POST requests:\n\n* We no longer support Rails-like POST payload, like translating\n `{:foo => [1, 2]}` to `'foo[]=1&foo[]=2'`. It would now be translated to\n `'foo=1&foo=2'`. If you like `'foo[]'` as the key, simply pass it as\n `{'foo[]' => [1, 2]}`.\n\n* This also applies to nested hashes like `{:foo => {:bar => 1}`. If you\n want that behaviour, just pass `{'foo[bar]' => 1}` which would then be\n translated to `'foo[bar]=1'`.\n"
100
+ s.post_install_message = "# [rest-core] Since 2.1.0, Incompatible changes for POST requests:\n\n* We no longer support Rails-like POST payload, like translating\n `{:foo => [1, 2]}` to `'foo[]=1&foo[]=2'`. It would now be translated to\n `'foo=1&foo=2'`. If you like `'foo[]'` as the key, simply pass it as\n `{'foo[]' => [1, 2]}`.\n\n* This also applies to nested hashes like `{:foo => {:bar => 1}`. If you\n want that behaviour, just pass `{'foo[bar]' => 1}` which would then be\n translated to `'foo[bar]=1'`.\n"
101
101
  s.require_paths = ["lib"]
102
102
  s.rubygems_version = "2.0.3"
103
103
  s.summary = "Modular Ruby clients interface for REST APIs."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cardinal Blue
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-08 00:00:00.000000000 Z
12
+ date: 2013-05-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -130,7 +130,7 @@ licenses:
130
130
  - Apache License 2.0
131
131
  metadata: {}
132
132
  post_install_message: |
133
- # [rest-core] Incompatible changes for POST requests:
133
+ # [rest-core] Since 2.1.0, Incompatible changes for POST requests:
134
134
 
135
135
  * We no longer support Rails-like POST payload, like translating
136
136
  `{:foo => [1, 2]}` to `'foo[]=1&foo[]=2'`. It would now be translated to