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.
This commit is contained in:
Chris Lamb 2020-05-11 12:24:57 +01:00
parent e61e93712c
commit f08ec1522a

View File

@ -2,9 +2,11 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import contextlib
import mimetypes import mimetypes
import os import os
import re import re
import socket
import signal import signal
import sys import sys
import zlib import zlib
@ -339,6 +341,16 @@ help_text = (
usage = 'image-file-or-url-or-directory ...' 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( def process_single_item(
item: Union[bytes, str], item: Union[bytes, str],
args: IcatCLIOptions, args: IcatCLIOptions,
@ -358,7 +370,8 @@ def process_single_item(
from urllib.request import urlretrieve from urllib.request import urlretrieve
with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf: with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf:
try: try:
urlretrieve(item, filename=tf.name) with socket_timeout(30):
urlretrieve(item, filename=tf.name)
except Exception as e: except Exception as e:
raise SystemExit('Failed to download image at URL: {} with error: {}'.format(item, e)) raise SystemExit('Failed to download image at URL: {} with error: {}'.format(item, e))
item = tf.name item = tf.name