synapse 2.162.0__py311-none-any.whl → 2.163.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +48 -40
- synapse/cortex.py +4 -0
- synapse/lib/cell.py +63 -0
- synapse/lib/oauth.py +1 -7
- synapse/lib/schemas.py +10 -0
- synapse/lib/stormhttp.py +52 -28
- synapse/lib/stormtypes.py +188 -7
- synapse/lib/version.py +2 -2
- synapse/tests/test_cortex.py +2 -2
- synapse/tests/test_lib_ast.py +1 -1
- synapse/tests/test_lib_storm.py +1 -1
- synapse/tests/test_lib_stormhttp.py +164 -1
- synapse/tests/test_lib_stormtypes.py +32 -7
- {synapse-2.162.0.dist-info → synapse-2.163.0.dist-info}/METADATA +1 -1
- {synapse-2.162.0.dist-info → synapse-2.163.0.dist-info}/RECORD +18 -18
- {synapse-2.162.0.dist-info → synapse-2.163.0.dist-info}/LICENSE +0 -0
- {synapse-2.162.0.dist-info → synapse-2.163.0.dist-info}/WHEEL +0 -0
- {synapse-2.162.0.dist-info → synapse-2.163.0.dist-info}/top_level.txt +0 -0
synapse/axon.py
CHANGED
|
@@ -593,7 +593,8 @@ class AxonApi(s_cell.CellApi, s_share.Share): # type: ignore
|
|
|
593
593
|
await self._reqUserAllowed(('axon', 'del'))
|
|
594
594
|
return await self.cell.dels(sha256s)
|
|
595
595
|
|
|
596
|
-
async def wget(self, url, params=None, headers=None, json=None, body=None, method='GET',
|
|
596
|
+
async def wget(self, url, params=None, headers=None, json=None, body=None, method='GET',
|
|
597
|
+
ssl=True, timeout=None, proxy=None, ssl_opts=None):
|
|
597
598
|
'''
|
|
598
599
|
Stream a file download directly into the Axon.
|
|
599
600
|
|
|
@@ -606,11 +607,20 @@ class AxonApi(s_cell.CellApi, s_share.Share): # type: ignore
|
|
|
606
607
|
method (str): The HTTP method to use.
|
|
607
608
|
ssl (bool): Perform SSL verification.
|
|
608
609
|
timeout (int): The timeout of the request, in seconds.
|
|
610
|
+
ssl_opts (dict): Additional SSL/TLS options.
|
|
609
611
|
|
|
610
612
|
Notes:
|
|
611
613
|
The response body will be stored, regardless of the response code. The ``ok`` value in the reponse does not
|
|
612
614
|
reflect that a status code, such as a 404, was encountered when retrieving the URL.
|
|
613
615
|
|
|
616
|
+
The ssl_opts dictionary may contain the following values::
|
|
617
|
+
|
|
618
|
+
{
|
|
619
|
+
'verify': <bool> - Perform SSL/TLS verification. Is overridden by the ssl argument.
|
|
620
|
+
'client_cert': <str> - PEM encoded full chain certificate for use in mTLS.
|
|
621
|
+
'client_key': <str> - PEM encoded key for use in mTLS. Alternatively, can be included in client_cert.
|
|
622
|
+
}
|
|
623
|
+
|
|
614
624
|
The dictionary returned by this may contain the following values::
|
|
615
625
|
|
|
616
626
|
{
|
|
@@ -640,18 +650,20 @@ class AxonApi(s_cell.CellApi, s_share.Share): # type: ignore
|
|
|
640
650
|
dict: An information dictionary containing the results of the request.
|
|
641
651
|
'''
|
|
642
652
|
await self._reqUserAllowed(('axon', 'wget'))
|
|
643
|
-
return await self.cell.wget(url, params=params, headers=headers, json=json, body=body, method=method,
|
|
644
|
-
timeout=timeout, proxy=proxy)
|
|
653
|
+
return await self.cell.wget(url, params=params, headers=headers, json=json, body=body, method=method,
|
|
654
|
+
ssl=ssl, timeout=timeout, proxy=proxy, ssl_opts=ssl_opts)
|
|
645
655
|
|
|
646
|
-
async def postfiles(self, fields, url, params=None, headers=None, method='POST',
|
|
656
|
+
async def postfiles(self, fields, url, params=None, headers=None, method='POST',
|
|
657
|
+
ssl=True, timeout=None, proxy=None, ssl_opts=None):
|
|
647
658
|
await self._reqUserAllowed(('axon', 'wput'))
|
|
648
|
-
return await self.cell.postfiles(fields, url, params=params, headers=headers,
|
|
649
|
-
|
|
659
|
+
return await self.cell.postfiles(fields, url, params=params, headers=headers, method=method,
|
|
660
|
+
ssl=ssl, timeout=timeout, proxy=proxy, ssl_opts=ssl_opts)
|
|
650
661
|
|
|
651
|
-
async def wput(self, sha256, url, params=None, headers=None, method='PUT',
|
|
662
|
+
async def wput(self, sha256, url, params=None, headers=None, method='PUT',
|
|
663
|
+
ssl=True, timeout=None, proxy=None, ssl_opts=None):
|
|
652
664
|
await self._reqUserAllowed(('axon', 'wput'))
|
|
653
|
-
return await self.cell.wput(sha256, url, params=params, headers=headers, method=method,
|
|
654
|
-
timeout=timeout, proxy=proxy)
|
|
665
|
+
return await self.cell.wput(sha256, url, params=params, headers=headers, method=method,
|
|
666
|
+
ssl=ssl, timeout=timeout, proxy=proxy, ssl_opts=ssl_opts)
|
|
655
667
|
|
|
656
668
|
async def metrics(self):
|
|
657
669
|
'''
|
|
@@ -1434,7 +1446,8 @@ class Axon(s_cell.Cell):
|
|
|
1434
1446
|
raise s_exc.BadJsonText(mesg=f'Bad json line encountered while processing {sha256}, ({e})',
|
|
1435
1447
|
sha256=sha256) from None
|
|
1436
1448
|
|
|
1437
|
-
async def postfiles(self, fields, url, params=None, headers=None, method='POST',
|
|
1449
|
+
async def postfiles(self, fields, url, params=None, headers=None, method='POST',
|
|
1450
|
+
ssl=True, timeout=None, proxy=None, ssl_opts=None):
|
|
1438
1451
|
'''
|
|
1439
1452
|
Send files from the axon as fields in a multipart/form-data HTTP request.
|
|
1440
1453
|
|
|
@@ -1447,6 +1460,7 @@ class Axon(s_cell.Cell):
|
|
|
1447
1460
|
ssl (bool): Perform SSL verification.
|
|
1448
1461
|
timeout (int): The timeout of the request, in seconds.
|
|
1449
1462
|
proxy (bool|str|null): Use a specific proxy or disable proxy use.
|
|
1463
|
+
ssl_opts (dict): Additional SSL/TLS options.
|
|
1450
1464
|
|
|
1451
1465
|
Notes:
|
|
1452
1466
|
The dictionaries in the fields list may contain the following values::
|
|
@@ -1460,6 +1474,14 @@ class Axon(s_cell.Cell):
|
|
|
1460
1474
|
'content_transfer_encoding': <str> - Optional content-transfer-encoding header for the field.
|
|
1461
1475
|
}
|
|
1462
1476
|
|
|
1477
|
+
The ssl_opts dictionary may contain the following values::
|
|
1478
|
+
|
|
1479
|
+
{
|
|
1480
|
+
'verify': <bool> - Perform SSL/TLS verification. Is overridden by the ssl argument.
|
|
1481
|
+
'client_cert': <str> - PEM encoded full chain certificate for use in mTLS.
|
|
1482
|
+
'client_key': <str> - PEM encoded key for use in mTLS. Alternatively, can be included in client_cert.
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1463
1485
|
The dictionary returned by this may contain the following values::
|
|
1464
1486
|
|
|
1465
1487
|
{
|
|
@@ -1478,20 +1500,12 @@ class Axon(s_cell.Cell):
|
|
|
1478
1500
|
if proxy is None:
|
|
1479
1501
|
proxy = self.conf.get('http:proxy')
|
|
1480
1502
|
|
|
1481
|
-
|
|
1503
|
+
ssl = self.getCachedSslCtx(opts=ssl_opts, verify=ssl)
|
|
1482
1504
|
|
|
1483
1505
|
connector = None
|
|
1484
1506
|
if proxy:
|
|
1485
1507
|
connector = aiohttp_socks.ProxyConnector.from_url(proxy)
|
|
1486
1508
|
|
|
1487
|
-
if ssl is False:
|
|
1488
|
-
pass
|
|
1489
|
-
elif cadir:
|
|
1490
|
-
ssl = s_common.getSslCtx(cadir)
|
|
1491
|
-
else:
|
|
1492
|
-
# default aiohttp behavior
|
|
1493
|
-
ssl = None
|
|
1494
|
-
|
|
1495
1509
|
atimeout = aiohttp.ClientTimeout(total=timeout)
|
|
1496
1510
|
|
|
1497
1511
|
async with aiohttp.ClientSession(connector=connector, timeout=atimeout) as sess:
|
|
@@ -1556,27 +1570,19 @@ class Axon(s_cell.Cell):
|
|
|
1556
1570
|
}
|
|
1557
1571
|
|
|
1558
1572
|
async def wput(self, sha256, url, params=None, headers=None, method='PUT', ssl=True, timeout=None,
|
|
1559
|
-
filename=None, filemime=None, proxy=None):
|
|
1573
|
+
filename=None, filemime=None, proxy=None, ssl_opts=None):
|
|
1560
1574
|
'''
|
|
1561
1575
|
Stream a blob from the axon as the body of an HTTP request.
|
|
1562
1576
|
'''
|
|
1563
1577
|
if proxy is None:
|
|
1564
|
-
|
|
1578
|
+
proxy = self.conf.get('http:proxy')
|
|
1565
1579
|
|
|
1566
|
-
|
|
1580
|
+
ssl = self.getCachedSslCtx(opts=ssl_opts, verify=ssl)
|
|
1567
1581
|
|
|
1568
1582
|
connector = None
|
|
1569
1583
|
if proxy:
|
|
1570
1584
|
connector = aiohttp_socks.ProxyConnector.from_url(proxy)
|
|
1571
1585
|
|
|
1572
|
-
if ssl is False:
|
|
1573
|
-
pass
|
|
1574
|
-
elif cadir:
|
|
1575
|
-
ssl = s_common.getSslCtx(cadir)
|
|
1576
|
-
else:
|
|
1577
|
-
# default aiohttp behavior
|
|
1578
|
-
ssl = None
|
|
1579
|
-
|
|
1580
1586
|
atimeout = aiohttp.ClientTimeout(total=timeout)
|
|
1581
1587
|
|
|
1582
1588
|
async with aiohttp.ClientSession(connector=connector, timeout=atimeout) as sess:
|
|
@@ -1638,7 +1644,8 @@ class Axon(s_cell.Cell):
|
|
|
1638
1644
|
|
|
1639
1645
|
return info
|
|
1640
1646
|
|
|
1641
|
-
async def wget(self, url, params=None, headers=None, json=None, body=None, method='GET',
|
|
1647
|
+
async def wget(self, url, params=None, headers=None, json=None, body=None, method='GET',
|
|
1648
|
+
ssl=True, timeout=None, proxy=None, ssl_opts=None):
|
|
1642
1649
|
'''
|
|
1643
1650
|
Stream a file download directly into the Axon.
|
|
1644
1651
|
|
|
@@ -1652,11 +1659,20 @@ class Axon(s_cell.Cell):
|
|
|
1652
1659
|
ssl (bool): Perform SSL verification.
|
|
1653
1660
|
timeout (int): The timeout of the request, in seconds.
|
|
1654
1661
|
proxy (bool|str|null): Use a specific proxy or disable proxy use.
|
|
1662
|
+
ssl_opts (dict): Additional SSL/TLS options.
|
|
1655
1663
|
|
|
1656
1664
|
Notes:
|
|
1657
1665
|
The response body will be stored, regardless of the response code. The ``ok`` value in the reponse does not
|
|
1658
1666
|
reflect that a status code, such as a 404, was encountered when retrieving the URL.
|
|
1659
1667
|
|
|
1668
|
+
The ssl_opts dictionary may contain the following values::
|
|
1669
|
+
|
|
1670
|
+
{
|
|
1671
|
+
'verify': <bool> - Perform SSL/TLS verification. Is overridden by the ssl argument.
|
|
1672
|
+
'client_cert': <str> - PEM encoded full chain certificate for use in mTLS.
|
|
1673
|
+
'client_key': <str> - PEM encoded key for use in mTLS. Alternatively, can be included in client_cert.
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1660
1676
|
The dictionary returned by this may contain the following values::
|
|
1661
1677
|
|
|
1662
1678
|
{
|
|
@@ -1690,7 +1706,7 @@ class Axon(s_cell.Cell):
|
|
|
1690
1706
|
if proxy is None:
|
|
1691
1707
|
proxy = self.conf.get('http:proxy')
|
|
1692
1708
|
|
|
1693
|
-
|
|
1709
|
+
ssl = self.getCachedSslCtx(opts=ssl_opts, verify=ssl)
|
|
1694
1710
|
|
|
1695
1711
|
connector = None
|
|
1696
1712
|
if proxy:
|
|
@@ -1698,14 +1714,6 @@ class Axon(s_cell.Cell):
|
|
|
1698
1714
|
|
|
1699
1715
|
atimeout = aiohttp.ClientTimeout(total=timeout)
|
|
1700
1716
|
|
|
1701
|
-
if ssl is False:
|
|
1702
|
-
pass
|
|
1703
|
-
elif cadir:
|
|
1704
|
-
ssl = s_common.getSslCtx(cadir)
|
|
1705
|
-
else:
|
|
1706
|
-
# default aiohttp behavior
|
|
1707
|
-
ssl = None
|
|
1708
|
-
|
|
1709
1717
|
async with aiohttp.ClientSession(connector=connector, timeout=atimeout) as sess:
|
|
1710
1718
|
|
|
1711
1719
|
try:
|
synapse/cortex.py
CHANGED
|
@@ -3879,6 +3879,10 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
3879
3879
|
if proxyurl is not None:
|
|
3880
3880
|
conf['http:proxy'] = proxyurl
|
|
3881
3881
|
|
|
3882
|
+
cadir = self.conf.get('tls:ca:dir')
|
|
3883
|
+
if cadir is not None:
|
|
3884
|
+
conf['tls:ca:dir'] = cadir
|
|
3885
|
+
|
|
3882
3886
|
self.axon = await s_axon.Axon.anit(path, conf=conf, parent=self)
|
|
3883
3887
|
self.axoninfo = await self.axon.getCellInfo()
|
|
3884
3888
|
self.axon.onfini(self.axready.clear)
|
synapse/lib/cell.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import gc
|
|
2
2
|
import os
|
|
3
|
+
import ssl
|
|
3
4
|
import copy
|
|
4
5
|
import time
|
|
5
6
|
import fcntl
|
|
@@ -12,6 +13,7 @@ import tarfile
|
|
|
12
13
|
import argparse
|
|
13
14
|
import datetime
|
|
14
15
|
import platform
|
|
16
|
+
import tempfile
|
|
15
17
|
import functools
|
|
16
18
|
import contextlib
|
|
17
19
|
import multiprocessing
|
|
@@ -32,6 +34,7 @@ import synapse.lib.boss as s_boss
|
|
|
32
34
|
import synapse.lib.coro as s_coro
|
|
33
35
|
import synapse.lib.hive as s_hive
|
|
34
36
|
import synapse.lib.link as s_link
|
|
37
|
+
import synapse.lib.cache as s_cache
|
|
35
38
|
import synapse.lib.const as s_const
|
|
36
39
|
import synapse.lib.nexus as s_nexus
|
|
37
40
|
import synapse.lib.queue as s_queue
|
|
@@ -58,6 +61,7 @@ import synapse.tools.backup as s_t_backup
|
|
|
58
61
|
logger = logging.getLogger(__name__)
|
|
59
62
|
|
|
60
63
|
SLAB_MAP_SIZE = 128 * s_const.mebibyte
|
|
64
|
+
SSLCTX_CACHE_SIZE = 64
|
|
61
65
|
|
|
62
66
|
'''
|
|
63
67
|
Base classes for the synapse "cell" microservice architecture.
|
|
@@ -1151,6 +1155,8 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
1151
1155
|
self.usermetadb = self.slab.initdb('user:meta') # useriden + <valu> -> dict valu
|
|
1152
1156
|
self.rolemetadb = self.slab.initdb('role:meta') # roleiden + <valu> -> dict valu
|
|
1153
1157
|
|
|
1158
|
+
self._sslctx_cache = s_cache.FixedCache(self._makeCachedSslCtx, size=SSLCTX_CACHE_SIZE)
|
|
1159
|
+
|
|
1154
1160
|
self.hive = await self._initCellHive()
|
|
1155
1161
|
|
|
1156
1162
|
# self.cellinfo, a HiveDict for general purpose persistent storage
|
|
@@ -4342,3 +4348,60 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
4342
4348
|
self.slab.delete(key_iden, db=self.apikeydb)
|
|
4343
4349
|
self.slab.delete(lkey, db=self.usermetadb)
|
|
4344
4350
|
await asyncio.sleep(0)
|
|
4351
|
+
|
|
4352
|
+
def _makeCachedSslCtx(self, opts):
|
|
4353
|
+
|
|
4354
|
+
opts = dict(opts)
|
|
4355
|
+
|
|
4356
|
+
cadir = self.conf.get('tls:ca:dir')
|
|
4357
|
+
|
|
4358
|
+
if cadir is not None:
|
|
4359
|
+
sslctx = s_common.getSslCtx(cadir, purpose=ssl.Purpose.SERVER_AUTH)
|
|
4360
|
+
else:
|
|
4361
|
+
sslctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
|
|
4362
|
+
|
|
4363
|
+
if not opts['verify']:
|
|
4364
|
+
sslctx.check_hostname = False
|
|
4365
|
+
sslctx.verify_mode = ssl.CERT_NONE
|
|
4366
|
+
|
|
4367
|
+
if not opts['client_cert']:
|
|
4368
|
+
return sslctx
|
|
4369
|
+
|
|
4370
|
+
client_cert = opts['client_cert'].encode()
|
|
4371
|
+
|
|
4372
|
+
if opts['client_key']:
|
|
4373
|
+
client_key = opts['client_key'].encode()
|
|
4374
|
+
else:
|
|
4375
|
+
client_key = None
|
|
4376
|
+
client_key_path = None
|
|
4377
|
+
|
|
4378
|
+
with self.getTempDir() as tmpdir:
|
|
4379
|
+
|
|
4380
|
+
with tempfile.NamedTemporaryFile(dir=tmpdir, mode='wb', delete=False) as fh:
|
|
4381
|
+
fh.write(client_cert)
|
|
4382
|
+
client_cert_path = fh.name
|
|
4383
|
+
|
|
4384
|
+
if client_key:
|
|
4385
|
+
with tempfile.NamedTemporaryFile(dir=tmpdir, mode='wb', delete=False) as fh:
|
|
4386
|
+
fh.write(client_key)
|
|
4387
|
+
client_key_path = fh.name
|
|
4388
|
+
|
|
4389
|
+
try:
|
|
4390
|
+
sslctx.load_cert_chain(client_cert_path, keyfile=client_key_path)
|
|
4391
|
+
except ssl.SSLError as e:
|
|
4392
|
+
raise s_exc.BadArg(mesg=f'Error loading client cert: {str(e)}') from None
|
|
4393
|
+
|
|
4394
|
+
return sslctx
|
|
4395
|
+
|
|
4396
|
+
def getCachedSslCtx(self, opts=None, verify=None):
|
|
4397
|
+
|
|
4398
|
+
if opts is None:
|
|
4399
|
+
opts = {}
|
|
4400
|
+
|
|
4401
|
+
if verify is not None:
|
|
4402
|
+
opts['verify'] = verify
|
|
4403
|
+
|
|
4404
|
+
opts = s_schemas.reqValidSslCtxOpts(opts)
|
|
4405
|
+
|
|
4406
|
+
key = tuple(sorted(opts.items()))
|
|
4407
|
+
return self._sslctx_cache.get(key)
|
synapse/lib/oauth.py
CHANGED
|
@@ -230,13 +230,7 @@ class OAuthMixin(s_nexus.Pusher):
|
|
|
230
230
|
|
|
231
231
|
timeout = aiohttp.ClientTimeout(total=DEFAULT_TIMEOUT)
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
if ssl_verify is False:
|
|
235
|
-
ssl = False
|
|
236
|
-
elif cadir:
|
|
237
|
-
ssl = s_common.getSslCtx(cadir)
|
|
238
|
-
else:
|
|
239
|
-
ssl = None
|
|
233
|
+
ssl = self.getCachedSslCtx(verify=ssl_verify)
|
|
240
234
|
|
|
241
235
|
async with aiohttp.ClientSession(timeout=timeout) as sess:
|
|
242
236
|
|
synapse/lib/schemas.py
CHANGED
|
@@ -263,3 +263,13 @@ _cellUserApiKeySchema = {
|
|
|
263
263
|
],
|
|
264
264
|
}
|
|
265
265
|
reqValidUserApiKeyDef = s_config.getJsValidator(_cellUserApiKeySchema)
|
|
266
|
+
|
|
267
|
+
reqValidSslCtxOpts = s_config.getJsValidator({
|
|
268
|
+
'type': 'object',
|
|
269
|
+
'properties': {
|
|
270
|
+
'verify': {'type': 'boolean', 'default': True},
|
|
271
|
+
'client_cert': {'type': ['string', 'null'], 'default': None},
|
|
272
|
+
'client_key': {'type': ['string', 'null'], 'default': None},
|
|
273
|
+
},
|
|
274
|
+
'additionalProperties': False,
|
|
275
|
+
})
|
synapse/lib/stormhttp.py
CHANGED
|
@@ -13,6 +13,7 @@ import synapse.common as s_common
|
|
|
13
13
|
|
|
14
14
|
import synapse.lib.base as s_base
|
|
15
15
|
import synapse.lib.msgpack as s_msgpack
|
|
16
|
+
import synapse.lib.version as s_version
|
|
16
17
|
import synapse.lib.stormtypes as s_stormtypes
|
|
17
18
|
|
|
18
19
|
@s_stormtypes.registry.registerType
|
|
@@ -87,6 +88,14 @@ class WebSocket(s_base.Base, s_stormtypes.StormType):
|
|
|
87
88
|
class LibHttp(s_stormtypes.Lib):
|
|
88
89
|
'''
|
|
89
90
|
A Storm Library exposing an HTTP client API.
|
|
91
|
+
|
|
92
|
+
For APIs that accept an ssl_opts argument, the dictionary may contain the following values::
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
'verify': <bool> - Perform SSL/TLS verification. Is overridden by the ssl_verify argument.
|
|
96
|
+
'client_cert': <str> - PEM encoded full chain certificate for use in mTLS.
|
|
97
|
+
'client_key': <str> - PEM encoded key for use in mTLS. Alternatively, can be included in client_cert.
|
|
98
|
+
}
|
|
90
99
|
'''
|
|
91
100
|
_storm_locals = (
|
|
92
101
|
{'name': 'get', 'desc': 'Get the contents of a given URL.',
|
|
@@ -105,6 +114,9 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
105
114
|
'default': True},
|
|
106
115
|
{'name': 'proxy', 'type': ['bool', 'null', 'str'],
|
|
107
116
|
'desc': 'Set to a proxy URL string or $lib.false to disable proxy use.', 'default': None},
|
|
117
|
+
{'name': 'ssl_opts', 'type': 'dict',
|
|
118
|
+
'desc': 'Optional SSL/TLS options. See $lib.inet.http help for additional details.',
|
|
119
|
+
'default': None},
|
|
108
120
|
),
|
|
109
121
|
'returns': {'type': 'inet:http:resp', 'desc': 'The response object.'}}},
|
|
110
122
|
{'name': 'post', 'desc': 'Post data to a given URL.',
|
|
@@ -134,6 +146,9 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
134
146
|
'default': None},
|
|
135
147
|
{'name': 'proxy', 'type': ['bool', 'null', 'str'],
|
|
136
148
|
'desc': 'Set to a proxy URL string or $lib.false to disable proxy use.', 'default': None},
|
|
149
|
+
{'name': 'ssl_opts', 'type': 'dict',
|
|
150
|
+
'desc': 'Optional SSL/TLS options. See $lib.inet.http help for additional details.',
|
|
151
|
+
'default': None},
|
|
137
152
|
),
|
|
138
153
|
'returns': {'type': 'inet:http:resp', 'desc': 'The response object.'}}},
|
|
139
154
|
{'name': 'head', 'desc': 'Get the HEAD response for a URL.',
|
|
@@ -153,6 +168,9 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
153
168
|
'default': False},
|
|
154
169
|
{'name': 'proxy', 'type': ['bool', 'null', 'str'],
|
|
155
170
|
'desc': 'Set to a proxy URL string or $lib.false to disable proxy use.', 'default': None},
|
|
171
|
+
{'name': 'ssl_opts', 'type': 'dict',
|
|
172
|
+
'desc': 'Optional SSL/TLS options. See $lib.inet.http help for additional details.',
|
|
173
|
+
'default': None},
|
|
156
174
|
),
|
|
157
175
|
'returns': {'type': 'inet:http:resp', 'desc': 'The response object.'}}},
|
|
158
176
|
{'name': 'request', 'desc': 'Make an HTTP request using the given HTTP method to the url.',
|
|
@@ -183,6 +201,9 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
183
201
|
'default': None},
|
|
184
202
|
{'name': 'proxy', 'type': ['bool', 'null', 'str'],
|
|
185
203
|
'desc': 'Set to a proxy URL string or $lib.false to disable proxy use.', 'default': None},
|
|
204
|
+
{'name': 'ssl_opts', 'type': 'dict',
|
|
205
|
+
'desc': 'Optional SSL/TLS options. See $lib.inet.http help for additional details.',
|
|
206
|
+
'default': None},
|
|
186
207
|
),
|
|
187
208
|
'returns': {'type': 'inet:http:resp', 'desc': 'The response object.'}
|
|
188
209
|
}
|
|
@@ -201,6 +222,9 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
201
222
|
'default': None},
|
|
202
223
|
{'name': 'proxy', 'type': ['bool', 'null', 'str'],
|
|
203
224
|
'desc': 'Set to a proxy URL string or $lib.false to disable proxy use.', 'default': None},
|
|
225
|
+
{'name': 'ssl_opts', 'type': 'dict',
|
|
226
|
+
'desc': 'Optional SSL/TLS options. See $lib.inet.http help for additional details.',
|
|
227
|
+
'default': None},
|
|
204
228
|
),
|
|
205
229
|
'returns': {'type': 'inet:http:socket', 'desc': 'A websocket object.'}}},
|
|
206
230
|
{'name': 'urlencode', 'desc': '''
|
|
@@ -290,28 +314,31 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
290
314
|
return s_common.httpcodereason(code)
|
|
291
315
|
|
|
292
316
|
async def _httpEasyHead(self, url, headers=None, ssl_verify=True, params=None, timeout=300,
|
|
293
|
-
allow_redirects=False, proxy=None):
|
|
317
|
+
allow_redirects=False, proxy=None, ssl_opts=None):
|
|
294
318
|
return await self._httpRequest('HEAD', url, headers=headers, ssl_verify=ssl_verify, params=params,
|
|
295
|
-
timeout=timeout, allow_redirects=allow_redirects, proxy=proxy)
|
|
319
|
+
timeout=timeout, allow_redirects=allow_redirects, proxy=proxy, ssl_opts=ssl_opts)
|
|
296
320
|
|
|
297
321
|
async def _httpEasyGet(self, url, headers=None, ssl_verify=True, params=None, timeout=300,
|
|
298
|
-
allow_redirects=True, proxy=None):
|
|
322
|
+
allow_redirects=True, proxy=None, ssl_opts=None):
|
|
299
323
|
return await self._httpRequest('GET', url, headers=headers, ssl_verify=ssl_verify, params=params,
|
|
300
|
-
timeout=timeout, allow_redirects=allow_redirects, proxy=proxy)
|
|
324
|
+
timeout=timeout, allow_redirects=allow_redirects, proxy=proxy, ssl_opts=ssl_opts)
|
|
301
325
|
|
|
302
326
|
async def _httpPost(self, url, headers=None, json=None, body=None, ssl_verify=True,
|
|
303
|
-
params=None, timeout=300, allow_redirects=True, fields=None, proxy=None):
|
|
327
|
+
params=None, timeout=300, allow_redirects=True, fields=None, proxy=None, ssl_opts=None):
|
|
304
328
|
return await self._httpRequest('POST', url, headers=headers, json=json, body=body,
|
|
305
329
|
ssl_verify=ssl_verify, params=params, timeout=timeout,
|
|
306
|
-
allow_redirects=allow_redirects, fields=fields, proxy=proxy)
|
|
330
|
+
allow_redirects=allow_redirects, fields=fields, proxy=proxy, ssl_opts=ssl_opts)
|
|
307
331
|
|
|
308
|
-
async def inetHttpConnect(self, url, headers=None, ssl_verify=True, timeout=300,
|
|
332
|
+
async def inetHttpConnect(self, url, headers=None, ssl_verify=True, timeout=300,
|
|
333
|
+
params=None, proxy=None, ssl_opts=None):
|
|
309
334
|
|
|
310
335
|
url = await s_stormtypes.tostr(url)
|
|
311
336
|
headers = await s_stormtypes.toprim(headers)
|
|
312
337
|
timeout = await s_stormtypes.toint(timeout, noneok=True)
|
|
313
338
|
params = await s_stormtypes.toprim(params)
|
|
314
339
|
proxy = await s_stormtypes.toprim(proxy)
|
|
340
|
+
ssl_verify = await s_stormtypes.tobool(ssl_verify, noneok=True)
|
|
341
|
+
ssl_opts = await s_stormtypes.toprim(ssl_opts)
|
|
315
342
|
|
|
316
343
|
headers = self.strify(headers)
|
|
317
344
|
|
|
@@ -332,15 +359,7 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
332
359
|
if params:
|
|
333
360
|
kwargs['params'] = params
|
|
334
361
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if ssl_verify is False:
|
|
338
|
-
kwargs['ssl'] = False
|
|
339
|
-
elif cadir:
|
|
340
|
-
kwargs['ssl'] = s_common.getSslCtx(cadir)
|
|
341
|
-
else:
|
|
342
|
-
# default aiohttp behavior
|
|
343
|
-
kwargs['ssl'] = None
|
|
362
|
+
kwargs['ssl'] = self.runt.snap.core.getCachedSslCtx(opts=ssl_opts, verify=ssl_verify)
|
|
344
363
|
|
|
345
364
|
try:
|
|
346
365
|
sess = await sock.enter_context(aiohttp.ClientSession(connector=connector, timeout=timeout))
|
|
@@ -374,7 +393,7 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
374
393
|
|
|
375
394
|
async def _httpRequest(self, meth, url, headers=None, json=None, body=None,
|
|
376
395
|
ssl_verify=True, params=None, timeout=300, allow_redirects=True,
|
|
377
|
-
fields=None, proxy=None):
|
|
396
|
+
fields=None, proxy=None, ssl_opts=None):
|
|
378
397
|
meth = await s_stormtypes.tostr(meth)
|
|
379
398
|
url = await s_stormtypes.tostr(url)
|
|
380
399
|
json = await s_stormtypes.toprim(json)
|
|
@@ -386,6 +405,7 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
386
405
|
ssl_verify = await s_stormtypes.tobool(ssl_verify, noneok=True)
|
|
387
406
|
allow_redirects = await s_stormtypes.tobool(allow_redirects)
|
|
388
407
|
proxy = await s_stormtypes.toprim(proxy)
|
|
408
|
+
ssl_opts = await s_stormtypes.toprim(ssl_opts)
|
|
389
409
|
|
|
390
410
|
kwargs = {'allow_redirects': allow_redirects}
|
|
391
411
|
if params:
|
|
@@ -399,12 +419,24 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
399
419
|
if fields:
|
|
400
420
|
if any(['sha256' in field for field in fields]):
|
|
401
421
|
self.runt.confirm(('storm', 'lib', 'axon', 'wput'))
|
|
422
|
+
|
|
423
|
+
kwargs = {}
|
|
424
|
+
axonvers = self.runt.snap.core.axoninfo['synapse']['version']
|
|
425
|
+
if axonvers >= s_stormtypes.AXON_MINVERS_PROXY:
|
|
426
|
+
kwargs['proxy'] = proxy
|
|
427
|
+
|
|
428
|
+
if ssl_opts is not None:
|
|
429
|
+
mesg = f'The ssl_opts argument requires an Axon Synapse version {s_stormtypes.AXON_MINVERS_SSLOPTS}, ' \
|
|
430
|
+
f'but the Axon is running {axonvers}'
|
|
431
|
+
s_version.reqVersion(axonvers, s_stormtypes.AXON_MINVERS_SSLOPTS, mesg=mesg)
|
|
432
|
+
kwargs['ssl_opts'] = ssl_opts
|
|
433
|
+
|
|
402
434
|
axon = self.runt.snap.core.axon
|
|
403
|
-
info = await axon.postfiles(fields, url, headers=headers, params=params,
|
|
404
|
-
|
|
435
|
+
info = await axon.postfiles(fields, url, headers=headers, params=params, method=meth,
|
|
436
|
+
ssl=ssl_verify, timeout=timeout, **kwargs)
|
|
405
437
|
return HttpResp(info)
|
|
406
438
|
|
|
407
|
-
|
|
439
|
+
kwargs['ssl'] = self.runt.snap.core.getCachedSslCtx(opts=ssl_opts, verify=ssl_verify)
|
|
408
440
|
|
|
409
441
|
if proxy is None:
|
|
410
442
|
proxy = await self.runt.snap.core.getConfOpt('http:proxy')
|
|
@@ -413,14 +445,6 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
413
445
|
if proxy:
|
|
414
446
|
connector = aiohttp_socks.ProxyConnector.from_url(proxy)
|
|
415
447
|
|
|
416
|
-
if ssl_verify is False:
|
|
417
|
-
kwargs['ssl'] = False
|
|
418
|
-
elif cadir:
|
|
419
|
-
kwargs['ssl'] = s_common.getSslCtx(cadir)
|
|
420
|
-
else:
|
|
421
|
-
# default aiohttp behavior
|
|
422
|
-
kwargs['ssl'] = None
|
|
423
|
-
|
|
424
448
|
timeout = aiohttp.ClientTimeout(total=timeout)
|
|
425
449
|
|
|
426
450
|
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as sess:
|