/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/_urllib2_wrappers.py

merge bzr.dev r3998

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
    )
68
68
 
69
69
 
70
 
class _BufferedMakefileSocket(object):
71
 
 
72
 
    def __init__(self, sock):
 
70
class _ReportingFileSocket(object):
 
71
 
 
72
    def __init__(self, filesock, report_activity=None):
 
73
        self.filesock = filesock
 
74
        self._report_activity = report_activity
 
75
 
 
76
 
 
77
    def read(self, size=1):
 
78
        s = self.filesock.read(size)
 
79
        self._report_activity(len(s), 'read')
 
80
        return s
 
81
 
 
82
    def readline(self):
 
83
        # This should be readline(self, size=-1), but httplib in python 2.4 and
 
84
        #  2.5 defines a SSLFile wrapper whose readline method lacks the size
 
85
        #  parameter.  So until we drop support for 2.4 and 2.5 and since we
 
86
        #  don't *need* the size parameter we'll stay with readline(self)
 
87
        #  --  vila 20090209
 
88
        s = self.filesock.readline()
 
89
        self._report_activity(len(s), 'read')
 
90
        return s
 
91
 
 
92
    def __getattr__(self, name):
 
93
        return getattr(self.filesock, name)
 
94
 
 
95
 
 
96
class _ReportingSocket(object):
 
97
 
 
98
    def __init__(self, sock, report_activity=None):
73
99
        self.sock = sock
 
100
        self._report_activity = report_activity
 
101
 
 
102
    def send(self, s, *args):
 
103
        self.sock.send(s, *args)
 
104
        self._report_activity(len(s), 'write')
 
105
 
 
106
    def sendall(self, s, *args):
 
107
        self.sock.send(s, *args)
 
108
        self._report_activity(len(s), 'write')
 
109
 
 
110
    def recv(self, *args):
 
111
        s = self.sock.recv(*args)
 
112
        self._report_activity(len(s), 'read')
 
113
        return s
74
114
 
75
115
    def makefile(self, mode='r', bufsize=-1):
76
 
        return self.sock.makefile(mode, 65536)
 
116
        # httplib creates a fileobject that doesn't do buffering, which
 
117
        # makes fp.readline() very expensive because it only reads one byte
 
118
        # at a time.  So we wrap the socket in an object that forces
 
119
        # sock.makefile to make a buffered file.
 
120
        fsock = self.sock.makefile(mode, 65536)
 
121
        # And wrap that into a reporting kind of fileobject
 
122
        return _ReportingFileSocket(fsock, self._report_activity)
77
123
 
78
124
    def __getattr__(self, name):
79
125
        return getattr(self.sock, name)
96
142
    # 8k chunks should be fine.
97
143
    _discarded_buf_size = 8192
98
144
 
99
 
    def __init__(self, sock, *args, **kwargs):
100
 
        # httplib creates a fileobject that doesn't do buffering, which
101
 
        # makes fp.readline() very expensive because it only reads one byte
102
 
        # at a time.  So we wrap the socket in an object that forces
103
 
        # sock.makefile to make a buffered file.
104
 
        sock = _BufferedMakefileSocket(sock)
105
 
        httplib.HTTPResponse.__init__(self, sock, *args, **kwargs)
106
 
 
107
145
    def begin(self):
