~ubuntu-branches/ubuntu/karmic/bzr/karmic-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2009-02-14 00:24:06 UTC
  • mfrom: (1.1.48 upstream)
  • Revision ID: james.westby@ubuntu.com-20090214002406-h2zfezq54iylm2w8
Tags: 1.12-1
New upstream release.

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(),
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(),