riak-client 0.9.0.beta → 0.9.0.beta2

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.
Files changed (50) hide show
  1. data/Gemfile +10 -7
  2. data/Rakefile +21 -3
  3. data/erl_src/riak_kv_test_backend.beam +0 -0
  4. data/erl_src/riak_kv_test_backend.erl +29 -13
  5. data/lib/riak/bucket.rb +1 -1
  6. data/lib/riak/cache_store.rb +1 -1
  7. data/lib/riak/client.rb +119 -8
  8. data/lib/riak/client/beefcake/messages.rb +162 -0
  9. data/lib/riak/client/beefcake/object_methods.rb +92 -0
  10. data/lib/riak/client/beefcake_protobuffs_backend.rb +186 -0
  11. data/lib/riak/client/curb_backend.rb +10 -16
  12. data/lib/riak/client/excon_backend.rb +14 -18
  13. data/lib/riak/client/http_backend.rb +13 -13
  14. data/lib/riak/client/http_backend/object_methods.rb +1 -1
  15. data/lib/riak/client/http_backend/transport_methods.rb +6 -2
  16. data/lib/riak/client/net_http_backend.rb +33 -20
  17. data/lib/riak/client/protobuffs_backend.rb +103 -0
  18. data/lib/riak/client/pump.rb +44 -0
  19. data/lib/riak/failed_request.rb +58 -3
  20. data/lib/riak/locale/en.yml +11 -3
  21. data/lib/riak/map_reduce.rb +15 -6
  22. data/lib/riak/map_reduce/filter_builder.rb +4 -4
  23. data/lib/riak/test_server.rb +5 -1
  24. data/lib/riak/util/multipart.rb +30 -16
  25. data/lib/riak/util/multipart/stream_parser.rb +74 -0
  26. data/riak-client.gemspec +14 -12
  27. data/spec/fixtures/server.cert.crt +15 -0
  28. data/spec/fixtures/server.cert.key +15 -0
  29. data/spec/fixtures/test.pem +1 -0
  30. data/spec/integration/riak/http_backends_spec.rb +45 -0
  31. data/spec/integration/riak/protobuffs_backends_spec.rb +45 -0
  32. data/spec/integration/riak/test_server_spec.rb +2 -2
  33. data/spec/riak/bucket_spec.rb +4 -4
  34. data/spec/riak/client_spec.rb +209 -3
  35. data/spec/riak/excon_backend_spec.rb +8 -7
  36. data/spec/riak/http_backend/configuration_spec.rb +64 -0
  37. data/spec/riak/http_backend/object_methods_spec.rb +1 -1
  38. data/spec/riak/http_backend/transport_methods_spec.rb +129 -0
  39. data/spec/riak/http_backend_spec.rb +13 -1
  40. data/spec/riak/map_reduce/filter_builder_spec.rb +45 -0
  41. data/spec/riak/map_reduce/phase_spec.rb +149 -0
  42. data/spec/riak/map_reduce_spec.rb +5 -5
  43. data/spec/riak/net_http_backend_spec.rb +1 -0
  44. data/spec/riak/{object_spec.rb → robject_spec.rb} +1 -1
  45. data/spec/riak/stream_parser_spec.rb +66 -0
  46. data/spec/support/drb_mock_server.rb +2 -2
  47. data/spec/support/http_backend_implementation_examples.rb +27 -0
  48. data/spec/support/mock_server.rb +22 -1
  49. data/spec/support/unified_backend_examples.rb +255 -0
  50. metadata +43 -54
@@ -17,27 +17,15 @@ module Riak
17
17
  module Util
18
18
  # Utility methods for handling multipart/mixed responses
19
19
  module Multipart
20
+ autoload :StreamParser, "riak/util/multipart/stream_parser"
20
21
  extend self
21
22
  # Parses a multipart/mixed body into its constituent parts, including nested multipart/mixed sections
22
23
  # @param [String] data the multipart body data
23
24
  # @param [String] boundary the boundary string given in the Content-Type header
24
25
  def parse(data, boundary)
