Skip to content

Commit fe03d29

Browse files
jomaOliverjomaOliver
andauthored
New feature: Default destination; Allow us to forward requests based only on the path and default destination. (#32)
Co-authored-by: jomaOliver <olivedavid@jomashop.io>
1 parent b587273 commit fe03d29

3 files changed

Lines changed: 88 additions & 13 deletions

File tree

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ https://udl.fdo.cr/?r=https://reservation.com/restaurants/silvestre
3030

3131
This will bypass the limitation of Safari (embedded webview) that doesn't allow your Universal Links to trigger. You should now have a working "open in app" UX.
3232

33+
### Default destination support
34+
If the `DEFAULT_DESTINATION` environment variable is set and no `r` query parameter is provided:
35+
36+
- A request to the root path:
37+
38+
- `https://udl.fdo.cr/` will redirect to `DEFAULT_DESTINATION`
39+
40+
- A request with a path:
41+
42+
- `https://udl.fdo.cr/restaurants/silvestre` will redirect to `DEFAULT_DESTINATION + "/restaurants/silvestre"`
43+
44+
The original `?r=` format continues to work as before. If `DEFAULT_DESTINATION` is not set, behavior remains unchanged.
45+
46+
3347
`https://udl.fdo.cr` is a **public (free to use) UDL Server** instance for anyone to try out and use on your own. It has usage limits (throttling), which should be more than enough for most low-medium traffic websites.
3448

3549
If this service adds value to you or your company please consider sponsoring me right here on GitHub. I offer different sponsor tiers too where I will host a private instance without usage limits for ensured reliability. [Read more about this on my profile](https://github.com/sponsors/fdocr) to support the OSS work I do on my free time.

spec/server_spec.cr

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
require "./spec_helper"
22

3+
def with_default_destination(value)
4+
original = ENV["DEFAULT_DESTINATION"]?
5+
ENV["DEFAULT_DESTINATION"] = value
6+
yield
7+
ensure
8+
if original
9+
ENV["DEFAULT_DESTINATION"] = original
10+
else
11+
ENV.delete("DEFAULT_DESTINATION")
12+
end
13+
end
14+
15+
def without_default_destination
16+
original = ENV["DEFAULT_DESTINATION"]?
17+
ENV.delete("DEFAULT_DESTINATION")
18+
yield
19+
ensure
20+
ENV["DEFAULT_DESTINATION"] = original if original
21+
end
22+
323
describe "UDL Server" do
424
context "success" do
525
it "redirects to the Target URI parameter if valid" do
@@ -16,6 +36,24 @@ describe "UDL Server" do
1636
response.headers["Location"].should eq(target_url)
1737
end
1838

39+
it "redirects to DEFAULT_DESTINATION when root path has no r parameter and DEFAULT_DESTINATION is set" do
40+
with_default_destination("https://example.com") do
41+
get "/"
42+
43+
response.status_code.should eq(302)
44+
response.headers["Location"].should eq("https://example.com")
45+
end
46+
end
47+
48+
it "redirects to DEFAULT_DESTINATION + path when path has no r parameter and DEFAULT_DESTINATION is set" do
49+
with_default_destination("https://example.com") do
50+
get "/about"
51+
52+
response.status_code.should eq(302)
53+
response.headers["Location"].should eq("https://example.com/about")
54+
end
55+
end
56+
1957
it "populates apple-app-site-association file" do
2058
get "/.well-known/apple-app-site-association"
2159

@@ -26,20 +64,24 @@ describe "UDL Server" do
2664
end
2765

2866
context "failure" do
29-
it "renders fallback page if target redirect not provided" do
30-
get "/"
67+
it "renders fallback page if target redirect not provided and DEFAULT_DESTINATION is not set" do
68+
without_default_destination do
69+
get "/"
3170

32-
response.status_code.should eq(200)
33-
response.body.should contain("Something went wrong")
34-
response.body.should contain("Check out the <a href=\"https://github.com/fdocr/udl-server#Troubleshooting\">README</a> for more details")
71+
response.status_code.should eq(200)
72+
response.body.should contain("Something went wrong")
73+
response.body.should contain("Check out the <a href=\"https://github.com/fdocr/udl-server#Troubleshooting\">README</a> for more details")
74+
end
3575
end
3676

37-
it "renders fallback page if requesting any other path" do
38-
get "/about-us"
77+
it "renders fallback page if requesting any other path and DEFAULT_DESTINATION is not set" do
78+
without_default_destination do
79+
get "/about-us"
3980

40-
response.status_code.should eq(200)
41-
response.body.should contain("Something went wrong")
42-
response.body.should contain("Check out the <a href=\"https://github.com/fdocr/udl-server#Troubleshooting\">README</a> for more details")
81+
response.status_code.should eq(200)
82+
response.body.should contain("Something went wrong")
83+
response.body.should contain("Check out the <a href=\"https://github.com/fdocr/udl-server#Troubleshooting\">README</a> for more details")
84+
end
4385
end
4486

4587
it "renders fallback page if r parameter is an invalid URL" do

src/server.cr

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,19 @@ error_context = "Use the root path instead, i.e. `/?r=TARGET_URL_HERE`"
1313

1414
get "/" do |env|
1515
begin
16-
target_uri = URI.parse(env.params.query["r"])
16+
redirect_param = env.params.query["r"]?
17+
18+
# If no r parameter, redirect to DEFAULT_DESTINATION (only if set)
19+
unless redirect_param
20+
if default_destination = ENV["DEFAULT_DESTINATION"]?
21+
env.redirect default_destination
22+
next
23+
else
24+
raise "Missing redirect parameter"
25+
end
26+
end
27+
28+
target_uri = URI.parse(redirect_param)
1729

1830
# Check that it's a valid URL
1931
valid_uri = /https?/ =~ target_uri.scheme && target_uri.host
@@ -48,8 +60,15 @@ get "/.well-known/apple-app-site-association" do |env|
4860
end
4961

5062
get "/*" do |env|
51-
udl_error = "Invalid path `#{env.request.path}` - #{error_context}"
52-
render "src/views/fallback.ecr"
63+
# If DEFAULT_DESTINATION is set, redirect to it + path; otherwise show fallback.
64+
if default_target = ENV["DEFAULT_DESTINATION"]?
65+
path = env.request.path
66+
final_url = default_target.rstrip("/") + "/" + path.lstrip("/")
67+
env.redirect final_url
68+
else
69+
udl_error = "Invalid path `#{env.request.path}` - #{error_context}"
70+
render "src/views/fallback.ecr"
71+
end
5372
end
5473

5574
error 404 do

0 commit comments

Comments
 (0)