redirectly 0.3.0 → 0.4.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 +4 -4
- data/README.md +38 -6
- data/lib/redirectly/app.rb +46 -6
- data/lib/redirectly/command.rb +10 -3
- data/lib/redirectly/refinements.rb +9 -1
- data/lib/redirectly/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28d72de69cfc6b42a127abbfdca9c9f7a1cde760d68ad82c266454322d57d7dd
|
4
|
+
data.tar.gz: 62e1e4b12baef717c4d1a1da76769e159fd76299d55a3bad926e75680253d72f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 422b81686d1b73abbf17f0a595598ac0b017c96f03e2c3e63cf934c204c45f2a10e21535c9a234da5e52245b6c0bb53c053f358d937b6f4d833e43080eb6c87a
|
7
|
+
data.tar.gz: f39c63692882148bd630ad0fba5972d5a8f0dd8fd2176228f2497c0526491c22e253bcae847616c776c06637db8ce697aedce6b60fdc188a1b8c86025396673c
|
data/README.md
CHANGED
@@ -95,6 +95,8 @@ example.com = https://other-site.com/
|
|
95
95
|
example.org/* = https://other-site.com/
|
96
96
|
*.old-site.com = !https://permanent.redirect.com
|
97
97
|
:sub.app.localhost/* = http://it-works.com/%{sub}
|
98
|
+
proxy.localhost/*rest = @https://proxy.target.com/base/*rest
|
99
|
+
internal.localhost/reload = :reload
|
98
100
|
(*)old-domain.com/*rest = http://new-domain.com/%{rest}
|
99
101
|
```
|
100
102
|
|
@@ -109,14 +111,44 @@ The configuration file is built of `pattern = target` pairs, where:
|
|
109
111
|
- `pattern` - is any URL pattern that is supported by [Mustermann][mustermann].
|
110
112
|
- `target` - is the target URL to redirect to.
|
111
113
|
|
112
|
-
|
114
|
+
### Special INI Notation
|
113
115
|
|
114
|
-
|
115
|
-
redirect (301), otherwise it will be a temporary redirect (302).
|
116
|
-
- If `pattern` includes named arguments (e.g. `example.com/:something`), they
|
117
|
-
will be available to the `target` as Ruby string substitution variables
|
118
|
-
(e.g. `%{something}`).
|
116
|
+
#### Redirect type
|
119
117
|
|
118
|
+
If the target starts with `!`, a permanent redirect (301) will be performed.
|
119
|
+
If it does not, a temporary redirect (302) will be performed by default:
|
120
|
+
|
121
|
+
```ini
|
122
|
+
test.localhost/temporary = http://example.com
|
123
|
+
test.localhost/permanent = !http://example.com
|
124
|
+
```
|
125
|
+
|
126
|
+
#### Proxying
|
127
|
+
|
128
|
+
If the target starts with `@`, the content will be proxied instead of being
|
129
|
+
redirected:
|
130
|
+
|
131
|
+
```ini
|
132
|
+
test.localhost = @http://example.com
|
133
|
+
```
|
134
|
+
|
135
|
+
#### Named arguments
|
136
|
+
|
137
|
+
Patterns that include strings starting with a colon `:` will expose those
|
138
|
+
strings as Ruby substitution variables in the target:
|
139
|
+
|
140
|
+
```ini
|
141
|
+
test.localhost/:anything = http://example.com/path/%{anything}
|
142
|
+
```
|
143
|
+
|
144
|
+
#### Splats
|
145
|
+
|
146
|
+
You can use a splat `*` or a named splat `*name` in the pattern.
|
147
|
+
Named splats will also be exposed as Ruby substitution variables in the target:
|
148
|
+
|
149
|
+
```ini
|
150
|
+
(*)test.localhost/*rest = http://example.com/%{rest}
|
151
|
+
```
|
120
152
|
|
121
153
|
## Contributing / Support
|
122
154
|
|
data/lib/redirectly/app.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'cgi'
|
2
|
-
require 'rack'
|
3
2
|
require 'mustermann'
|
3
|
+
require 'net/http'
|
4
|
+
require 'rack'
|
5
|
+
require 'uri'
|
4
6
|
|
5
7
|
module Redirectly
|
6
8
|
class App
|
@@ -14,10 +16,10 @@ module Redirectly
|
|
14
16
|
|
15
17
|
def call(env)
|
16
18
|
@req = Rack::Request.new env
|
17
|
-
found =
|
19
|
+
found = find_match
|
18
20
|
|
19
21
|
if found
|
20
|
-
|
22
|
+
handle_target found
|
21
23
|
else
|
22
24
|
not_found
|
23
25
|
end
|
@@ -25,6 +27,16 @@ module Redirectly
|
|
25
27
|
|
26
28
|
private
|
27
29
|
|
30
|
+
def handle_target(target)
|
31
|
+
if target.start_with? ':'
|
32
|
+
run_internal_command target[1..]
|
33
|
+
elsif target.start_with? '@'
|
34
|
+
proxy_to target[1..]
|
35
|
+
else
|
36
|
+
redirect_to target
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
28
40
|
def redirect_to(target)
|
29
41
|
code = 302
|
30
42
|
|
@@ -36,20 +48,48 @@ module Redirectly
|
|
36
48
|
[code, { 'location' => target }, []]
|
37
49
|
end
|
38
50
|
|
51
|
+
def proxy_to(target)
|
52
|
+
uri = URI target
|
53
|
+
uri.query = req.query_string unless req.query_string.empty?
|
54
|
+
|
55
|
+
response = Net::HTTP.get_response uri
|
56
|
+
|
57
|
+
headers = { 'Content-Type' => response['Content-Type'] }
|
58
|
+
[response.code.to_i, headers, [response.body]]
|
59
|
+
rescue => e
|
60
|
+
[502, { 'Content-Type' => 'text/plain' }, ["Bad Gateway: #{e.message}"]]
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_internal_command(target)
|
64
|
+
case target.to_sym
|
65
|
+
when :reload then reload_ini
|
66
|
+
else not_found
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
39
70
|
def not_found
|
40
71
|
[404, { 'content-type' => 'text/plain' }, ['Not Found']]
|
41
72
|
end
|
42
73
|
|
43
74
|
def redirects
|
44
|
-
|
75
|
+
if ENV['REDIRECTLY_RELOAD']
|
76
|
+
ini_read config_path
|
77
|
+
else
|
78
|
+
@redirects ||= ini_read(config_path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def reload_ini
|
83
|
+
@redirects = nil
|
84
|
+
[200, { 'content-type' => 'text/plain' }, ['OK (:reload)']]
|
45
85
|
end
|
46
86
|
|
47
87
|
def ini_read(path)
|
48
|
-
content = File.readlines(path, chomp: true).reject(&:
|
88
|
+
content = File.readlines(path, chomp: true).reject(&:ignored?)
|
49
89
|
content.to_h { |line| line.split(/\s*=\s*/, 2) }
|
50
90
|
end
|
51
91
|
|
52
|
-
def
|
92
|
+
def find_match
|
53
93
|
redirects.each do |pattern, target|
|
54
94
|
found = find_target pattern, target
|
55
95
|
return found if found
|
data/lib/redirectly/command.rb
CHANGED
@@ -8,17 +8,21 @@ module Redirectly
|
|
8
8
|
help 'Start the redirect server'
|
9
9
|
version Redirectly::VERSION
|
10
10
|
|
11
|
-
usage 'redirectly [CONFIG --port PORT]'
|
11
|
+
usage 'redirectly [CONFIG --port PORT --reload]'
|
12
12
|
usage 'redirectly --init'
|
13
|
-
usage 'redirectly --help | --version'
|
13
|
+
usage 'redirectly -h | --help | --version'
|
14
14
|
|
15
15
|
option '-p --port PORT', 'Listening port [default: 3000]'
|
16
16
|
option '-i --init', 'Create a sample config file and exit'
|
17
|
+
option '-r --reload', 'Read the INI file with every request'
|
17
18
|
|
18
19
|
param 'CONFIG', 'Path to config file [default: redirects.ini]'
|
19
20
|
|
21
|
+
environment 'REDIRECTLY_RELOAD',
|
22
|
+
'Set to a non empty value in order to read the INI file with every request (same as --reload)'
|
23
|
+
|
20
24
|
example 'redirectly --init'
|
21
|
-
example 'redirectly config.ini'
|
25
|
+
example 'redirectly config.ini --port 4000 --reload'
|
22
26
|
|
23
27
|
attr_reader :config_path, :port
|
24
28
|
|
@@ -44,6 +48,8 @@ module Redirectly
|
|
44
48
|
example.org/* = https://other-site.com/
|
45
49
|
*.old-site.com = !https://permanent.redirect.com
|
46
50
|
:sub.app.localhost/* = http://it-works.com/%{sub}
|
51
|
+
proxy.localhost/*rest = @https://proxy.target.com/base/*rest
|
52
|
+
internal.localhost/reload = :reload
|
47
53
|
(*)old-domain.com/*rest = http://new-domain.com/%{rest}
|
48
54
|
TEMPLATE
|
49
55
|
end
|
@@ -51,6 +57,7 @@ module Redirectly
|
|
51
57
|
def start_server
|
52
58
|
raise ArgumentError, "Cannot find config file #{config_path}" unless File.exist? config_path
|
53
59
|
|
60
|
+
ENV['REDIRECTLY_RELOAD'] = '1' if args['--reload']
|
54
61
|
Rackup::Server.start(app: app, Port: port, environment: 'production')
|
55
62
|
end
|
56
63
|
|
@@ -1,8 +1,16 @@
|
|
1
1
|
module Redirectly
|
2
2
|
module Refinements
|
3
3
|
refine String do
|
4
|
+
def ignored?
|
5
|
+
empty? || comment? || section?
|
6
|
+
end
|
7
|
+
|
4
8
|
def comment?
|
5
|
-
start_with?
|
9
|
+
start_with?(';') || start_with?('#')
|
10
|
+
end
|
11
|
+
|
12
|
+
def section?
|
13
|
+
match?(/^\[.+\]\s*$/)
|
6
14
|
end
|
7
15
|
end
|
8
16
|
end
|
data/lib/redirectly/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redirectly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mister_bin
|
@@ -122,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
122
|
requirements:
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '3.
|
125
|
+
version: '3.1'
|
126
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
128
|
- - ">="
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
|
-
rubygems_version: 3.5.
|
132
|
+
rubygems_version: 3.5.23
|
133
133
|
signing_key:
|
134
134
|
specification_version: 4
|
135
135
|
summary: Redirectly redirect server
|