import socket

try:
    import requests.packages.urllib3 as urllib3
except ImportError:
    import urllib3


class CancellableStream(object):
    """
    Stream wrapper for real-time events, logs, etc. from the server.

    Example:
        >>> events = client.events()
        >>> for event in events:
        ...   print event
        >>> # and cancel from another thread
        >>> events.close()
    """

    def __init__(self, stream, response):
        self._stream = stream
        self._response = response

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self._stream)
        except urllib3.exceptions.ProtocolError:
            raise StopIteration
        except socket.error:
            raise StopIteration

    next = __next__

    def close(self):
        """
        Closes the event streaming.
        """

        if not self._response.raw.closed:
            # find the underlying socket object
            # based on api.client._get_raw_response_socket

            sock_fp = self._response.raw._fp.fp

            if hasattr(sock_fp, 'raw'):
                sock_raw = sock_fp.raw

                if hasattr(sock_raw, 'sock'):
                    sock = sock_raw.sock

                elif hasattr(sock_raw, '_sock'):
                    sock = sock_raw._sock

            else:
                sock = sock_fp._sock

            sock.shutdown(socket.SHUT_RDWR)
            sock.close()

import socket

try:
    import requests.packages.urllib3 as urllib3
except ImportError:
    import urllib3


class CancellableStream(object):
    """
    Stream wrapper for real-time events, logs, etc. from the server.

    Example:
        >>> events = client.events()
        >>> for event in events:
        ...   print event
        >>> # and cancel from another thread
        >>> events.close()
    """

    def __init__(self, stream, response):
        self._stream = stream
        self._response = response

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self._stream)
        except urllib3.exceptions.ProtocolError:
            raise StopIteration
        except socket.error:
            raise StopIteration

    next = __next__

    def close(self):
        """
        Closes the event streaming.
        """

        if not self._response.raw.closed:
            # find the underlying socket object
            # based on api.client._get_raw_response_socket

            sock_fp = self._response.raw._fp.fp

            if hasattr(sock_fp, 'raw'):
                sock_raw = sock_fp.raw

                if hasattr(sock_raw, 'sock'):
                    sock = sock_raw.sock

                elif hasattr(sock_raw, '_sock'):
                    sock = sock_raw._sock

            else:
                sock = sock_fp._sock
            if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket):
                sock = sock.socket

            sock.shutdown(socket.SHUT_RDWR)
            sock.close()

Fix cancellable streams on Windows clients + HTTPS transport
Fix cancellable streams on Windows clients + HTTPS transport

Signed-off-by: Joffrey F <2e95f49799afcec0080c0aeb8813776d949e0768@docker.com>

  import socket
  
  try:
      import requests.packages.urllib3 as urllib3
  except ImportError:
      import urllib3
  
  
  class CancellableStream(object):
      """
      Stream wrapper for real-time events, logs, etc. from the server.
  
      Example:
          >>> events = client.events()
          >>> for event in events:
          ...   print event
          >>> # and cancel from another thread
          >>> events.close()
      """
  
      def __init__(self, stream, response):
          self._stream = stream
          self._response = response
  
      def __iter__(self):
          return self
  
      def __next__(self):
          try:
              return next(self._stream)
          except urllib3.exceptions.ProtocolError:
              raise StopIteration
          except socket.error:
              raise StopIteration
  
      next = __next__
  
      def close(self):
          """
          Closes the event streaming.
          """
  
          if not self._response.raw.closed:
              # find the underlying socket object
              # based on api.client._get_raw_response_socket
  
              sock_fp = self._response.raw._fp.fp
  
              if hasattr(sock_fp, 'raw'):
                  sock_raw = sock_fp.raw
  
                  if hasattr(sock_raw, 'sock'):
                      sock = sock_raw.sock
  
                  elif hasattr(sock_raw, '_sock'):
                      sock = sock_raw._sock
  
              else:
                  sock = sock_fp._sock
+             if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket):
+                 sock = sock.socket
  
              sock.shutdown(socket.SHUT_RDWR)
              sock.close()
  
Fix cancellable streams on Windows clients + HTTPS transport
## Code Before:
import socket

try:
    import requests.packages.urllib3 as urllib3
except ImportError:
    import urllib3


class CancellableStream(object):
    """
    Stream wrapper for real-time events, logs, etc. from the server.

    Example:
        >>> events = client.events()
        >>> for event in events:
        ...   print event
        >>> # and cancel from another thread
        >>> events.close()
    """

    def __init__(self, stream, response):
        self._stream = stream
        self._response = response

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self._stream)
        except urllib3.exceptions.ProtocolError:
            raise StopIteration
        except socket.error:
            raise StopIteration

    next = __next__

    def close(self):
        """
        Closes the event streaming.
        """

        if not self._response.raw.closed:
            # find the underlying socket object
            # based on api.client._get_raw_response_socket

            sock_fp = self._response.raw._fp.fp

            if hasattr(sock_fp, 'raw'):
                sock_raw = sock_fp.raw

                if hasattr(sock_raw, 'sock'):
                    sock = sock_raw.sock

                elif hasattr(sock_raw, '_sock'):
                    sock = sock_raw._sock

            else:
                sock = sock_fp._sock

            sock.shutdown(socket.SHUT_RDWR)
            sock.close()

## Instruction:
Fix cancellable streams on Windows clients + HTTPS transport
## Code After:
import socket

try:
    import requests.packages.urllib3 as urllib3
except ImportError:
    import urllib3


class CancellableStream(object):
    """
    Stream wrapper for real-time events, logs, etc. from the server.

    Example:
        >>> events = client.events()
        >>> for event in events:
        ...   print event
        >>> # and cancel from another thread
        >>> events.close()
    """

    def __init__(self, stream, response):
        self._stream = stream
        self._response = response

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self._stream)
        except urllib3.exceptions.ProtocolError:
            raise StopIteration
        except socket.error:
            raise StopIteration

    next = __next__

    def close(self):
        """
        Closes the event streaming.
        """

        if not self._response.raw.closed:
            # find the underlying socket object
            # based on api.client._get_raw_response_socket

            sock_fp = self._response.raw._fp.fp

            if hasattr(sock_fp, 'raw'):
                sock_raw = sock_fp.raw

                if hasattr(sock_raw, 'sock'):
                    sock = sock_raw.sock

                elif hasattr(sock_raw, '_sock'):
                    sock = sock_raw._sock

            else:
                sock = sock_fp._sock
            if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket):
                sock = sock.socket

            sock.shutdown(socket.SHUT_RDWR)
            sock.close()
