mercurial/url.py
author Matt Mackall <mpm@selenic.com>
Wed, 30 Mar 2011 13:34:39 -0500
changeset 13807 974490c1768f
parent 13772 463aca32a937
child 13814 03dfe0c85c1a
permissions -rw-r--r--
url: deal with drive letters
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     1
# url.py - HTTP handling for mercurial
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     2
#
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     3
# Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     4
# Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     5
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     6
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     7
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9852
diff changeset
     8
# GNU General Public License version 2 or any later version.
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
     9
12742
6ab4a7d3c179 url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12607
diff changeset
    10
import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO
11880
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
    11
import __builtin__
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
    12
from i18n import _
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
    13
import keepalive, util
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
    14
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    15
class url(object):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    16
    """Reliable URL parser.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    17
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    18
    This parses URLs and provides attributes for the following
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    19
    components:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    20
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    21
    <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    22
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    23
    Missing components are set to None. The only exception is
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    24
    fragment, which is set to '' if present but empty.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    25
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    26
    If parse_fragment is False, fragment is included in query. If
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    27
    parse_query is False, query is included in path. If both are
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    28
    False, both fragment and query are included in path.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    29
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    30
    See http://www.ietf.org/rfc/rfc2396.txt for more information.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    31
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    32
    Examples:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    33
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    34
    >>> url('http://www.ietf.org/rfc/rfc2396.txt')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    35
    <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    36
    >>> url('ssh://[::1]:2200//home/joe/repo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    37
    <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    38
    >>> url('file:///home/joe/repo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    39
    <url scheme: 'file', path: '/home/joe/repo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    40
    >>> url('bundle:foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    41
    <url scheme: 'bundle', path: 'foo'>
13807
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    42
    >>> url('c:\\\\foo\\\\bar')
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    43
    <url path: 'c:\\\\foo\\\\bar'>
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    44
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    45
    Authentication credentials:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    46
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    47
    >>> url('ssh://joe:xyz@x/repo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    48
    <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    49
    >>> url('ssh://joe@x/repo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    50
    <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    51
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    52
    Query strings and fragments:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    53
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    54
    >>> url('http://host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    55
    <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    56
    >>> url('http://host/a?b#c', parse_query=False, parse_fragment=False)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    57
    <url scheme: 'http', host: 'host', path: 'a?b#c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    58
    """
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    59
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    60
    _safechars = "!~*'()+"
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    61
    _safepchars = "/!~*'()+"
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    62
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    63
    def __init__(self, path, parse_query=True, parse_fragment=True):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    64
        # We slowly chomp away at path until we have only the path left
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    65
        self.scheme = self.user = self.passwd = self.host = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    66
        self.port = self.path = self.query = self.fragment = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    67
        self._localpath = True
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    68
13807
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    69
        # special case for Windows drive letters
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    70
        if path[1:2] == ':' and path[0:1].isalpha():
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    71
            self.path = path
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    72
            return