25
- contents = data.match(/\r?\n--#{Regexp.escape(boundary)}--\r?\n/).pre_match rescue ""
26
- contents.split(/\r?\n--#{Regexp.escape(boundary)}\r?\n/).reject(&:blank?).map do |part|
27
- headers = Headers.new
28
- if md = part.match(/\r?\n\r?\n/)
29
- body = md.post_match
30
- md.pre_match.split(/\r?\n/).each do |line|
31
- headers.parse(line)
32
- end
33
-
34
- if headers["content-type"] =~ /multipart\/mixed/
35
- boundary = extract_boundary(headers.to_hash["content-type"].first)
36
- parse(body, boundary)
37
- else
38
- {:headers => headers.to_hash, :body => body}
39
- end
40
- end
26
+ contents = data.match(end_boundary_regex(boundary)).pre_match rescue ""
27
+ contents.split(inner_boundary_regex(boundary)).reject(&:blank?).map do |part|
28
+ parse_multipart_section(part)
41
29
  end.compact
42
30
  end
43
31
 
@@ -47,6 +35,32 @@ module Riak
47
35
  def extract_boundary(header_string)
48
36
  $1 if header_string =~ /boundary=([A-Za-z0-9\'()+_,-.\/:=?]+)/
49
37
  end
38
+
39
+ private
40
+ def end_boundary_regex(boundary)
41
+ /\r?\n--#{Regexp.escape(boundary)}--\r?\n/
42
+ end
43
+
44
+ def inner_boundary_regex(boundary)
45
+ /\r?\n--#{Regexp.escape(boundary)}\r?\n/
46
+ end
47
+
48
+ def parse_multipart_section(part)
49
+ headers = Headers.new
50
+ if md = part.match(/\r?\n\r?\n/)
51
+ body = md.post_match
52
+ md.pre_match.split(/\r?\n/).each do |line|
53
+ headers.parse(line)
54
+ end
55
+
56
+ if headers["content-type"] =~ /multipart\/mixed/
57
+ boundary = extract_boundary(headers.to_hash["content-type"].first)
58
+ parse(body, boundary)
59
+ else
60
+ {:headers => headers.to_hash, :body => body}
61
+ end
62
+ end
63
+ end
50
64
  end
51
65
  end
52
66
  end
@@ -0,0 +1,74 @@
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/util/multipart'
15
+
16
+ module Riak
17
+ module Util
18
+ module Multipart
19
+ # This class is parses chunked/streamed multipart HTTP
20
+ # streams. It is used by streaming MapReduce queries, and in the
21
+ # future streaming key-lists (once implemented on the Riak side).
22
+ class StreamParser
23
+ include Multipart
24
+ include Translation
25
+ # Creates a new StreamParser.
26
+ #
27
+ # Example usage:
28
+ # http.get(200, "/riak", "foo", {}, &StreamParser.new {|part| ... })
29
+ #
30
+ # @yield [Hash] parts of the multipart/mixed stream,
31
+ # containing :headers and :body keys
32
+ def initialize(&block)
33
+ raise ArgumentError, t('missing_block') unless block_given?
34
+ @buffer = ""
35
+ @block = block
36
+ @state = :get_boundary
37
+ end
38
+
39
+ # Accepts a chunk of the HTTP response stream, and yields to
40
+ # the block when appropriate.
41
+ def accept(chunk)
42
+ @buffer << chunk
43
+ @state = send(@state)
44
+ end
45
+
46
+ # Returns a Proc that can be passed to an HTTP request method.
47
+ def to_proc
48
+ method(:accept).to_proc
49
+ end
50
+
51
+ private
52
+ CAPTURE_BOUNDARY = /^--([A-Za-z0-9\'()+_,-.\/:=?]+)\r?\n/
53
+
54
+ def get_boundary
55
+ if @buffer =~ CAPTURE_BOUNDARY
56
+ @re = /\r?\n--#{Regexp.escape($1)}(?:--)?\r?\n/
57
+ @buffer = $~.post_match
58
+ buffering
59
+ else
60
+ :get_boundary
61
+ end
62
+ end
63
+
64
+ def buffering
65
+ while @buffer =~ @re
66
+ @block.call parse_multipart_section($~.pre_match)
67
+ @buffer = $~.post_match
68
+ end
69
+ :buffering
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
data/riak-client.gemspec CHANGED
@@ -2,48 +2,50 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{riak-client}
5
- s.version = "0.9.0.beta"
5
+ s.version = "0.9.0.beta2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Sean Cribbs"]
9
- s.date = %q{2010-12-29}
9
+ s.date = %q{2011-03-28}
10
10
  s.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.}
11
11
  s.email = %q{sean@basho.com}
12
- s.files = ["erl_src/riak_kv_test_backend.beam", "erl_src/riak_kv_test_backend.erl", "Gemfile", "lib/active_support/cache/riak_store.rb", "lib/riak/bucket.rb", "lib/riak/cache_store.rb", "lib/riak/client/curb_backend.rb", "lib/riak/client/excon_backend.rb", "lib/riak/client/http_backend/configuration.rb", "lib/riak/client/http_backend/object_methods.rb", "lib/riak/client/http_backend/request_headers.rb", "lib/riak/client/http_backend/transport_methods.rb", "lib/riak/client/http_backend.rb", "lib/riak/client/net_http_backend.rb", "lib/riak/client.rb", "lib/riak/core_ext/blank.rb", "lib/riak/core_ext/extract_options.rb", "lib/riak/core_ext/slice.rb", "lib/riak/core_ext/stringify_keys.rb", "lib/riak/core_ext/symbolize_keys.rb", "lib/riak/core_ext/to_param.rb", "lib/riak/core_ext.rb", "lib/riak/failed_request.rb", "lib/riak/i18n.rb", "lib/riak/invalid_response.rb", "lib/riak/link.rb", "lib/riak/locale/en.yml", "lib/riak/map_reduce/filter_builder.rb", "lib/riak/map_reduce/phase.rb", "lib/riak/map_reduce.rb", "lib/riak/map_reduce_error.rb", "lib/riak/robject.rb", "lib/riak/search.rb", "lib/riak/test_server.rb", "lib/riak/util/escape.rb", "lib/riak/util/fiber1.8.rb", "lib/riak/util/headers.rb", "lib/riak/util/multipart.rb", "lib/riak/util/tcp_socket_extensions.rb", "lib/riak/util/translation.rb", "lib/riak/walk_spec.rb", "lib/riak.rb", "Rakefile", "riak-client.gemspec", "spec/fixtures/cat.jpg", "spec/fixtures/multipart-blank.txt", "spec/fixtures/multipart-with-body.txt", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend/object_methods_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/object_spec.rb", "spec/riak/search_spec.rb", "spec/riak/walk_spec_spec.rb", "spec/spec_helper.rb", "spec/support/drb_mock_server.rb", "spec/support/http_backend_implementation_examples.rb", "spec/support/mock_server.rb", "spec/support/mocks.rb", "spec/support/test_server.yml.example"]
12
+ s.files = ["erl_src/riak_kv_test_backend.beam", "erl_src/riak_kv_test_backend.erl", "Gemfile", "lib/active_support/cache/riak_store.rb", "lib/riak/bucket.rb", "lib/riak/cache_store.rb", "lib/riak/client/beefcake/messages.rb", "lib/riak/client/beefcake/object_methods.rb", "lib/riak/client/beefcake_protobuffs_backend.rb", "lib/riak/client/curb_backend.rb", "lib/riak/client/excon_backend.rb", "lib/riak/client/http_backend/configuration.rb", "lib/riak/client/http_backend/object_methods.rb", "lib/riak/client/http_backend/request_headers.rb", "lib/riak/client/http_backend/transport_methods.rb", "lib/riak/client/http_backend.rb", "lib/riak/client/net_http_backend.rb", "lib/riak/client/protobuffs_backend.rb", "lib/riak/client/pump.rb", "lib/riak/client.rb", "lib/riak/core_ext/blank.rb", "lib/riak/core_ext/extract_options.rb", "lib/riak/core_ext/slice.rb", "lib/riak/core_ext/stringify_keys.rb", "lib/riak/core_ext/symbolize_keys.rb", "lib/riak/core_ext/to_param.rb", "lib/riak/core_ext.rb", "lib/riak/failed_request.rb", "lib/riak/i18n.rb", "lib/riak/invalid_response.rb", "lib/riak/link.rb", "lib/riak/locale/en.yml", "lib/riak/map_reduce/filter_builder.rb", "lib/riak/map_reduce/phase.rb", "lib/riak/map_reduce.rb", "lib/riak/map_reduce_error.rb", "lib/riak/robject.rb", "lib/riak/search.rb", "lib/riak/test_server.rb", "lib/riak/util/escape.rb", "lib/riak/util/fiber1.8.rb", "lib/riak/util/headers.rb", "lib/riak/util/multipart/stream_parser.rb", "lib/riak/util/multipart.rb", "lib/riak/util/tcp_socket_extensions.rb", "lib/riak/util/translation.rb", "lib/riak/walk_spec.rb", "lib/riak.rb", "Rakefile", "riak-client.gemspec", "spec/fixtures/cat.jpg", "spec/fixtures/multipart-blank.txt", "spec/fixtures/multipart-with-body.txt", "spec/fixtures/server.cert.crt", "spec/fixtures/server.cert.key", "spec/fixtures/test.pem", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/http_backends_spec.rb", "spec/integration/riak/protobuffs_backends_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend/configuration_spec.rb", "spec/riak/http_backend/object_methods_spec.rb", "spec/riak/http_backend/transport_methods_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce/filter_builder_spec.rb", "spec/riak/map_reduce/phase_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/robject_spec.rb", "spec/riak/search_spec.rb", "spec/riak/stream_parser_spec.rb", "spec/riak/walk_spec_spec.rb", "spec/spec_helper.rb", "spec/support/drb_mock_server.rb", "spec/support/http_backend_implementation_examples.rb", "spec/support/mock_server.rb", "spec/support/mocks.rb", "spec/support/test_server.yml.example", "spec/support/unified_backend_examples.rb"]
13
13
  s.homepage = %q{http://seancribbs.github.com/ripple}
14
14
  s.require_paths = ["lib"]
15
- s.rubygems_version = %q{1.3.7}
15
+ s.rubygems_version = %q{1.6.1}
16
16
  s.summary = %q{riak-client is a rich client for Riak, the distributed database by Basho.}
17
- s.test_files = ["lib/riak/walk_spec.rb", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend/object_methods_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/object_spec.rb", "spec/riak/search_spec.rb", "spec/riak/walk_spec_spec.rb"]
17
+ s.test_files = ["lib/riak/walk_spec.rb", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/http_backends_spec.rb", "spec/integration/riak/protobuffs_backends_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend/configuration_spec.rb", "spec/riak/http_backend/object_methods_spec.rb", "spec/riak/http_backend/transport_methods_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce/filter_builder_spec.rb", "spec/riak/map_reduce/phase_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/robject_spec.rb", "spec/riak/search_spec.rb", "spec/riak/stream_parser_spec.rb", "spec/riak/walk_spec_spec.rb"]
18
18
 
19
19
  if s.respond_to? :specification_version then
20
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
21
20
  s.specification_version = 3
22
21
 
23
22
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
- s.add_development_dependency(%q<rspec>, ["~> 2.0.0"])
23
+ s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
25
24
  s.add_development_dependency(%q<fakeweb>, [">= 1.2"])
26
25
  s.add_development_dependency(%q<rack>, [">= 1.0"])
27
26
  s.add_development_dependency(%q<curb>, [">= 0.6"])
28
- s.add_development_dependency(%q<excon>, ["~> 0.3.4"])
27
+ s.add_development_dependency(%q<excon>, ["~> 0.5.7"])
29
28
  s.add_runtime_dependency(%q<i18n>, [">= 0.4.0"])
30
29
  s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
30
+ s.add_runtime_dependency(%q<beefcake>, ["~> 0.2.0"])
31
31
  else
32
- s.add_dependency(%q<rspec>, ["~> 2.0.0"])
32
+ s.add_dependency(%q<rspec>, ["~> 2.4.0"])
33
33
  s.add_dependency(%q<fakeweb>, [">= 1.2"])
34
34
  s.add_dependency(%q<rack>, [">= 1.0"])
35
35
  s.add_dependency(%q<curb>, [">= 0.6"])
36
- s.add_dependency(%q<excon>, ["~> 0.3.4"])
36
+ s.add_dependency(%q<excon>, ["~> 0.5.7"])
37
37
  s.add_dependency(%q<i18n>, [">= 0.4.0"])
38
38
  s.add_dependency(%q<builder>, ["~> 2.1.2"])
39
+ s.add_dependency(%q<beefcake>, ["~> 0.2.0"])
39
40
  end
40
41
  else
41
- s.add_dependency(%q<rspec>, ["~> 2.0.0"])
42
+ s.add_dependency(%q<rspec>, ["~> 2.4.0"])
42
43
  s.add_dependency(%q<fakeweb>, [">= 1.2"])
43
44
  s.add_dependency(%q<rack>, [">= 1.0"])
44
45
  s.add_dependency(%q<curb>, [">= 0.6"])
45
- s.add_dependency(%q<excon>, ["~> 0.3.4"])
46
+ s.add_dependency(%q<excon>, ["~> 0.5.7"])
46
47
  s.add_dependency(%q<i18n>, [">= 0.4.0"])
47
48
  s.add_dependency(%q<builder>, ["~> 2.1.2"])
49
+ s.add_dependency(%q<beefcake>, ["~> 0.2.0"])
48
50
  end
49
51
  end
@@ -0,0 +1,15 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPzCCAagCCQDfZhEdJjSgTDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJV
3
+ UzELMAkGA1UECBMCTkMxEjAQBgNVBAcTCUNoYXJsb3R0ZTEOMAwGA1UEChMFQmFz
4
+ aG8xEDAOBgNVBAsTB1N1cHBvcnQxEjAQBgNVBAMTCTEyNy4wLjAuMTAeFw0xMTAz
5
+ MjYxNjMzMzNaFw0zODA4MTAxNjMzMzNaMGQxCzAJBgNVBAYTAlVTMQswCQYDVQQI
6
+ EwJOQzESMBAGA1UEBxMJQ2hhcmxvdHRlMQ4wDAYDVQQKEwVCYXNobzEQMA4GA1UE
7
+ CxMHU3VwcG9ydDESMBAGA1UEAxMJMTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEBAQUA
8
+ A4GNADCBiQKBgQCtfHMCsR86HQEAsO52/WvtFWCEigXll0rxYjXvdqeszEPEMFIy
9
+ Qlg3GlRxH51YrBzp46ReF9Qv5sf0Nh6SR7HGzlWmMEVfPeuAKcz1fzVcjD+IXWHK
10
+ qklAQjpxz+18dvaGxQ7ZJMPsBlq1v64siTLXI0yhjxXOuQPJWrWsvuuXkQIDAQAB
11
+ MA0GCSqGSIb3DQEBBQUAA4GBAIqt1A5Ah7s2oUoYQ8YCKC83fKbXbbNCiLFLwIzy
12
+ TGYXd8j7JTfeY8ettbtitlYgP+ouf23LzonuMo47GRuMgVKRWm4l+ZVMP5Qbkx9t
13
+ uspx+6lHUWnMT9aRdP9/2I7dscyfuhtzs0UxddADLzL9Cif4Y06E1NhR/KK+zo46
14
+ Nep8
15
+ -----END CERTIFICATE-----
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXQIBAAKBgQCtfHMCsR86HQEAsO52/WvtFWCEigXll0rxYjXvdqeszEPEMFIy
3
+ Qlg3GlRxH51YrBzp46ReF9Qv5sf0Nh6SR7HGzlWmMEVfPeuAKcz1fzVcjD+IXWHK
4
+ qklAQjpxz+18dvaGxQ7ZJMPsBlq1v64siTLXI0yhjxXOuQPJWrWsvuuXkQIDAQAB
5
+ AoGBAJIguzdPPgBTId8VKSes+lVupie9oo3qy8NaeBfGGCIixAnisbmHzIpNcUb/
6
+ 3CcuggQ4LODcrWvTtiTr2QBZx1FL7E4POBJl/N7zJMaQd+pGjmrJGfv5haSSQN+H
7
+ r74Ix3HCd0RPdSgt5pmlT4KfsqkfRmqsPd6Nw54zbyLFMlTpAkEA4ar3ZJi2+Y+u
8
+ FH3AycXuPdDtVW0tKFtxfvKlS48gshB6gmkd06Ugss5eZkdbSY0voAp88Tr2shOJ
9
+ +pXc++Zl6wJBAMTN9K9k728cVCf41pR6mDVxIaaqjJeY4DWppGQFSqw/fmYz/Quu
10
+ PlTvk6pGRYiGN6y9CZFNoL2I/SWcd4ukrXMCQCyfYOHsbKn2Zka5Awki8VQZ3wQ4
11
+ XWiQhGXE1ziUqbNsHL1yyaoTCd8xfWseCwgFOficek49CZD22h7JyXOqAFcCQCn2
12
+ mFPFu9//NFqJjod+VHIgu0IkX3H7oOMQVwMUtcVgjH0SXMRe1N+bbesCrNTdeYWV
13
+ kTKwULPZP9EDOeJGrM0CQQCsX+8VZ15yKTy6ADINrOt26PNpD4ib4552TE6T/1wG
14
+ LKdjn5l0qB5K7ILc22z3LCenNBa0Uxbg5/RSdoX57aHA
15
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ i-am-a-pem
@@ -0,0 +1,45 @@
1
+ # Copyright 2010 Sean Cribbs 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 File.expand_path("../../spec_helper", File.dirname(__FILE__))
15
+
16
+ describe "HTTP" do
17
+ before :all do
18
+ if $test_server
19
+ @web_port = 9000
20
+ $test_server.start
21
+ end
22
+ end
23
+
24
+ before do
25
+ @web_port ||= 8098
26
+ @client = Riak::Client.new(:port => @web_port)
27
+ end
28
+
29
+ after do
30
+ $test_server.recycle if $test_server.started?
31
+ end
32
+
33
+ [:CurbBackend, :ExconBackend, :NetHTTPBackend].each do |klass|
34
+ bklass = Riak::Client.const_get(klass)
35
+ if bklass.configured?
36
+ describe klass.to_s do
37
+ before do
38
+ @backend = bklass.new(@client)
39
+ end
40
+
41
+ it_should_behave_like "Unified backend API"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # Copyright 2010 Sean Cribbs 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 File.expand_path("../../spec_helper", File.dirname(__FILE__))
15
+
16
+ describe "Protocol Buffers" do
17
+ before :all do
18
+ if $test_server
19
+ @pbc_port = 9002
20
+ $test_server.start
21
+ end
22
+ end
23
+
24
+ before do
25
+ @pbc_port ||= 8087
26
+ @client = Riak::Client.new(:port => @pbc_port, :protocol => "pbc")
27
+ end
28
+
29
+ after do
30
+ $test_server.recycle if $test_server.started?
31
+ end
32
+
33
+ [:BeefcakeProtobuffsBackend].each do |klass|
34
+ bklass = Riak::Client.const_get(klass)
35
+ if bklass.configured?
36
+ describe klass.to_s do
37
+ before do
38
+ @backend = bklass.new(@client)
39
+ end
40
+
41
+ it_should_behave_like "Unified backend API"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -43,9 +43,9 @@ if $test_server
43
43
  config[0..0].should == '['
44
44
  end
45
45
 
46
- it "should set the backend to use the cache backend" do
46
+ it "should set the backend to use the test backend" do
47
47
  File.readlines(@app_config).should be_any do |line|
48
- line =~ /\{storage_backend\s*,\s*(.*)\}/ && $1 == "riak_kv_cache_backend"
48
+ line =~ /\{storage_backend\s*,\s*(.*)\}/ && $1 == "riak_kv_test_backend"
49
49
  end
50
50
  end
51
51
 
@@ -120,15 +120,15 @@ describe Riak::Bucket do
120
120
  end
121
121
 
122
122
  it "should create a new blank object if the key does not exist" do
123
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "File not found"))
123
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "File not found"))
124
124
  obj = @bucket.get_or_new('db')
125
125
  obj.key.should == 'db'
126
126
  obj.data.should be_blank
127
127
  end
128
128
 
129
129
  it "should bubble up non-ok non-missing errors" do
130
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, 200, 500, {}, "File not found"))
131
- lambda { @bucket.get_or_new('db') }.should raise_error(Riak::FailedRequest)
130
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 500, {}, "File not found"))
131
+ lambda { @bucket.get_or_new('db') }.should raise_error(Riak::HTTPFailedRequest)
132
132
  end
133
133
 
134
134
  it "should pass along the given R quorum parameter" do
@@ -192,7 +192,7 @@ describe Riak::Bucket do
192
192
  end
193
193
 
194
194
  it "should return false if the object doesn't exist" do
195
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, [200,300], 404, {}, "not found"))
195
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, [200,300], 404, {}, "not found"))
196
196
  @bucket.exists?("foo").should be_false
