prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Socket is not connected error when closing currently open stream with VLC
  ### Checklist
  
  - [x] This is a bug report.
  - [ ] This is a feature request.
  - [ ] This is a plugin (improvement) request.
  - [ ] I have read the contribution guidelines.
  
  ### Description
  
  Every time I close a stream that was playing in VLC, I get the following error:
  
  ```
  [cli][info] Closing currently open stream...
  Traceback (most recent call last):
    File "/usr/local/bin/streamlink", line 11, in <module>
      load_entry_point('streamlink==0.6.0', 'console_scripts', 'streamlink')()
    File "/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py", line 1027, in main
      handle_url()
    File "/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py", line 502, in handle_url
      handle_stream(plugin, streams, stream_name)
    File "/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py", line 380, in handle_stream
      return output_stream_http(plugin, streams)
    File "/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py", line 192, in output_stream_http
      server.close()
    File "/usr/local/lib/python2.7/site-packages/streamlink_cli/utils/http_server.py", line 116, in close
      self.socket.shutdown(2)
    File "/usr/local/lib/python2.7/socket.py", line 228, in meth
      return getattr(self._sock,name)(*args)
  socket.error: [Errno 57] Socket is not connected
  ```
  
  This has been happening to me since 0.4.0, but I haven't had a chance to report it earlier. I've only been watching streams on Twtich so I have no idea if other services are affected by this too.
  
  Issue #604 might be something similar, but the error is quite different although some parts of the backtrace are similar.
  
  ### Expected / Actual behavior
  
  Expected: No error when closing the stream.
  Actual: The above error happens.
  
  ### Reproduction steps / Explicit stream URLs to test
  
  1. Load a Twitch stream with VLC as the player.
  2. Close VLC.
  
  This happens regardless of if the stream was still running when VLC is closed or if the stream already ended and VLC is not playing anything.
  
  ### Environment details
  
  Operating system and version: FreeBSD 11.0-RELEASE-p8
  Streamlink and Python version: Streamlink 0.6.0, Python 2.7.13
  VLC version: 2.2.5.1
  
  My .streamlinkrc file contains the following (excluding my Twitch OAuth token):
  
  ```
  player-continuous-http
  default-stream=best
  hls-segment-threads=10
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/streamlink_cli/utils/http_server.py`
  Content:
  ```
  1 import socket
  2 
  3 from io import BytesIO
  4 
  5 try:
  6     from BaseHTTPServer import BaseHTTPRequestHandler
  7 except ImportError:
  8     from http.server import BaseHTTPRequestHandler
  9 
  10 
  11 class HTTPRequest(BaseHTTPRequestHandler):
  12     def __init__(self, request_text):
  13         self.rfile = BytesIO(request_text)
  14         self.raw_requestline = self.rfile.readline()
  15         self.error_code = self.error_message = None
  16         self.parse_request()
  17 
  18     def send_error(self, code, message):
  19         self.error_code = code
  20         self.error_message = message
  21 
  22 
  23 class HTTPServer(object):
  24     def __init__(self):
  25         self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  26         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  27         self.conn = self.host = self.port = None
  28         self.bound = False
  29 
  30     @property
  31     def addresses(self):
  32         if self.host:
  33             return [self.host]
  34 
  35         addrs = set()
  36         try:
  37             for info in socket.getaddrinfo(socket.gethostname(), self.port,
  38                                            socket.AF_INET):
  39                 addrs.add(info[4][0])
  40         except socket.gaierror:
  41             pass
  42 
  43         addrs.add("127.0.0.1")
  44         return sorted(addrs)
  45 
  46     @property
  47     def urls(self):
  48         for addr in self.addresses:
  49             yield "http://{0}:{1}/".format(addr, self.port)
  50 
  51     @property
  52     def url(self):
  53         return next(self.urls, None)
  54 
  55     def bind(self, host="127.0.0.1", port=0):
  56         try:
  57             self.socket.bind((host or "", port))
  58         except socket.error as err:
  59             raise OSError(err)
  60 
  61         self.socket.listen(1)
  62         self.bound = True
  63         self.host, self.port = self.socket.getsockname()
  64         if self.host == "0.0.0.0":
  65             self.host = None
  66 
  67     def open(self, timeout=30):
  68         self.socket.settimeout(timeout)
  69 
  70         try:
  71             conn, addr = self.socket.accept()
  72             conn.settimeout(None)
  73         except socket.timeout:
  74             raise OSError("Socket accept timed out")
  75 
  76         try:
  77             req_data = conn.recv(1024)
  78         except socket.error:
  79             raise OSError("Failed to read data from socket")
  80 
  81         req = HTTPRequest(req_data)
  82         if req.command not in ("GET", "HEAD"):
  83             conn.send(b"HTTP/1.1 501 Not Implemented\r\n")
  84             conn.close()
  85             raise OSError("Invalid request method: {0}".format(req.command))
  86 
  87         try:
  88             conn.send(b"HTTP/1.1 200 OK\r\n")
  89             conn.send(b"Server: Streamlink\r\n")
  90             conn.send(b"Content-Type: video/unknown\r\n")
  91             conn.send(b"\r\n")
  92         except socket.error:
  93             raise OSError("Failed to write data to socket")
  94 
  95         # We don't want to send any data on HEAD requests.
  96         if req.command == "HEAD":
  97             conn.close()
  98             raise OSError
  99 
  100         self.conn = conn
  101 
  102         return req
  103 
  104     def write(self, data):
  105         if not self.conn:
  106             raise IOError("No connection")
  107 
  108         self.conn.sendall(data)
  109 
  110     def close(self, client_only=False):
  111         if self.conn:
  112             self.conn.close()
  113 
  114         if not client_only:
  115             try:
  116                 self.socket.shutdown(2)
  117             except OSError:
  118                 pass
  119             self.socket.close()
  120
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/streamlink_cli/utils/http_server.py b/src/streamlink_cli/utils/http_server.py
  --- a/src/streamlink_cli/utils/http_server.py
  +++ b/src/streamlink_cli/utils/http_server.py
  @@ -114,6 +114,6 @@
           if not client_only:
               try:
                   self.socket.shutdown(2)
  -            except OSError:
  +            except (OSError, socket.error):
                   pass
               self.socket.close()
  
verification_info: {"golden_diff": "diff --git a/src/streamlink_cli/utils/http_server.py b/src/streamlink_cli/utils/http_server.py\n--- a/src/streamlink_cli/utils/http_server.py\n+++ b/src/streamlink_cli/utils/http_server.py\n@@ -114,6 +114,6 @@\n         if not client_only:\n             try:\n                 self.socket.shutdown(2)\n-            except OSError:\n+            except (OSError, socket.error):\n                 pass\n             self.socket.close()\n", "issue": "Socket is not connected error when closing currently open stream with VLC\n### Checklist\r\n\r\n- [x] This is a bug report.\r\n- [ ] This is a feature request.\r\n- [ ] This is a plugin (improvement) request.\r\n- [ ] I have read the contribution guidelines.\r\n\r\n### Description\r\n\r\nEvery time I close a stream that was playing in VLC, I get the following error:\r\n\r\n```\r\n[cli][info] Closing currently open stream...\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/streamlink\", line 11, in <module>\r\n    load_entry_point('streamlink==0.6.0', 'console_scripts', 'streamlink')()\r\n  File \"/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py\", line 1027, in main\r\n    handle_url()\r\n  File \"/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py\", line 502, in handle_url\r\n    handle_stream(plugin, streams, stream_name)\r\n  File \"/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py\", line 380, in handle_stream\r\n    return output_stream_http(plugin, streams)\r\n  File \"/usr/local/lib/python2.7/site-packages/streamlink_cli/main.py\", line 192, in output_stream_http\r\n    server.close()\r\n  File \"/usr/local/lib/python2.7/site-packages/streamlink_cli/utils/http_server.py\", line 116, in close\r\n    self.socket.shutdown(2)\r\n  File \"/usr/local/lib/python2.7/socket.py\", line 228, in meth\r\n    return getattr(self._sock,name)(*args)\r\nsocket.error: [Errno 57] Socket is not connected\r\n```\r\n\r\nThis has been happening to me since 0.4.0, but I haven't had a chance to report it earlier. I've only been watching streams on Twtich so I have no idea if other services are affected by this too.\r\n\r\nIssue #604 might be something similar, but the error is quite different although some parts of the backtrace are similar.\r\n\r\n### Expected / Actual behavior\r\n\r\nExpected: No error when closing the stream.\r\nActual: The above error happens.\r\n\r\n### Reproduction steps / Explicit stream URLs to test\r\n\r\n1. Load a Twitch stream with VLC as the player.\r\n2. Close VLC.\r\n\r\nThis happens regardless of if the stream was still running when VLC is closed or if the stream already ended and VLC is not playing anything.\r\n\r\n### Environment details\r\n\r\nOperating system and version: FreeBSD 11.0-RELEASE-p8\r\nStreamlink and Python version: Streamlink 0.6.0, Python 2.7.13\r\nVLC version: 2.2.5.1\r\n\r\nMy .streamlinkrc file contains the following (excluding my Twitch OAuth token):\r\n\r\n```\r\nplayer-continuous-http\r\ndefault-stream=best\r\nhls-segment-threads=10\r\n```\n", "before_files": [{"content": "import socket\n\nfrom io import BytesIO\n\ntry:\n    from BaseHTTPServer import BaseHTTPRequestHandler\nexcept ImportError:\n    from http.server import BaseHTTPRequestHandler\n\n\nclass HTTPRequest(BaseHTTPRequestHandler):\n    def __init__(self, request_text):\n        self.rfile = BytesIO(request_text)\n        self.raw_requestline = self.rfile.readline()\n        self.error_code = self.error_message = None\n        self.parse_request()\n\n    def send_error(self, code, message):\n        self.error_code = code\n        self.error_message = message\n\n\nclass HTTPServer(object):\n    def __init__(self):\n        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        self.conn = self.host = self.port = None\n        self.bound = False\n\n    @property\n    def addresses(self):\n        if self.host:\n            return [self.host]\n\n        addrs = set()\n        try:\n            for info in socket.getaddrinfo(socket.gethostname(), self.port,\n                                           socket.AF_INET):\n                addrs.add(info[4][0])\n        except socket.gaierror:\n            pass\n\n        addrs.add(\"127.0.0.1\")\n        return sorted(addrs)\n\n    @property\n    def urls(self):\n        for addr in self.addresses:\n            yield \"http://{0}:{1}/\".format(addr, self.port)\n\n    @property\n    def url(self):\n        return next(self.urls, None)\n\n    def bind(self, host=\"127.0.0.1\", port=0):\n        try:\n            self.socket.bind((host or \"\", port))\n        except socket.error as err:\n            raise OSError(err)\n\n        self.socket.listen(1)\n        self.bound = True\n        self.host, self.port = self.socket.getsockname()\n        if self.host == \"0.0.0.0\":\n            self.host = None\n\n    def open(self, timeout=30):\n        self.socket.settimeout(timeout)\n\n        try:\n            conn, addr = self.socket.accept()\n            conn.settimeout(None)\n        except socket.timeout:\n            raise OSError(\"Socket accept timed out\")\n\n        try:\n            req_data = conn.recv(1024)\n        except socket.error:\n            raise OSError(\"Failed to read data from socket\")\n\n        req = HTTPRequest(req_data)\n        if req.command not in (\"GET\", \"HEAD\"):\n            conn.send(b\"HTTP/1.1 501 Not Implemented\\r\\n\")\n            conn.close()\n            raise OSError(\"Invalid request method: {0}\".format(req.command))\n\n        try:\n            conn.send(b\"HTTP/1.1 200 OK\\r\\n\")\n            conn.send(b\"Server: Streamlink\\r\\n\")\n            conn.send(b\"Content-Type: video/unknown\\r\\n\")\n            conn.send(b\"\\r\\n\")\n        except socket.error:\n            raise OSError(\"Failed to write data to socket\")\n\n        # We don't want to send any data on HEAD requests.\n        if req.command == \"HEAD\":\n            conn.close()\n            raise OSError\n\n        self.conn = conn\n\n        return req\n\n    def write(self, data):\n        if not self.conn:\n            raise IOError(\"No connection\")\n\n        self.conn.sendall(data)\n\n    def close(self, client_only=False):\n        if self.conn:\n            self.conn.close()\n\n        if not client_only:\n            try:\n                self.socket.shutdown(2)\n            except OSError:\n                pass\n            self.socket.close()\n", "path": "src/streamlink_cli/utils/http_server.py"}], "after_files": [{"content": "import socket\n\nfrom io import BytesIO\n\ntry:\n    from BaseHTTPServer import BaseHTTPRequestHandler\nexcept ImportError:\n    from http.server import BaseHTTPRequestHandler\n\n\nclass HTTPRequest(BaseHTTPRequestHandler):\n    def __init__(self, request_text):\n        self.rfile = BytesIO(request_text)\n        self.raw_requestline = self.rfile.readline()\n        self.error_code = self.error_message = None\n        self.parse_request()\n\n    def send_error(self, code, message):\n        self.error_code = code\n        self.error_message = message\n\n\nclass HTTPServer(object):\n    def __init__(self):\n        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        self.conn = self.host = self.port = None\n        self.bound = False\n\n    @property\n    def addresses(self):\n        if self.host:\n            return [self.host]\n\n        addrs = set()\n        try:\n            for info in socket.getaddrinfo(socket.gethostname(), self.port,\n                                           socket.AF_INET):\n                addrs.add(info[4][0])\n        except socket.gaierror:\n            pass\n\n        addrs.add(\"127.0.0.1\")\n        return sorted(addrs)\n\n    @property\n    def urls(self):\n        for addr in self.addresses:\n            yield \"http://{0}:{1}/\".format(addr, self.port)\n\n    @property\n    def url(self):\n        return next(self.urls, None)\n\n    def bind(self, host=\"127.0.0.1\", port=0):\n        try:\n            self.socket.bind((host or \"\", port))\n        except socket.error as err:\n            raise OSError(err)\n\n        self.socket.listen(1)\n        self.bound = True\n        self.host, self.port = self.socket.getsockname()\n        if self.host == \"0.0.0.0\":\n            self.host = None\n\n    def open(self, timeout=30):\n        self.socket.settimeout(timeout)\n\n        try:\n            conn, addr = self.socket.accept()\n            conn.settimeout(None)\n        except socket.timeout:\n            raise OSError(\"Socket accept timed out\")\n\n        try:\n            req_data = conn.recv(1024)\n        except socket.error:\n            raise OSError(\"Failed to read data from socket\")\n\n        req = HTTPRequest(req_data)\n        if req.command not in (\"GET\", \"HEAD\"):\n            conn.send(b\"HTTP/1.1 501 Not Implemented\\r\\n\")\n            conn.close()\n            raise OSError(\"Invalid request method: {0}\".format(req.command))\n\n        try:\n            conn.send(b\"HTTP/1.1 200 OK\\r\\n\")\n            conn.send(b\"Server: Streamlink\\r\\n\")\n            conn.send(b\"Content-Type: video/unknown\\r\\n\")\n            conn.send(b\"\\r\\n\")\n        except socket.error:\n            raise OSError(\"Failed to write data to socket\")\n\n        # We don't want to send any data on HEAD requests.\n        if req.command == \"HEAD\":\n            conn.close()\n            raise OSError\n\n        self.conn = conn\n\n        return req\n\n    def write(self, data):\n        if not self.conn:\n            raise IOError(\"No connection\")\n\n        self.conn.sendall(data)\n\n    def close(self, client_only=False):\n        if self.conn:\n            self.conn.close()\n\n        if not client_only:\n            try:\n                self.socket.shutdown(2)\n            except (OSError, socket.error):\n                pass\n            self.socket.close()\n", "path": "src/streamlink_cli/utils/http_server.py"}]}