974490c1768f url: deal with drive letters
Matt Mackall <mpm@selenic.com>
parents: 13772
diff changeset
    73
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    74
        if not path.startswith('/') and ':' in path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    75
            parts = path.split(':', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    76
            if parts[0]:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    77
                self.scheme, path = parts
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    78
                self._localpath = False
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    79
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    80
        if not path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    81
            path = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    82
            if self._localpath:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    83
                self.path = ''
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    84
                return
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    85
        else:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    86
            if parse_fragment and '#' in path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    87
                path, self.fragment = path.split('#', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    88
                if not path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    89
                    path = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    90
            if self._localpath:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    91
                self.path = path
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    92
                return
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    93
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    94
            if parse_query and '?' in path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    95
                path, self.query = path.split('?', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    96
                if not path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    97
                    path = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    98
                if not self.query:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
    99
                    self.query = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   100
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   101
            # // is required to specify a host/authority
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   102
            if path and path.startswith('//'):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   103
                parts = path[2:].split('/', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   104
                if len(parts) > 1:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   105
                    self.host, path = parts
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   106
                    path = path
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   107
                else:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   108
                    self.host = parts[0]
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   109
                    path = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   110
                if not self.host:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   111
                    self.host = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   112
                    if path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   113
                        path = '/' + path
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   114
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   115
            if self.host and '@' in self.host:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   116
                self.user, self.host = self.host.rsplit('@', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   117
                if ':' in self.user:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   118
                    self.user, self.passwd = self.user.split(':', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   119
                if not self.host:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   120
                    self.host = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   121
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   122
            # Don't split on colons in IPv6 addresses without ports
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   123
            if (self.host and ':' in self.host and
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   124
                not (self.host.startswith('[') and self.host.endswith(']'))):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   125
                self.host, self.port = self.host.rsplit(':', 1)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   126
                if not self.host:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   127
                    self.host = None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   128
        self.path = path
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   129
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   130
        for a in ('user', 'passwd', 'host', 'port',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   131
                  'path', 'query', 'fragment'):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   132
            v = getattr(self, a)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   133
            if v is not None:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   134
                setattr(self, a, urllib.unquote(v))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   135
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   136
    def __repr__(self):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   137
        attrs = []
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   138
        for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   139
                  'query', 'fragment'):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   140
            v = getattr(self, a)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   141
            if v is not None:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   142
                attrs.append('%s: %r' % (a, v))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   143
        return '<url %s>' % ', '.join(attrs)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   144
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   145
    def __str__(self):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   146
        """Join the URL's components back into a URL string.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   147
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   148
        Examples:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   149
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   150
        >>> str(url('http://user:pw@host:80/?foo#bar'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   151
        'http://user:pw@host:80/?foo#bar'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   152
        >>> str(url('ssh://user:pw@[::1]:2200//home/joe#'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   153
        'ssh://user:pw@[::1]:2200//home/joe#'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   154
        >>> str(url('http://localhost:80//'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   155
        'http://localhost:80//'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   156
        >>> str(url('http://localhost:80/'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   157
        'http://localhost:80/'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   158
        >>> str(url('http://localhost:80'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   159
        'http://localhost:80'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   160
        >>> str(url('bundle:foo'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   161
        'bundle:foo'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   162
        >>> str(url('path'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   163
        'path'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   164
        """
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   165
        if self._localpath:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   166
            s = self.path
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   167
            if self.fragment:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   168
                s += '#' + self.fragment
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   169
            return s
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   170
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   171
        s = self.scheme + ':'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   172
        if (self.user or self.passwd or self.host or
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   173
            self.scheme and not self.path):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   174
            s += '//'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   175
        if self.user:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   176
            s += urllib.quote(self.user, safe=self._safechars)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   177
        if self.passwd:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   178
            s += ':' + urllib.quote(self.passwd, safe=self._safechars)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   179
        if self.user or self.passwd:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   180
            s += '@'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   181
        if self.host:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   182
            if not (self.host.startswith('[') and self.host.endswith(']')):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   183
                s += urllib.quote(self.host)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   184
            else:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   185
                s += self.host
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   186
        if self.port:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   187
            s += ':' + urllib.quote(self.port)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   188
        if ((self.host and self.path is not None) or
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   189
            (self.host and self.query or self.fragment)):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   190
            s += '/'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   191
        if self.path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   192
            s += urllib.quote(self.path, safe=self._safepchars)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   193
        if self.query:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   194
            s += '?' + urllib.quote(self.query, safe=self._safepchars)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   195
        if self.fragment is not None:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   196
            s += '#' + urllib.quote(self.fragment, safe=self._safepchars)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   197
        return s
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   198
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   199
    def authinfo(self):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   200
        user, passwd = self.user, self.passwd
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   201
        try:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   202
            self.user, self.passwd = None, None
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   203
            s = str(self)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   204
        finally:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   205
            self.user, self.passwd = user, passwd
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   206
        if not self.user:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   207
            return (s, None)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   208
        return (s, (None, (str(self), self.host),
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   209
                    self.user, self.passwd or ''))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   210
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   211
def has_scheme(path):
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   212
    return bool(url(path).scheme)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13544
diff changeset
   213
13772
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   214
def hidepassword(u):
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   215
    '''hide user credential in a url string'''
13772
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   216
    u = url(u)
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   217
    if u.passwd:
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   218
        u.passwd = '***'
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   219
    return str(u)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   220
13772
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   221
def removeauth(u):
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   222
    '''remove all authentication information from a url string'''
13772
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   223
    u = url(u)
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   224
    u.user = u.passwd = None
463aca32a937 url: use url.url in hidepassword() and removeauth()
Brodie Rao <brodie@bitheap.org>
parents: 13770
diff changeset
   225
    return str(u)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   226
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   227
def netlocsplit(netloc):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   228
    '''split [user[:passwd]@]host[:port] into 4-tuple.'''
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   229
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   230
    a = netloc.find('@')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   231
    if a == -1:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   232
        user, passwd = None, None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   233
    else:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   234
        userpass, netloc = netloc[:a], netloc[a + 1:]
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   235
        c = userpass.find(':')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   236
        if c == -1:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   237
            user, passwd = urllib.unquote(userpass), None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   238
        else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   239
            user = urllib.unquote(userpass[:c])
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   240
            passwd = urllib.unquote(userpass[c + 1:])
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   241
    c = netloc.find(':')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   242
    if c == -1:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   243
        host, port = netloc, None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   244
    else:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   245
        host, port = netloc[:c], netloc[c + 1:]
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   246
    return host, port, user, passwd
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   247
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   248
def netlocunsplit(host, port, user=None, passwd=None):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   249
    '''turn host, port, user, passwd into [user[:passwd]@]host[:port].'''
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   250
    if port:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   251
        hostport = host + ':' + port
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   252
    else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   253
        hostport = host
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   254
    if user:
10484
cadd7e076b69 url: correctly quote '/' in user and password embedded in urls
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10482
diff changeset
   255
        quote = lambda s: urllib.quote(s, safe='')
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   256
        if passwd:
10484
cadd7e076b69 url: correctly quote '/' in user and password embedded in urls
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10482
diff changeset
   257
            userpass = quote(user) + ':' + quote(passwd)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   258
        else:
10484
cadd7e076b69 url: correctly quote '/' in user and password embedded in urls
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10482
diff changeset
   259
            userpass = quote(user)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   260
        return userpass + '@' + hostport
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   261
    return hostport
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   262
13371
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   263
def readauthforuri(ui, uri):
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   264
    # Read configuration
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   265
    config = dict()
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   266
    for key, val in ui.configitems('auth'):
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   267
        if '.' not in key:
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   268
            ui.warn(_("ignoring invalid [auth] key '%s'\n") % key)
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   269
            continue
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   270
        group, setting = key.rsplit('.', 1)
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   271
        gdict = config.setdefault(group, dict())
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   272
        if setting in ('username', 'cert', 'key'):
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   273
            val = util.expandpath(val)
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   274
        gdict[setting] = val
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   275
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   276
    # Find the best match
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   277
    scheme, hostpath = uri.split('://', 1)
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   278
    bestlen = 0
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   279
    bestauth = None
13372
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   280
    for group, auth in config.iteritems():
13371
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   281
        prefix = auth.get('prefix')
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   282
        if not prefix:
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   283
            continue
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   284
        p = prefix.split('://', 1)
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   285
        if len(p) > 1:
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   286
            schemes, prefix = [p[0]], p[1]
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   287
        else:
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   288
            schemes = (auth.get('schemes') or 'https').split()
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   289
        if (prefix == '*' or hostpath.startswith(prefix)) and \
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   290
            len(prefix) > bestlen and scheme in schemes:
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   291
            bestlen = len(prefix)
13372
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   292
            bestauth = group, auth
13371
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   293
    return bestauth
c691cfdc6b4d url: move [auth] parsing out into a utility function
Steve Borho <steve@borho.org>
parents: 13370
diff changeset
   294
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   295
_safe = ('abcdefghijklmnopqrstuvwxyz'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   296
         'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   297
         '0123456789' '_.-/')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   298
_safeset = None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   299
_hex = None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   300
def quotepath(path):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   301
    '''quote the path part of a URL
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   302
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   303
    This is similar to urllib.quote, but it also tries to avoid
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   304
    quoting things twice (inspired by wget):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   305
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   306
    >>> quotepath('abc def')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   307
    'abc%20def'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   308
    >>> quotepath('abc%20def')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   309
    'abc%20def'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   310
    >>> quotepath('abc%20 def')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   311
    'abc%20%20def'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   312
    >>> quotepath('abc def%20')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   313
    'abc%20def%20'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   314
    >>> quotepath('abc def%2')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   315
    'abc%20def%252'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   316
    >>> quotepath('abc def%')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   317
    'abc%20def%25'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   318
    '''
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   319
    global _safeset, _hex
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   320
    if _safeset is None:
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 7285
diff changeset
   321
        _safeset = set(_safe)
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 7285
diff changeset
   322
        _hex = set('abcdefABCDEF0123456789')
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   323
    l = list(path)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   324
    for i in xrange(len(l)):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   325
        c = l[i]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   326
        if (c == '%' and i + 2 < len(l) and
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   327
            l[i + 1] in _hex and l[i + 2] in _hex):
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   328
            pass
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   329
        elif c not in _safeset:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   330
            l[i] = '%%%02X' % ord(c)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   331
    return ''.join(l)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   332
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   333
class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   334
    def __init__(self, ui):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   335
        urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   336
        self.ui = ui
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   337
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   338
    def find_user_password(self, realm, authuri):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   339
        authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   340
            self, realm, authuri)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   341
        user, passwd = authinfo
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   342
        if user and passwd:
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   343
            self._writedebug(user, passwd)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   344
            return (user, passwd)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   345
8344
873429914ec5 url: fix bug in passwordmgr related to auth configuration
Sune Foldager <cryo@cyanite.org>
parents: 8333
diff changeset
   346
        if not user:
13372
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   347
            res = readauthforuri(self.ui, authuri)
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   348
            if res:
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   349
                group, auth = res
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   350
                user, passwd = auth.get('username'), auth.get('password')
13372
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   351
                self.ui.debug("using auth.%s.* for authentication\n" % group)
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   352
        if not user or not passwd:
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   353
            if not self.ui.interactive():
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   354
                raise util.Abort(_('http authorization required'))
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   355
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   356
            self.ui.write(_("http authorization required\n"))
12862
9d6adddc8eea url: show realm/user when asking for username/password
timeless <timeless@gmail.com>
parents: 12770
diff changeset
   357
            self.ui.write(_("realm: %s\n") % realm)
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   358
            if user:
12862
9d6adddc8eea url: show realm/user when asking for username/password
timeless <timeless@gmail.com>
parents: 12770
diff changeset
   359
                self.ui.write(_("user: %s\n") % user)
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   360
            else:
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   361
                user = self.ui.prompt(_("user:"), default=None)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   362
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   363
            if not passwd:
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   364
                passwd = self.ui.getpass()
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   365
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   366
        self.add_password(realm, authuri, user, passwd)
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   367
        self._writedebug(user, passwd)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   368
        return (user, passwd)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   369
8333
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   370
    def _writedebug(self, user, passwd):
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   371
        msg = _('http auth: user %s, password %s\n')
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   372
        self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set'))
89c80c3dc584 allow http authentication information to be specified in the configuration
Sune Foldager <cryo@cyanite.org>
parents: 8225
diff changeset
   373
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   374
class proxyhandler(urllib2.ProxyHandler):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   375
    def __init__(self, ui):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   376
        proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   377
        # XXX proxyauthinfo = None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   378
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   379
        if proxyurl:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   380
            # proxy can be proper url or host[:port]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   381
            if not (proxyurl.startswith('http:') or
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   382
                    proxyurl.startswith('https:')):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   383
                proxyurl = 'http://' + proxyurl + '/'
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   384
            snpqf = urlparse.urlsplit(proxyurl)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   385
            proxyscheme, proxynetloc, proxypath, proxyquery, proxyfrag = snpqf
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   386
            hpup = netlocsplit(proxynetloc)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   387
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   388
            proxyhost, proxyport, proxyuser, proxypasswd = hpup
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   389
            if not proxyuser:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   390
                proxyuser = ui.config("http_proxy", "user")
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   391
                proxypasswd = ui.config("http_proxy", "passwd")
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   392
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   393
            # see if we should use a proxy for this url
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   394
            no_list = ["localhost", "127.0.0.1"]
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   395
            no_list.extend([p.lower() for
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   396
                            p in ui.configlist("http_proxy", "no")])
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   397
            no_list.extend([p.strip().lower() for
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   398
                            p in os.getenv("no_proxy", '').split(',')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   399
                            if p.strip()])
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   400
            # "http_proxy.always" config is for running tests on localhost
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   401
            if ui.configbool("http_proxy", "always"):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   402
                self.no_list = []
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   403
            else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   404
                self.no_list = no_list
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   405
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   406
            proxyurl = urlparse.urlunsplit((
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   407
                proxyscheme, netlocunsplit(proxyhost, proxyport,
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   408
                                                proxyuser, proxypasswd or ''),
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   409
                proxypath, proxyquery, proxyfrag))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   410
            proxies = {'http': proxyurl, 'https': proxyurl}
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9347
diff changeset
   411
            ui.debug('proxying through http://%s:%s\n' %
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   412
                      (proxyhost, proxyport))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   413
        else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   414
            proxies = {}
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   415
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   416
        # urllib2 takes proxy values from the environment and those
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   417
        # will take precedence if found, so drop them
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   418
        for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   419
            try:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   420
                if env in os.environ:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   421
                    del os.environ[env]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   422
            except OSError:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   423
                pass
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   424
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   425
        urllib2.ProxyHandler.__init__(self, proxies)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   426
        self.ui = ui
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   427
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   428
    def proxy_open(self, req, proxy, type_):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   429
        host = req.get_host().split(':')[0]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   430
        if host in self.no_list:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   431
            return None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   432
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   433
        # work around a bug in Python < 2.4.2
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   434
        # (it leaves a "\n" at the end of Proxy-authorization headers)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   435
        baseclass = req.__class__
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   436
        class _request(baseclass):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   437
            def add_header(self, key, val):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   438
                if key.lower() == 'proxy-authorization':
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   439
                    val = val.strip()
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   440
                return baseclass.add_header(self, key, val)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   441
        req.__class__ = _request
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   442
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   443
        return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   444
11880
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   445
class httpsendfile(object):
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   446
    """This is a wrapper around the objects returned by python's "open".
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   447
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   448
    Its purpose is to send file-like objects via HTTP and, to do so, it
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   449
    defines a __len__ attribute to feed the Content-Length header.
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   450
    """
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   451
13115
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   452
    def __init__(self, ui, *args, **kwargs):
11880
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   453
        # We can't just "self._data = open(*args, **kwargs)" here because there
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   454
        # is an "open" function defined in this module that shadows the global
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   455
        # one
13115
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   456
        self.ui = ui
11880
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   457
        self._data = __builtin__.open(*args, **kwargs)
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   458
        self.seek = self._data.seek
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   459
        self.close = self._data.close
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   460
        self.write = self._data.write
13115
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   461
        self._len = os.fstat(self._data.fileno()).st_size
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   462
        self._pos = 0
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   463
        self._total = len(self) / 1024 * 2
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   464
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   465
    def read(self, *args, **kwargs):
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   466
        try:
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   467
            ret = self._data.read(*args, **kwargs)
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   468
        except EOFError:
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   469
            self.ui.progress(_('sending'), None)
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   470
        self._pos += len(ret)
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   471
        # We pass double the max for total because we currently have
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   472
        # to send the bundle twice in the case of a server that
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   473
        # requires authentication. Since we can't know until we try
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   474
        # once whether authentication will be required, just lie to
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   475
        # the user and maybe the push succeeds suddenly at 50%.
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   476
        self.ui.progress(_('sending'), self._pos / 1024,
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   477
                         unit=_('kb'), total=self._total)
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   478
        return ret
11880
e3526634d5a3 url.py: removed 'file' inheritance in the httpsendfile class
Renato Cunha <renatoc@gmail.com>
parents: 11876
diff changeset
   479
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   480
    def __len__(self):
13115
bda5f35fbf67 httpsendfile: record progress information during read()
Augie Fackler <durin42@gmail.com>
parents: 12906
diff changeset
   481
        return self._len
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   482
13420
051f498628f7 url: refactor _gen_sendfile
Mads Kiilerich <mads@kiilerich.com>
parents: 13419
diff changeset
   483
def _gen_sendfile(orgsend):
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   484
    def _sendfile(self, data):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   485
        # send a file
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   486
        if isinstance(data, httpsendfile):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   487
            # if auth required, some data sent twice, so rewind here
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   488
            data.seek(0)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   489
            for chunk in util.filechunkiter(data):
13420
051f498628f7 url: refactor _gen_sendfile
Mads Kiilerich <mads@kiilerich.com>
parents: 13419
diff changeset
   490
                orgsend(self, chunk)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   491
        else:
13420
051f498628f7 url: refactor _gen_sendfile
Mads Kiilerich <mads@kiilerich.com>
parents: 13419
diff changeset
   492
            orgsend(self, data)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   493
    return _sendfile
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   494
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   495
has_https = hasattr(urllib2, 'HTTPSHandler')
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   496
if has_https:
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   497
    try:
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   498
        # avoid using deprecated/broken FakeSocket in python 2.6
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   499
        import ssl
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   500
        _ssl_wrap_socket = ssl.wrap_socket
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   501
        CERT_REQUIRED = ssl.CERT_REQUIRED
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   502
    except ImportError:
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   503
        CERT_REQUIRED = 2
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   504
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   505
        def _ssl_wrap_socket(sock, key_file, cert_file,
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   506
                             cert_reqs=CERT_REQUIRED, ca_certs=None):
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   507
            if ca_certs:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   508
                raise util.Abort(_(
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   509
                    'certificate checking requires Python 2.6'))
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   510
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   511
            ssl = socket.ssl(sock, key_file, cert_file)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   512
            return httplib.FakeSocket(sock, ssl)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   513
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   514
    try:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   515
        _create_connection = socket.create_connection
10411
af4c42ec19ed ssl: fix compatibility with pre-2.6 Python
Matt Mackall <mpm@selenic.com>
parents: 10409
diff changeset
   516
    except AttributeError:
10482
95265afff99f url: fix python < 2.6 with ssl installed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10415
diff changeset
   517
        _GLOBAL_DEFAULT_TIMEOUT = object()
95265afff99f url: fix python < 2.6 with ssl installed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10415
diff changeset
   518
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   519
        def _create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   520
                               source_address=None):
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   521
            # lifted from Python 2.6
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   522
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   523
            msg = "getaddrinfo returns an empty list"
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   524
            host, port = address
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   525
            for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   526
                af, socktype, proto, canonname, sa = res
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   527
                sock = None
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   528
                try:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   529
                    sock = socket.socket(af, socktype, proto)
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   530
                    if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   531
                        sock.settimeout(timeout)
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   532
                    if source_address:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   533
                        sock.bind(source_address)
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   534
                    sock.connect(sa)
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   535
                    return sock
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   536
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   537
                except socket.error, msg:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   538
                    if sock is not None:
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   539
                        sock.close()
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   540
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   541
            raise socket.error, msg
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   542
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   543
class httpconnection(keepalive.HTTPConnection):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   544
    # must be able to send big bundle as stream.
13420
051f498628f7 url: refactor _gen_sendfile
Mads Kiilerich <mads@kiilerich.com>
parents: 13419
diff changeset
   545
    send = _gen_sendfile(keepalive.HTTPConnection.send)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   546
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   547
    def connect(self):
10415
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   548
        if has_https and self.realhostport: # use CONNECT proxy
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   549
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   550
            self.sock.connect((self.host, self.port))
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   551
            if _generic_proxytunnel(self):
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   552
                # we do not support client x509 certificates
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   553
                self.sock = _ssl_wrap_socket(self.sock, None, None)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   554
        else:
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   555
            keepalive.HTTPConnection.connect(self)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   556
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   557
    def getresponse(self):
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   558
        proxyres = getattr(self, 'proxyres', None)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   559
        if proxyres:
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   560
            if proxyres.will_close:
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   561
                self.close()
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   562
            self.proxyres = None
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   563
            return proxyres
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   564
        return keepalive.HTTPConnection.getresponse(self)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   565
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   566
# general transaction handler to support different ways to handle
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   567
# HTTPS proxying before and after Python 2.6.3.
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   568
def _generic_start_transaction(handler, h, req):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   569
    if hasattr(req, '_tunnel_host') and req._tunnel_host:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   570
        tunnel_host = req._tunnel_host
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   571
        if tunnel_host[:7] not in ['http://', 'https:/']:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   572
            tunnel_host = 'https://' + tunnel_host
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   573
        new_tunnel = True
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   574
    else:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   575
        tunnel_host = req.get_selector()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   576
        new_tunnel = False
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   577
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   578
    if new_tunnel or tunnel_host == req.get_full_url(): # has proxy
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   579
        urlparts = urlparse.urlparse(tunnel_host)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   580
        if new_tunnel or urlparts[0] == 'https': # only use CONNECT for HTTPS
10415
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   581
            realhostport = urlparts[1]
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   582
            if realhostport[-1] == ']' or ':' not in realhostport:
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   583
                realhostport += ':443'
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   584
10415
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   585
            h.realhostport = realhostport
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   586
            h.headers = req.headers.copy()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   587
            h.headers.update(handler.parent.addheaders)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   588
            return
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   589
10415
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   590
    h.realhostport = None
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   591
    h.headers = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   592
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   593
def _generic_proxytunnel(self):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   594
    proxyheaders = dict(
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   595
            [(x, self.headers[x]) for x in self.headers
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   596
             if x.lower().startswith('proxy-')])
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   597
    self._set_hostport(self.host, self.port)
10415
677f15da38c1 url: proxy handling, simplify and correctly deal with IPv6
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10411
diff changeset
   598
    self.send('CONNECT %s HTTP/1.0\r\n' % self.realhostport)
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   599
    for header in proxyheaders.iteritems():
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   600
        self.send('%s: %s\r\n' % header)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   601
    self.send('\r\n')
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   602
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   603
    # majority of the following code is duplicated from
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   604
    # httplib.HTTPConnection as there are no adequate places to
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   605
    # override functions to provide the needed functionality
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   606
    res = self.response_class(self.sock,
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   607
                              strict=self.strict,
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   608
                              method=self._method)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   609
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   610
    while True:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   611
        version, status, reason = res._read_status()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   612
        if status != httplib.CONTINUE:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   613
            break
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   614
        while True:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   615
            skip = res.fp.readline().strip()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   616
            if not skip:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   617
                break
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   618
    res.status = status
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   619
    res.reason = reason.strip()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   620
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   621
    if res.status == 200:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   622
        while True:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   623
            line = res.fp.readline()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   624
            if line == '\r\n':
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   625
                break
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   626
        return True
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   627
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   628
    if version == 'HTTP/1.0':
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   629
        res.version = 10
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   630
    elif version.startswith('HTTP/1.'):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   631
        res.version = 11
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   632
    elif version == 'HTTP/0.9':
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   633
        res.version = 9
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   634
    else:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   635
        raise httplib.UnknownProtocol(version)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   636
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   637
    if res.version == 9:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   638
        res.length = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   639
        res.chunked = 0
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   640
        res.will_close = 1
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   641
        res.msg = httplib.HTTPMessage(cStringIO.StringIO())
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   642
        return False
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   643
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   644
    res.msg = httplib.HTTPMessage(res.fp)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   645
    res.msg.fp = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   646
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   647
    # are we using the chunked-style of transfer encoding?
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   648
    trenc = res.msg.getheader('transfer-encoding')
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   649
    if trenc and trenc.lower() == "chunked":
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   650
        res.chunked = 1
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   651
        res.chunk_left = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   652
    else:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   653
        res.chunked = 0
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   654
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   655
    # will the connection close at the end of the response?
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   656
    res.will_close = res._check_close()
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   657
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   658
    # do we have a Content-Length?
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   659
    # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   660
    length = res.msg.getheader('content-length')
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   661
    if length and not res.chunked:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   662
        try:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   663
            res.length = int(length)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   664
        except ValueError:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   665
            res.length = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   666
        else:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   667
            if res.length < 0:  # ignore nonsensical negative lengths
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   668
                res.length = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   669
    else:
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   670
        res.length = None
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   671
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   672
    # does the body have a fixed length? (of zero)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   673
    if (status == httplib.NO_CONTENT or status == httplib.NOT_MODIFIED or
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   674
        100 <= status < 200 or # 1xx codes
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   675
        res._method == 'HEAD'):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   676
        res.length = 0
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   677
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   678
    # if the connection remains open, and we aren't using chunked, and
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   679
    # a content-length was not provided, then assume that the connection
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   680
    # WILL close.
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   681
    if (not res.will_close and
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   682
       not res.chunked and
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   683
       res.length is None):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   684
        res.will_close = 1
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   685
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   686
    self.proxyres = res
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   687
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   688
    return False
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   689
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   690
class httphandler(keepalive.HTTPHandler):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   691
    def http_open(self, req):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   692
        return self.do_open(httpconnection, req)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   693
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   694
    def _start_transaction(self, h, req):
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   695
        _generic_start_transaction(self, h, req)
8590
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   696
        return keepalive.HTTPHandler._start_transaction(self, h, req)
59acb9c7d90f url: use CONNECT for HTTPS connections through HTTP proxy (issue967)
Henrik Stuart <hg@hstuart.dk>
parents: 8344
diff changeset
   697
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   698
def _verifycert(cert, hostname):
12742
6ab4a7d3c179 url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12607
diff changeset
   699
    '''Verify that cert (in socket.getpeercert() format) matches hostname.
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   700
    CRLs is not handled.
12770
614f0d8724ab check-code: find trailing whitespace
Martin Geisler <mg@lazybytes.net>
parents: 12742
diff changeset
   701
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   702
    Returns error message if any problems are found and None on success.
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   703
    '''
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   704
    if not cert:
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   705
        return _('no certificate received')
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   706
    dnsname = hostname.lower()
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   707
    def matchdnsname(certname):
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   708
        return (certname == dnsname or
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   709
                '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1])
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   710
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   711
    san = cert.get('subjectAltName', [])
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   712
    if san:
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   713
        certnames = [value.lower() for key, value in san if key == 'DNS']
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   714
        for name in certnames:
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   715
            if matchdnsname(name):
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   716
                return None
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   717
        return _('certificate is for %s') % ', '.join(certnames)
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   718
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   719
    # subject is only checked when subjectAltName is empty
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   720
    for s in cert.get('subject', []):
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   721
        key, value = s[0]
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   722
        if key == 'commonName':
13248
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 13231
diff changeset
   723
            try:
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 13231
diff changeset
   724
                # 'subject' entries are unicode
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 13231
diff changeset
   725
                certname = value.lower().encode('ascii')
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 13231
diff changeset
   726
            except UnicodeEncodeError:
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 13231
diff changeset
   727
                return _('IDN in certificate not supported')
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   728
            if matchdnsname(certname):
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   729
                return None
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   730
            return _('certificate is for %s') % certname
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
   731
    return _('no commonName or subjectAltName found in certificate')
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   732
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   733
if has_https:
13424
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   734
    class httpsconnection(httplib.HTTPSConnection):
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   735
        response_class = keepalive.HTTPResponse
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   736
        # must be able to send big bundle as stream.
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   737
        send = _gen_sendfile(keepalive.safesend)
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   738
        getresponse = keepalive.wrapgetresponse(httplib.HTTPSConnection)
9726
430e59ff3437 keepalive: handle broken pipes gracefully during large POSTs
Augie Fackler <durin42@gmail.com>
parents: 9467
diff changeset
   739
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   740
        def connect(self):
13422
ebce5196b9db url: always create BetterHTTPS connections the same way
Mads Kiilerich <mads@kiilerich.com>
parents: 13421
diff changeset
   741
            self.sock = _create_connection((self.host, self.port))
ebce5196b9db url: always create BetterHTTPS connections the same way
Mads Kiilerich <mads@kiilerich.com>
parents: 13421
diff changeset
   742
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   743
            host = self.host
13424
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   744
            if self.realhostport: # use CONNECT proxy
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   745
                something = _generic_proxytunnel(self)
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   746
                host = self.realhostport.rsplit(':', 1)[0]
08f9c587141f url: merge BetterHTTPS with httpsconnection to get some proxy https validation
Mads Kiilerich <mads@kiilerich.com>
parents: 13422
diff changeset
   747
13419
1cc73868c740 url: remove test for self.ui in BetterHTTPS
Mads Kiilerich <mads@kiilerich.com>
parents: 13372
diff changeset
   748
            cacerts = self.ui.config('web', 'cacerts')
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   749
            hostfingerprint = self.ui.config('hostfingerprints', host)
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   750
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   751
            if cacerts and not hostfingerprint:
13544
66d65bccbf06 cacert: improve error report when web.cacert file does not exist
timeless <timeless@gmail.com>
parents: 13424
diff changeset
   752
                cacerts = util.expandpath(cacerts)
66d65bccbf06 cacert: improve error report when web.cacert file does not exist
timeless <timeless@gmail.com>
parents: 13424
diff changeset
   753
                if not os.path.exists(cacerts):
66d65bccbf06 cacert: improve error report when web.cacert file does not exist
timeless <timeless@gmail.com>
parents: 13424
diff changeset
   754
                    raise util.Abort(_('could not find '
66d65bccbf06 cacert: improve error report when web.cacert file does not exist
timeless <timeless@gmail.com>
parents: 13424
diff changeset
   755
                                       'web.cacerts: %s') % cacerts)
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   756
                self.sock = _ssl_wrap_socket(self.sock, self.key_file,
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   757
                    self.cert_file, cert_reqs=CERT_REQUIRED,
13544
66d65bccbf06 cacert: improve error report when web.cacert file does not exist
timeless <timeless@gmail.com>
parents: 13424
diff changeset
   758
                    ca_certs=cacerts)
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   759
                msg = _verifycert(self.sock.getpeercert(), host)
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12391
diff changeset
   760
                if msg:
13328
a939f08fae9c url: add --insecure option to bypass verification of ssl certificates
Yuya Nishihara <yuya@tcha.org>
parents: 13314
diff changeset
   761
                    raise util.Abort(_('%s certificate error: %s '
a939f08fae9c url: add --insecure option to bypass verification of ssl certificates
Yuya Nishihara <yuya@tcha.org>
parents: 13314
diff changeset
   762
                                       '(use --insecure to connect '
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   763
                                       'insecurely)') % (host, msg))
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   764
                self.ui.debug('%s certificate successfully verified\n' % host)
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   765
            else:
13422
ebce5196b9db url: always create BetterHTTPS connections the same way
Mads Kiilerich <mads@kiilerich.com>
parents: 13421
diff changeset
   766
                self.sock = _ssl_wrap_socket(self.sock, self.key_file,
ebce5196b9db url: always create BetterHTTPS connections the same way
Mads Kiilerich <mads@kiilerich.com>
parents: 13421
diff changeset
   767
                    self.cert_file)
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   768
                if hasattr(self.sock, 'getpeercert'):
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   769
                    peercert = self.sock.getpeercert(True)
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   770
                    peerfingerprint = util.sha1(peercert).hexdigest()
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   771
                    nicefingerprint = ":".join([peerfingerprint[x:x + 2]
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   772
                        for x in xrange(0, len(peerfingerprint), 2)])
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   773
                    if hostfingerprint:
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   774
                        if peerfingerprint.lower() != \
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   775
                                hostfingerprint.replace(':', '').lower():
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   776
                            raise util.Abort(_('invalid certificate for %s '
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   777
                                               'with fingerprint %s') %
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   778
                                             (host, nicefingerprint))
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   779
                        self.ui.debug('%s certificate matched fingerprint %s\n' %
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   780
                                      (host, nicefingerprint))
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   781
                    else:
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   782
                        self.ui.warn(_('warning: %s certificate '
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   783
                                       'with fingerprint %s not verified '
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   784
                                       '(check hostfingerprints or web.cacerts '
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   785
                                       'config setting)\n') %
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   786
                                     (host, nicefingerprint))
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   787
                else: # python 2.5 ?
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   788
                    if hostfingerprint:
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   789
                        raise util.Abort(_('no certificate for %s with '
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   790
                                           'configured hostfingerprint') % host)
13314
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   791
                    self.ui.warn(_('warning: %s certificate not verified '
8dc488dfcdb4 url: 'ssh known host'-like checking of fingerprints of HTTPS certificates
Mads Kiilerich <mads@kiilerich.com>
parents: 13249
diff changeset
   792
                                   '(check web.cacerts config setting)\n') %
13421
bd8bfa85d5a5 url: refactor BetterHTTPS.connect
Mads Kiilerich <mads@kiilerich.com>
parents: 13420
diff changeset
   793
                                 host)
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   794
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   795
    class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   796
        def __init__(self, ui):
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   797
            keepalive.KeepAliveHandler.__init__(self)
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   798
            urllib2.HTTPSHandler.__init__(self)
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   799
            self.ui = ui
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   800
            self.pwmgr = passwordmgr(self.ui)
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   801
9852
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   802
        def _start_transaction(self, h, req):
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   803
            _generic_start_transaction(self, h, req)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   804
            return keepalive.KeepAliveHandler._start_transaction(self, h, req)
917cf6bb6d0c url: generalise HTTPS proxy handling to accomodate Python changes
Henrik Stuart <hg@hstuart.dk>
parents: 9726
diff changeset
   805
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   806
        def https_open(self, req):
13372
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   807
            res = readauthforuri(self.ui, req.get_full_url())
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   808
            if res:
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   809
                group, auth = res
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   810
                self.auth = auth
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   811
                self.ui.debug("using auth.%s.* for authentication\n" % group)
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   812
            else:
5bced0d28a39 url: return the matched authentication group name from readauthforuri()
Steve Borho <steve@borho.org>
parents: 13371
diff changeset
   813
                self.auth = None
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   814
            return self.do_open(self._makeconnection, req)
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   815
10408
50fb1fe143ff url: httplib.HTTPSConnection already handles IPv6 and port parsing fine
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
   816
        def _makeconnection(self, host, port=None, *args, **kwargs):
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   817
            keyfile = None
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   818
            certfile = None
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   819
10511
6f61c480f51c url: *args argument is a tuple, not a list (found by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10484
diff changeset
   820
            if len(args) >= 1: # key_file
6f61c480f51c url: *args argument is a tuple, not a list (found by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10484
diff changeset
   821
                keyfile = args[0]
6f61c480f51c url: *args argument is a tuple, not a list (found by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10484
diff changeset
   822
            if len(args) >= 2: # cert_file
6f61c480f51c url: *args argument is a tuple, not a list (found by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10484
diff changeset
   823
                certfile = args[1]
6f61c480f51c url: *args argument is a tuple, not a list (found by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10484
diff changeset
   824
            args = args[2:]
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   825
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   826
            # if the user has specified different key/cert files in
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   827
            # hgrc, we prefer these
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   828
            if self.auth and 'key' in self.auth and 'cert' in self.auth:
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   829
                keyfile = self.auth['key']
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   830
                certfile = self.auth['cert']
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   831
10409
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   832
            conn = httpsconnection(host, port, keyfile, certfile, *args, **kwargs)
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   833
            conn.ui = self.ui
4c94a3df4b10 url: SSL server certificate verification using web.cacerts file (issue1174)
Henrik Stuart <hg@hstuart.dk>
parents: 10408
diff changeset
   834
            return conn
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   835
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   836
class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
11457
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   837
    def __init__(self, *args, **kwargs):
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   838
        urllib2.HTTPDigestAuthHandler.__init__(self, *args, **kwargs)
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   839
        self.retried_req = None
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   840
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   841
    def reset_retry_count(self):
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   842
        # Python 2.6.5 will call this on 401 or 407 errors and thus loop
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   843
        # forever. We disable reset_retry_count completely and reset in
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   844
        # http_error_auth_reqed instead.
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   845
        pass
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   846
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   847
    def http_error_auth_reqed(self, auth_header, host, req, headers):
11457
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   848
        # Reset the retry counter once for each request.
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   849
        if req is not self.retried_req:
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   850
            self.retried_req = req
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   851
            self.retried = 0
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   852
        # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   853
        # it doesn't know about the auth type requested. This can happen if
2ec346160783 http digest auth: reset redirect counter on new requests (issue2255)
Mads Kiilerich <mads@kiilerich.com>
parents: 11415
diff changeset
   854
        # somebody is using BasicAuth and types a bad password.
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   855
        try:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   856
            return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   857
                        self, auth_header, host, req, headers)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   858
        except ValueError, inst:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   859
            arg = inst.args[0]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   860
            if arg.startswith("AbstractDigestAuthHandler doesn't know "):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   861
                return
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   862
            raise
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   863
11844
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   864
class httpbasicauthhandler(urllib2.HTTPBasicAuthHandler):
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   865
    def __init__(self, *args, **kwargs):
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   866
        urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   867
        self.retried_req = None
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   868
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   869
    def reset_retry_count(self):
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   870
        # Python 2.6.5 will call this on 401 or 407 errors and thus loop
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   871
        # forever. We disable reset_retry_count completely and reset in
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   872
        # http_error_auth_reqed instead.
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   873
        pass
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   874
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   875
    def http_error_auth_reqed(self, auth_header, host, req, headers):
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   876
        # Reset the retry counter once for each request.
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   877
        if req is not self.retried_req:
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   878
            self.retried_req = req
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   879
            self.retried = 0
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   880
        return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   881
                        self, auth_header, host, req, headers)
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   882
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   883
def getauthinfo(path):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   884
    scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   885
    if not urlpath:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   886
        urlpath = '/'
7284
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   887
    if scheme != 'file':
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   888
        # XXX: why are we quoting the path again with some smart
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   889
        # heuristic here? Anyway, it cannot be done with file://
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   890
        # urls since path encoding is os/fs dependent (see
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   891
        # urllib.pathname2url() for details).
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   892
        urlpath = quotepath(urlpath)
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   893
    host, port, user, passwd = netlocsplit(netloc)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   894
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   895
    # urllib cannot handle URLs with embedded user or passwd
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   896
    url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   897
                              urlpath, query, frag))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   898
    if user:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   899
        netloc = host
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   900
        if port:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   901
            netloc += ':' + port
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   902
        # Python < 2.4.3 uses only the netloc to search for a password
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   903
        authinfo = (None, (url, netloc), user, passwd or '')
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   904
    else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   905
        authinfo = None
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   906
    return url, authinfo
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   907
9347
d0474b184347 url: add support for custom handlers in extensions
Henrik Stuart <hg@hstuart.dk>
parents: 9122
diff changeset
   908
handlerfuncs = []
d0474b184347 url: add support for custom handlers in extensions
Henrik Stuart <hg@hstuart.dk>
parents: 9122
diff changeset
   909
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   910
def opener(ui, authinfo=None):
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   911
    '''
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   912
    construct an opener suitable for urllib2
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   913
    authinfo will be added to the password manager
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   914
    '''
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   915
    handlers = [httphandler()]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   916
    if has_https:
8847
7951f385fcb7 url: support client certificate files over HTTPS (issue643)
Henrik Stuart <hg@hstuart.dk>
parents: 8590
diff changeset
   917
        handlers.append(httpshandler(ui))
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   918
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   919
    handlers.append(proxyhandler(ui))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   920
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   921
    passmgr = passwordmgr(ui)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   922
    if authinfo is not None:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   923
        passmgr.add_password(*authinfo)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   924
        user, passwd = authinfo[2:4]
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9347
diff changeset
   925
        ui.debug('http auth: user %s, password %s\n' %
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   926
                 (user, passwd and '*' * len(passwd) or 'not set'))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   927
11844
6c51a5056020 http basic auth: reset redirect counter on new requests (issue2255)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11457
diff changeset
   928
    handlers.extend((httpbasicauthhandler(passmgr),
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   929
                     httpdigestauthhandler(passmgr)))
9347
d0474b184347 url: add support for custom handlers in extensions
Henrik Stuart <hg@hstuart.dk>
parents: 9122
diff changeset
   930
    handlers.extend([h(ui, passmgr) for h in handlerfuncs])
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   931
    opener = urllib2.build_opener(*handlers)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   932
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   933
    # 1.0 here is the _protocol_ version
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   934
    opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   935
    opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   936
    return opener
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   937
7285
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   938
scheme_re = re.compile(r'^([a-zA-Z0-9+-.]+)://')
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   939
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   940
def open(ui, url, data=None):
7285
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   941
    scheme = None
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   942
    m = scheme_re.search(url)
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   943
    if m:
5ad99abfab79 url: detect scheme with a regexp instead of urlsplit()
Patrick Mezard <pmezard@gmail.com>
parents: 7284
diff changeset
   944
        scheme = m.group(1).lower()
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   945
    if not scheme:
7284
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   946
        path = util.normpath(os.path.abspath(url))
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   947
        url = 'file://' + urllib.pathname2url(path)
ac81ffac0f35 url: fix file:// URL handling
Patrick Mezard <pmezard@gmail.com>
parents: 7270
diff changeset
   948
        authinfo = None
7270
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   949
    else:
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   950
        url, authinfo = getauthinfo(url)
2db33c1a5654 factor out the url handling from httprepo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   951
    return opener(ui, authinfo).open(url, data)