From f08ec1522a2945917dc3b3e30caf43a8c330d5c1 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Mon, 11 May 2020 12:24:57 +0100 Subject: [PATCH] Set a default socket timeout when retrieving remote items in icat. Otherwise we can easily hang when "icat"-ing resources from unreliable websites/webcams, etc. --- kittens/icat/main.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/kittens/icat/main.py b/kittens/icat/main.py index 4b1e9adbc..637c9308d 100755 --- a/kittens/icat/main.py +++ b/kittens/icat/main.py @@ -2,9 +2,11 @@ # vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2017, Kovid Goyal +import contextlib import mimetypes import os import re +import socket import signal import sys import zlib @@ -339,6 +341,16 @@ help_text = ( usage = 'image-file-or-url-or-directory ...' +@contextlib.contextmanager +def socket_timeout(seconds: int): + old = socket.getdefaulttimeout() + socket.setdefaulttimeout(seconds) + try: + yield + finally: + socket.setdefaulttimeout(old) + + def process_single_item( item: Union[bytes, str], args: IcatCLIOptions, @@ -358,7 +370,8 @@ def process_single_item( from urllib.request import urlretrieve with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf: try: - urlretrieve(item, filename=tf.name) + with socket_timeout(30): + urlretrieve(item, filename=tf.name) except Exception as e: raise SystemExit('Failed to download image at URL: {} with error: {}'.format(item, e)) item = tf.name