Kouhei Sutou
null+****@clear*****
Sun Mar 13 18:59:25 JST 2016
Kouhei Sutou 2016-03-13 18:59:25 +0900 (Sun, 13 Mar 2016) New Revision: ee7ec6c2107ad50ddba3fc030e278a3fb9bf1256 https://github.com/ranguba/groonga-client/commit/ee7ec6c2107ad50ddba3fc030e278a3fb9bf1256 Message: Support URI for specifying Groonga server Modified files: lib/groonga/client.rb lib/groonga/client/protocol/gqtp.rb lib/groonga/client/protocol/http.rb lib/groonga/client/protocol/http/synchronous.rb test/protocol/test-gqtp.rb test/protocol/test-http.rb test/test-client.rb Modified: lib/groonga/client.rb (+58 -5) =================================================================== --- lib/groonga/client.rb 2016-03-13 18:08:07 +0900 (b015c13) +++ lib/groonga/client.rb 2016-03-13 18:59:25 +0900 (a102786) @@ -17,6 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +require "uri" require "json" require "groonga/client/default" @@ -31,6 +32,8 @@ module Groonga class << self # @!macro [new] initialize_options # @param [Hash] options The options. + # @option options [String, URI::Generic, URI::HTTP, URI::HTTPS] + # :url The URL of Groonga server. # @option options [:gqtp, :http] :protocol The protocol that is # used by the client. # @option options [String] :user User ID. Currently used for HTTP @@ -71,15 +74,21 @@ module Groonga # @macro initialize_options def initialize(options={}) options = options.dup - protocol = options.delete(:protocol) || :gqtp + url = options[:url] || build_url(options) + url = URL.parse(url) unless url.is_a?(URI::Generic) + options[:url] = url options[:read_timeout] ||= Default::READ_TIMEOUT @connection = nil - if protocol == :gqtp - @connection = Groonga::Client::Protocol::GQTP.new(options) + case url.scheme + when "gqtp" + @connection = Groonga::Client::Protocol::GQTP.new(url, options) + when "http", "https" + @connection = Groonga::Client::Protocol::HTTP.new(url, options) else - options[:use_tls] = true if protocol == :https - @connection = Groonga::Client::Protocol::HTTP.new(options) + message = "unsupported scheme: <#{url.scheme}>: " + message << "supported: [gqtp, http, https]" + raise ArgumentError, message end end @@ -234,6 +243,50 @@ module Groonga end private + def build_url(options) + scheme = (options.delete(:protocol) || "gqtp").to_s + host = options.delete(:host) || options.delete(:address) || "127.0.0.1" + port = options.delete(:port) || default_port(scheme) + user = options.delete(:user) + password = options.delete(:password) + if user and password + userinfo = "#{user}:#{password}" + else + userinfo = nil + end + + arguments = [ + scheme, + userinfo, + host, + port, + nil, + nil, + nil, + nil, + nil, + ] + case scheme + when "http" + URI::HTTP.new(*arguments) + when "https" + URI::HTTPS.new(*arguments) + else + URI::Generic.new(*arguments) + end + end + + def default_port(scheme) + case scheme + when "gqtp" + 10043 + when "http", "https" + 10041 + else + nil + end + end + def execute_command(command_name, parameters={}, &block) parameters = normalize_parameters(parameters) command_class = Groonga::Command.find(command_name) Modified: lib/groonga/client/protocol/gqtp.rb (+4 -5) =================================================================== --- lib/groonga/client/protocol/gqtp.rb 2016-03-13 18:08:07 +0900 (b5e2b11) +++ lib/groonga/client/protocol/gqtp.rb 2016-03-13 18:59:25 +0900 (fe3441e) @@ -1,7 +1,5 @@ -# -*- coding: utf-8 -*- -# # Copyright (C) 2013 Haruka Yoshihara <yoshihara �� clear-code.com> -# Copyright (C) 2013-2014 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -29,9 +27,10 @@ module Groonga class Client module Protocol class GQTP - def initialize(options) + def initialize(url, options={}) begin - @client = ::GQTP::Client.new(options) + @client = ::GQTP::Client.new(:host => url.host, + :port => url.port) rescue ::GQTP::ConnectionError raise WrappedError.new($!) end Modified: lib/groonga/client/protocol/http.rb (+3 -4) =================================================================== --- lib/groonga/client/protocol/http.rb 2016-03-13 18:08:07 +0900 (1b857ad) +++ lib/groonga/client/protocol/http.rb 2016-03-13 18:59:25 +0900 (6be75af) @@ -32,9 +32,8 @@ module Groonga end end - def initialize(options) - @host = options[:host] || "127.0.0.1" - @port = options[:port] || 10041 + def initialize(url, options) + @url = url @options = default_options.merge(options) @backend = create_backend end @@ -69,7 +68,7 @@ module Groonga backend_name = backend.to_s.capitalize backend_class = self.class.const_get(backend_name) - backend_class.new(@host, @port, @options) + backend_class.new(@url, @options) end end end Modified: lib/groonga/client/protocol/http/synchronous.rb (+12 -8) =================================================================== --- lib/groonga/client/protocol/http/synchronous.rb 2016-03-13 18:08:07 +0900 (3461ce4) +++ lib/groonga/client/protocol/http/synchronous.rb 2016-03-13 18:59:25 +0900 (211650c) @@ -1,5 +1,5 @@ # Copyright (C) 2013 Haruka Yoshihara <yoshihara �� clear-code.com> -# Copyright (C) 2013-2014 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -26,15 +26,17 @@ module Groonga module Protocol class HTTP class Synchronous - def initialize(host, port, options) - @host = host - @port = port + def initialize(url, options={}) + @url = url @options = options end def send(command) begin - Net::HTTP.start(@host, @port, use_ssl: @options[:use_tls]) do |http| + options = { + :use_ssl => @url.scheme == "https" + } + Net::HTTP.start(@url.host, @url.port, options) do |http| http.read_timeout = read_timeout response = send_request(http, command) case response @@ -123,10 +125,12 @@ module Groonga end def setup_authentication(request) - user = @options[:user] - password = @options[:password] - return if user.nil? or password.nil? + userinfo =****@url***** + return if userinfo.nil? + user, password = userinfo.split(/:/, 2).collect do |component| + URI.decode_www_form_component(component) + end request.basic_auth(user, password) end end Modified: test/protocol/test-gqtp.rb (+9 -10) =================================================================== --- test/protocol/test-gqtp.rb 2016-03-13 18:08:07 +0900 (95361e2) +++ test/protocol/test-gqtp.rb 2016-03-13 18:59:25 +0900 (1d93589) @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2014 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -60,11 +58,10 @@ class TestProtocolGQTP < Test::Unit::TestCase private def connect(options={}) - default_options = { - :host => @address, - :port => @port, - } - Groonga::Client::Protocol::GQTP.new(default_options.merge(options)) + url = URI::Generic.build(:scheme => "gqtp", + :host => @address, + :port => @port) + Groonga::Client::Protocol::GQTP.new(url, options) end def process_client_close(client) @@ -84,9 +81,11 @@ class TestProtocolGQTP < Test::Unit::TestCase server = TCPServer.new("127.0.0.1", 0) free_port = server.addr[1] server.close + url = URI::Generic.build(:scheme => "gqtp", + :host => "127.0.0.1", + :port => free_port) assert_raise(Groonga::Client::Protocol::WrappedError) do - Groonga::Client::Protocol::GQTP.new(:host => "127.0.0.1", - :port => free_port) + Groonga::Client::Protocol::GQTP.new(url, {}) end end end Modified: test/protocol/test-http.rb (+4 -8) =================================================================== --- test/protocol/test-http.rb 2016-03-13 18:08:07 +0900 (afcf85b) +++ test/protocol/test-http.rb 2016-03-13 18:59:25 +0900 (52f6bb9) @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2014 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -74,11 +72,9 @@ EOH end def connect(options={}) - default_options = { - :host => @address, - :port => @port, - } - Groonga::Client::Protocol::HTTP.new(default_options.merge(options)) + url = URI::HTTP.build(:host => @address, + :port => @port) + Groonga::Client::Protocol::HTTP.new(url, options) end def test_connected? Modified: test/test-client.rb (+39 -10) =================================================================== --- test/test-client.rb 2016-03-13 18:08:07 +0900 (aa619c4) +++ test/test-client.rb 2016-03-13 18:59:25 +0900 (faa03db) @@ -1,7 +1,5 @@ -# -*- coding: utf-8 -*- -# # Copyright (C) 2013 Haruka Yoshihara <yoshihara �� clear-code.com> -# Copyright (C) 2013-2015 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -50,13 +48,15 @@ class TestClient < Test::Unit::TestCase end def open_client(&block) - options = { - :host => @address, - :port => @port, - :protocol => @protocol, - :user => @user, - :password => @password, - } + url = "#{@protocol}://" + if @user and @password + url << URI.encode_www_form_component(@user) + url << ":" + url << URI.encode_www_form_component(@password) + url << "@" + end + url << "#{@address}:#{@port}" + options = {:url => URI.parse(url)} Groonga::Client.open(options, &block) end @@ -229,6 +229,19 @@ JSON end assert_equal("response", response) end + + def test_open_components + stub_response("[29]") + options = { + :host => @address, + :port => @port, + :protocol => @protocol, + } + response = Groonga::Client.open(options) do |client| + client.status + end + assert_equal([29], response.body) + end end module LoadTests @@ -412,6 +425,22 @@ EOH assert_equal("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", @request_headers["authorization"]) end + + def test_open_components + stub_response("[]") + options = { + :host => @address, + :port => @port, + :protocol => @protocol, + :user => @user, + :password => @password, + } + Groonga::Client.open(options) do |client| + client.status + end + assert_equal("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", + @request_headers["authorization"]) + end end end end -------------- next part -------------- HTML����������������������������...Download