GNServer 0.0.0.0.24__py3-none-any.whl → 0.0.0.0.26__py3-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.
GNServer/_client.py CHANGED
@@ -101,7 +101,11 @@ class GNExceptions:
101
101
 
102
102
 
103
103
  from KeyisBClient.gn import GNRequest, GNResponse
104
+ from KeyisBTools import TTLDict
104
105
 
106
+ from KeyisBTools.cryptography.sign import M1
107
+
108
+ m1 = M1()
105
109
 
106
110
 
107
111
 
@@ -117,9 +121,13 @@ class AsyncClient:
117
121
  self._active_connections: Dict[str, QuicClient] = {}
118
122
 
119
123
  self.__dns_client: Optional[AsyncClient] = None
124
+ self._dns_cache: TTLDict = TTLDict()
120
125
 
121
-
122
- async def getCoreDNS(self, domain: str) -> str:
126
+ async def getCoreDNS(self, domain: str, token: Optional[bytes] = None, use_cache: bool = True, keep_alive: bool = False) -> str:
127
+ if use_cache:
128
+ resuilt = self._dns_cache.get(domain)
129
+ if resuilt is not None:
130
+ return resuilt
123
131
 
124
132
  if ':' in domain and domain.split('.')[-1].split(':')[0].isdigit() and domain.split(':')[-1].isdigit():
125
133
  return domain
@@ -128,57 +136,73 @@ class AsyncClient:
128
136
  if self.__dns_client is None:
129
137
  self.__dns_client = AsyncClient()
130
138
 
131
- r1 = await self.__dns_client.request(GNRequest('GET', Url(f'gn://{self.__dns_core__ipv4}/getIp?d={domain}')), keep_alive=False)
139
+ if token is not None:
140
+ payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': m1.sign(token)}}
141
+ else:
142
+ payload = None
143
+
144
+ r1 = await self.__dns_client.request(GNRequest('GET', Url(f'gn://{self.__dns_core__ipv4}/getIp?d={domain}'), payload=payload), keep_alive=keep_alive)
132
145
 
133
146
  if r1.command != 'ok':
134
147
  raise GNExceptions.ConnectionError.dns.data
135
148
 
136
149
  r1_data = r1.payload
137
150
 
138
- return r1_data['ip'] + ':' + str(r1_data['port'])
151
+ result = r1_data['ip'] + ':' + str(r1_data['port'])
152
+
153
+ self._dns_cache.set(domain, result, r1_data.get('ttl'))
154
+
155
+ return result
139
156
 
140
157
  except httpx.TimeoutException:
141
158
  raise GNExceptions.ConnectionError.dns.timeout
142
159
  except:
143
160
  raise GNExceptions.ConnectionError.dns.connection
144
161
 
145
-
162
+ async def getGNDNS(self, domain: str, token: Optional[bytes] = None, use_cache: bool = True, keep_alive: bool = False) -> str:
163
+ if use_cache:
164
+ resuilt = self._dns_cache.get(domain)
165
+ if resuilt is not None:
166
+ return resuilt
146
167
 
147
- async def getGNDNS(self, domain: str, token: Optional[str] = None) -> str:
148
-
149
168
  if ':' in domain and domain.split('.')[-1].split(':')[0].isdigit() and domain.split(':')[-1].isdigit():
150
169
  return domain
151
170
 
152
-
153
171
  if self.__dns_gn__ipv4 is None:
154
172
  self.__dns_gn__ipv4 = await self.getCoreDNS('dns.gn')
155
173
 
156
-
157
174
  try:
158
175
  if self.__dns_client is None:
159
176
  self.__dns_client = AsyncClient()
160
177
 
161
178
  if token is not None:
162
- payload = {'token': token}
179
+ payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': m1.sign(token)}}
163
180
  else:
164
181
  payload = None
165
182
 
166
- r1 = await self.__dns_client.request(GNRequest('GET', Url(f'gn://{self.__dns_gn__ipv4}/getIp?d={domain}'), payload=payload))
183
+ r1 = await self.__dns_client.request(GNRequest('GET', Url(f'gn://{self.__dns_gn__ipv4}/getIp?d={domain}'), payload=payload), keep_alive=keep_alive)
167
184
 
168
185
  if r1.command != 'ok':
169
186
  raise GNExceptions.ConnectionError.dns.data
170
187
 
171
188
  r1_data = r1.payload
172
189
 
173
- return r1_data['ip'] + ':' + str(r1_data['port'])
190
+ result = r1_data['ip'] + ':' + str(r1_data['port'])
191
+
192
+ self._dns_cache.set(domain, result, r1_data.get('ttl'))
193
+
194
+ return result
174
195
 
175
196
  except httpx.TimeoutException:
176
197
  raise GNExceptions.ConnectionError.dns.timeout
177
198
  except:
178
199
  raise GNExceptions.ConnectionError.dns.connection
179
200
 
180
-
181
-
201
+ async def getDNS(self, domain: str, token: Optional[str] = None, use_cache: bool = True, keep_alive: bool = False):
202
+ if domain.endswith(('.core', '.gw', '.gn', '.cdn', '.sys', '.gwis', '.abs')):
203
+ return await self.getCoreDNS(domain=domain, use_cache=use_cache, keep_alive=keep_alive)
204
+ else:
205
+ return await self.getGNDNS(domain=domain, token=token, use_cache=use_cache, keep_alive=keep_alive)
182
206
 
183
207
  def addRequestCallback(self, callback: Callable, name: str):
184
208
  self.__request_callbacks[name] = callback
@@ -199,7 +223,7 @@ class AsyncClient:
199
223
  print('дождались')
200
224
  if c.status == 'active':
201
225
  return c