197
197
  end
198
198
  end
@@ -21,6 +21,11 @@ describe Riak::Client do
21
21
  client.port.should == 8098
22
22
  end
23
23
 
24
+ it "should accept a protocol" do
25
+ client = Riak::Client.new :protocol => 'https'
26
+ client.protocol.should eq('https')
27
+ end
28
+
24
29
  it "should accept a host" do
25
30
  client = Riak::Client.new :host => "riak.basho.com"
26
31
  client.host.should == "riak.basho.com"
@@ -31,6 +36,15 @@ describe Riak::Client do
31
36
  client.port.should == 9000
32
37
  end
33
38
 
39
+ it "should default the port to 8087 when the protocol is pbc" do
40
+ Riak::Client.new(:protocol => "pbc").port.should == 8087
41
+ end
42
+
43
+ it "should accept basic_auth" do
44
+ client = Riak::Client.new :basic_auth => "user:pass"
45
+ client.basic_auth.should eq("user:pass")
46
+ end
47
+
34
48
  it "should accept a client ID" do
35
49
  client = Riak::Client.new :client_id => "AAAAAA=="
36
50
  client.client_id.should == "AAAAAA=="
@@ -78,6 +92,25 @@ describe Riak::Client do
78
92
  @client = Riak::Client.new
79
93
  end
