Re: URI handling of "//hostname.foo.com/" as base_uri

Gisle Aas (gisle@activestate.com)
18 Apr 2001 16:50:51 -0700


Ben Scott <scotsman@euphorion.com> writes:

> I'm working on some scripts to change URLs to "akamized" ARLs.  The site
> I'm working on has a number of files which are are used in both http and
> https.  The suggestion by Akamai on how to handle this is to leave off the
> scheme portion of the URL, making it:
> <a href="//a248.e.akamai.net/...">
> instead of
> <a href="http://a248.e.akamai.net/...">

Looks reasonable.

> This allows the browser to decide from the calling context whether to 
> use http or https.  This is indeed part of the URI RFC (RFC2396).
> Unfortunately the following does not work:
> 
>   use URI;
>   $url = "images/foo.gif";
>   $base = "//a248.e.akamai.net/.../";
>   $arl = URI->new_abs($url,$base);

The $base argument should be an absolute URI.  "//a248.e.akamai.net/.../" is not.
The doc for the method says:

       $uri = URI->new_abs( $str, $base_uri )
           This constructs a new absolute URI object.  The $str
           argument can denote a relative or absolute URI.  If
           relative, then it will be absolutized using $base_uri
           as base. The $base_uri must be an absolute URI.

> This results in the following error:
> 
> Warning: Use of "require" without parens is ambiguous at (eval 21) line 1, <IN> chunk 43.
>         eval 'requireURI:://a248_Oe_Oakamai_Onet/.../
> ;' called at /usr/local/lib/perl5/site_perl/5.005/URI.pm line 116
>         URI::implementor('//a248.e.akamai.net/f/.../') called at /usr/local/lib/perl5/site_perl/5.005/URI.pm line 53
>         URI::new('URI', 'images/foo.gif', '//a248.e.akamai.net/f/.../') called at /usr/local/lib/perl5/site_perl/5.005/URI.pm line 65
>         URI::new_abs('URI', '/images/foo.gif', '//a248.e.akamai.net/f/.../') called at update.new line 170

But I agree that this error message was not a very nice sight.
The following patch fixes that problem:

Index: URI.pm
===================================================================
RCS file: /cvsroot/libwww-perl/uri/URI.pm,v
retrieving revision 1.38
diff -u -p -r1.38 URI.pm
--- URI.pm	2001/02/27 17:35:13	1.38
+++ URI.pm	2001/04/18 23:33:46
@@ -82,7 +82,7 @@ sub _init
 sub implementor
 {
     my($scheme, $impclass) = @_;
-    unless ($scheme) {
+    if (!$scheme || $scheme !~ /\A$scheme_re\z/o) {
 	require URI::_generic;
 	return "URI::_generic";
     }

This patch also makes your code work, but that is more by accident
then anything else.  The second argument to URI->new_abs() should
really still be an absolute URI.

I would suggest you use code like this:

sub akamize {
   my($uri, $base) = @_;
   $base = URI->new($base, "http");
   $base->scheme("http") unless $base->scheme;  # ensure absoluteness
   $uri = URI->new_abs($uri, $base);
   $uri->scheme(undef);                         # make it relative
   return $uri;
}

It should work nicely both with and without the URI.pm patch.

Regards,
Gisle