/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1540.3.3 by Martin Pool
Review updates of pycurl transport
1
# Copyright (C) 2005, 2006 Canonical Ltd
1540.3.18 by Martin Pool
Style review fixes (thanks robertc)
2
#
1540.3.3 by Martin Pool
Review updates of pycurl transport
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1540.3.18 by Martin Pool
Style review fixes (thanks robertc)
7
#
1540.3.3 by Martin Pool
Review updates of pycurl transport
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1540.3.18 by Martin Pool
Style review fixes (thanks robertc)
12
#
1540.3.3 by Martin Pool
Review updates of pycurl transport
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2004.1.2 by vila
Implements a BasicAuthManager.
17
from cStringIO import StringIO
1540.3.3 by Martin Pool
Review updates of pycurl transport
18
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
19
from bzrlib import (
20
    ui,
21
    errors,
22
    )
1540.3.3 by Martin Pool
Review updates of pycurl transport
23
from bzrlib.trace import mutter
1636.1.2 by Robert Collins
More review fixen to the relpath at '/' fixes.
24
from bzrlib.transport import register_urlparse_netloc_protocol
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
25
from bzrlib.transport.http import HttpTransportBase
2004.1.9 by vila
Takes jam's remarks into account when possible, add TODOs for the rest.
26
# TODO: handle_response should be integrated into the _urllib2_wrappers
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
27
from bzrlib.transport.http.response import handle_response
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
28
from bzrlib.transport.http._urllib2_wrappers import (
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
29
    Opener,
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
30
    Request,
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
31
    )
32
1540.3.3 by Martin Pool
Review updates of pycurl transport
33
1636.1.2 by Robert Collins
More review fixen to the relpath at '/' fixes.
34
register_urlparse_netloc_protocol('http+urllib')
1636.1.1 by Robert Collins
Fix calling relpath() and abspath() on transports at their root.
35
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
36
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
37
class HttpTransport_urllib(HttpTransportBase):
1786.1.33 by John Arbash Meinel
Cleanup pass #2
38
    """Python urllib transport for http and https."""
1540.3.3 by Martin Pool
Review updates of pycurl transport
39
2004.1.9 by vila
Takes jam's remarks into account when possible, add TODOs for the rest.
40
    # In order to debug we have to issue our traces in sync with
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
41
    # httplib, which use print :(
42
    _debuglevel = 0
2004.3.1 by vila
Test ConnectionError exceptions.
43
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
44
    _opener_class = Opener
45
46
    def __init__(self, base, from_transport=None):
1540.3.3 by Martin Pool
Review updates of pycurl transport
47
        """Set the base path where files will be stored."""
2208.2.1 by v.ladeuil+lp at free
Trivial small fixes.
48
        super(HttpTransport_urllib, self).__init__(base, from_transport)
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
49
        if from_transport is not None:
50
            self._connection = from_transport._connection
2004.1.2 by vila
Implements a BasicAuthManager.
51
            self._user = from_transport._user
52
            self._password = from_transport._password
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
53
            self._opener = from_transport._opener
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
54
        else:
55
            self._connection = None
2004.1.2 by vila
Implements a BasicAuthManager.
56
            self._user = None
57
            self._password = None
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
58
            self._opener = self._opener_class()
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
59
2004.1.2 by vila
Implements a BasicAuthManager.
60
    def ask_password(self, request):
61
        """Ask for a password if none is already provided in the request"""
2004.2.1 by John Arbash Meinel
Cleanup of urllib functions
62
        # TODO: jam 20060915 There should be a test that asserts we ask 
63
        #       for a password at the right time.
2004.1.2 by vila
Implements a BasicAuthManager.
64
        if request.password is None:
2004.1.7 by vila
Better handling of passwords (user should be queried only once).
65
            # We can't predict realm, let's try None, we'll get a
66
            # 401 if we are wrong anyway
67
            realm = None
2004.1.4 by vila
Fix user handling.
68
            host = request.get_host()
2004.1.2 by vila
Implements a BasicAuthManager.
69
            password_manager = self._opener.password_manager
2004.1.9 by vila
Takes jam's remarks into account when possible, add TODOs for the rest.
70
            # Query the password manager first
2004.1.7 by vila
Better handling of passwords (user should be queried only once).
71
            user, password = password_manager.find_user_password(None, host)
72
            if user == request.user and password is not None:
73
                request.password = password
74
            else:
2004.1.9 by vila
Takes jam's remarks into account when possible, add TODOs for the rest.
75
                # Ask the user if we MUST
2004.1.7 by vila
Better handling of passwords (user should be queried only once).
76
                http_pass = 'HTTP %(user)s@%(host)s password'
2004.1.8 by vila
Merge jam's cleanup
77
                request.password = ui.ui_factory.get_password(prompt=http_pass,
78
                                                              user=request.user,
79
                                                              host=host)
2004.1.7 by vila
Better handling of passwords (user should be queried only once).
80
                password_manager.add_password(None, host,
81
                                              request.user, request.password)