80
94
 
95
+ describe "setting the protocol" do
96
+ it "should allow setting the protocol" do
97
+ @client.should respond_to(:protocol=)
98
+ @client.protocol = "https"
99
+ @client.protocol.should eq("https")
100
+ end
101
+
102
+ it "should require a valid protocol to be set" do
103
+ lambda { @client.protocol = 'invalid-protocol' }.should(
104
+ raise_error(ArgumentError, /^'invalid-protocol' is not a valid protocol/))
105
+ end
106
+
107
+ it "should reset the unified backend when changing the protocol" do
108
+ old = @client.backend
109
+ @client.protocol = "pbc"
110
+ old.should_not eq(@client.backend)
111
+ end
112
+ end
113
+
81
114
  describe "setting the host" do
82
115
  it "should allow setting the host" do
83
116
  @client.should respond_to(:host=)
@@ -112,6 +145,18 @@ describe Riak::Client do
112
145
  end
113
146
  end
114
147
 
148
+ describe "setting http auth" do
149
+ it "should allow setting basic_auth" do
150
+ @client.should respond_to(:basic_auth=)
151
+ @client.basic_auth = "user:pass"
152
+ @client.basic_auth.should eq("user:pass")
153
+ end
154
+
155
+ it "should require that basic auth splits into two even parts" do
156
+ lambda { @client.basic_auth ="user" }.should raise_error(ArgumentError, "basic auth must be set using 'user:pass'")
157
+ end
158
+ end
159
+
115
160
  it "should allow setting the prefix" do
