Apache-ProxyRewrite
view release on metacpan or search on metacpan
ProxyRewrite.pm view on Meta::CPAN
$$tagblock .= " $key=\"$value\"";
}
} else {
$$tagblock .= " $blocks[$i]";
}
} else {
$$tagblock .= " $blocks[$i]";
}
}
}
}
###############################################################################
###############################################################################
# rewrite_url: rewrite URLs as per the mappings hash
###############################################################################
###############################################################################
sub rewrite_url {
my ($r, $remote_site, $url, $mapref) = @_;
$r->log->debug("rewrite_url: Looking at rewriting $$url");
$r->log->debug("rewrite_url: remote_site: $remote_site");
# Remove remote_site from URI to get just the relative-from-root information
if ($$url =~ s/^$remote_site//) {
$r->log->debug("rewrite_url: Shrunk to $$url");
}
# Standardize host on lowercase
if ($$url =~ m!([^:]+://)([^/]+)(.*)!) {
my ($protocol, $url_host, $uri) = ($1, $2, $3);
$url_host =~ tr/A-Z/a-z/;
$$url = $protocol . $url_host . $uri;
}
# Ensure we go from most to least specific rewrite
foreach my $mapping (sort { $b cmp $a } keys(%$mapref)) {
$r->log->debug("rewrite_url: Testing match of $mapping ",
"($$mapref{$mapping})");
last if ($$url =~ s/^$mapping/$$mapref{$mapping}/);
}
}
###############################################################################
###############################################################################
# respond: respond to the client
###############################################################################
###############################################################################
sub respond {
my ($r, $remote_site, $remote_location, $auth_redirect,
$response, $mapref) = @_;
my $parsed_uri = Apache::URI->parse($r);
$r->log->debug("respond: URI: ", $r->uri);
$r->log->debug("respond: Parsed hostinfo: ", $parsed_uri->hostinfo());
# feed reponse back into our request_record
$response->scan(sub {
my ($header, $value) = @_;
$r->log->debug("respond: OUT $header: $value");
if ($header =~ /^Set-Cookie/i) {
$value =~ /path=([^;]+)/i;
my $cookie_path = $1;
&rewrite_url($r, $remote_site, \$cookie_path, $mapref);
# Handle the special case of when the value
# begins with a port
if ($cookie_path =~ /^:/) {
$value =~
s/(path=)([^;]+)/$1$remote_site$cookie_path/i;
} else {
$value =~ s/(path=)([^;]+)/$1$cookie_path/i;
}
} elsif ($header =~/^Client-Peer/i) {
my $local_addr = $r->connection->local_addr;
my ($port, $ip) =
Socket::unpack_sockaddr_in($local_addr);
$ip = Socket::inet_ntoa($ip);
$value = "$ip:$port";
}
$r->log->debug("respond: OUT-MOD $header: $value");
$r->headers_out->{$header} = $value;
});
$r->content_type($response->header('Content-type'));
$r->status($response->code);
$r->status_line(join " ", $response->code, $response->message);
# deal with redirects
if ($r->status =~ /(301|302)/) {
my $location = $response->header('Location');
&rewrite_url($r, $remote_site, \$location, $mapref);
# Only modify location if rewritten URL is relative
unless ($location =~ m!://!) {
if ($location =~ m!^/!) {
$location = $parsed_uri->scheme . '://' . $parsed_uri->hostinfo .
$location;
} else {
my $base = $r->uri;
$base =~ s!(/)[^/]+$!$1!;
$location = $parsed_uri->scheme . '://' . $parsed_uri->hostinfo .
$base . $location;
}
}
$r->log->debug("respond: Location: $location");
$r->headers_out->{'Location'} = $location;
}
# deal with auth required redirects
if ($r->status == 401 && $auth_redirect =~ /^on$/i) {
my $base = $r->location();
my $location = '';
if ($base ne '/') {
($location = $r->uri) =~ s/^$base//;
} else {
$location = $r->uri;
}
$location = $remote_location . $location;
$r->status('302');
$r->status_line(join " ", '302', 'Moved Temporarily');
$r->log->debug("respond: Location: $location");
$r->headers_out->{'Location'} = $location;
$response->content(undef);
( run in 1.303 second using v1.01-cache-2.11-cpan-2398b32b56e )