После прочтения документа и проведения нескольких тестов я могу сказать, что чтение может происходить в обоих случаях.
urlopen
является блокирующим вызовом и фактически ожидает конца части заголовков.В этот момент доступны атрибуты кода и заголовков.
Но если сервер имеет временную задержку, urlopen
может вернуться до того, как будет получена вся часть данных.В этом случае read(n)
может блокироваться, если получено менее n байтов, и read()
будет блокироваться, пока не будет получен весь ответ.
Код, демонстрирующий, что:
Сервер:
class ReqHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print("GOT", self.command)
print("Headers", self.headers)
self.wfile.write(b"HTTP/1.1 200 OK\r\n")
time.sleep(2)
self.wfile.write(b"Server: BaseHTTP/0.6 Python/3.6.2\r\n\
Date: Mon, 11 Jun 2018 15:47:00 GMT\r\n\r\n")
time.sleep(2)
self.wfile.write("""<html>
<header><title>Test page</title></html>
<body><h1>Test</h1>
<p>This is a simple test...</p>""".encode())
time.sleep(5)
self.wfile.write("""<p>and here is the end of the page</p>
</body></html>""".encode())
server = http.server.HTTPServer(('localhost', 8080), ReqHandler)
server.handle_request()
Клиент:
def ask():
print(time.asctime())
r = urllib.request.urlopen("http://localhost:8080/test_page")
print(time.asctime())
print(r.read(10))
print(time.asctime())
print(r.read())
print(time.asctime())
ask()
А вот пример клиентской стороны:
Mon Jun 11 18:13:12 2018
Mon Jun 11 18:13:15 2018
b'<html>\n<he'
Mon Jun 11 18:13:17 2018
b'ader><title>Test page</title></html>\n<body><h1>Test</h1>\n<p>Ceci est un simple test</p><p>mais avec des charact\xe8res accentu\xe9s</p>\n</body></html>'
Mon Jun 11 18:13:22 2018
Итак:
- urlopen подождите 3 секунды, до конца части заголовка
- первое чтение (
read(10)
) ждет еще 2 секунды для первой части сообщения - второе чтение (
read()
)ждет еще 5 секунд до конца сообщения