116
161
  @client.should respond_to(:prefix=)
117
162
  @client.prefix = "/another-prefix"
@@ -157,11 +202,45 @@ describe Riak::Client do
157
202
 
158
203
  it "should raise an error when the chosen backend is not valid" do
159
204
  Riak::Client::NetHTTPBackend.should_receive(:configured?).and_return(false)
160
- @client = Riak::Client.new(:http_backend => :NetHTTP)
205
+ # @client = Riak::Client.new(:http_backend => :NetHTTP)
161
206
  lambda { @client.http }.should raise_error
162
207
  end
163
208
  end
164
209
 
210
+ describe "choosing a Protobuffs backend" do
211
+ before :each do
212
+ @client = Riak::Client.new(:protocol => "pbc")
213
+ end
214
+
215
+ it "should choose the selected backend" do
216
+ @client.protobuffs_backend = :Beefcake
217
+ @client.protobuffs.should be_instance_of(Riak::Client::BeefcakeProtobuffsBackend)
218
+ end
219
+
220
+ it "should raise an error when the chosen backend is not valid" do
221
+ Riak::Client::BeefcakeProtobuffsBackend.should_receive(:configured?).and_return(false)
222
+ lambda { @client.protobuffs }.should raise_error
223
+ end
224
+ end
225
+
226
+ describe "choosing a unified backend" do
227
+ before :each do
228
+ @client = Riak::Client.new
229
+ end
230
+
231
+ it "should use HTTP when the protocol is http or https" do
232
+ %w[http https].each do |p|
233
+ @client.protocol = p
234
+ @client.backend.should be_kind_of(Riak::Client::HTTPBackend)
235
+ end
236
+ end
237
+
238
+ it "should use Protobuffs when the protocol is pbc" do
239
+ @client.protocol = "pbc"
240
+ @client.backend.should be_kind_of(Riak::Client::ProtobuffsBackend)
241
+ end
242
+ end
243
+
165
244
  describe "retrieving a bucket" do
