Add --socks-proxy parameter to use SOCKS proxy
This allows the user to specify a socks proxy to tunnel the connection through. This feature requires that PySocks is available. If the user tries to use a SOCKS proxy without PySocks available an error is printed and the process is aborted.
This commit is contained in:
parent
725d1c58aa
commit
8e30e9ed17
@ -52,6 +52,7 @@ from .utils import (
|
||||
locked_file,
|
||||
make_HTTPS_handler,
|
||||
MaxDownloadsReached,
|
||||
OptionalDependencyNotFound,
|
||||
PagedList,
|
||||
parse_filesize,
|
||||
PerRequestProxyHandler,
|
||||
@ -1953,11 +1954,39 @@ class YoutubeDL(object):
|
||||
proxies['https'] = proxies['http']
|
||||
proxy_handler = PerRequestProxyHandler(proxies)
|
||||
|
||||
socks_handler = None
|
||||
opts_socks = self.params.get('socksproxy')
|
||||
if opts_socks is not None and opts_socks:
|
||||
# Try to import the dependencies for this feature
|
||||
try:
|
||||
import socks
|
||||
except ImportError:
|
||||
raise OptionalDependencyNotFound(module_name='socks',
|
||||
feature_name='--socks-proxy')
|
||||
try:
|
||||
from sockshandler import SocksiPyHandler
|
||||
except ImportError:
|
||||
raise OptionalDependencyNotFound(module_name='sockshandler',
|
||||
feature_name='--socks-proxy')
|
||||
|
||||
pair = opts_socks.split(':')
|
||||
if len(pair) == 2:
|
||||
socks_handler = SocksiPyHandler(socks.PROXY_TYPE_SOCKS5,
|
||||
pair[0],
|
||||
int(pair[1]))
|
||||
else:
|
||||
socks_handler = SocksiPyHandler(socks.PROXY_TYPE_SOCKS5,
|
||||
'localhost',
|
||||
int(pair[0]))
|
||||
|
||||
debuglevel = 1 if self.params.get('debug_printtraffic') else 0
|
||||
https_handler = make_HTTPS_handler(self.params, debuglevel=debuglevel)
|
||||
ydlh = YoutubeDLHandler(self.params, debuglevel=debuglevel)
|
||||
opener = compat_urllib_request.build_opener(
|
||||
proxy_handler, https_handler, cookie_processor, ydlh)
|
||||
proxy_list = []
|
||||
if socks_handler:
|
||||
proxy_list.append(socks_handler)
|
||||
proxy_list += [proxy_handler, https_handler, cookie_processor, ydlh]
|
||||
opener = compat_urllib_request.build_opener(*proxy_list)
|
||||
|
||||
# Delete the default user-agent header, which would otherwise apply in
|
||||
# cases where our custom HTTP handler doesn't come into play
|
||||
|
@ -29,6 +29,7 @@ from .utils import (
|
||||
DownloadError,
|
||||
match_filter_func,
|
||||
MaxDownloadsReached,
|
||||
OptionalDependencyNotFound,
|
||||
preferredencoding,
|
||||
read_batch_urls,
|
||||
SameFileError,
|
||||
@ -346,6 +347,7 @@ def _real_main(argv=None):
|
||||
'nocheckcertificate': opts.no_check_certificate,
|
||||
'prefer_insecure': opts.prefer_insecure,
|
||||
'proxy': opts.proxy,
|
||||
'socksproxy': opts.socksproxy,
|
||||
'socket_timeout': opts.socket_timeout,
|
||||
'bidi_workaround': opts.bidi_workaround,
|
||||
'debug_printtraffic': opts.debug_printtraffic,
|
||||
@ -414,5 +416,7 @@ def main(argv=None):
|
||||
sys.exit('ERROR: fixed output name but more than one file to download')
|
||||
except KeyboardInterrupt:
|
||||
sys.exit('\nERROR: Interrupted by user')
|
||||
except OptionalDependencyNotFound as e:
|
||||
sys.exit(str(e))
|
||||
|
||||
__all__ = ['main', 'YoutubeDL', 'gen_extractors', 'list_extractors']
|
||||
|
@ -181,6 +181,11 @@ def parseOpts(overrideArguments=None):
|
||||
'--proxy', dest='proxy',
|
||||
default=None, metavar='URL',
|
||||
help='Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection')
|
||||
network.add_option(
|
||||
'--socks-proxy', dest='socksproxy', default=None, metavar='URL',
|
||||
help=('Use the specified socks proxy. Pass in an empty string '
|
||||
'(--socks-proxy "") for direct connection. This feature requires'
|
||||
'the pysocks library.'))
|
||||
network.add_option(
|
||||
'--socket-timeout',
|
||||
dest='socket_timeout', type=float, default=None, metavar='SECONDS',
|
||||
|
@ -586,6 +586,23 @@ class ContentTooShortError(Exception):
|
||||
self.expected = expected
|
||||
|
||||
|
||||
class OptionalDependencyNotFound(Exception):
|
||||
"""Optional dependency not found
|
||||
|
||||
This exception may be raised by YoutubeDL, when the user tries to use a
|
||||
feature that requires an optional dependency which could not be found.
|
||||
"""
|
||||
|
||||
def __init__(self, module_name, feature_name):
|
||||
self.module_name = str(module_name)
|
||||
self.feature_name = str(feature_name)
|
||||
|
||||
def __str__(self):
|
||||
return ("Unable to use '{feature}', because it depends on '{module}' "
|
||||
"which was not found.").format(
|
||||
feature=self.feature_name, module=self.module_name)
|
||||
|
||||
|
||||
def _create_http_connection(ydl_handler, http_class, is_https, *args, **kwargs):
|
||||
# Working around python 2 bug (see http://bugs.python.org/issue17849) by limiting
|
||||
# expected HTTP responses to meet HTTP/1.0 or later (see also
|
||||
|
Loading…
x
Reference in New Issue
Block a user