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)
| 290 | default_request_version = "HTTP/0.9" |
| 291 | |
| 292 | def parse_request(self): |
| 293 | """Parse a request (internal). |
| 294 | |
| 295 | The request should be stored in self.raw_requestline; the results |
| 296 | are in self.command, self.path, self.request_version and |
| 297 | self.headers. |
| 298 | |
| 299 | Return True for success, False for failure; on failure, any relevant |
| 300 | error response has already been sent back. |
| 301 | |
| 302 | """ |
| 303 | is_http_0_9 = False |
| 304 | self.command = None # set in case of error on the first line |
| 305 | self.request_version = version = self.default_request_version |
| 306 | self.close_connection = True |
| 307 | requestline = str(self.raw_requestline, 'iso-8859-1') |
| 308 | requestline = requestline.rstrip('\r\n') |
| 309 | self.requestline = requestline |
| 310 | words = requestline.split() |
| 311 | if len(words) == 0: |
| 312 | return False |
| 313 | |
| 314 | if len(words) >= 3: # Enough to determine protocol version |
| 315 | version = words[-1] |
| 316 | try: |
| 317 | if not version.startswith('HTTP/'): |
| 318 | raise ValueError |
| 319 | base_version_number = version.split('/', 1)[1] |
| 320 | version_number = base_version_number.split(".") |
| 321 | # RFC 2145 section 3.1 says there can be only one "." and |
| 322 | # - major and minor numbers MUST be treated as |
| 323 | # separate integers; |
| 324 | # - HTTP/2.4 is a lower version than HTTP/2.13, which in |
| 325 | # turn is lower than HTTP/12.3; |
| 326 | # - Leading zeros MUST be ignored by recipients. |
| 327 | if len(version_number) != 2: |
| 328 | raise ValueError |
| 329 | if any(not component.isdigit() for component in version_number): |
| 330 | raise ValueError("non digit in http version") |
| 331 | if any(len(component) > 10 for component in version_number): |
| 332 | raise ValueError("unreasonable length http version") |
| 333 | version_number = int(version_number[0]), int(version_number[1]) |
| 334 | except (ValueError, IndexError): |
| 335 | self.send_error( |
| 336 | HTTPStatus.BAD_REQUEST, |
| 337 | "Bad request version (%r)" % version) |
| 338 | return False |
| 339 | if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": |
| 340 | self.close_connection = False |
| 341 | if version_number >= (2, 0): |
| 342 | self.send_error( |
| 343 | HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, |
| 344 | "Invalid HTTP version (%s)" % base_version_number) |
| 345 | return False |
| 346 | self.request_version = version |
| 347 | |
| 348 | if not 2 <= len(words) <= 3: |
| 349 | self.send_error( |
no test coverage detected