[PATCH] Accept file://localhost/ style urls as local

Brendan Cully brendan at kublai.com
Sun Sep 9 01:03:28 CDT 2007


On Saturday, 08 September 2007 at 03:13, Christian Ebert wrote:
> * Brendan Cully on Thursday, September 06, 2007 at 19:28:10 -0700
> > I'd be tempted to just skip over the host part of a file: URL --
> > anything other than a local hostname is probably useless anyway. But
> > if that's a bad idea, I think we should at least look for localhost
> > and 127.0.0.1 statically before doing any address lookup. That saves
> > any silly DNS lookups for 99% of the time.
> 
> Another attempt:
> 
> # HG changeset patch
> # User Christian Ebert <blacktrash at gmx.net>
> # Date 1189077749 -7200
> # Node ID acd92fec1e5a481b52ce989597a3113c465cf2f0
> # Parent  f8c36b215281a7e8f3aaed632206d3627ee21e6e
> Drop local hostnames with url scheme in file urls
> 
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -14,7 +14,7 @@ platform-specific details from the core.
>  
>  from i18n import _
>  import cStringIO, errno, getpass, popen2, re, shutil, sys, tempfile, strutil
> -import os, stat, threading, time, calendar, ConfigParser, locale, glob
> +import os, stat, threading, time, calendar, ConfigParser, locale, glob, socket
>  
>  try:
>      set = set
> @@ -1674,10 +1674,24 @@ def bytecount(nbytes):
>              return format % (nbytes / float(divisor))
>      return units[-1][2] % nbytes
>  
> +def _localhostnames():
> +    hl = []
> +    for h in socket.gethostbyaddr(socket.gethostname()):
> +        if isinstance(h, str):
> +            h = [h]
> +        hl += h
> +    return hl
> +
>  def drop_scheme(scheme, path):
>      sc = scheme + ':'
>      if path.startswith(sc):
>          path = path[len(sc):]
>          if path.startswith('//'):
>              path = path[2:]
> +            if scheme == 'file' and not path.startswith('/'):
> +                if path[:10] in ('localhost/', '127.0.0.1/'):
> +                    return path[9:]
> +                for h in _localhostnames():
> +                    if path.startswith(h + '/'):
> +                        return path[len(h):]
>      return path

Hrm. I like the general approach, but I'm not sure it does the right
thing when the hostname isn't local. file://otherhost/foo appears to
turn into `pwd`/otherhost/foo in this case. We could raise an
exception here, but it's a little annoying to have to put drop_scheme
into a try/except block to handle this extremely unlikely error.

I'm still not convinced this isn't stillborn code. I have a feeling
it's just as likely for applications to insert hostnames meant to be
local but that don't reverse resolve as it is for them to deliberately
constrain the host in file URL for safety (and that neither is
common). The fact that one result is RFC compliant and one isn't is
cold comfort.


More information about the Mercurial-devel mailing list