Parse a request (internal). The request should be stored in self.raw_requestline; the results are in self.command, self.path, self.request_version and self.headers. Return True for success, False for failure; on failure, any relevant error response has alrea
(self)
| 318 | default_request_version = "HTTP/0.9" |
| 319 | |
| 320 | def parse_request(self): |
| 321 | """Parse a request (internal). |
| 322 | |
| 323 | The request should be stored in self.raw_requestline; the results |
| 324 | are in self.command, self.path, self.request_version and |
| 325 | self.headers. |
| 326 | |
| 327 | Return True for success, False for failure; on failure, any relevant |
| 328 | error response has already been sent back. |
| 329 | |
| 330 | """ |
| 331 | is_http_0_9 = False |
| 332 | self.command = None # set in case of error on the first line |
| 333 | self.request_version = version = self.default_request_version |
| 334 | self.close_connection = True |
| 335 | requestline = str(self.raw_requestline, 'iso-8859-1') |
| 336 | requestline = requestline.rstrip('\r\n') |
| 337 | self.requestline = requestline |
| 338 | words = requestline.split() |
| 339 | if len(words) == 0: |
| 340 | return False |
| 341 | |
| 342 | if len(words) >= 3: # Enough to determine protocol version |
| 343 | version = words[-1] |
| 344 | try: |
| 345 | if not version.startswith('HTTP/'): |
| 346 | raise ValueError |
| 347 | base_version_number = version.split('/', 1)[1] |
| 348 | version_number = base_version_number.split(".") |
| 349 | # RFC 2145 section 3.1 says there can be only one "." and |
| 350 | # - major and minor numbers MUST be treated as |
| 351 | # separate integers; |
| 352 | # - HTTP/2.4 is a lower version than HTTP/2.13, which in |
| 353 | # turn is lower than HTTP/12.3; |
| 354 | # - Leading zeros MUST be ignored by recipients. |
| 355 | if len(version_number) != 2: |
| 356 | raise ValueError |
| 357 | if any(not component.isdigit() for component in version_number): |
| 358 | raise ValueError("non digit in http version") |
| 359 | if any(len(component) > 10 for component in version_number): |
| 360 | raise ValueError("unreasonable length http version") |
| 361 | version_number = int(version_number[0]), int(version_number[1]) |
| 362 | except (ValueError, IndexError): |
| 363 | self.send_error( |
| 364 | HTTPStatus.BAD_REQUEST, |
| 365 | "Bad request version (%r)" % version) |
| 366 | return False |
| 367 | if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": |
| 368 | self.close_connection = False |
| 369 | if version_number >= (2, 0): |
| 370 | self.send_error( |
| 371 | HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, |
| 372 | "Invalid HTTP version (%s)" % base_version_number) |
| 373 | return False |
| 374 | self.request_version = version |
| 375 | |
| 376 | if not 2 <= len(words) <= 3: |
| 377 | self.send_error( |
no test coverage detected