~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Andrew Bennetts
  • Date: 2008-10-01 05:40:45 UTC
  • mfrom: (3753 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3756.
  • Revision ID: andrew.bennetts@canonical.com-20081001054045-z50qc0d3p9qsc5im
Merge from bzr.dev; resolve osutils.py conflict by reverting my sha import hackery.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import urlparse
26
26
import urllib
27
27
import sys
 
28
import weakref
28
29
 
29
30
from bzrlib import (
30
31
    debug,
79
80
    return url
80
81
 
81
82
 
82
 
class HttpTransportBase(ConnectedTransport, medium.SmartClientMedium):
 
83
class HttpTransportBase(ConnectedTransport):
83
84
    """Base class for http implementations.
84
85
 
85
86
    Does URL parsing, etc, but not any network IO.
103
104
        self._impl_name = impl_name
104
105
        super(HttpTransportBase, self).__init__(base,
105
106
                                                _from_transport=_from_transport)
 
107
        self._medium = None
106
108
        # range hint is handled dynamically throughout the life
107
109
        # of the transport object. We start by trying multi-range
108
110
        # requests and if the server returns bogus results, we
161
163
                    path=self._path)
162
164
        return auth
163
165
 
164
 
    def get_request(self):
165
 
        return SmartClientHTTPMediumRequest(self)
166
 
 
167
166
    def get_smart_medium(self):
168
 
        """See Transport.get_smart_medium.
 
167
        """See Transport.get_smart_medium."""
 
168
        if self._medium is None:
 
169
            # Since medium holds some state (smart server probing at least), we
 
170
            # need to keep it around. Note that this is needed because medium
 
171
            # has the same 'base' attribute as the transport so it can't be
 
172
            # shared between transports having different bases.
 
173
            self._medium = SmartClientHTTPMedium(self)
 
174
        return self._medium
169
175
 
170
 
        HttpTransportBase directly implements the minimal interface of
171
 
        SmartMediumClient, so this returns self.
172
 
        """
173
 
        return self
174
176
 
175
177
    def _degrade_range_hint(self, relpath, ranges, exc_info):
176
178
        if self._range_hint == 'multi':
515
517
 
516
518
        return ','.join(strings)
517
519
 
518
 
    def send_http_smart_request(self, bytes):
519
 
        try:
520
 
            code, body_filelike = self._post(bytes)
521
 
            if code != 200:
522
 
                raise InvalidHttpResponse(
523
 
                    self._remote_path('.bzr/smart'),
524
 
                    'Expected 200 response code, got %r' % (code,))
525
 
        except errors.InvalidHttpResponse, e:
526
 
            raise errors.SmartProtocolError(str(e))
527
 
        return body_filelike
 
520
 
 
521
# TODO: May be better located in smart/medium.py with the other
 
522
# SmartMedium classes
 
523
class SmartClientHTTPMedium(medium.SmartClientMedium):
 
524
 
 
525
    def __init__(self, http_transport):
 
526
        super(SmartClientHTTPMedium, self).__init__(http_transport.base)
 
527
        # We don't want to create a circular reference between the http
 
528
        # transport and its associated medium. Since the transport will live
 
529
        # longer than the medium, the medium keep only a weak reference to its
 
530
        # transport.
 
531
        self._http_transport_ref = weakref.ref(http_transport)
 
532
 
 
533
    def get_request(self):
 
534
        return SmartClientHTTPMediumRequest(self)
528
535
 
529
536
    def should_probe(self):
530
537
        return True
538
545
        rel_url = urlutils.relative_url(self.base, transport_base)
539
546
        return urllib.unquote(rel_url)
540
547
 
541
 
 
 
548
    def send_http_smart_request(self, bytes):
 
549
        try:
 
550
            # Get back the http_transport hold by the weak reference
 
551
            t = self._http_transport_ref()
 
552
            code, body_filelike = t._post(bytes)
 
553
            if code != 200:
 
554
                raise InvalidHttpResponse(
 
555
                    t._remote_path('.bzr/smart'),
 
556
                    'Expected 200 response code, got %r' % (code,))
 
557
        except errors.InvalidHttpResponse, e:
 
558
            raise errors.SmartProtocolError(str(e))
 
559
        return body_filelike
 
560
 
 
561
 
 
562
# TODO: May be better located in smart/medium.py with the other
 
563
# SmartMediumRequest classes
542
564
class SmartClientHTTPMediumRequest(medium.SmartClientMediumRequest):
543
565
    """A SmartClientMediumRequest that works with an HTTP medium."""
544
566