202
- elif c.status == 'connecting': # если очень дого подключаемся, то кидаем ошибку
226
+ elif c.status == 'connecting': # если очень долго подключаемся, то кидаем ошибку
203
227
  await self.disconnect(domain)
204
228
  raise GNExceptions.ConnectionError.client.timeout
205
229
  elif c.status == 'disconnect':
@@ -215,7 +239,7 @@ class AsyncClient:
215
239
  c.status = 'connecting'
216
240
  self._active_connections[domain] = c
217
241
 
218
- data = await self.getCoreDNS(domain)
242
+ data = await self.getDNS(domain)
219
243
 
220
244
  data = data.split(':')
221
245
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GNServer
3
- Version: 0.0.0.0.24
3
+ Version: 0.0.0.0.26
4
4
  Summary: GNServer
5
5
  Home-page: https://github.com/KeyisB/libs/tree/main/GNServer
6
6
  Author: KeyisB
@@ -0,0 +1,9 @@
1
+ GNServer/___client.py,sha256=hmeUL2Vqp-BnwJeRcLZAaIfRNVxBrRRB_AFk9ofkei4,25459
2
+ GNServer/__init__.py,sha256=V50sMYrrPdOGuI1iJm-SW7izhX-eggDH16AHvtIKjmM,1480
3
+ GNServer/_app.py,sha256=WYK16u-G6TDEMBa3MVaJP3-HzTh4NIcmzsyOdxaSsm0,30664
4
+ GNServer/_client.py,sha256=TMBVo1C0nj7uSbnQHXoQDFMRB9Mb_tIc9C0zrIaOOlc,29869
5
+ gnserver-0.0.0.0.26.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
6
+ gnserver-0.0.0.0.26.dist-info/METADATA,sha256=bC3T30RqCGzP7Y1QSjq_0MRXmD6gVIh0YcSLM3kl-UM,805
7
+ gnserver-0.0.0.0.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ gnserver-0.0.0.0.26.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
9
+ gnserver-0.0.0.0.26.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- from ._models import TTLDict
GNServer/tools/_models.py DELETED
@@ -1,74 +0,0 @@
1
- import time
2
- import asyncio
3
- from typing import Optional
4
-
5
-
6
-
7
- class TTLDict:
8
- def __init__(self, default_ttl: int = 60, cleanup_interval: int = 300):
9
- """
10
- :param default_ttl: TTL по умолчанию (сек), если при записи не указан
11
- :param cleanup_interval: периодическая очистка от просроченных ключей (сек), по умолчанию 5 мин
12
- """
13
-
14
- self._store = {}
15
- self._default_ttl = default_ttl
16
- self._cleanup_interval = cleanup_interval
17
- self._task = None
18
-
19
- def set(self, key, value, ttl: Optional[int] = None):
20
- if ttl is None:
21
- ttl = self._default_ttl
22
- expire_at = time.monotonic() + ttl
23
- self._store[key] = (value, expire_at)
24
-
25
- if self._task is None:
26
- loop = asyncio.get_running_loop()
27
- self._task = loop.create_task(self._cleanup_worker())
28
-
29
- def get(self, key):
30
- now = time.monotonic()
31
- item = self._store.get(key)
32
- if not item:
33
- return None
34
-
35
- value, expire_at = item
36
- if expire_at < now:
37
- del self._store[key]
38
- return None
39
- return value
40
-
41
- def __setitem__(self, key, value):
42
- self.set(key, value, self._default_ttl)
43
-
44
- def __getitem__(self, key):
45
- return self.get(key)
46
-
47
- def __contains__(self, key):
48
- return self.get(key) is not None
49
-
50
- def __len__(self):
51
- return len(self._store)
52
-
53
- def __repr__(self):
54
- return f"<TTLDict size={len(self._store)}>"
55
-
56
- async def _cleanup_worker(self):
57
- while True:
58
- await asyncio.sleep(self._cleanup_interval)
59
- self.cleanup()
60
-
61
- def cleanup(self):
62
- """Удалить все просроченные ключи"""
63
- now = time.monotonic()
64
- expired = [k for k, (_, exp) in self._store.items() if exp < now]
65
- for k in expired:
66
- self._store.pop(k, None)
67
-
68
- async def stop(self):
69
- """Остановить фон очистки"""
70
- self._task.cancel()
71
- try:
72
- await self._task
73
- except asyncio.CancelledError:
74
- pass
@@ -1,11 +0,0 @@
1
- GNServer/___client.py,sha256=hmeUL2Vqp-BnwJeRcLZAaIfRNVxBrRRB_AFk9ofkei4,25459
2
- GNServer/__init__.py,sha256=V50sMYrrPdOGuI1iJm-SW7izhX-eggDH16AHvtIKjmM,1480
3
- GNServer/_app.py,sha256=WYK16u-G6TDEMBa3MVaJP3-HzTh4NIcmzsyOdxaSsm0,30664
4
- GNServer/_client.py,sha256=9zw3DbkVHjNr-DNhlLV92r2sNJ-VY9Ahc4QjP1sUCII,28443
5
- GNServer/tools/__init__.py,sha256=itqkS5iBB2GEHqz8H-htqgd55rUi6utnuKVAzBBByCM,28
6
- GNServer/tools/_models.py,sha256=1V94cbNHQGAl5l9DJbGvvkm1gmsgTEMgkjzlnZk8ymw,2264
7
- gnserver-0.0.0.0.24.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
8
- gnserver-0.0.0.0.24.dist-info/METADATA,sha256=kVi7DeXW2P6Zgk8y3ZcUuDNFiS_gRvrsR8exkZPJ3vM,805
9
- gnserver-0.0.0.0.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- gnserver-0.0.0.0.24.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
11
- gnserver-0.0.0.0.24.dist-info/RECORD,,