final_redirect_url 0.1.0 → 2.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 +5 -5
- data/.github/workflows/ci.yml +32 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +61 -0
- data/README.md +44 -12
- data/final_redirect_url.gemspec +21 -24
- data/lib/final_redirect_url/version.rb +1 -1
- data/lib/final_redirect_url.rb +75 -35
- metadata +35 -18
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 522f5bf5f63725bfacfd9615a3b37ae003e42712a9663fd5f7af11b8ce2c2f52
|
|
4
|
+
data.tar.gz: b25c7ff42bade483244d24c1642da9097cd930326f6ebbee4f1e1aba5e854699
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bafed8a367867eee62492c7f101682595a7a0c37736e3d71e7e79b29f0716c962b5e00af2ef3c5338148fb7e2e533a003a8e20b42dc852dbd0fa16d866b30514
|
|
7
|
+
data.tar.gz: e3dd7b15536e3e4bdcccfed12b227042707c6134f64f32d8045f86dd9c015ed1d5dfd05e119673416a1bd97efd0d4d79a7863e929adb893685fef2e1d429982e
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main, "feature/**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Ruby ${{ matrix.ruby }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
ruby:
|
|
17
|
+
- "3.0"
|
|
18
|
+
- "3.1"
|
|
19
|
+
- "3.2"
|
|
20
|
+
- "3.3"
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Set up Ruby ${{ matrix.ruby }}
|
|
26
|
+
uses: ruby/setup-ruby@v1
|
|
27
|
+
with:
|
|
28
|
+
ruby-version: ${{ matrix.ruby }}
|
|
29
|
+
bundler-cache: true
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.3.1
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project
|
|
6
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [2.0.0] – 2026-11-05
|
|
11
|
+
|
|
12
|
+
### Breaking Changes
|
|
13
|
+
- **Minimum Ruby version raised to 3.0.** Ruby 2.x is no longer supported.
|
|
14
|
+
- Private helper methods (`valid_url?`, `resolve_redirects`, `fetch_response`, `absolute_url`) are now
|
|
15
|
+
truly private (defined inside `class << self` with `private`). Calling them from outside the module
|
|
16
|
+
now raises `NoMethodError`. This was always the intended behaviour; previous versions accidentally
|
|
17
|
+
exposed them as public singleton methods (fixes [#4][i4]).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **GitHub Actions CI** replacing the removed Travis CI configuration. The matrix tests Ruby 3.0,
|
|
21
|
+
3.1, 3.2, and 3.3 on every push and pull request.
|
|
22
|
+
- **WebMock** test dependency — the full test suite now runs without any real network connections.
|
|
23
|
+
- `CHANGELOG.md` (this file).
|
|
24
|
+
- Gem metadata fields (`homepage_uri`, `source_code_uri`, `changelog_uri`).
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Port numbers are now preserved** in final URLs. For example,
|
|
28
|
+
`final_redirect_url("http://localhost:3000/path")` now correctly returns
|
|
29
|
+
`"http://localhost:3000/path"` instead of `"http://localhost/path"` (fixes [#6][i6]).
|
|
30
|
+
- **Redirect depth limit now works correctly.** When the hop limit was reached the gem previously
|
|
31
|
+
returned a bare `String` to `url_string_from_uri`, causing a `NoMethodError`. The limit guard now
|
|
32
|
+
returns the current `URI` object (fixes [#2][i2]).
|
|
33
|
+
- **Relative-path redirects now carry forward the original host's port.** The gem uses `URI.join`
|
|
34
|
+
instead of manual string concatenation, so a redirect `Location: /new-path` from
|
|
35
|
+
`http://localhost:3000/old-path` resolves to `http://localhost:3000/new-path`.
|
|
36
|
+
- **Non-redirect, non-200 responses** (403, 404, 500 …) are now handled gracefully: the gem returns
|
|
37
|
+
the last reachable URL rather than crashing with a `TypeError` on a nil `Location` header.
|
|
38
|
+
- **HTTPS support** — connections now set `use_ssl = true` when the scheme is `https`. Previously
|
|
39
|
+
only plain-HTTP URLs worked.
|
|
40
|
+
- **`URI::regexp` removed** — the old `is_valid_url?` used the deprecated (and Ruby-3.x-removed)
|
|
41
|
+
`URI::regexp`. Replaced with `URI.parse` + `URI::HTTP` class check.
|
|
42
|
+
- **`rescue Exception`** replaced with `rescue StandardError` to avoid masking signals and other
|
|
43
|
+
non-recoverable errors.
|
|
44
|
+
- **`$stdout`** used instead of bare `STDOUT` constant (style/frozen-string consistency).
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
- Switched from `Net::HTTP.get_response` (GET) to explicit `Net::HTTP::Head` requests. HEAD is
|
|
48
|
+
sufficient for redirect resolution and avoids downloading response bodies.
|
|
49
|
+
- Added `open_timeout` and `read_timeout` (10 s each) to prevent indefinite hangs.
|
|
50
|
+
- Added a `User-Agent` header so servers that require it don't return unexpected responses.
|
|
51
|
+
|
|
52
|
+
### Known Limitations
|
|
53
|
+
- JavaScript- and AMP-based redirects (e.g. certain Google News AMP URLs — [#3][i3]) require a
|
|
54
|
+
headless browser and are outside the scope of this gem. The gem returns the last HTTP-level
|
|
55
|
+
reachable URL in such cases.
|
|
56
|
+
|
|
57
|
+
[2.0.0]: https://github.com/indyarocks/final_redirect_url/compare/v0.1.1...v2.0.0
|
|
58
|
+
[i2]: https://github.com/indyarocks/final_redirect_url/issues/2
|
|
59
|
+
[i3]: https://github.com/indyarocks/final_redirect_url/issues/3
|
|
60
|
+
[i4]: https://github.com/indyarocks/final_redirect_url/issues/4
|
|
61
|
+
[i6]: https://github.com/indyarocks/final_redirect_url/issues/6
|
data/README.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# FinalRedirectUrl
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/indyarocks/final_redirect_url/actions/workflows/ci.yml)
|
|
4
|
+
[](https://badge.fury.io/rb/final_redirect_url)
|
|
5
|
+
|
|
6
|
+
Ruby gem that follows HTTP/HTTPS redirects and returns the final destination URL.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Ruby >= 3.0
|
|
4
11
|
|
|
5
12
|
## Installation
|
|
6
13
|
|
|
@@ -10,30 +17,55 @@ Add this line to your application's Gemfile:
|
|
|
10
17
|
gem 'final_redirect_url'
|
|
11
18
|
```
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
Then run:
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
```
|
|
23
|
+
$ bundle install
|
|
24
|
+
```
|
|
16
25
|
|
|
17
|
-
Or install
|
|
26
|
+
Or install directly:
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
```
|
|
29
|
+
$ gem install final_redirect_url
|
|
30
|
+
```
|
|
20
31
|
|
|
21
32
|
## Usage
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
The input URL **must** include the `http://` or `https://` scheme.
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
```ruby
|
|
37
|
+
require 'final_redirect_url'
|
|
26
38
|
|
|
27
|
-
|
|
39
|
+
# Simple redirect following
|
|
40
|
+
FinalRedirectUrl.final_redirect_url('http://google.com')
|
|
41
|
+
# => "https://www.google.com/"
|
|
28
42
|
|
|
29
|
-
|
|
43
|
+
# Ports are preserved
|
|
44
|
+
FinalRedirectUrl.final_redirect_url('http://localhost:3000/items/42')
|
|
45
|
+
# => "http://localhost:3000/items/42"
|
|
30
46
|
|
|
31
|
-
|
|
47
|
+
# Custom redirect depth (default: 10)
|
|
48
|
+
FinalRedirectUrl.final_redirect_url('http://example.com', depth: 5)
|
|
49
|
+
# => "http://final.example.com/"
|
|
50
|
+
|
|
51
|
+
# Invalid / missing protocol → empty string
|
|
52
|
+
FinalRedirectUrl.final_redirect_url('www.example.com')
|
|
53
|
+
# => ""
|
|
54
|
+
```
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
## Limitations
|
|
34
57
|
|
|
58
|
+
- **JavaScript / AMP redirects** (e.g. some Google News AMP URLs) are not followed. These require a
|
|
59
|
+
headless browser. The gem returns the last HTTP-reachable URL in such cases.
|
|
60
|
+
- Redirects are followed using HTTP `HEAD` requests. Servers that reject `HEAD` with `405 Method Not Allowed`
|
|
61
|
+
may not resolve correctly.
|
|
62
|
+
|
|
63
|
+
## Contributing
|
|
64
|
+
|
|
65
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/indyarocks/final_redirect_url>.
|
|
66
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected
|
|
67
|
+
to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
35
68
|
|
|
36
69
|
## License
|
|
37
70
|
|
|
38
71
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
39
|
-
|
data/final_redirect_url.gemspec
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
3
|
require 'final_redirect_url/version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name =
|
|
6
|
+
spec.name = 'final_redirect_url'
|
|
8
7
|
spec.version = FinalRedirectUrl::VERSION
|
|
9
|
-
spec.authors = [
|
|
10
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['Chandan Jhunjhunwal']
|
|
9
|
+
spec.email = ['chandan.jhun@gmail.com']
|
|
11
10
|
|
|
12
|
-
spec.summary =
|
|
13
|
-
spec.description =
|
|
14
|
-
|
|
15
|
-
spec.homepage =
|
|
16
|
-
spec.license =
|
|
11
|
+
spec.summary = 'Get the final redirect URL for any given URL.'
|
|
12
|
+
spec.description = 'Follows HTTP redirects (including HTTPS, relative paths, and ' \
|
|
13
|
+
'non-standard ports) to resolve the final destination URL.'
|
|
14
|
+
spec.homepage = 'https://github.com/indyarocks/final_redirect_url'
|
|
15
|
+
spec.license = 'MIT'
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
20
|
-
# if spec.respond_to?(:metadata)
|
|
21
|
-
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
|
22
|
-
# else
|
|
23
|
-
# raise "RubyGems 2.0 or newer is required to protect against " \
|
|
24
|
-
# "public gem pushes."
|
|
25
|
-
# end
|
|
17
|
+
spec.required_ruby_version = '>= 3.0'
|
|
26
18
|
|
|
27
|
-
spec.
|
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
21
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
|
22
|
+
|
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
28
24
|
f.match(%r{^(test|spec|features)/})
|
|
29
25
|
end
|
|
30
|
-
spec.bindir =
|
|
26
|
+
spec.bindir = 'exe'
|
|
31
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
32
|
-
spec.require_paths = [
|
|
28
|
+
spec.require_paths = ['lib']
|
|
33
29
|
|
|
34
|
-
spec.add_development_dependency
|
|
35
|
-
spec.add_development_dependency
|
|
36
|
-
spec.add_development_dependency
|
|
30
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
31
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
33
|
+
spec.add_development_dependency 'webmock', '~> 3.0'
|
|
37
34
|
end
|
data/lib/final_redirect_url.rb
CHANGED
|
@@ -1,50 +1,90 @@
|
|
|
1
1
|
require 'final_redirect_url/version'
|
|
2
2
|
require 'net/http'
|
|
3
|
+
require 'net/https'
|
|
4
|
+
require 'uri'
|
|
3
5
|
require 'logger'
|
|
4
6
|
|
|
5
7
|
module FinalRedirectUrl
|
|
8
|
+
DEFAULT_DEPTH = 10
|
|
9
|
+
USER_AGENT = "FinalRedirectUrl/#{VERSION} (+https://github.com/indyarocks/final_redirect_url)".freeze
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
class << self
|
|
12
|
+
# Resolves all HTTP/HTTPS redirects for the given URL and returns the final
|
|
13
|
+
# destination as a string. Returns an empty string for invalid input or on
|
|
14
|
+
# unrecoverable network errors.
|
|
15
|
+
#
|
|
16
|
+
# @param url [String] the starting URL (must include http:// or https://)
|
|
17
|
+
# @param options [Hash]
|
|
18
|
+
# @option options [Integer] :depth maximum redirect hops (default: 10)
|
|
19
|
+
# @return [String]
|
|
20
|
+
def final_redirect_url(url, options = {})
|
|
21
|
+
return '' unless valid_url?(url)
|
|
22
|
+
|
|
23
|
+
limit = options.fetch(:depth, DEFAULT_DEPTH).to_i
|
|
24
|
+
limit = DEFAULT_DEPTH unless limit.positive?
|
|
25
|
+
|
|
26
|
+
resolve_redirects(url, limit).to_s
|
|
27
|
+
rescue StandardError => ex
|
|
28
|
+
Logger.new($stdout).error(ex.message)
|
|
29
|
+
''
|
|
18
30
|
end
|
|
19
|
-
final_url
|
|
20
|
-
end
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Returns true only for syntactically valid HTTP/HTTPS URLs.
|
|
35
|
+
# Fixes issue #4: private via class << self so the method is genuinely
|
|
36
|
+
# inaccessible from outside the module.
|
|
37
|
+
def valid_url?(url)
|
|
38
|
+
uri = URI.parse(url.to_s)
|
|
39
|
+
uri.is_a?(URI::HTTP)
|
|
40
|
+
rescue URI::InvalidURIError
|
|
41
|
+
false
|
|
42
|
+
end
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if
|
|
36
|
-
|
|
44
|
+
# Recursively follows redirects up to +limit+ hops.
|
|
45
|
+
# Fixes issue #2: when the hop limit is reached, returns the current URI
|
|
46
|
+
# (a proper URI object, not a bare string) so url_string_from_uri never
|
|
47
|
+
# receives a plain String.
|
|
48
|
+
# Fixes issue #6: uses URI.join to build absolute redirect targets, which
|
|
49
|
+
# preserves non-standard ports from the base URI (e.g. localhost:3000).
|
|
50
|
+
def resolve_redirects(url, limit)
|
|
51
|
+
uri = URI.parse(url)
|
|
52
|
+
return uri if limit <= 0
|
|
53
|
+
|
|
54
|
+
response = fetch_response(uri)
|
|
55
|
+
|
|
56
|
+
case response
|
|
57
|
+
when Net::HTTPOK
|
|
58
|
+
uri
|
|
59
|
+
when Net::HTTPRedirection
|
|
60
|
+
location = response['location']
|
|
61
|
+
warn "redirected to #{location}"
|
|
62
|
+
resolve_redirects(absolute_url(uri, location), limit - 1)
|
|
63
|
+
else
|
|
64
|
+
# Non-redirect, non-200 response (e.g. 404, 403, 500): return the
|
|
65
|
+
# current URI rather than trying to follow a missing Location header.
|
|
66
|
+
uri
|
|
37
67
|
end
|
|
38
|
-
warn "redirected to #{redirect_location}"
|
|
39
|
-
get_final_redirect_url(redirect_location, limit - 1)
|
|
40
68
|
end
|
|
41
|
-
end
|
|
42
69
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
# Opens an HTTP/HTTPS connection and fires a HEAD request.
|
|
71
|
+
# HEAD is sufficient for redirect resolution and avoids downloading bodies.
|
|
72
|
+
def fetch_response(uri)
|
|
73
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
74
|
+
http.use_ssl = (uri.scheme == 'https')
|
|
75
|
+
http.open_timeout = 10
|
|
76
|
+
http.read_timeout = 10
|
|
77
|
+
|
|
78
|
+
request = Net::HTTP::Head.new(uri.request_uri)
|
|
79
|
+
request['User-Agent'] = USER_AGENT
|
|
80
|
+
|
|
81
|
+
http.request(request)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Converts a potentially relative +location+ into an absolute URL,
|
|
85
|
+
# keeping the scheme, host, and port of +base_uri+.
|
|
86
|
+
def absolute_url(base_uri, location)
|
|
87
|
+
URI.join(base_uri.to_s, location).to_s
|
|
47
88
|
end
|
|
48
|
-
url_str
|
|
49
89
|
end
|
|
50
90
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: final_redirect_url
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chandan Jhunjhunwal
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-11-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,28 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '2.0'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '2.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '13.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '13.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,18 +52,33 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '3.0'
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: webmock
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.0'
|
|
69
|
+
description: Follows HTTP redirects (including HTTPS, relative paths, and non-standard
|
|
70
|
+
ports) to resolve the final destination URL.
|
|
58
71
|
email:
|
|
59
72
|
- chandan.jhun@gmail.com
|
|
60
73
|
executables: []
|
|
61
74
|
extensions: []
|
|
62
75
|
extra_rdoc_files: []
|
|
63
76
|
files:
|
|
77
|
+
- ".github/workflows/ci.yml"
|
|
64
78
|
- ".gitignore"
|
|
65
79
|
- ".rspec"
|
|
66
|
-
- ".
|
|
80
|
+
- ".ruby-version"
|
|
81
|
+
- CHANGELOG.md
|
|
67
82
|
- CODE_OF_CONDUCT.md
|
|
68
83
|
- Gemfile
|
|
69
84
|
- LICENSE.txt
|
|
@@ -77,8 +92,11 @@ files:
|
|
|
77
92
|
homepage: https://github.com/indyarocks/final_redirect_url
|
|
78
93
|
licenses:
|
|
79
94
|
- MIT
|
|
80
|
-
metadata:
|
|
81
|
-
|
|
95
|
+
metadata:
|
|
96
|
+
homepage_uri: https://github.com/indyarocks/final_redirect_url
|
|
97
|
+
source_code_uri: https://github.com/indyarocks/final_redirect_url
|
|
98
|
+
changelog_uri: https://github.com/indyarocks/final_redirect_url/blob/master/CHANGELOG.md
|
|
99
|
+
post_install_message:
|
|
82
100
|
rdoc_options: []
|
|
83
101
|
require_paths:
|
|
84
102
|
- lib
|
|
@@ -86,16 +104,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
86
104
|
requirements:
|
|
87
105
|
- - ">="
|
|
88
106
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0'
|
|
107
|
+
version: '3.0'
|
|
90
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
109
|
requirements:
|
|
92
110
|
- - ">="
|
|
93
111
|
- !ruby/object:Gem::Version
|
|
94
112
|
version: '0'
|
|
95
113
|
requirements: []
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
signing_key:
|
|
114
|
+
rubygems_version: 3.5.9
|
|
115
|
+
signing_key:
|
|
99
116
|
specification_version: 4
|
|
100
|
-
summary: Get
|
|
117
|
+
summary: Get the final redirect URL for any given URL.
|
|
101
118
|
test_files: []
|