error response has already been sent back.
"""
+ is_http_0_9 = False
self.command = None # set in case of error on the first line
self.request_version = version = self.default_request_version
self.close_connection = True
HTTPStatus.BAD_REQUEST,
"Bad HTTP/0.9 request type (%r)" % command)
return False
+ is_http_0_9 = True
self.command, self.path = command, path
# gh-87389: The purpose of replacing '//' with '/' is to protect
if self.path.startswith('//'):
self.path = '/' + self.path.lstrip('/') # Reduce to a single /
+ # For HTTP/0.9, headers are not expected at all.
+ if is_http_0_9:
+ self.headers = {}
+ return True
+
# Examine the headers and look for a Connection directive.
try:
self.headers = http.client.parse_headers(self.rfile,
SimpleHTTPRequestHandler, CGIHTTPRequestHandler
from http import server, HTTPStatus
+import contextlib
import os
import socket
import sys
self.assertEqual(b'', data)
+class HTTP09ServerTestCase(BaseTestCase):
+
+ class request_handler(NoLogRequestHandler, BaseHTTPRequestHandler):
+ """Request handler for HTTP/0.9 server."""
+
+ def do_GET(self):
+ self.wfile.write(f'OK: here is {self.path}\r\n'.encode())
+
+ def setUp(self):
+ super().setUp()
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sock = self.enterContext(self.sock)
+ self.sock.connect((self.HOST, self.PORT))
+
+ def test_simple_get(self):
+ self.sock.send(b'GET /index.html\r\n')
+ res = self.sock.recv(1024)
+ self.assertEqual(res, b"OK: here is /index.html\r\n")
+
+ def test_invalid_request(self):
+ self.sock.send(b'POST /index.html\r\n')
+ res = self.sock.recv(1024)
+ self.assertIn(b"Bad HTTP/0.9 request type ('POST')", res)
+
+ def test_single_request(self):
+ self.sock.send(b'GET /foo.html\r\n')
+ res = self.sock.recv(1024)
+ self.assertEqual(res, b"OK: here is /foo.html\r\n")
+
+ # Ignore errors if the connection is already closed,
+ # as this is the expected behavior of HTTP/0.9.
+ with contextlib.suppress(OSError):
+ self.sock.send(b'GET /bar.html\r\n')
+ res = self.sock.recv(1024)
+ # The server should not process our request.
+ self.assertEqual(res, b'')
+
+
class RequestHandlerLoggingTestCase(BaseTestCase):
class request_handler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'