| 220 | Returns RawResponseMessage""" |
| 221 | |
| 222 | def __call__(self, out, buf): |
| 223 | # read HTTP message (response line + headers) |
| 224 | try: |
| 225 | raw_data = yield from buf.readuntil( |
| 226 | b'\r\n\r\n', self.max_line_size + self.max_headers) |
| 227 | except errors.LineLimitExceededParserError as exc: |
| 228 | raise errors.LineTooLong(exc.limit) from None |
| 229 | |
| 230 | lines = raw_data.split(b'\r\n') |
| 231 | |
| 232 | line = lines[0].decode('utf-8', 'surrogateescape') |
| 233 | try: |
| 234 | version, status = line.split(None, 1) |
| 235 | except ValueError: |
| 236 | raise errors.BadStatusLine(line) from None |
| 237 | else: |
| 238 | try: |
| 239 | status, reason = status.split(None, 1) |
| 240 | except ValueError: |
| 241 | reason = '' |
| 242 | |
| 243 | # version |
| 244 | match = VERSRE.match(version) |
| 245 | if match is None: |
| 246 | raise errors.BadStatusLine(line) |
| 247 | version = HttpVersion(int(match.group(1)), int(match.group(2))) |
| 248 | |
| 249 | # The status code is a three-digit number |
| 250 | try: |
| 251 | status = int(status) |
| 252 | except ValueError: |
| 253 | raise errors.BadStatusLine(line) from None |
| 254 | |
| 255 | if status < 100 or status > 999: |
| 256 | raise errors.BadStatusLine(line) |
| 257 | |
| 258 | # read headers |
| 259 | headers, raw_headers, close, compression = self.parse_headers(lines) |
| 260 | |
| 261 | if close is None: |
| 262 | close = version <= HttpVersion10 |
| 263 | |
| 264 | out.feed_data( |
| 265 | RawResponseMessage( |
| 266 | version, status, reason.strip(), |
| 267 | headers, raw_headers, close, compression), |
| 268 | len(raw_data)) |
| 269 | out.feed_eof() |
| 270 | |
| 271 | |
| 272 | class HttpPayloadParser: |