Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Convert relative to absolute URL given a base URL, without modules

by Aristotle (Chancellor)
on Jan 17, 2006 at 06:07 UTC ( #523679=snippet: print w/ replies, xml ) Need Help??

Description:

I wrote this mainly because someone asked how to do this in PHP. Turns out there is nothing in like the venerable URI module in all of PHP-dom (how pathetic is that for a language as web-centric as it?).

First, I tried writing this with mostly string functions, but that was too painful, so I switched to doing it using regexes, even though they’re piss-poorly supported. After a while, my eyes glazed over, so I resorted to writing and debugging the code in Perl first, and then compiling it down to machine code PHP.

I thought I’d post this byproduct here for posterity, in case someone needs it in some circumstance.

Tests included, but I’m pretty sure they’re not extensive enough to be 100% confident in the code. Proceed at your discretion.

sub abs_url {
    my ( $relative, $base ) = @_;

    return $relative if $relative =~ m{ \A http:// }ix;

    my ( $host, $hostrelative_abs ) = $base =~ m{
        \A
        http:// # skip scheme
        ([^/]*) # capture hostname
        /*      # skip front slashes
        (.*?)   # capture everything that follows, but
        [^/]*   # leave out the optional final non-directory component
        \z
    }ix;

    $hostrelative_abs = '' if $relative =~ m!^/!;

    my $abs_url = join '/', $host, $hostrelative_abs, $relative;

    # replace '//' or '/./' with '/'
    1 while $abs_url =~ s{ / \.? (?=/|\z) }{}x;

    # remove '/foo/..' (but be careful to skip '/../..')
    1 while $abs_url =~ s{ / (?!\.\.) [^/]+ / \.\. (?=/|\z) }{}x;

    return "http://$abs_url";
}
use Test::More;
my @test = qw(
 /foo/bar.gif      http://www.example.com/baz/quux/    http://www.exam
+ple.com/foo/bar.gif
 foo/bar.gif       http://www.example.com/baz/quux/    http://www.exam
+ple.com/baz/quux/foo/bar.gif
 ../../bar.gif     http://www.example.com/baz/quux/    http://www.exam
+ple.com/bar.gif
 foo/bar.gif       http://www.example.com/baz/quux     http://www.exam
+ple.com/baz/foo/bar.gif
 ../foo/bar.gif    http://www.example.com/baz/quux     http://www.exam
+ple.com/foo/bar.gif
 ../../foo/bar.gif http://www.example.com/baz/quux/qux http://www.exam
+ple.com/foo/bar.gif
);
plan tests => @test / 3;
do { is abs_url( $test[0], $test[1] ), $test[2]; splice @test, 0, 3 } 
+while @test;
Comment on Convert relative to absolute URL given a base URL, without modules
Select or Download Code
Reaped: Re: Convert relative to absolute URL given a base URL, without modules
by NodeReaper (Curate) on Jun 23, 2015 at 18:06 UTC
Reaped: Re: Convert relative to absolute URL given a base URL, without modules
by NodeReaper (Curate) on Jun 23, 2015 at 18:07 UTC
Re: Convert relative to absolute URL given a base URL, without modules
by cbarrette (Initiate) on Jun 23, 2015 at 18:09 UTC
     href="vote?for=8620307&dir=up&whence=%6e%65%77%73"

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://523679]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (17)
As of 2015-07-02 19:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (44 votes), past polls