166
245
  before :each do
167
246
  @client = Riak::Client.new
@@ -183,7 +262,6 @@ describe Riak::Client do
183
262
  @client.bucket("foo", :keys => true)
184
263
  end
185
264
 
186
-
187
265
  it "should memoize bucket parameters" do
188
266
  @bucket = mock("Bucket")
189
267
  Riak::Bucket.should_receive(:new).with(@client, "baz").once.and_return(@bucket)
@@ -282,10 +360,138 @@ describe Riak::Client do
282
360
  @client.get_file("docs/A Big PDF.pdf")
283
361
  # Streamed get escapes keys
284
362
  @http.should_receive(:get).with(200, "/luwak", "docs%2FA%20Big%20PDF.pdf").and_yield("foo").and_return(:headers => {"content-type" => ["text/plain"]}, :code => 200)
285
- @client.get_file("docs/A Big PDF.pdf"){|chunk| chunk }
363
+ @client.get_file("docs/A Big PDF.pdf"){|chunk| chunk}
286
364
  # Put escapes keys
287
365
  @http.should_receive(:put).with(204, "/luwak", "docs%2FA%20Big%20PDF.pdf", "foo", {"Content-Type" => "text/plain"})
288
366
  @client.store_file("docs/A Big PDF.pdf", "text/plain", "foo")
