/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 breezy/transport/http/response.py

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
responses.
22
22
"""
23
23
 
24
 
from __future__ import absolute_import
25
 
 
 
24
import cgi
 
25
from io import BytesIO
26
26
import os
27
 
try:
28
 
    import http.client as http_client
29
 
except ImportError:  # python < 3
30
 
    import httplib as http_client
31
 
try:
32
 
    import email.utils as email_utils
33
 
except ImportError:  # python < 3
34
 
    import rfc822 as email_utils
 
27
import http.client as http_client
 
28
import email.utils as email_utils
35
29
 
36
30
from ... import (
37
31
    errors,
38
32
    osutils,
39
33
    )
40
 
from ...sixish import (
41
 
    BytesIO,
42
 
    PY3,
43
 
    )
44
34
 
45
35
 
46
36
class ResponseFile(object):
79
69
        :param size:  The number of bytes to read.  Leave unspecified or pass
80
70
            -1 to read to EOF.
81
71
        """
82
 
        if size is None and not PY3:
83
 
            size = -1
84
72
        data = self._file.read(size)
85
73
        self._pos += len(data)
86
74
        return data
90
78
        self._pos += len(data)
91
79
        return data
92
80
 
 
81
    def readlines(self, size=None):
 
82
        data = self._file.readlines()
 
83
        self._pos += sum(map(len, data))
 
84
        return data
 
85
 
93
86
    def __iter__(self):
94
87
        while True:
95
88
            line = self.readline()
219
212
        Parse the headers including the empty line following them so that we
220
213
        are ready to read the data itself.
221
214
        """
222
 
        if PY3:
223
 
            self._headers = http_client.parse_headers(self._file)
224
 
        else:
225
 
            self._headers = http_client.HTTPMessage(self._file, seekable=0)
 
215
        self._headers = http_client.parse_headers(self._file)
226
216
        # Extract the range definition
227
217
        content_range = self._headers.get('content-range', None)
228
218
        if content_range is None:
369
359
        return self._pos
370
360
 
371
361
 
372
 
def handle_response(url, code, msg, data):
 
362
def handle_response(url, code, getheader, data):
373
363
    """Interpret the code & headers and wrap the provided data in a RangeFile.
374
364
 
375
365
    This is a factory method which returns an appropriate RangeFile based on
377
367
 
378
368
    :param url: The url being processed. Mostly for error reporting
379
369
    :param code: The integer HTTP response code
380
 
    :param msg: An HTTPMessage containing the headers for the response
 
370
    :param getheader: Function for retrieving header
381
371
    :param data: A file-like object that can be read() to get the
382
372
                 requested data
383
373
    :return: A file-like object that can seek()+read() the
388
378
        rfile = ResponseFile(url, data)
389
379
    elif code == 206:
390
380
        rfile = RangeFile(url, data)
391
 
        content_type = msg.get('content-type', None)
392
 
        if content_type is None:
393
 
            # When there is no content-type header we treat the response as
394
 
            # being of type 'application/octet-stream' as per RFC2616 section
395
 
            # 7.2.1.
396
 
            # Therefore it is obviously not multipart
397
 
            content_type = 'application/octet-stream'
398
 
            is_multipart = False
399
 
        else:
400
 
            if PY3:
401
 
                is_multipart = (msg.get_content_maintype() == 'multipart'
402
 
                                and msg.get_content_subtype() == 'byteranges')
403
 
            else:
404
 
                is_multipart = (msg.getmaintype() == 'multipart'
405
 
                                and msg.getsubtype() == 'byteranges')
406
 
 
407
 
        if is_multipart:
408
 
            # Full fledged multipart response
409
 
            if PY3:
410
 
                boundary = msg.get_param('boundary')
411
 
            else:
412
 
                boundary = msg.getparam('boundary')
413
 
            rfile.set_boundary(boundary.encode('ascii'))
 
381
        # When there is no content-type header we treat the response as
 
382
        # being of type 'application/octet-stream' as per RFC2616 section
 
383
        # 7.2.1.
 
384
        # Therefore it is obviously not multipart
 
385
        content_type = getheader('content-type', 'application/octet-stream')
 
386
        mimetype, options = cgi.parse_header(content_type)
 
387
        if mimetype == 'multipart/byteranges':
 
388
            rfile.set_boundary(options['boundary'].encode('ascii'))
414
389
        else:
415
390
            # A response to a range request, but not multipart
416
 
            content_range = msg.get('content-range', None)
 
391
            content_range = getheader('content-range', None)
417
392
            if content_range is None:
418
 
                raise errors.InvalidHttpResponse(url,
419
 
                                                 'Missing the Content-Range header in a 206 range response')
 
393
                raise errors.InvalidHttpResponse(
 
394
                    url, 'Missing the Content-Range header in a 206 range response')
420
395
            rfile.set_range_from_header(content_range)
421
396
    else:
422
 
        raise errors.InvalidHttpResponse(url,
423
 
                                         'Unknown response code %s' % code)
 
397
        raise errors.UnexpectedHttpStatus(url, code)
424
398
 
425
399
    return rfile