PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/mongo/address/ipv6.rb

http://github.com/mongodb/mongo-ruby-driver
Ruby | 112 lines | 41 code | 9 blank | 62 comment | 3 complexity | 82e2ba52503cb0c71534a43b18ab6c94 MD5 | raw file
Possible License(s): Apache-2.0
  1. # Copyright (C) 2014-2020 MongoDB 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. module Mongo
  15. class Address
  16. # Sets up resolution with IPv6 support if the address is an ip
  17. # address.
  18. #
  19. # @since 2.0.0
  20. class IPv6
  21. # @return [ String ] host The host.
  22. attr_reader :host
  23. # @return [ String ] host_name The original host name.
  24. attr_reader :host_name
  25. # @return [ Integer ] port The port.
  26. attr_reader :port
  27. # The regular expression to use to match an IPv6 ip address.
  28. #
  29. # @since 2.0.0
  30. MATCH = Regexp.new('::').freeze
  31. # Parse an IPv6 address into its host and port.
  32. #
  33. # @example Parse the address.
  34. # IPv6.parse("[::1]:28011")
  35. #
  36. # @param [ String ] address The address to parse.
  37. #
  38. # @return [ Array<String, Integer> ] The host and port pair.
  39. #
  40. # @since 2.0.0
  41. def self.parse(address)
  42. # IPAddr's parser handles IP address only, not port.
  43. # Therefore we need to handle the port ourselves
  44. if address =~ /[\[\]]/
  45. parts = address.match(/\A\[(.+)\](?::(\d+))?\z/)
  46. if parts.nil?
  47. raise ArgumentError, "Invalid IPv6 address: #{address}"
  48. end
  49. host = parts[1]
  50. port = (parts[2] || 27017).to_i
  51. else
  52. host = address
  53. port = 27017
  54. end
  55. # Validate host.
  56. # This will raise IPAddr::InvalidAddressError
  57. # on newer rubies which is a subclass of ArgumentError
  58. # if host is invalid
  59. begin
  60. IPAddr.new(host)
  61. rescue ArgumentError
  62. raise ArgumentError, "Invalid IPv6 address: #{address}"
  63. end
  64. [ host, port ]
  65. end
  66. # Initialize the IPv6 resolver.
  67. #
  68. # @example Initialize the resolver.
  69. # IPv6.new("::1", 28011, 'localhost')
  70. #
  71. # @param [ String ] host The host.
  72. # @param [ Integer ] port The port.
  73. #
  74. # @since 2.0.0
  75. def initialize(host, port, host_name=nil)
  76. @host = host
  77. @port = port
  78. @host_name = host_name
  79. end
  80. # Get a socket for the provided address type, given the options.
  81. #
  82. # @example Get an IPv6 socket.
  83. # ipv4.socket(5, :ssl => true)
  84. #
  85. # @param [ Float ] socket_timeout The socket timeout.
  86. # @param [ Hash ] ssl_options SSL options.
  87. # @param [ Hash ] options The options.
  88. #
  89. # @option options [ Float ] :connect_timeout Connect timeout.
  90. #
  91. # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP ] The socket.
  92. #
  93. # @since 2.0.0
  94. def socket(socket_timeout, ssl_options = {}, options = {})
  95. unless ssl_options.empty?
  96. Socket::SSL.new(host, port, host_name, socket_timeout, Socket::PF_INET6, ssl_options.merge(options))
  97. else
  98. Socket::TCP.new(host, port, socket_timeout, Socket::PF_INET6, options)
  99. end
  100. end
  101. end
  102. end
  103. end