riak-client 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +14 -5
- data/Rakefile +71 -18
- data/lib/riak.rb +13 -6
- data/lib/riak/bucket.rb +7 -4
- data/lib/riak/cache_store.rb +7 -1
- data/lib/riak/client.rb +31 -14
- data/lib/riak/client/curb_backend.rb +11 -18
- data/lib/riak/client/excon_backend.rb +60 -0
- data/lib/riak/client/http_backend.rb +33 -2
- data/lib/riak/client/net_http_backend.rb +11 -2
- data/lib/riak/core_ext.rb +6 -0
- data/lib/riak/core_ext/blank.rb +39 -0
- data/lib/riak/core_ext/extract_options.rb +7 -0
- data/lib/riak/core_ext/slice.rb +18 -0
- data/lib/riak/core_ext/stringify_keys.rb +10 -0
- data/lib/riak/core_ext/symbolize_keys.rb +10 -0
- data/lib/riak/core_ext/to_param.rb +31 -0
- data/lib/riak/i18n.rb +1 -5
- data/lib/riak/link.rb +36 -19
- data/lib/riak/locale/en.yml +1 -1
- data/lib/riak/map_reduce.rb +9 -8
- data/lib/riak/robject.rb +13 -6
- data/lib/riak/search.rb +7 -2
- data/lib/riak/test_server.rb +5 -1
- data/riak-client.gemspec +49 -0
- data/spec/integration/riak/cache_store_spec.rb +2 -1
- data/spec/riak/client_spec.rb +15 -9
- data/spec/riak/curb_backend_spec.rb +14 -15
- data/spec/riak/excon_backend_spec.rb +76 -0
- data/spec/riak/link_spec.rb +8 -14
- data/spec/riak/object_spec.rb +0 -4
- data/spec/riak/search_spec.rb +2 -2
- data/spec/support/drb_mock_server.rb +39 -0
- data/spec/support/mock_server.rb +16 -3
- data/spec/support/test_server.yml.example +2 -0
- metadata +42 -18
- data/Gemfile.lock +0 -35
data/Gemfile
CHANGED
@@ -1,13 +1,22 @@
|
|
1
|
-
# A sample Gemfile
|
2
1
|
source :gemcutter
|
3
2
|
|
4
|
-
gem 'activesupport', '~>2.3.5' #'~>3.0.0'
|
5
3
|
gem 'i18n'
|
6
|
-
|
4
|
+
gem 'builder'
|
7
5
|
gem 'rspec', "~>2.0.0"
|
8
6
|
gem 'fakeweb', ">=1.2"
|
9
7
|
gem 'rack', '>=1.0'
|
10
|
-
gem 'curb', '>=0.6'
|
11
|
-
gem 'yajl-ruby'
|
12
8
|
gem 'rake'
|
13
9
|
gem 'bundler'
|
10
|
+
gem 'excon', "~>0.3.4"
|
11
|
+
|
12
|
+
if defined? JRUBY_VERSION
|
13
|
+
gem 'json'
|
14
|
+
gem 'jruby-openssl'
|
15
|
+
else
|
16
|
+
gem 'curb', '>=0.6'
|
17
|
+
gem 'yajl-ruby'
|
18
|
+
end
|
19
|
+
|
20
|
+
group :integration do
|
21
|
+
gem 'activesupport', '~>3.0'
|
22
|
+
end
|
data/Rakefile
CHANGED
@@ -6,32 +6,85 @@ gemspec = Gem::Specification.new do |gem|
|
|
6
6
|
gem.summary = %Q{riak-client is a rich client for Riak, the distributed database by Basho.}
|
7
7
|
gem.description = %Q{riak-client is a rich client for Riak, the distributed database by Basho. It supports the full HTTP interface including storage operations, bucket configuration, link-walking and map-reduce.}
|
8
8
|
gem.version = File.read('../VERSION').strip
|
9
|
-
gem.email = "
|
9
|
+
gem.email = "sean@basho.com"
|
10
10
|
gem.homepage = "http://seancribbs.github.com/ripple"
|
11
11
|
gem.authors = ["Sean Cribbs"]
|
12
12
|
gem.add_development_dependency "rspec", "~>2.0.0"
|
13
13
|
gem.add_development_dependency "fakeweb", ">=1.2"
|
14
14
|
gem.add_development_dependency "rack", ">=1.0"
|
15
15
|
gem.add_development_dependency "curb", ">=0.6"
|
16
|
-
gem.
|
17
|
-
gem.add_dependency "i18n", "
|
18
|
-
gem.
|
16
|
+
gem.add_development_dependency "excon", "~>0.3.4"
|
17
|
+
gem.add_dependency "i18n", ">=0.4.0"
|
18
|
+
gem.add_dependency "builder", "~>2.1.2"
|
19
19
|
|
20
|
-
files =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
gem.files = %W{
|
21
|
+
erl_src/riak_kv_test_backend.beam
|
22
|
+
erl_src/riak_kv_test_backend.erl
|
23
|
+
Gemfile
|
24
|
+
lib/active_support/cache/riak_store.rb
|
25
|
+
lib/riak/bucket.rb
|
26
|
+
lib/riak/cache_store.rb
|
27
|
+
lib/riak/client/curb_backend.rb
|
28
|
+
lib/riak/client/excon_backend.rb
|
29
|
+
lib/riak/client/http_backend.rb
|
30
|
+
lib/riak/client/net_http_backend.rb
|
31
|
+
lib/riak/client.rb
|
32
|
+
lib/riak/core_ext/blank.rb
|
33
|
+
lib/riak/core_ext/extract_options.rb
|
34
|
+
lib/riak/core_ext/slice.rb
|
35
|
+
lib/riak/core_ext/stringify_keys.rb
|
36
|
+
lib/riak/core_ext/symbolize_keys.rb
|
37
|
+
lib/riak/core_ext/to_param.rb
|
38
|
+
lib/riak/core_ext.rb
|
39
|
+
lib/riak/failed_request.rb
|
40
|
+
lib/riak/i18n.rb
|
41
|
+
lib/riak/invalid_response.rb
|
42
|
+
lib/riak/link.rb
|
43
|
+
lib/riak/locale
|
44
|
+
lib/riak/locale/en.yml
|
45
|
+
lib/riak/map_reduce.rb
|
46
|
+
lib/riak/map_reduce_error.rb
|
47
|
+
lib/riak/robject.rb
|
48
|
+
lib/riak/search.rb
|
49
|
+
lib/riak/test_server.rb
|
50
|
+
lib/riak/util/escape.rb
|
51
|
+
lib/riak/util/fiber1.8.rb
|
52
|
+
lib/riak/util/headers.rb
|
53
|
+
lib/riak/util/multipart.rb
|
54
|
+
lib/riak/util/tcp_socket_extensions.rb
|
55
|
+
lib/riak/util/translation.rb
|
56
|
+
lib/riak/walk_spec.rb
|
57
|
+
lib/riak.rb
|
58
|
+
Rakefile
|
59
|
+
riak-client.gemspec
|
60
|
+
spec/fixtures/cat.jpg
|
61
|
+
spec/fixtures/multipart-blank.txt
|
62
|
+
spec/fixtures/multipart-with-body.txt
|
63
|
+
spec/integration/riak/cache_store_spec.rb
|
64
|
+
spec/integration/riak/test_server_spec.rb
|
65
|
+
spec/riak/bucket_spec.rb
|
66
|
+
spec/riak/client_spec.rb
|
67
|
+
spec/riak/curb_backend_spec.rb
|
68
|
+
spec/riak/escape_spec.rb
|
69
|
+
spec/riak/excon_backend_spec.rb
|
70
|
+
spec/riak/headers_spec.rb
|
71
|
+
spec/riak/http_backend_spec.rb
|
72
|
+
spec/riak/link_spec.rb
|
73
|
+
spec/riak/map_reduce_spec.rb
|
74
|
+
spec/riak/multipart_spec.rb
|
75
|
+
spec/riak/net_http_backend_spec.rb
|
76
|
+
spec/riak/object_spec.rb
|
77
|
+
spec/riak/search_spec.rb
|
78
|
+
spec/riak/walk_spec_spec.rb
|
79
|
+
spec/spec_helper.rb
|
80
|
+
spec/support/drb_mock_server.rb
|
81
|
+
spec/support/http_backend_implementation_examples.rb
|
82
|
+
spec/support/mock_server.rb
|
83
|
+
spec/support/mocks.rb
|
84
|
+
spec/support/test_server.yml.example
|
85
|
+
}
|
31
86
|
|
32
|
-
gem.
|
33
|
-
|
34
|
-
gem.test_files = FileList["spec/**/*.rb"].to_a
|
87
|
+
gem.test_files = gem.files.grep(/_spec\.rb$/)
|
35
88
|
end
|
36
89
|
|
37
90
|
# Gem packaging tasks
|
data/lib/riak.rb
CHANGED
@@ -13,16 +13,25 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
$KCODE = "UTF8" if RUBY_VERSION < "1.9"
|
15
15
|
|
16
|
-
require 'active_support/all'
|
17
|
-
require 'active_support/json'
|
18
|
-
require 'active_support/version'
|
19
16
|
require 'base64'
|
20
17
|
require 'uri'
|
21
18
|
require 'cgi'
|
19
|
+
require 'set'
|
22
20
|
require 'net/http'
|
23
21
|
require 'yaml'
|
24
22
|
require 'riak/i18n'
|
25
23
|
|
24
|
+
# Load JSON
|
25
|
+
unless defined? JSON
|
26
|
+
begin
|
27
|
+
require 'yajl/json_gem'
|
28
|
+
rescue LoadError
|
29
|
+
require 'json'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'riak/core_ext'
|
34
|
+
|
26
35
|
# The Riak module contains all aspects of the HTTP client interface
|
27
36
|
# to Riak.
|
28
37
|
module Riak
|
@@ -35,9 +44,7 @@ module Riak
|
|
35
44
|
autoload :MapReduce, "riak/map_reduce"
|
36
45
|
|
37
46
|
# Cache store - only supports Rails 3 style
|
38
|
-
|
39
|
-
autoload :CacheStore, "riak/cache_store"
|
40
|
-
end
|
47
|
+
autoload :CacheStore, "riak/cache_store"
|
41
48
|
|
42
49
|
# Exceptions
|
43
50
|
autoload :FailedRequest, "riak/failed_request"
|
data/lib/riak/bucket.rb
CHANGED
@@ -41,10 +41,11 @@ module Riak
|
|
41
41
|
# @return [Bucket] self
|
42
42
|
# @see Client#bucket
|
43
43
|
def load(response={})
|
44
|
-
|
44
|
+
content_type = response[:headers]['content-type'].first rescue ""
|
45
|
+
unless content_type =~ /json$/
|
45
46
|
raise Riak::InvalidResponse.new({"content-type" => ["application/json"]}, response[:headers], t("loading_bucket", :name => name))
|
46
47
|
end
|
47
|
-
payload =
|
48
|
+
payload = JSON.parse(response[:body])
|
48
49
|
@keys = payload['keys'].map {|k| CGI.unescape(k) } if payload['keys']
|
49
50
|
@props = payload['props'] if payload['props']
|
50
51
|
self
|
@@ -61,7 +62,8 @@ module Riak
|
|
61
62
|
def keys(options={})
|
62
63
|
if block_given?
|
63
64
|
@client.http.get(200, @client.prefix, escape(name), {:props => false, :keys => 'stream'}, {}) do |chunk|
|
64
|
-
obj =
|
65
|
+
obj = JSON.parse(chunk) rescue nil
|
66
|
+
next unless obj and obj['keys']
|
65
67
|
yield obj['keys'].map {|k| CGI.unescape(k) } if obj['keys']
|
66
68
|
end
|
67
69
|
elsif @keys.nil? || options[:reload]
|
@@ -97,13 +99,14 @@ module Riak
|
|
97
99
|
@client.http.put(204, @client.prefix, escape(name), body, {"Content-Type" => "application/json"})
|
98
100
|
@props.merge!(properties)
|
99
101
|
end
|
102
|
+
alias properties= props=
|
100
103
|
|
101
104
|
# @return [Hash] Internal Riak bucket properties.
|
102
105
|
# @see #props=
|
103
106
|
def props
|
104
107
|
@props
|
105
108
|
end
|
106
|
-
|
109
|
+
alias properties props
|
107
110
|
|
108
111
|
# Retrieve an object from within the bucket.
|
109
112
|
# @param [String] key the key of the object to retrieve
|
data/lib/riak/cache_store.rb
CHANGED
@@ -12,6 +12,12 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
require 'riak'
|
15
|
+
require 'active_support/version'
|
16
|
+
if ActiveSupport::VERSION::STRING < "3.0.0"
|
17
|
+
raise LoadError, "ActiveSupport 3.0.0 or greater is required to use Riak::CacheStore."
|
18
|
+
else
|
19
|
+
require 'active_support/cache'
|
20
|
+
end
|
15
21
|
|
16
22
|
module Riak
|
17
23
|
# An ActiveSupport::Cache::Store implementation that uses Riak.
|
@@ -71,7 +77,7 @@ module Riak
|
|
71
77
|
begin
|
72
78
|
bucket.get(key).data
|
73
79
|
rescue Riak::FailedRequest => fr
|
74
|
-
raise fr unless fr.code == 404
|
80
|
+
raise fr unless fr.code.to_i == 404
|
75
81
|
nil
|
76
82
|
end
|
77
83
|
end
|
data/lib/riak/client.rb
CHANGED
@@ -24,6 +24,7 @@ module Riak
|
|
24
24
|
autoload :HTTPBackend, "riak/client/http_backend"
|
25
25
|
autoload :NetHTTPBackend, "riak/client/net_http_backend"
|
26
26
|
autoload :CurbBackend, "riak/client/curb_backend"
|
27
|
+
autoload :ExconBackend, "riak/client/excon_backend"
|
27
28
|
|
28
29
|
# When using integer client IDs, the exclusive upper-bound of valid values.
|
29
30
|
MAX_CLIENT_ID = 4294967296
|
@@ -49,6 +50,9 @@ module Riak
|
|
49
50
|
# @return [String] The URL path to the luwak HTTP endpoint
|
50
51
|
attr_accessor :luwak
|
51
52
|
|
53
|
+
# @return [Symbol] The HTTP backend/client to use
|
54
|
+
attr_accessor :http_backend
|
55
|
+
|
52
56
|
# Creates a client connection to Riak
|
53
57
|
# @param [Hash] options configuration options for the client
|
54
58
|
# @option options [String] :host ('127.0.0.1') The host or IP address for the Riak endpoint
|
@@ -56,15 +60,19 @@ module Riak
|
|
56
60
|
# @option options [String] :prefix ('/riak/') The URL path prefix to the main HTTP endpoint
|
57
61
|
# @option options [String] :mapred ('/mapred') The path to the map-reduce HTTP endpoint
|
58
62
|
# @option options [Fixnum, String] :client_id (rand(MAX_CLIENT_ID)) The internal client ID used by Riak to route responses
|
63
|
+
# @option options [String, Symbol] :http_backend (:NetHTTP) which HTTP backend to use
|
59
64
|
# @raise [ArgumentError] raised if any options are invalid
|
60
65
|
def initialize(options={})
|
61
|
-
options.
|
62
|
-
|
63
|
-
|
64
|
-
self.
|
65
|
-
self.
|
66
|
-
self.
|
67
|
-
self.
|
66
|
+
unless (options.keys - [:host, :port, :prefix, :client_id, :mapred, :luwak, :http_backend]).empty?
|
67
|
+
raise ArgumentError, "invalid options"
|
68
|
+
end
|
69
|
+
self.host = options[:host] || "127.0.0.1"
|
70
|
+
self.port = options[:port] || 8098
|
71
|
+
self.client_id = options[:client_id] || make_client_id
|
72
|
+
self.prefix = options[:prefix] || "/riak/"
|
73
|
+
self.mapred = options[:mapred] || "/mapred"
|
74
|
+
self.luwak = options[:luwak] || "/luwak"
|
75
|
+
self.http_backend = options[:http_backend] || :NetHTTP
|
68
76
|
raise ArgumentError, t("missing_host_and_port") unless @host && @port
|
69
77
|
end
|
70
78
|
|
@@ -101,17 +109,24 @@ module Riak
|
|
101
109
|
@port = value
|
102
110
|
end
|
103
111
|
|
112
|
+
# Sets the desired HTTP backend
|
113
|
+
def http_backend=(value)
|
114
|
+
@http = nil
|
115
|
+
@http_backend = value
|
116
|
+
end
|
117
|
+
|
104
118
|
# Automatically detects and returns an appropriate HTTP backend.
|
105
119
|
# The HTTP backend is used internally by the Riak client, but can also
|
106
120
|
# be used to access the server directly.
|
107
121
|
# @return [HTTPBackend] the HTTP backend for this client
|
108
122
|
def http
|
109
123
|
@http ||= begin
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
124
|
+
klass = self.class.const_get("#{@http_backend}Backend")
|
125
|
+
if klass.configured?
|
126
|
+
klass.new(self)
|
127
|
+
else
|
128
|
+
raise t('http_configuration', :backend => @http_backend)
|
129
|
+
end
|
115
130
|
end
|
116
131
|
end
|
117
132
|
|
@@ -122,7 +137,9 @@ module Riak
|
|
122
137
|
# @option options [Boolean] :props (true) whether to retreive the bucket properties
|
123
138
|
# @return [Bucket] the requested bucket
|
124
139
|
def bucket(name, options={})
|
125
|
-
options.
|
140
|
+
unless (options.keys - [:keys, :props]).empty?
|
141
|
+
raise ArgumentError, "invalid options"
|
142
|
+
end
|
126
143
|
response = http.get(200, prefix, escape(name), {:keys => false}.merge(options), {})
|
127
144
|
Bucket.new(self, name).load(response)
|
128
145
|
end
|
@@ -185,7 +202,7 @@ module Riak
|
|
185
202
|
http.delete([204,404], luwak, escape(filename))
|
186
203
|
true
|
187
204
|
end
|
188
|
-
|
205
|
+
|
189
206
|
# Checks whether a file exists in "Luwak".
|
190
207
|
# @param [String] key the key to check
|
191
208
|
# @return [true, false] whether the key exists in "Luwak"
|
@@ -22,14 +22,21 @@ end
|
|
22
22
|
module Riak
|
23
23
|
class Client
|
24
24
|
# An HTTP backend for Riak::Client that uses the 'curb' library/gem.
|
25
|
-
# If the 'curb' library is present, this backend will be preferred to
|
26
|
-
# the backend based on Net::HTTP.
|
27
25
|
# Conforms to the Riak::Client::HTTPBackend interface.
|
28
26
|
class CurbBackend < HTTPBackend
|
27
|
+
def self.configured?
|
28
|
+
begin
|
29
|
+
require 'curb'
|
30
|
+
true
|
31
|
+
rescue LoadError
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
29
36
|
private
|
30
37
|
def perform(method, uri, headers, expect, data=nil)
|
31
38
|
# Setup
|
32
|
-
curl.headers =
|
39
|
+
curl.headers = RequestHeaders.new(headers).to_a
|
33
40
|
curl.url = uri.to_s
|
34
41
|
response_headers.initialize_http_header(nil)
|
35
42
|
if block_given?
|
@@ -53,7 +60,7 @@ module Riak
|
|
53
60
|
# Hacks around limitations in curb's PUT semantics
|
54
61
|
_headers, curl.headers = curl.headers, {}
|
55
62
|
curl.put_data = data
|
56
|
-
curl.headers =
|
63
|
+
curl.headers = RequestHeaders.new(curl.headers).to_a + _headers
|
57
64
|
curl.http("PUT")
|
58
65
|
else
|
59
66
|
curl.send("http_#{method}")
|
@@ -80,20 +87,6 @@ module Riak
|
|
80
87
|
end
|
81
88
|
end
|
82
89
|
end
|
83
|
-
|
84
|
-
def response_headers
|
85
|
-
Thread.current[:response_headers] ||= Riak::Util::Headers.new
|
86
|
-
end
|
87
|
-
|
88
|
-
def create_request_headers(hash)
|
89
|
-
h = Riak::Util::Headers.new
|
90
|
-
hash.each {|k,v| h.add_field(k,v) }
|
91
|
-
[].tap do |arr|
|
92
|
-
h.each_capitalized do |k,v|
|
93
|
-
arr << "#{k}: #{v}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
90
|
end
|
98
91
|
end
|
99
92
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'riak'
|
15
|
+
|
16
|
+
module Riak
|
17
|
+
class Client
|
18
|
+
# An HTTP backend for Riak::Client that uses Wesley Beary's Excon
|
19
|
+
# HTTP library. Comforms to the Riak::Client::HTTPBackend
|
20
|
+
# interface.
|
21
|
+
class ExconBackend < HTTPBackend
|
22
|
+
def self.configured?
|
23
|
+
begin
|
24
|
+
require 'excon'
|
25
|
+
Excon::VERSION >= "0.3.4"
|
26
|
+
rescue LoadError
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def perform(method, uri, headers, expect, data=nil, &block)
|
33
|
+
params = {
|
34
|
+
:method => method.to_s.upcase,
|
35
|
+
:headers => RequestHeaders.new(headers).to_hash,
|
36
|
+
:path => uri.path
|
37
|
+
}
|
38
|
+
params[:query] = uri.query if uri.query
|
39
|
+
params[:body] = data if [:put,:post].include?(method)
|
40
|
+
params[:idempotent] = (method != :post)
|
41
|
+
|
42
|
+
response = connection.request(params, &block)
|
43
|
+
if valid_response?(expect, response.status)
|
44
|
+
response_headers.initialize_http_header(response.headers)
|
45
|
+
result = {:headers => response_headers.to_hash, :code => response.status}
|
46
|
+
if return_body?(method, response.status, block_given?)
|
47
|
+
result[:body] = response.body
|
48
|
+
end
|
49
|
+
result
|
50
|
+
else
|
51
|
+
raise FailedRequest.new(method, expect, response.status, response.headers, response.body)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def connection
|
56
|
+
@connection ||= Excon::Connection.new(root_uri.to_s)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -171,7 +171,7 @@ module Riak
|
|
171
171
|
resource = Array(resource).flatten
|
172
172
|
raise ArgumentError, t("resource_path_short") unless resource.length > 1 || resource.include?(@client.mapred)
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
# Checks the expected response codes against the actual response code. Use internally when
|
176
176
|
# implementing {#perform}.
|
177
177
|
# @param [String, Fixnum, Array<String,Fixnum>] expected the expected response code(s)
|
@@ -190,7 +190,7 @@ module Riak
|
|
190
190
|
def return_body?(method, code, has_block)
|
191
191
|
method != :head && !valid_response?([204,205,304], code) && !has_block
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
# Executes requests according to the underlying HTTP client library semantics.
|
195
195
|
# @abstract Subclasses must implement this internal method to perform HTTP requests
|
196
196
|
# according to the API of their HTTP libraries.
|
@@ -205,6 +205,37 @@ module Riak
|
|
205
205
|
def perform(method, uri, headers, expect, body=nil)
|
206
206
|
raise NotImplementedError
|
207
207
|
end
|
208
|
+
|
209
|
+
private
|
210
|
+
def response_headers
|
211
|
+
Thread.current[:response_headers] ||= Riak::Util::Headers.new
|
212
|
+
end
|
213
|
+
|
214
|
+
# @private
|
215
|
+
class RequestHeaders < Riak::Util::Headers
|
216
|
+
alias each each_capitalized
|
217
|
+
|
218
|
+
def initialize(hash)
|
219
|
+
initialize_http_header(hash)
|
220
|
+
end
|
221
|
+
|
222
|
+
def to_a
|
223
|
+
[].tap do |arr|
|
224
|
+
each_capitalized do |k,v|
|
225
|
+
arr << "#{k}: #{v}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_hash
|
231
|
+
{}.tap do |hash|
|
232
|
+
each_capitalized do |k,v|
|
233
|
+
hash[k] ||= []
|
234
|
+
hash[k] << v
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
208
239
|
end
|
209
240
|
end
|
210
241
|
end
|