289
367
  end
290
368
  end
369
+
370
+ describe "ssl", :ssl => true do
371
+ before :each do
372
+ @client = Riak::Client.new
373
+ end
374
+
375
+ it "should allow passing ssl options into the initializer" do
376
+ lambda { client = Riak::Client.new(:ssl => {:verify_mode => "peer"}) }.should_not raise_error
377
+ end
378
+
379
+ it "should not have ssl options by default" do
380
+ @client.ssl_options.should be_nil
381
+ end
382
+
383
+ it "should have a blank hash for ssl options if the protocol is set to https" do
384
+ @client.protocol = 'https'
385
+ @client.ssl_options.should be_a(Hash)
386
+ end
387
+
388
+ # The api should have an ssl= method for setting up all of the ssl
389
+ # options. Once the ssl options have been assigned via `ssl=` they should
390
+ # be read back out using the read only `ssl_options`. This is to provide
391
+ # a seperate api for setting ssl options via client configuration and
392
+ # reading them inside of a http backend.
393
+ it "should not allow reading ssl options via ssl" do
394
+ @client.should_not respond_to(:ssl)
395
+ end
396
+
397
+ it "should now allow writing ssl options via ssl_options=" do
398
+ @client.should_not respond_to(:ssl_options=)
399
+ end
400
+
401
+ it "should allow setting ssl to true" do
402
+ @client.ssl = true
403
+ @client.ssl_options[:verify_mode].should eq('none')
404
+ end
405
+
406
+ it "should allow setting ssl options as a hash" do
407
+ @client.ssl = {:verify_mode => "peer"}
408
+ @client.ssl_options[:verify_mode].should eq('peer')
409
+ end
410
+
411
+ it "should set the protocol to https when setting ssl to true" do
412
+ @client.ssl = true
413
+ @client.protocol.should eq("https")
414
+ end
415
+
416
+ it "should set the protocol to http when setting ssl to false" do
417
+ @client.protocol = 'https'
418
+ @client.ssl = false
419
+ @client.protocol.should eq('http')
420
+ end
421
+
422
+ it "should should clear ssl options when setting ssl to false" do
423
+ @client.ssl = true
424
+ @client.ssl_options.should_not be_nil
425
+ @client.ssl = false
426
+ @client.ssl_options.should be_nil
427
+ end
428
+
429
+ it "should set the protocol to https when setting ssl options" do
430
+ @client.ssl = {:verify_mode => "peer"}
431
+ @client.protocol.should eq("https")
432
+ end
433
+
434
+ it "should allow setting the verify_mode to none" do
435
+ @client.ssl = {:verify_mode => "none"}
436
+ @client.ssl_options[:verify_mode].should eq("none")
437
+ end
438
+
439
+ it "should allow setting the verify_mode to peer" do
440
+ @client.ssl = {:verify_mode => "peer"}
441
+ @client.ssl_options[:verify_mode].should eq("peer")
442
+ end
443
+
444
+ it "should not allow setting the verify_mode to anything else" do
445
+ lambda {@client.ssl = {:verify_mode => :your_mom}}.should raise_error(ArgumentError)
446
+ end
447
+
448
+ it "should default verify_mode to none" do
449
+ @client.ssl = true
450
+ @client.ssl_options[:verify_mode].should eq("none")
451
+ end
452
+
453
+ it "should let the backend know if ssl is enabled" do
454
+ @client.should_not be_ssl_enabled
455
+ @client.ssl = true
456
+ @client.should be_ssl_enabled
457
+ end
458
+
459
+ it "should allow setting the pem" do
460
+ @client.ssl = {:pem => 'i-am-a-pem'}
461
+ @client.ssl_options[:pem].should eq('i-am-a-pem')
462
+ end
463
+
464
+ it "should set them pem from the contents of pem_file" do
465
+ filepath = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test.pem'))
466
+ @client.ssl = {:pem_file => filepath}
467
+ @client.ssl_options[:pem].should eq("i-am-a-pem\n")
468
+ end
469
+
470
+ it "should allow setting the pem_password" do
471
+ @client.ssl = {:pem_password => 'pem-pass'}
472
+ @client.ssl_options[:pem_password].should eq('pem-pass')
473
+ end
474
+
475
+ it "should allow setting the ca_file" do
476
+ @client.ssl = {:ca_file => '/path/to/ca.crt'}
477
+ @client.ssl_options[:ca_file].should eq('/path/to/ca.crt')
478
+ end
479
+
480
+ it "should allow setting the ca_path" do
481
+ @client.ssl = {:ca_path => '/path/to/certs/'}
482
+ @client.ssl_options[:ca_path].should eq('/path/to/certs/')
483
+ end
484
+
485
+ %w[pem ca_file ca_path].each do |option|
486
+ it "should default the verify_mode to peer when setting the #{option}" do
487
+ @client.ssl = {option.to_sym => 'test-data'}
488
+ @client.ssl_options[:verify_mode].should eq("peer")
489
+ end
490
+
491
+ it "should allow setting the verify mode when setting the #{option}" do
492
+ @client.ssl = {option.to_sym => 'test-data', :verify_mode => "none"}
493
+ @client.ssl_options[:verify_mode].should eq("none")
494
+ end
495
+ end
496
+ end
291
497
  end