Send and log an error reply. Arguments are * code: an HTTP error code 3 digits * message: a simple optional 1 line reason phrase. *( HTAB / SP / VCHAR / %x80-FF ) defaults to short entry matching the response code
(self, code, message=None, explain=None)
| 470 | self.handle_one_request() |
| 471 | |
| 472 | def send_error(self, code, message=None, explain=None): |
| 473 | """Send and log an error reply. |
| 474 | |
| 475 | Arguments are |
| 476 | * code: an HTTP error code |
| 477 | 3 digits |
| 478 | * message: a simple optional 1 line reason phrase. |
| 479 | *( HTAB / SP / VCHAR / %x80-FF ) |
| 480 | defaults to short entry matching the response code |
| 481 | * explain: a detailed message defaults to the long entry |
| 482 | matching the response code. |
| 483 | |
| 484 | This sends an error response (so it must be called before any |
| 485 | output has been generated), logs the error, and finally sends |
| 486 | a piece of HTML explaining the error to the user. |
| 487 | |
| 488 | """ |
| 489 | |
| 490 | try: |
| 491 | shortmsg, longmsg = self.responses[code] |
| 492 | except KeyError: |
| 493 | shortmsg, longmsg = '???', '???' |
| 494 | if message is None: |
| 495 | message = shortmsg |
| 496 | if explain is None: |
| 497 | explain = longmsg |
| 498 | self.log_error("code %d, message %s", code, message) |
| 499 | self.send_response(code, message) |
| 500 | self.send_header('Connection', 'close') |
| 501 | |
| 502 | # Message body is omitted for cases described in: |
| 503 | # - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified) |
| 504 | # - RFC7231: 6.3.6. 205(Reset Content) |
| 505 | body = None |
| 506 | if (code >= 200 and |
| 507 | code not in (HTTPStatus.NO_CONTENT, |
| 508 | HTTPStatus.RESET_CONTENT, |
| 509 | HTTPStatus.NOT_MODIFIED)): |
| 510 | # HTML encode to prevent Cross Site Scripting attacks |
| 511 | # (see bug #1100201) |
| 512 | content = (self.error_message_format % { |
| 513 | 'code': code, |
| 514 | 'message': html.escape(message, quote=False), |
| 515 | 'explain': html.escape(explain, quote=False) |
| 516 | }) |
| 517 | body = content.encode('UTF-8', 'replace') |
| 518 | self.send_header("Content-Type", self.error_content_type) |
| 519 | self.send_header('Content-Length', str(len(body))) |
| 520 | self.end_headers() |
| 521 | |
| 522 | if self.command != 'HEAD' and body: |
| 523 | self.wfile.write(body) |
| 524 | |
| 525 | def send_response(self, code, message=None): |
| 526 | """Add the response header to the headers buffer and log the |