2004.1.2 by vila
Implements a BasicAuthManager.
82
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
83
    def _perform(self, request):
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
84
        """Send the request to the server and handles common errors.
85
86
        :returns: urllib2 Response object
87
        """
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
88
        if self._connection is not None:
2004.1.2 by vila
Implements a BasicAuthManager.
89
            # Give back shared info
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
90
            request.connection = self._connection
2004.1.4 by vila
Fix user handling.
91
            if self._user is not None:
92
                request.user = self._user
93
                request.password = self._password
94
        elif request.user is not None:
2004.1.2 by vila
Implements a BasicAuthManager.
95
            # We will issue our first request, time to ask for a
96
            # password if needed
97
            self.ask_password(request)
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
98
99
        mutter('%s: [%s]' % (request.method, request.get_full_url()))
100
        if self._debuglevel > 0:
101
            print 'perform: %s base: %s, url: %s' % (request.method, self.base,
102
                                                     request.get_full_url())
103
104
        response = self._opener.open(request)
105
        if self._connection is None:
106
            # Acquire connection when the first request is able
107
            # to connect to the server
108
            self._connection = request.connection
2004.1.2 by vila
Implements a BasicAuthManager.
109
            self._user = request.user
110
            self._password = request.password
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
111
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
112
        code = response.code
2164.2.11 by Vincent Ladeuil
Explicit tests.
113
        if request.follow_redirections is False \
114
                and code in (301, 302, 303, 307):
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
115
            raise errors.RedirectRequested(request.get_full_url(),
116
                                           request.redirected_to,
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
117
                                           is_permament=(code == 301),
118
                                           qual_proto=self._qualified_proto)
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
119
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
120
        if request.redirected_to is not None:
121
            mutter('redirected from: %s to: %s' % (request.get_full_url(),
122
                                                   request.redirected_to))
123
124
        return response
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
125
2164.2.15 by Vincent Ladeuil
Http redirections are not followed by default. Do not use hints
126
    def _get(self, relpath, ranges, tail_amount=0):
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
127
        """See HttpTransport._get"""
128
129
        abspath = self._real_abspath(relpath)
130
        headers = {}
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
131
        if ranges or tail_amount:
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
132
            range_header = self.attempted_range_header(ranges, tail_amount)
133
            if range_header is not None:
134
                bytes = 'bytes=' + range_header
135
                headers = {'Range': bytes}
2004.3.1 by vila
Test ConnectionError exceptions.
136
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
137
        request = Request('GET', abspath, None, headers)
138
        response = self._perform(request)
139
140
        code = response.code
141
        if code == 404: # not found
142
            self._connection.fake_close()
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
143
            raise errors.NoSuchFile(abspath)
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
144
145
        data = handle_response(abspath, code, response.headers, response)
146
        # Close response to free the httplib.HTTPConnection pipeline
147
        self._connection.fake_close()
148
        return code, data
1540.3.3 by Martin Pool
Review updates of pycurl transport
149
2018.2.7 by Andrew Bennetts
Implement _post on HttpTransport_urllib.
150
    def _post(self, body_bytes):
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
151
        abspath = self._real_abspath('.bzr/smart')
152
        response = self._perform(Request('POST', abspath, body_bytes))
153
        code = response.code
154
        data = handle_response(abspath, code, response.headers, response)
155
        # Close response to free the httplib.HTTPConnection pipeline
156
        self._connection.fake_close()
157
        return code, data
2018.2.7 by Andrew Bennetts
Implement _post on HttpTransport_urllib.
158
1540.3.3 by Martin Pool
Review updates of pycurl transport
159
    def should_cache(self):
160
        """Return True if the data pulled across should be cached locally.
161
        """
162
        return True
163
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
164
    def _head(self, relpath):
165
        """Request the HEAD of a file.
166
167
        Performs the request and leaves callers handle the results.
168
        """
169
        abspath = self._real_abspath(relpath)
170
        request = Request('HEAD', abspath)
171
        response = self._perform(request)
172
173
        self._connection.fake_close()
174
        return response
175
1540.3.3 by Martin Pool
Review updates of pycurl transport
176
    def has(self, relpath):
177
        """Does the target location exist?
178
        """
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
179
        response = self._head(relpath)
180
181
        code = response.code
2164.2.16 by Vincent Ladeuil
Add tests.
182
        if code == 200: # "ok",
1540.3.3 by Martin Pool
Review updates of pycurl transport
183
            return True
184
        else:
2164.2.16 by Vincent Ladeuil
Add tests.
185
            assert(code == 404, 'Only 200 or 404 are correct')
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
186
            return False
1540.3.25 by Martin Pool
New 'http+urllib' scheme
187
188
1540.3.6 by Martin Pool
[merge] update from bzr.dev
189
def get_test_permutations():
190
    """Return the permutations to be used in testing."""
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
191
    from bzrlib.tests.HttpServer import HttpServer_urllib
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
192
    return [(HttpTransport_urllib, HttpServer_urllib),
1540.3.6 by Martin Pool
[merge] update from bzr.dev
193
            ]