Blame SOURCES/backport-util-socket-fixes-rhbz1501782.patch

5b57c4
From 7761a8cf3568f25243e7881b315b9fc922237673 Mon Sep 17 00:00:00 2001
5b57c4
From: Tomas Tomecek <ttomecek@redhat.com>
5b57c4
Date: Thu, 10 May 2018 16:10:36 +0200
5b57c4
Subject: [PATCH] asd
5b57c4
5b57c4
---
5b57c4
 docker/api/container.py |  4 +++-
5b57c4
 docker/api/exec_api.py  |  2 +-
5b57c4
 docker/client.py        | 22 ++++++++++++++++------
5b57c4
 docker/utils/socket.py  | 31 +++++++++++++++++++++++++++----
5b57c4
 tests/unit/api_test.py  |  2 +-
5b57c4
 5 files changed, 48 insertions(+), 13 deletions(-)
5b57c4
5b57c4
diff --git a/docker/api/container.py b/docker/api/container.py
5b57c4
index b8507d8..a164e7d 100644
5b57c4
--- a/docker/api/container.py
5b57c4
+++ b/docker/api/container.py
5b57c4
@@ -26,7 +26,9 @@ class ContainerApiMixin(object):
5b57c4
         u = self._url("/containers/{0}/attach", container)
5b57c4
         response = self._post(u, headers=headers, params=params, stream=stream)
5b57c4
 
5b57c4
-        return self._read_from_socket(response, stream)
5b57c4
+        return self._read_from_socket(
5b57c4
+            response, stream, self._check_is_tty(container)
5b57c4
+        )
5b57c4
 
5b57c4
     @utils.check_resource
5b57c4
     def attach_socket(self, container, params=None, ws=False):
5b57c4
diff --git a/docker/api/exec_api.py b/docker/api/exec_api.py
5b57c4
index 6e49996..9468f46 100644
5b57c4
--- a/docker/api/exec_api.py
5b57c4
+++ b/docker/api/exec_api.py
5b57c4
@@ -78,4 +78,4 @@ class ExecApiMixin(object):
5b57c4
 
5b57c4
         if socket:
5b57c4
             return self._get_raw_response_socket(res)
5b57c4
-        return self._read_from_socket(res, stream)
5b57c4
+        return self._read_from_socket(res, stream, tty)
5b57c4
diff --git a/docker/client.py b/docker/client.py
5b57c4
index 3fa19e0..eb928c6 100644
5b57c4
--- a/docker/client.py
5b57c4
+++ b/docker/client.py
5b57c4
@@ -16,7 +16,7 @@ from .ssladapter import ssladapter
5b57c4
 from .tls import TLSConfig
5b57c4
 from .transport import UnixAdapter
5b57c4
 from .utils import utils, check_resource, update_headers, kwargs_from_env
5b57c4
-from .utils.socket import frames_iter
5b57c4
+from .utils.socket import frames_iter, socket_raw_iter
5b57c4
 try:
5b57c4
     from .transport import NpipeAdapter
5b57c4
 except ImportError:
5b57c4
@@ -317,13 +317,19 @@ class Client(
5b57c4
         for out in response.iter_content(chunk_size=1, decode_unicode=True):
5b57c4
             yield out
5b57c4
 
5b57c4
-    def _read_from_socket(self, response, stream):
5b57c4
+    def _read_from_socket(self, response, stream, tty=False):
5b57c4
         socket = self._get_raw_response_socket(response)
5b57c4
 
5b57c4
+        gen = None
5b57c4
+        if tty is False:
5b57c4
+            gen = frames_iter(socket)
5b57c4
+        else:
5b57c4
+            gen = socket_raw_iter(socket)
5b57c4
+
5b57c4
         if stream:
5b57c4
-            return frames_iter(socket)
5b57c4
+            return gen
5b57c4
         else:
5b57c4
-            return six.binary_type().join(frames_iter(socket))
5b57c4
+            return six.binary_type().join(gen)
5b57c4
 
5b57c4
     def _disable_socket_timeout(self, socket):
5b57c4
         """ Depending on the combination of python version and whether we're
5b57c4
@@ -353,9 +359,13 @@ class Client(
5b57c4
 
5b57c4
             s.settimeout(None)
5b57c4
 
5b57c4
-    def _get_result(self, container, stream, res):
5b57c4
+    @check_resource
5b57c4
+    def _check_is_tty(self, container):
5b57c4
         cont = self.inspect_container(container)
5b57c4
-        return self._get_result_tty(stream, res, cont['Config']['Tty'])
5b57c4
+        return cont['Config']['Tty']
5b57c4
+
5b57c4
+    def _get_result(self, container, stream, res):
5b57c4
+        return self._get_result_tty(stream, res, self._check_is_tty(container))
5b57c4
 
5b57c4
     def _get_result_tty(self, stream, res, is_tty):
5b57c4
         # Stream multi-plexing was only introduced in API v1.6. Anything
5b57c4
diff --git a/docker/utils/socket.py b/docker/utils/socket.py
5b57c4
index 164b845..c3a5f90 100644
5b57c4
--- a/docker/utils/socket.py
5b57c4
+++ b/docker/utils/socket.py
5b57c4
@@ -59,7 +59,7 @@ def next_frame_size(socket):
5b57c4
     try:
5b57c4
         data = read_exactly(socket, 8)
5b57c4
     except SocketError:
5b57c4
-        return 0
5b57c4
+        return -1
5b57c4
 
5b57c4
     _, actual = struct.unpack('>BxxxL', data)
5b57c4
     return actual
5b57c4
@@ -69,7 +69,30 @@ def frames_iter(socket):
5b57c4
     """
5b57c4
     Returns a generator of frames read from socket
5b57c4
     """
5b57c4
-    n = next_frame_size(socket)
5b57c4
-    while n > 0:
5b57c4
-        yield read(socket, n)
5b57c4
+    while True:
5b57c4
         n = next_frame_size(socket)
5b57c4
+        if n < 0:
5b57c4
+            break
5b57c4
+        while n > 0:
5b57c4
+            result = read(socket, n)
5b57c4
+            if result is None:
5b57c4
+                continue
5b57c4
+            data_length = len(result)
5b57c4
+            if data_length == 0:
5b57c4
+                # We have reached EOF
5b57c4
+                return
5b57c4
+            n -= data_length
5b57c4
+            yield result
5b57c4
+
5b57c4
+
5b57c4
+def socket_raw_iter(socket):
5b57c4
+    """
5b57c4
+    Returns a generator of data read from the socket.
5b57c4
+    This is used for non-multiplexed streams.
5b57c4
+    """
5b57c4
+    while True:
5b57c4
+        result = read(socket)
5b57c4
+        if len(result) == 0:
5b57c4
+            # We have reached EOF
5b57c4
+            return
5b57c4
+        yield result
5b57c4
diff --git a/tests/unit/api_test.py b/tests/unit/api_test.py
5b57c4
index 8faca6b..3aeff85 100644
5b57c4
--- a/tests/unit/api_test.py
5b57c4
+++ b/tests/unit/api_test.py
5b57c4
@@ -83,7 +83,7 @@ def fake_delete(self, url, *args, **kwargs):
5b57c4
     return fake_request('DELETE', url, *args, **kwargs)
5b57c4
 
5b57c4
 
5b57c4
-def fake_read_from_socket(self, response, stream):
5b57c4
+def fake_read_from_socket(self, response, stream, tty=False):
5b57c4
     return six.binary_type()
5b57c4
 
5b57c4
 url_base = '{0}/'.format(fake_api.prefix)
5b57c4
-- 
5b57c4
2.17.0
5b57c4