|
|
6d47df |
From 4c0e7d69e461a28a254e7c7a27c2768be3163a3d Mon Sep 17 00:00:00 2001
|
|
|
6d47df |
From: Fraser Tweedale <ftweedal@redhat.com>
|
|
|
6d47df |
Date: Wed, 7 Nov 2018 17:06:47 +1100
|
|
|
6d47df |
Subject: [PATCH] rpc: always read response
|
|
|
6d47df |
|
|
|
6d47df |
If the server responds 401 and the response body is empty, the
|
|
|
6d47df |
client raises ResponseNotReady. This occurs because:
|
|
|
6d47df |
|
|
|
6d47df |
1. For a non-200 response, the response read only if the
|
|
|
6d47df |
Content-Length header occurs.
|
|
|
6d47df |
|
|
|
6d47df |
2. The response must be read before another request (e.g. the
|
|
|
6d47df |
follow-up request with WWW-Authenticate header set), and this
|
|
|
6d47df |
condition was not met. For details see
|
|
|
6d47df |
https://github.com/python/cpython/blob/v3.6.7/Lib/http/client.py#L1305-L1321.
|
|
|
6d47df |
|
|
|
6d47df |
This situation should not arise in regular use, because the client
|
|
|
6d47df |
either has a session cookie, or, knowing the details of the server
|
|
|
6d47df |
it is contacting, it establishes the GSS-API context and includes
|
|
|
6d47df |
the WWW-Authenticate header in the initial request.
|
|
|
6d47df |
|
|
|
6d47df |
Nevertheless, this problem has been observed in the wild. I do not
|
|
|
6d47df |
know its ordinary cause(s), but one can force the issue by removing
|
|
|
6d47df |
an authenticated user's session cache from /run/ipa/ccaches, then
|
|
|
6d47df |
performing a request.
|
|
|
6d47df |
|
|
|
6d47df |
Resolve the issue by always reading the response. It is safe to
|
|
|
6d47df |
call response.read() regardless of whether the Content-Length header
|
|
|
6d47df |
appears, or whether the body is empty.
|
|
|
6d47df |
|
|
|
6d47df |
Fixes: https://pagure.io/freeipa/issue/7752
|
|
|
6d47df |
Reviewed-By: Christian Heimes <cheimes@redhat.com>
|
|
|
6d47df |
---
|
|
|
6d47df |
ipalib/rpc.py | 11 +++++++++--
|
|
|
6d47df |
1 file changed, 9 insertions(+), 2 deletions(-)
|
|
|
6d47df |
|
|
|
6d47df |
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
|
|
|
6d47df |
index b27f3cef9c..23841d0a4c 100644
|
|
|
6d47df |
--- a/ipalib/rpc.py
|
|
|
6d47df |
+++ b/ipalib/rpc.py
|
|
|
6d47df |
@@ -712,8 +712,15 @@ def single_request(self, host, handler, request_body, verbose=0):
|
|
|
6d47df |
response = h.getresponse()
|
|
|
6d47df |
|
|
|
6d47df |
if response.status != 200:
|
|
|
6d47df |
- if (response.getheader("content-length", 0)):
|
|
|
6d47df |
- response.read()
|
|
|
6d47df |
+ # Must read response (even if it is empty)
|
|
|
6d47df |
+ # before sending another request.
|
|
|
6d47df |
+ #
|
|
|
6d47df |
+ # https://docs.python.org/3/library/http.client.html
|
|
|
6d47df |
+ # #http.client.HTTPConnection.getresponse
|
|
|
6d47df |
+ #
|
|
|
6d47df |
+ # https://pagure.io/freeipa/issue/7752
|
|
|
6d47df |
+ #
|
|
|
6d47df |
+ response.read()
|
|
|
6d47df |
|
|
|
6d47df |
if response.status == 401:
|
|
|
6d47df |
if not self._auth_complete(response):
|