Skip to content

Instantly share code, notes, and snippets.

@s1037989
Last active August 11, 2021 09:48
Show Gist options
  • Save s1037989/2d760ea41a7725c80d2e1330c255daa9 to your computer and use it in GitHub Desktop.
Save s1037989/2d760ea41a7725c80d2e1330c255daa9 to your computer and use it in GitHub Desktop.
PERL5LIB=/var/mojo/prod/tpa/local/lib/perl5/5.30.2/x86_64-linux:/var/mojo/prod/tpa/local/lib/perl5/5.30.2:/var/mojo/prod/tpa/local/lib/perl5/x86_64-linux:/var/mojo/prod/tpa/local/lib/perl5:/home/stefan/perl5/perlbrew/perls/perl-5.30.2/lib/site_perl/5.30.2/x86_64-linux:/home/stefan/perl5/perlbrew/perls/perl-5.30.2/lib/site_perl/5.30.2:/home/stefan/perl5/perlbrew/perls/perl-5.30.2/lib/5.30.2/x86_64-linux:/home/stefan/perl5/perlbrew/perls/perl-5.30.2/lib/5.30.2
PERLBREW_HOME=/home/stefan/.perlbrew
PERLBREW_MANPATH=/home/stefan/perl5/perlbrew/perls/perl-5.30.2/man
PERLBREW_PATH=/home/stefan/perl5/perlbrew/bin:/home/stefan/perl5/perlbrew/perls/perl-5.30.2/bin
PERLBREW_PERL=perl-5.30.2
PERLBREW_ROOT=/home/stefan/perl5/perlbrew
PERLBREW_SHELLRC_VERSION=0.88
PERLBREW_VERSION=0.88
package Mojolicious::Plugin::RequestBase;
use Mojo::Base 'Mojolicious::Plugin';
sub register {
my ($self, $app, $conf) = @_;
$app->hook(before_dispatch => sub {
my $c = shift;
#warn $c->req->url;
return unless $c->req->reverse_proxy;
return unless my $base = $c->req->headers->header('X-Request-Base');
$c->req->url->base(Mojo::URL->new($base));
});
}
1;
package Mojolicious::Plugin::ReverseProxyWithPath;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::File qw(curfile path);
our $VERSION = '0.01';
use constant DEBUG => $ENV{MOJO_REVERSEPROXY_DEBUG} || 0;
sub register {
my ($self, $app) = @_;
$app->helper(base => sub {
my $c = shift;
$c->tag('base', href => $c->req->url->base, @_);
});
$app->hook(before_dispatch => sub {
my $c = shift;
if ( $ENV{MOJO_REVERSE_PROXY} && $ENV{MOJO_REVERSE_PROXY} =~ /^\D/ ) {
my $rp = Mojo::URL->new($ENV{MOJO_REVERSE_PROXY});
my $url = $c->req->url;
my $base = $url->base;
$base->scheme($rp->scheme)->host($rp->host)->port($rp->port)
if $rp->scheme && $rp->host_port;
push @{$base->path}, grep /\S/, @{$rp->path};
$base->path->trailing_slash(1);
$url->path->leading_slash(0);
$c->req->headers->header('X-Request-Base' => $base->to_abs->to_string);
warn "[MOJO_REVERSE_PROXY=$ENV{MOJO_REVERSE_PROXY}] Base: ".$c->req->url->base if DEBUG;
warn "[MOJO_REVERSE_PROXY=$ENV{MOJO_REVERSE_PROXY}] URL: ".$c->req->url if DEBUG;
}
if ( my $base = $c->req->headers->header('X-Request-Base') ) {
my $url = Mojo::URL->new($base);
if ( $url->host ) {
$c->req->url->base($url);
}
else {
$c->req->url->base->path($url->path);
}
warn "[X-Request-Base] Base: ".$c->req->url->base if DEBUG;
warn "[X-Request-Base] URL: ".$c->req->url if DEBUG;
}
});
}
1;
__END__
=encoding utf8
=head1 NAME
Mojolicious::Plugin::ReverseProxyWithPath - Mojolicious Plugin
=head1 SYNOPSIS
# Mojolicious
$self->plugin('ReverseProxyWithPath');
# Mojolicious::Lite
plugin 'ReverseProxyWithPath';
#location ~ ^/(?<app>[a-zA-z]+)(?<ruri>.*)$ {
# if ( $ruri = "" ) {
# set $ruri "/";
# }
# proxy_pass http://unix:/var/mojo/unixsockets/$app.$http_host:$ruri$is_args$args;
=head1 DESCRIPTION
L<Mojolicious::Plugin::ReverseProxyWithPath> is a L<Mojolicious> plugin.
=head1 METHODS
L<Mojolicious::Plugin::ReverseProxyWithPath> inherits all methods from
L<Mojolicious::Plugin> and implements the following new ones.
=head2 register
$plugin->register(Mojolicious->new);
Register plugin in L<Mojolicious> application.
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
# https://mojolicious.io/blog/2019/03/18/reverse-proxy-with-path/
=cut
server {
# Listen on 80, and 443 with SSL
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server ssl;
listen [::]:443 default_server ssl;
client_max_body_size 2G;
# Use SNI-based certificates
ssl_certificate /etc/ssl/$ssl_server_name.crt;
ssl_certificate_key /etc/ssl/$ssl_server_name.key;
location /favicon.ico {
root /var/www/html;
}
location / {
# Proxy all requests to a unix socket at this location
proxy_pass http://unix:/var/mojo/unixsockets/$http_host:;
# Set some special headers for proxying. These are all very standard.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
# Listen on 80, and 443 with SSL
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name dev.* uat.* qa.* prod.*;
client_max_body_size 2G;
# Use SNI-based certificates
ssl_certificate /etc/ssl/$ssl_server_name.crt;
ssl_certificate_key /etc/ssl/$ssl_server_name.key;
location = /favicon.ico {
root /var/www/html;
allow all;
}
#location ~ ^/(?<app>[a-zA-z]+)(?<ruri>.*)$ {
# # Proxy all requests to a unix socket at this location
# if ( $ruri = "" ) {
# set $ruri "/";
# }
# #proxy_pass http://unix:/var/tmp/nginx/$http_host;
# proxy_pass http://unix:/var/mojo/unixsockets/$app.$http_host:$ruri$is_args$args;
# # Set some special headers for proxying. These are all very standard.
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# proxy_set_header Host $host;
# proxy_set_header X-Forwarded-Host $host;
# proxy_set_header X-Forwarded-Server $host;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
#}
# Mount convos under http://your-domain.com/whatever/convos
location ~ ^/(?<app>[a-zA-z0-9_-]+)(?<ruri>.*)$ {
# Pass requests on to the upstream defined above
rewrite ^/[a-zA-Z0-9_-]+/?(.*)$ /$1 break;
proxy_pass http://unix:/var/mojo/unixsockets/$app.$http_host:;
# Instruct Convos to do the right thing regarding
# HTTP and WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Enable Convos to construct correct URLs by passing on custom
# headers. X-Request-Base is only required if "location" above
# is not "/".
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Request-Base "$scheme://$host/$app";
proxy_set_header X-Nginx-Proxy-Pass "UDS";
}
}
[Unit]
Description=Mojolicious tpa application
After=network.target
[Service]
User=stefan
Group=stefan
UMask=0002
Type=forking
EnvironmentFile=/var/mojo/prod/perlbrew.env
EnvironmentFile=/var/mojo/prod/tpa/perlbrew.env
WorkingDirectory=/var/mojo/prod/tpa
PIDFile=/var/mojo/prod/tpa/script/hypnotoad.pid
ExecStart=/home/stefan/perl5/perlbrew/perls/perl-5.30.2/bin/hypnotoad script/tpa
ExecReload=/home/stefan/perl5/perlbrew/perls/perl-5.30.2/bin/hypnotoad script/tpa
ExecStop=/home/stefan/perl5/perlbrew/perls/perl-5.30.2/bin/hypnotoad script/tpa -s
KillMode=process
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment