Open Mis1eader-dev opened 1 year ago
Yes we will send back a redirection response with the Location header.
To give more context, see issue #1774
The primary reason for this plugin is cookie availability, and website entry point consistency.
If drogon is listening on 0.0.0.0, then it answers both example.com
and www.example.com
. But the browser cookies will not be available to both.
Google redirects to https://www.google.com
if you type Google's IP address in the URL bar. This allows the cookies to be sent.
Without domain and IP redirects, we will have multiple entry points, and hence different cookies for each entry point, which is far from ideal in a professional setting.
Just for information. google.com and www.google.com - two different sites with different IP addresses. In your example you demonstrate two domain (example.com and www.example.com) on the same IP address (here you created the problem to yourself) and then you can try to solve this problem. And I do not understand, why it is problem, if you have different cookies in different entry points. It is correct behaviour of cookies, browser. Sorry, it is not clear - if everything works as must work, what are you going to change?
Just for information. google.com and www.google.com - two different sites with different IP addresses. In your example you demonstrate two domain (example.com and www.example.com) on the same IP address (here you created the problem to yourself) and then you can try to solve this problem.
We could have two drogon servers listening on different IP addresses:
Server 1: 10.10.10.1
Server 2: 10.10.10.2
And have server 2 be the one responsible for taking in example.com
and redirect to www.example.com
.
However, this requires two machines to accomplish this, one with the main server application, and the 2nd one for redirecting.
For load balancing purposes it will come in handy. But personally I would like to use only one machine as the server.
And I do not understand, why it is problem, if you have different cookies in different entry points. It is correct behaviour of cookies, browser. Sorry, it is not clear - if everything works as must work, what are you going to change?
If Google didn't redirect IPs to its subdomain, and didn't redirect google.com -> www.google.com, then users have to remember on which one of these endpoints they logged in before, or perform a trial and error to see which one is logged in:
This is inconvenient for Google users if each one of these served the same page without redirecting to the only entry point www.google.com
I think this is a highly specific use case and should be part of a separate 3rd party plugin in its own repository.
You are welcome to let me know once you are finished with the plugin and I can add you to the list of unofficial third-party plugins provided by the Drogon community.
A new idea, we can expand upon the Redirector plugin and have a config entry for it called rules
, we can populate it this way:
"name": "drogon::plugin::Redirector",
"config": {
"rules": {
"10.10.10.1": "www.my-website.com",
"my-website.com": "www.my-website.com",
"ww.my-website.com": "www.my-website.com",
"image.my-website.com": "images.my-website.com"
}
}
This will not be a specific use case, accomplishes the same thing, and helps the cookie and single entry point issue.
The "rules"
config entry will go through each one and add these to an unordered_map, and when a request comes in, it checks whether the host is within that map, then it replaces it with that entry.
Edit: To reduce duplication, we can have the config in this fashion:
"name": "drogon::plugin::Redirector",
"config": {
"rules": {
"www.my-website.com": [
"10.10.10.1",
"my-website.com",
"ww.my-website.com"
],
"images.my-website.com": [
"image.my-website.com"
]
}
}
Just to get additional idea for you I would point to your example with Google. Google makes redirect as answer to GET request. You also can make controller , that gets a request on the example.com and makes 301 "Permanently moved" like Google does.
For example I tried to send HEAD request to 172.217.169.110:80 via telnet
telnet 172.217.169.110 80
HEAD / HTTP/1.0
[pressed ENTER]
[pressed ENTER]
and Google responded by 200 code with usual answer without any redirect. If Google does not make the complex things and makes simple redirect in only in GET controller, could you consider this option for you. It looks like standard straight-forward way.
@rbugajewski @Mis1eader-dev If I correctly understood idea, it can be said in other words - apache has mod_rewrite https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html , that can change URL and also redirect to other URL. From user point of view, it is done in usual configuration file by regex-like commands (no need to write controllers code or CGI code). I suppose, the idea to have something similar. Sounds interesting. In apache it is done as separate module, maybe it can be done as plugin in Drogon.
Yes that is the feature I want drogon to have, it will attract enterprises if it has the complete feature-set needed for an enterprise server.
A new idea, we can expand upon the Redirector plugin and have a config entry for it called
rules
, we can populate it this way:"name": "drogon::plugin::Redirector", "config": { "rules": { "10.10.10.1": "www.my-website.com", "my-website.com": "www.my-website.com", "ww.my-website.com": "www.my-website.com", "image.my-website.com": "images.my-website.com" } }
This will not be a specific use case, accomplishes the same thing, and helps the cookie and single entry point issue.
The
"rules"
config entry will go through each one and add these to an unordered_map, and when a request comes in, it checks whether the host is within that map, then it replaces it with that entry.Edit: To reduce duplication, we can have the config in this fashion:
"name": "drogon::plugin::Redirector", "config": { "rules": { "www.my-website.com": [ "10.10.10.1", "my-website.com", "ww.my-website.com" ], "images.my-website.com": [ "image.my-website.com" ] } }
I prefer to make a new plugin and keep the redirector plugin clean. Because we think of it as a container for all redirect handlers.
Ok, that sounds fair, what do we call the new plugin?
I have started the implementation of the plugin, however, there is more to it than just hosts:
maps.example.com
-> www.example.com/maps
The redirect rule has a path and a different host.
It is also possible some users may want a redirect from paths:
www.example.com/images
-> images.example.com
The request URL match has a host and a path.
This creates an issue, redirector->registerRedirectHandler
has a higher priority than SlashRemover's redirect handler redirector->registerPathRewriteHandler
, which means the redirect rule:
www.example.com/images
-> images.example.com
Will not work when the user puts in:
www.example.com///images
Edit: For this to work properly, this plugin's execution must sit between Redirector::pathRewriteHandlers_
and Redirector::forwardHandlers_
. This means we need to make the Redirector plugin have 4 groups instead of 3, and the 3rd group that comes between these two abovementioned handler groups will have the same function signature as handlers_
(Group 1)'s signature, but without the protocol reference in its parameters.
Host Redirector plugin
Creating a host redirector plugin poses some problems, it can be implemented in multiple ways, each with pros and cons. Before getting into the details, let's establish an environment for testing.
Subnet 1 (192.168.0.0/24)
Hosted by: Router Default gateway: 192.168.0.1 DNS server: 192.168.0.1 -> FORWARD -> 8.8.8.8 Devices connected:
Subnet 2 (10.10.10.0/24)
Hosted by: Drogon server (standalone machine) Default gateway: 10.10.10.1 DNS server: 10.10.10.1 (Custom DNS server running on the machine) DNS server rules:
Devices connected:
Scenario - Without Domain Redirector
Now if we connect to the router network using the phone, and navigate to
192.168.0.2
, drogon serves the webpage. Navigate toexample.com
, it serves example.com from the global internet. This is fine, it makes DNS queries to8.8.8.8
.Then connect to the drogon server network using the laptop, and navigate to
10.10.10.1
, again, drogon serves the webpage. Navigate toexample.com
, drogon also serves the webpage. Remember, we have a custom DNS server on that network that resolves DNS queries ofexample.com
to10.10.10.1
.Issues
example.com
and10.10.10.1
, even though they are the same thing on the 2nd subnet.Scenario - With Domain Redirector
Same as no redirector scenario for the router network.
But things change for the drogon server network. If you go to
10.10.10.1
, drogon will detect you put in an IP address to the server, and will redirect toexample.com
.Note how it did not redirect when the request came from the router network for
192.168.0.1
, that is becauseexample.com
within that subnet does not point to192.168.0.1
, it points somewhere else on the internet. If we had blindly redirected any IP toexample.com
, then drogon will redirect to the global example.com, away from itself.Possible solutions
1. Dynamic DNS Querying
Using DNS queries to dynamically obtain the IP address of the domain in question, its theoretical config:
This solution is ideal for safety and ease of use from a server developer or maintainer's point of view. It handles requests the following way:
c-ares may be able to help in this.
Pros:
Cons:
2. Hardcoded IP Addresses
Having a list of predefined IP addresses, theoretical config:
This is less ideal, as we have to keep track of what IP addresses we are allowed to redirect. Possible implementation:
Pros:
Cons:
Other ideas
If someone has better solutions or have something on your mind, share it with us to discuss.