def test_rtsp_url(data, callback):
import config
- data = dict(data)
- data.setdefault('scheme', 'rtsp')
- data.setdefault('host', '127.0.0.1')
- data['port'] = data.get('port') or '554'
- data.setdefault('path', '')
- data.setdefault('username', None)
- data.setdefault('password', None)
+ scheme = data.get('scheme', 'rtsp')
+ host = data.get('host', '127.0.0.1')
+ port = data.get('port') or '554'
+ path = data.get('path') or ''
+ username = data.get('username')
+ password = data.get('password')
url = '%(scheme)s://%(host)s%(port)s%(path)s' % {
- 'scheme': data['scheme'],
- 'host': data['host'],
- 'port': ':' + str(data['port']) if data['port'] else '',
- 'path': data['path'] or ''}
+ 'scheme': scheme,
+ 'host': host,
+ 'port': (':' + port) if port else '',
+ 'path': path}
called = [False]
+ send_auth = [False]
timeout = [None]
stream = None
io_loop = IOLoop.instance()
def connect():
- logging.debug('testing rtsp netcam at %s' % url)
+ if send_auth[0]:
+ logging.debug('testing rtsp netcam at %s (this time with credentials)' % url)
+
+ else:
+ logging.debug('testing rtsp netcam at %s' % url)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.settimeout(settings.MJPG_CLIENT_TIMEOUT)
stream = IOStream(s)
stream.set_close_callback(on_close)
- stream.connect((data['host'], int(data['port'])), on_connect)
-
+ stream.connect((host, int(port)), on_connect)
+
timeout[0] = io_loop.add_timeout(datetime.timedelta(seconds=settings.MJPG_CLIENT_TIMEOUT),
functools.partial(on_connect, _timeout=True))
'User-Agent: motionEye'
]
- if data['username']:
- auth_header = 'Authorization: ' + build_basic_header(data['username'], data['password'])
+ if username and send_auth[0]:
+ auth_header = 'Authorization: ' + build_basic_header(username, password)
lines.append(auth_header)
lines += [
if data:
if data.endswith('200 '):
seek_server()
-
+
elif data.endswith('401 '):
- handle_error('authentication failed')
+ if not username or send_auth[0]:
+ # either credentials not supplied, or already sent
+ handle_error('authentication failed')
+
+ else:
+ seek_www_authenticate()
else:
handle_error('rtsp netcam returned erroneous response: %s' % data)
-
+
else:
handle_error('timeout waiting for rtsp netcam response')
handle_success(identifier)
+ def seek_www_authenticate():
+ if check_error():
+ return
+
+ stream.read_until_regex('WWW-Authenticate: .*', on_www_authenticate)
+ timeout[0] = io_loop.add_timeout(datetime.timedelta(seconds=1), on_www_authenticate)
+
+ def on_www_authenticate(data=None):
+ io_loop.remove_timeout(timeout[0])
+
+ if data:
+ scheme = re.findall('WWW-Authenticate: ([^\s]+)', data)[0].strip()
+ logging.debug('rtsp netcam auth scheme: %s' % scheme)
+ if scheme.lower() == 'basic':
+ send_auth[0] = True
+ connect()
+
+ else:
+ logging.debug('rtsp auth scheme digest not supported, considering credentials ok')
+ handle_success('(unknown) ')
+
+ else:
+ logging.error('timeout waiting for rtsp auth scheme')
+ handle_error('timeout waiting for rtsp netcam response')
+
def on_close():
if called[0]:
return