File Coverage

blib/lib/Mojolicious/Plugin/RedirectHost.pm
Criterion Covered Total %
statement 26 26 100.0
branch 12 12 100.0
condition 6 8 75.0
subroutine 4 4 100.0
pod 1 1 100.0
total 49 51 96.0


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::RedirectHost;
2              
3 3     3   10683 use Mojo::Base 'Mojolicious::Plugin';
  3         5  
  3         14  
4 3     3   419 use Mojo::URL;
  3         4  
  3         19  
5              
6             our $VERSION = '1.06'; # VERSION
7              
8             # where to look for options
9             my $CONFIG_KEY = 'redirect_host';
10             my $DEFAULT_CODE = 301;
11             my $EXCEPT_PATH = '/robots.txt';
12              
13             sub register {
14 6     6 1 14269 my ($self, $app, $params) = @_;
15              
16 6         7 my %options;
17 6 100 50     40 if (ref $params eq 'HASH' && scalar keys %$params) {
    100          
18 4         11 %options = %$params;
19             }
20             elsif (ref $app->config($CONFIG_KEY) eq 'HASH') {
21 1         9 %options = %{$app->config($CONFIG_KEY)};
  1         3  
22             }
23              
24 6 100       31 unless ($options{host}) {
25 2         3 my $msg = 'RedirectHost plugin: define "host" option at least!';
26 2 100       6 $app->log->error($msg) unless $options{silent};
27              
28 2         15 return;
29             }
30              
31             $app->hook(
32             before_dispatch => sub {
33 9     9   43323 my $c = shift;
34 9         36 my $url = $c->req->url->to_abs;
35 9         1120 my $path = $c->req->url->path;
36              
37              
38             # don't need redirection
39 9 100       108 return if $url->host eq $options{host};
40              
41             # except_robots?
42 8 100 100     57 return if $options{er} && $path eq $EXCEPT_PATH;
43              
44             # main host
45 6         92 $url->host($options{host});
46              
47             # code
48 6   66     25 $c->res->code($options{code} || $DEFAULT_CODE);
49              
50              
51 6         75 $c->redirect_to($url->to_string);
52             }
53 4         18 );
54              
55 4         35 return;
56             }
57              
58             1;
59              
60             # ABSTRACT: Redirects requests from mirrors to the main host (useful for SEO)
61              
62             =head1 SYNOPSIS
63              
64              
65             Generates 301 redirect from C to C
66            
67             # Mojolicious
68             $app->plugin('RedirectHost', host => 'main.host');
69            
70             # Mojolicious::Lite
71             plugin RedirectHost => { host => 'main.host' };
72              
73             All requests with a C header that is not equal to the C option will be redirected to the main host (and to the same port, as it was in original request)
74             Don't forget about the port (don't expect something great from http://google.com:3000)
75              
76             http://www.main.host:3000 => http://main.host:3000
77             http://another.io:3000/foo?bar => http://main.host:3000/foo?bar
78             etc...
79              
80             You can point as many domains to your App by DNS, as you want. It doesn't matter, all of them will become a mirror. An equivalent apache .htaccess file looks like
81              
82             RewriteCond %{HTTP_HOST} !^alexbyk.com
83             RewriteRule ^(.*) http://alexbyk.com/$1 [R=301,L]
84              
85             It would be better if you'll be using per mode config files (your_app.production.conf etc). This would make possible
86             to redirect only in production enviropment (but do nothing while coding your app)
87              
88             Look at the `examples` directory of this distribution for a full application example
89              
90             =head1 OPTIONS/USAGE
91              
92             =head2 C
93              
94             Main domain. All requests to the mirrors will be redirected to the C (domain)
95             This option is required. Without it plugin do nothing
96              
97             =head2 C
98              
99             $app->plugin('RedirectHost', host => 'main.host', code => 302);
100              
101             Type of redirection. Default 301 (Moved Permanently)
102              
103             =head2 C (except /robots.txt)
104              
105             $app->plugin('RedirectHost', host => 'main.host', er => 1);
106              
107             If true, requests like /robots.txt will not be redirected but rendered. That's for Yandex search engine.
108             If you want to change a domain but worry about yandex TIC, it's recomended to make it possible for Yandex to read your robots.txt
109             with new Host directive. If so, that's exactly what you're looking for
110              
111             =head2 C
112              
113             If C is true, doesn't write messages to the error log even if L is missing.
114             Default value is C
115              
116             You can configure plugin in a production config file and define C in a development config.
117              
118             # app.production.conf
119             # redirect_host => {host => 'main.host'},
120              
121             # app.development.conf:
122             # redirect_host => {silent => 1},
123              
124              
125             =head1 CONFIG
126              
127             You can pass options to the plugin with the help of your config. Use C key.
128              
129             $app->config(redirect_host => {host => 'main.host'});
130              
131             TIP: use per mode config files (yourapp.production.conf) to pass parameters to the plugin to avoid redirection during
132             development process
133              
134             =head1 METHODS
135              
136             =head2 register
137              
138             Register. L
139              
140             =cut