riak-client 0.9.0.beta → 0.9.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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