local_ip_checker 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6729080644e1a9f257475491abec3785326bd3d4228e779693abeab4070c3ac3
4
+ data.tar.gz: 8fd0de18050aefde74ba780f6173388bbd09964d2896f2b3470a87a53396106b
5
+ SHA512:
6
+ metadata.gz: 6abbe04fdcf406b01658673d1bed8ce0ecbe5893283e4deffd936933b91daea9b9cd8272e4551ba60f25cf12cea7fe53f959d72eae960ceffb5ca8898f82b70c
7
+ data.tar.gz: 318c4cc84a46379d29a7eb4755f58be591243ece1990224ec58e70ebcaddca8239eca53e392fd0379134679657a88304b404772323467248e2bbbb3ba5880f79
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 1.0.0
2
+
3
+ Initial version.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 yaroslav2k
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # Local IP Checker
2
+
3
+ Simple ruby gem that provides checking if given URL resolves to local IP address.
4
+
5
+ ## Abstract
6
+
7
+ If your system makes HTTP requests to 3rd-party provided URL it's required to check if this URL maps to some kind of local IP address. This gem performs checks against following types of local IP addresses:
8
+
9
+ 1. IPv4 and IPv6 localhost addresses.
10
+ 2. IPv4 `0.0.0.0` and IPv6 `::` addresses.
11
+ 3. IPv4 private address ranges (e. g. `10.0.0.0/8`).
12
+ 4. IPv6 unique local addresses (`fc00::/7`).
13
+ 5. IPv6 site-local address (`fec0::/10`)
14
+ 6. IPv4 and IPv6 link-local addresses.
15
+
16
+ ## Usage
17
+
18
+ Example:
19
+ ```
20
+ require "local_ip_checker"
21
+
22
+ LocalIPChecker.local?("google.com") # => false
23
+ LocalIPChecker.nonlocal?("google.com") => true
24
+ LocalIPChecker.local?("localhost") => true
25
+ LocalIPChecker.local?("::") # => true
26
+ ```
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resolv"
4
+
5
+ require "local_ip_checker/adapters/base"
6
+ require "local_ip_checker/adapters/domain"
7
+ require "local_ip_checker/adapters/ip_address"
8
+
9
+ module LocalIPChecker
10
+ module Adapters
11
+ DOMAIN_REGEX = /(\w+\.?)+/.freeze
12
+
13
+ module_function
14
+
15
+ def build(value)
16
+ if value.match?(Resolv::IPv4::Regex) || value.match?(Resolv::IPv6::Regex)
17
+ LocalIPChecker::Adapters::IPAddress
18
+ elsif value.match?(DOMAIN_REGEX)
19
+ LocalIPChecker::Adapters::Domain
20
+ else
21
+ raise "ValueError #{value}"
22
+ end.new(value)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module LocalIPChecker
6
+ class Executor
7
+ HOST_IP_ADDRESSES = (%w[0.0.0.0 ::] + Socket.ip_address_list.map(&:ip_address)).freeze
8
+ IPV6_LINKLOCAL_ADDRESSES = IPAddr.new("169.254.0.0/16").freeze
9
+
10
+ class << self
11
+ def local?(value)
12
+ new(value).local?
13
+ end
14
+
15
+ def nonlocal?(value)
16
+ !local?(value)
17
+ end
18
+ end
19
+
20
+ def initialize(value)
21
+ @value = value
22
+ end
23
+
24
+ def local?
25
+ Enumerator.new do |enum|
26
+ enum << localhost?
27
+ enum << loopback?
28
+ enum << local_network?
29
+ enum << link_local?
30
+ end.any?(&:itself)
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :value
36
+
37
+ def localhost?
38
+ (HOST_IP_ADDRESSES & resolved_ips.map(&:ip_address)).any?
39
+ end
40
+
41
+ def loopback?
42
+ check_ips { |ip| ip.ipv4_loopback? || ip.ipv6_loopback? }
43
+ end
44
+
45
+ def local_network?
46
+ check_ips { |ip| ip.ipv4_private? || ip.ipv6_sitelocal? || ip.ipv6_unique_local? }
47
+ end
48
+
49
+ def link_local?
50
+ check_ips { |ip| ip.ipv6_linklocal? || IPV6_LINKLOCAL_ADDRESSES.include?(ip.ip_address) }
51
+ end
52
+
53
+ def check_ips(&block)
54
+ resolved_ips.any?(&block)
55
+ end
56
+
57
+ def resolved_ips
58
+ @resolved_ips ||=
59
+ Addrinfo.getaddrinfo(value, 80, nil, :STREAM).map do |ip|
60
+ ip.ipv6_v4mapped? ? ip.ipv6_to_ipv4 : ip
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LocalIPChecker
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require "local_ip_checker/version"
6
+ require "local_ip_checker/executor"
7
+
8
+ module LocalIPChecker
9
+ extend SingleForwardable
10
+
11
+ def_delegators "LocalIPChecker::Executor", *%i[local? nonlocal?]
12
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: local_ip_checker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yaroslav Kurbatov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '13.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '13.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email: yaroslav2kleet@yandex.ru
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - CHANGELOG.md
62
+ - LICENSE
63
+ - README.md
64
+ - lib/local_ip_checker.rb
65
+ - lib/local_ip_checker/adapters.rb
66
+ - lib/local_ip_checker/executor.rb
67
+ - lib/local_ip_checker/version.rb
68
+ homepage: https://github.com/yaroslav2k/local_ip_checker
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ rubygems_mfa_required: 'true'
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 2.5.0
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.1.2
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Simple gem to check if provided URL is mapped to local IP address
92
+ test_files: []