~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Ian Clatworthy
  • Date: 2008-03-27 07:51:10 UTC
  • mto: (3311.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 3312.
  • Revision ID: ian.clatworthy@canonical.com-20080327075110-afgd7x03ybju06ez
Reduce evangelism in the User Guide

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Handlers for HTTP Responses.
18
18
 
23
23
 
24
24
 
25
25
import httplib
26
 
from cStringIO import StringIO
27
 
import rfc822
28
26
 
29
27
from bzrlib import (
30
28
    errors,
31
29
    trace,
32
 
    osutils,
33
30
    )
34
31
 
35
32
 
64
61
    # 8k chunks should be fine.
65
62
    _discarded_buf_size = 8192
66
63
 
67
 
    # maximum size of read requests -- used to avoid MemoryError issues in recv
68
 
    _max_read_size = 512 * 1024
69
 
 
70
64
    def __init__(self, path, infile):
71
65
        """Constructor.
72
66
 
91
85
 
92
86
    def set_boundary(self, boundary):
93
87
        """Define the boundary used in a multi parts message.
94
 
 
 
88
        
95
89
        The file should be at the beginning of the body, the first range
96
90
        definition is read and taken into account.
97
91
        """
108
102
            # string entity.
109
103
            # To be on the safe side we allow it before any boundary line
110
104
            boundary_line = self._file.readline()
111
 
 
112
105
        if boundary_line != '--' + self._boundary + '\r\n':
113
 
            # rfc822.unquote() incorrectly unquotes strings enclosed in <>
114
 
            # IIS 6 and 7 incorrectly wrap boundary strings in <>
115
 
            # together they make a beautiful bug, which we will be gracious
116
 
            # about here
117
 
            if (self._unquote_boundary(boundary_line) !=
118
 
                '--' + self._boundary + '\r\n'):
119
 
                raise errors.InvalidHttpResponse(
120
 
                    self._path,
121
 
                    "Expected a boundary (%s) line, got '%s'"
122
 
                    % (self._boundary, boundary_line))
123
 
 
124
 
    def _unquote_boundary(self, b):
125
 
        return b[:2] + rfc822.unquote(b[2:-2]) + b[-2:]
 
106
            raise errors.InvalidHttpResponse(
 
107
                self._path,
 
108
                "Expected a boundary (%s) line, got '%s'" % (self._boundary,
 
109
                                                             boundary_line))
126
110
 
127
111
    def read_range_definition(self):
128
112
        """Read a new range definition in a multi parts message.
198
182
        client to clean the socket if we leave bytes unread. This may occur for
199
183
        the final boundary line of a multipart response or for any range
200
184
        request not entirely consumed by the client (due to offset coalescing)
201
 
 
202
 
        :param size:  The number of bytes to read.  Leave unspecified or pass
203
 
            -1 to read to EOF.
204
185
        """
205
186
        if (self._size > 0
206
187
            and self._pos == self._start + self._size):
220
201
                    "Can't read %s bytes across range (%s, %s)"
221
202
                    % (size, self._start, self._size))
222
203
 
223
 
        # read data from file
224
 
        buffer = StringIO()
225
 
        limited = size
226
204
        if self._size > 0:
227
205
            # Don't read past the range definition
228
206
            limited = self._start + self._size - self._pos
229
207
            if size >= 0:
230
208
                limited = min(limited, size)
231
 
        osutils.pumpfile(self._file, buffer, limited, self._max_read_size)
232
 
        data = buffer.getvalue()
233
 
 
 
209
            data = self._file.read(limited)
 
210
        else:
 
211
            # Size of file unknown, the user may have specified a size or not,
 
212
            # we delegate that to the filesocket object (-1 means read until
 
213
            # EOF)
 
214
            data = self._file.read(size)
234
215
        # Update _pos respecting the data effectively read
235
216
        self._pos += len(data)
236
217
        return data
288
269
    :param msg: An HTTPMessage containing the headers for the response
289
270
    :param data: A file-like object that can be read() to get the
290
271
                 requested data
291
 
    :return: A file-like object that can seek()+read() the
 
272
    :return: A file-like object that can seek()+read() the 
292
273
             ranges indicated by the headers.
293
274
    """
294
275
    rfile = RangeFile(url, data)