108
146
        """Begin to read the response from the server.
109
147
 
178
216
    # we want to warn. But not below a given thresold.
179
217
    _range_warning_thresold = 1024 * 1024
180
218
 
181
 
    def __init__(self):
 
219
    def __init__(self,
 
220
                 report_activity=None):
182
221
        self._response = None
 
222
        self._report_activity = report_activity
183
223
        self._ranges_received_whole_file = None
184
224
 
185
225
    def _mutter_connect(self):
216
256
        # Restore our preciousss
217
257
        self.sock = sock
218
258
 
 
259
    def _wrap_socket_for_reporting(self, sock):
 
260
        """Wrap the socket before anybody use it."""
 
261
        self.sock = _ReportingSocket(sock, self._report_activity)
 
262
 
219
263
 
220
264
class HTTPConnection(AbstractHTTPConnection, httplib.HTTPConnection):
221
265
 
222
266
    # XXX: Needs refactoring at the caller level.
223
 
    def __init__(self, host, port=None, proxied_host=None):
224
 
        AbstractHTTPConnection.__init__(self)
 
267
    def __init__(self, host, port=None, proxied_host=None,
 
268
                 report_activity=None):
 
269
        AbstractHTTPConnection.__init__(self, report_activity=report_activity)
225
270
        # Use strict=True since we don't support HTTP/0.9
226
271
        httplib.HTTPConnection.__init__(self, host, port, strict=True)
227
272
        self.proxied_host = proxied_host
230
275
        if 'http' in debug.debug_flags:
231
276
            self._mutter_connect()
232
277
        httplib.HTTPConnection.connect(self)
 
278
        self._wrap_socket_for_reporting(self.sock)
233
279
 
234
280
 
235
281
# Build the appropriate socket wrapper for ssl
248
294
class HTTPSConnection(AbstractHTTPConnection, httplib.HTTPSConnection):
249
295
 
250
296
    def __init__(self, host, port=None, key_file=None, cert_file=None,
251
 
                 proxied_host=None):
252
 
        AbstractHTTPConnection.__init__(self)
 
297
                 proxied_host=None,
 
298
                 report_activity=None):
 
299
        AbstractHTTPConnection.__init__(self, report_activity=report_activity)
253
300
        # Use strict=True since we don't support HTTP/0.9
254
301
        httplib.HTTPSConnection.__init__(self, host, port,
255
302
                                         key_file, cert_file, strict=True)
259
306
        if 'http' in debug.debug_flags:
260
307
            self._mutter_connect()
261
308
        httplib.HTTPConnection.connect(self)
 
309
        self._wrap_socket_for_reporting(self.sock)
262
310
        if self.proxied_host is None:
263
311
            self.connect_to_origin()
264
312
 
265
313
    def connect_to_origin(self):
266
 
        self.sock = _ssl_wrap_socket(self.sock, self.key_file, self.cert_file)
 
314
        ssl_sock = _ssl_wrap_socket(self.sock, self.key_file, self.cert_file)
 
315
        # Wrap the ssl socket before anybody use it
 
316
        self._wrap_socket_for_reporting(ssl_sock)
267
317
 
268
318
 
269
319
class Request(urllib2.Request):
355
405
 
356
406
    handler_order = 1000 # after all pre-processings
357
407
 
 
408
    def __init__(self, report_activity=None):
 
409
        self._report_activity = report_activity
 
410
 
358
411
    def create_connection(self, request, http_connection_class):
359
412
        host = request.get_host()
360
413
        if not host:
366
419
        # request is made)
367
420
        try:
368
421
            connection = http_connection_class(
369
 
                host, proxied_host=request.proxied_host)
 
422
                host, proxied_host=request.proxied_host,
 
423
                report_activity=self._report_activity)
370
424
        except httplib.InvalidURL, exception:
371
425
            # There is only one occurrence of InvalidURL in httplib
372
426
            raise errors.InvalidURL(request.get_full_url(),
965
1019
            raise KeyError('%s not found' % self.auth_required_header)
966
1020
 
967
1021
        auth = self.get_auth(request)
968
 
        if auth.get('user', None) is None:
969
 
            # Without a known user, we can't authenticate
970
 
            return None
971
 
 
972
1022
        auth['modified'] = False
973
1023
        if self.auth_match(server_header, auth):
974
1024
            # auth_match may have modified auth (by adding the
978
1028
                # We already tried that, give up
979
1029
                return None
980
1030
 
 
1031
            if auth.get('user', None) is None:
 
1032
                # Without a known user, we can't authenticate
 
1033
                return None
 
1034
 
981
1035
            # Housekeeping
982
1036
            request.connection.cleanup_pipe()
983
1037
            response = self.parent.open(request)
1039
1093
        self._retry_count = None
1040
1094
 
1041
1095
    def get_user_password(self, auth):
1042
 
        """Ask user for a password if none is already available."""
 
1096
        """Ask user for a password if none is already available.
 
1097
 
 
1098
        :param auth: authentication info gathered so far (from the initial url
 
1099
            and then during dialog with the server).
 
1100
        """
1043
1101
        auth_conf = config.AuthenticationConfig()
1044
1102
        user = auth['user']
1045
1103
        password = auth['password']
1046
1104
        realm = auth['realm']
1047
1105
 
1048
1106
        if user is None:
1049
 
            user = auth.get_user(auth['protocol'], auth['host'],
1050
 
                                 port=auth['port'], path=auth['path'],
1051
 
                                 realm=realm)
1052
 
            if user is None:
1053
 
                # Default to local user
1054
 
                user = getpass.getuser()
1055
 
 
1056
 
        if password is None:
 
1107
            user = auth_conf.get_user(auth['protocol'], auth['host'],
 
1108
                                      port=auth['port'], path=auth['path'],
 
1109
                                      realm=realm)
 
1110
        if user is not None and password is None:
1057
1111
            password = auth_conf.get_password(
1058
1112
                auth['protocol'], auth['host'], user, port=auth['port'],
1059
1113
                path=auth['path'], realm=realm,
1370
1424
    def __init__(self,
1371
1425
                 connection=ConnectionHandler,
1372
1426
                 redirect=HTTPRedirectHandler,
1373
 
                 error=HTTPErrorProcessor,):
1374
 
        self._opener = urllib2.build_opener( \
1375
 
            connection, redirect, error,
 
1427
                 error=HTTPErrorProcessor,
 
1428
                 report_activity=None):
 
1429
        self._opener = urllib2.build_opener(
 
1430
            connection(report_activity=report_activity),
 
1431
            redirect, error,
1376
1432
            ProxyHandler(),
1377
1433
            HTTPBasicAuthHandler(),
1378
1434
            HTTPDigestAuthHandler(),