GNServer 0.0.0.0.28__py3-none-any.whl → 0.0.0.0.30__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/_app.py CHANGED
@@ -45,105 +45,121 @@ console = logging.StreamHandler()
45
45
  console.setLevel(logging.INFO)
46
46
  console.setFormatter(logging.Formatter("[GNServer] %(name)s: %(levelname)s: %(message)s"))
47
47
 
48
-
48
+ PayloadType = Optional[Union[int, str, list, tuple, dict]]
49
49
 
50
50
  class _BaseEXception(Exception):
51
- def __init__(self, code: str, message=""):
51
+ def __init__(self, code: str, name="", message: Optional[str] = None, payload: PayloadType = None):
52
52
  self._code = code
53
+ self._name = name
53
54
  self._message = message
55
+ self._payload = payload
54
56
 
55
57
  def assembly(self):
56
58
  """
57
59
  Собирает ошибку в ответ типа `GNResponse`
58
60
  """
59
- return gn.GNResponse(f'gn:error:{self._code}', payload={'msg': self._message})
61
+ payload: dict = {'name': self._name}
62
+
63
+ if self._message is not None:
64
+ payload['message'] = self._message
65
+
66
+ if self._payload is not None:
67
+ payload['payload'] = self._payload
68
+
69
+ return gn.GNResponse(f'gn:error:{self._code}', payload=payload)
60
70
 
61
71
 
62
72
  class GNExceptions:
63
73
  class UnprocessableEntity(_BaseEXception):
64
- def __init__(self):
74
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
65
75
  """
66
76
  # Некорректные данные
67
77
  """
68
- super().__init__('422', "Unprocessable Entity")
78
+ super().__init__('422', "Unprocessable Entity", message=message, payload=payload)
69
79
 
70
80
  class BadRequest(_BaseEXception):
71
- def __init__(self):
81
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
72
82
  """
73
83
  # неправильного синтаксис url или параметров
74
84
  """
75
- super().__init__('400', "Bad Request")
85
+ super().__init__('400', "Bad Request", message=message, payload=payload)
76
86
 
77
87
  class Forbidden(_BaseEXception):
78
- def __init__(self):
88
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
79
89
  """
80
90
  # Доступ запрещён, даже при наличии авторизации
81
91
  """
82
- super().__init__('403', "Forbidden")
83
-
92
+ super().__init__('403', "Forbidden", message=message, payload=payload)
93
+
94
+ class Unauthorized(_BaseEXception):
95
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
96
+ """
97
+ # Требуется авторизация
98
+ """
99
+ super().__init__('401', "Unauthorized", message=message, payload=payload)
84
100
 
85
101
  class NotFound(_BaseEXception):
86
- def __init__(self):
102
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
87
103
  """
88
104
  # Ресурс не найден
89
105
  """
90
- super().__init__('404', "Not Found")
106
+ super().__init__('404', "Not Found", message=message, payload=payload)
91
107
 
92
108
 
93
109
  class MethodNotAllowed(_BaseEXception):
94
- def __init__(self):
110
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
95
111
  """
96
112
  # Метод запроса не поддерживается данным ресурсом
97
113
  """
98
- super().__init__('405', "Method Not Allowed")
114
+ super().__init__('405', "Method Not Allowed", message=message, payload=payload)
99
115
 
100
116
 
101
117
  class Conflict(_BaseEXception):
102
- def __init__(self):
118
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
103
119
  """
104
120
  # Конфликт состояния ресурса (например, дубликат)
105
121
  """
106
- super().__init__('409', "Conflict")
122
+ super().__init__('409', "Conflict", message=message, payload=payload)
107
123
 
108
124
 
109
125
  class InternalServerError(_BaseEXception):
110
- def __init__(self):
126
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
111
127
  """
112
128
  # Внутренняя ошибка сервера
113
129
  """
114
- super().__init__('500', "Internal Server Error")
130
+ super().__init__('500', "Internal Server Error", message=message, payload=payload)
115
131
 
116
132
 
117
133
  class NotImplemented(_BaseEXception):
118
- def __init__(self):
134
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
119
135
  """
120
136
  # Метод или функционал ещё не реализован
121
137
  """
122
- super().__init__('501', "Not Implemented")
138
+ super().__init__('501', "Not Implemented", message=message, payload=payload)
123
139
 
124
140
 
125
141
  class BadGateway(_BaseEXception):
126
- def __init__(self):
142
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
127
143
  """
128
144
  # Ошибка шлюза или прокси при обращении к апстриму
129
145
  """
130
- super().__init__('502', "Bad Gateway")
146
+ super().__init__('502', "Bad Gateway", message=message, payload=payload)
131
147
 
132
148
 
133
149
  class ServiceUnavailable(_BaseEXception):
134
- def __init__(self):
150
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
135
151
  """
136
152
  # Сервис временно недоступен
137
153
  """
138
- super().__init__('503', "Service Unavailable")
154
+ super().__init__('503', "Service Unavailable", message=message, payload=payload)
139
155
 
140
156
 
141
157
  class GatewayTimeout(_BaseEXception):
142
- def __init__(self):
158
+ def __init__(self, message: Optional[str] = None, payload: PayloadType = None):
143
159
  """
144
160
  # Таймаут при обращении к апстриму
145
161
  """
146
- super().__init__('504', "Gateway Timeout")
162
+ super().__init__('504', "Gateway Timeout", message=message, payload=payload)
147
163
 
148
164
  def guess_type(filename: str) -> str:
149
165
  """
GNServer/_client.py CHANGED
@@ -1,34 +1,36 @@
1
-
2
- import os
3
1
  import httpx
4
2
  import asyncio
5
- import typing as _typing
6
3
  import logging as logging2
7
4
  from typing import Union, List, Dict, Tuple, Optional
8
5
  import datetime
9
6
  logging2.basicConfig(level=logging2.INFO)
10
-
11
7
  from KeyisBLogging import logging
12
- from typing import Dict, List, Tuple, Optional, cast, AsyncGenerator, Callable, Literal
8
+ from typing import Dict, List, Tuple, Optional, AsyncGenerator, Callable, Literal, AsyncIterable
13
9
  from itertools import count
14
10
  from aioquic.asyncio.client import connect
15
11
  from aioquic.asyncio.protocol import QuicConnectionProtocol
16
- from aioquic.h3.connection import H3_ALPN, H3Connection
17
- from aioquic.h3.events import DataReceived, DatagramReceived, H3Event, HeadersReceived
18
12
  from aioquic.quic.configuration import QuicConfiguration
19
13
  from aioquic.quic.events import QuicEvent
14
+ from aioquic.asyncio.protocol import QuicConnectionProtocol
15
+ from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset
16
+ import asyncio
17
+ from collections import deque
18
+ from typing import Dict, Deque, Tuple, Optional
19
+
20
+ import asyncio
21
+ import time
22
+ from collections import deque
23
+ from itertools import count
24
+ from typing import Deque, Dict, Optional, Tuple, Union
25
+
26
+ from aioquic.quic.configuration import QuicConfiguration
27
+ from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset, ConnectionTerminated
20
28
 
21
29
 
22
30
  import time
23
- import json, ssl, asyncio, struct, base64, hashlib
24
31
  from typing import Any, Dict, Optional
25
- import websockets
26
32
 
27
- from cryptography.hazmat.primitives.ciphers.aead import AESGCM
28
- import os
29
- import msgpack
30
33
  import logging
31
- from httpx import Request, Headers, URL
32
34
  logging.basicConfig(level=logging.DEBUG)
33
35
  logging.getLogger("websockets").setLevel(logging.DEBUG)
34
36
 
@@ -103,9 +105,15 @@ class GNExceptions:
103
105
  from KeyisBClient.gn import GNRequest, GNResponse
104
106
  from KeyisBTools import TTLDict
105
107
 
106
- from KeyisBTools.cryptography.sign import M1
108
+ from KeyisBTools.cryptography.sign import S1
109
+
110
+ s1 = S1()
107
111
 
108
- m1 = M1()
112
+
113
+ async def chain_async(first_item, rest: AsyncIterable) -> AsyncGenerator:
114
+ yield first_item
115
+ async for x in rest:
116
+ yield x
109
117
 
110
118
 
111
119
 
@@ -137,7 +145,7 @@ class AsyncClient:
137
145
  self.__dns_client = AsyncClient()
138
146
 
139
147
  if token is not None:
140
- payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': m1.sign(token)}}
148
+ payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': s1.sign(token)}}
141
149
  else:
142
150
  payload = None
143
151
 
@@ -146,6 +154,9 @@ class AsyncClient:
146
154
  if r1.command != 'ok':
147
155
  raise GNExceptions.ConnectionError.dns.data
148
156
 
157
+ if r1.payload is None:
158
+ raise GNExceptions.ConnectionError.dns.data
159
+
149
160
  r1_data = r1.payload
150
161
 
151
162
  result = r1_data['ip'] + ':' + str(r1_data['port'])
@@ -176,7 +187,7 @@ class AsyncClient:
176
187
  self.__dns_client = AsyncClient()
177
188
 
178
189
  if token is not None:
179
- payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': m1.sign(token)}}
190
+ payload = {'sign': {'alg': 'KeyisB-c-s-m1', 'data': s1.sign(token)}}
180
191
  else:
181
192
  payload = None
182
193
 
@@ -185,6 +196,10 @@ class AsyncClient:
185
196
  if r1.command != 'ok':
186
197
  raise GNExceptions.ConnectionError.dns.data
187
198
 
199
+
200
+ if r1.payload is None:
201
+ raise GNExceptions.ConnectionError.dns.data
202
+
188
203
  r1_data = r1.payload
189
204
 
190
205
  result = r1_data['ip'] + ':' + str(r1_data['port'])
@@ -198,7 +213,7 @@ class AsyncClient:
198
213
  except:
199
214
  raise GNExceptions.ConnectionError.dns.connection
200
215
 
201
- async def getDNS(self, domain: str, token: Optional[str] = None, use_cache: bool = True, keep_alive: bool = False):
216
+ async def getDNS(self, domain: str, token: Optional[bytes] = None, use_cache: bool = True, keep_alive: bool = False):
202
217
  if domain.endswith(('.core', '.gw', '.gn', '.cdn', '.sys', '.gwis', '.abs')):
203
218
  return await self.getCoreDNS(domain=domain, use_cache=use_cache, keep_alive=keep_alive)
204
219
  else:
@@ -248,10 +263,10 @@ class AsyncClient:
248
263
  def f(domain):
249
264
  self._active_connections.pop(domain)
250
265
 
251
- c._disconnect_signal = f
252
- c._domain = domain
266
+ c._disconnect_signal = f # type: ignore
267
+ c._domain = domain # type: ignore
253
268
 
254
- await c.connect(data[0], data[1], keep_alive=keep_alive)
269
+ await c.connect(data[0], int(data[1]), keep_alive=keep_alive)
255
270
  await c.connect_future
256
271
 
257
272
  return c
@@ -285,23 +300,37 @@ class AsyncClient:
285
300
 
286
301
  return r
287
302
 
288
- # else:
289
- # async def wrapped(request) -> AsyncGenerator[GNRequest, None]:
290
- # async for req in request:
291
- # if req.gn_protocol is None:
292
- # req.setGNProtocol(self.__current_session['protocols'][0])
293
- # req._stream = True
294
-
295
- # for f in self.__request_callbacks.values():
296
- # asyncio.create_task(f(req))
297
-
298
- # yield req
299
- # r = await self.client.asyncRequest(wrapped(request))
300
-
301
- # for f in self.__response_callbacks.values():
302
- # asyncio.create_task(f(r))
303
-
304
- # return r
303
+ else:
304
+ c: Optional[QuicClient] = None
305
+
306
+ async def wrapped(request) -> AsyncGenerator[GNRequest, None]:
307
+ async for req in request:
308
+ if req.gn_protocol is None:
309
+ req.setGNProtocol(self.__current_session['protocols'][0])
310
+ req._stream = True
311
+
312
+ for f in self.__request_callbacks.values():
313
+ asyncio.create_task(f(req))
314
+
315
+ nonlocal c
316
+ if c is None: # инициализируем при первом req
317
+ c = await self.connect(request.url.hostname, restart_connection, reconnect_wait, keep_alive=keep_alive)
318
+
319
+ yield req
320
+
321
+ gen = wrapped(request)
322
+ first_req = await gen.__anext__()
323
+
324
+ if c is None:
325
+ raise GNExceptions.ConnectionError.client.data
326
+
327
+ r = await c.asyncRequest(chain_async(first_req, gen))
328
+
329
+ for f in self.__response_callbacks.values():
330
+ asyncio.create_task(f(r))
331
+
332
+ return r
333
+
305
334
 
306
335
  async def requestStream(self, request: Union[GNRequest, AsyncGenerator[GNRequest, Any]]) -> AsyncGenerator[GNResponse, None]:
307
336
  """
@@ -338,24 +367,6 @@ class AsyncClient:
338
367
 
339
368
  yield response
340
369
 
341
- from aioquic.asyncio.protocol import QuicConnectionProtocol
342
- from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset
343
- from aioquic.quic.connection import END_STATES
344
- import asyncio
345
- from collections import deque
346
- from typing import Dict, Deque, Tuple, Optional, List
347
-
348
- import asyncio
349
- import time
350
- from collections import deque
351
- from dataclasses import dataclass
352
- from itertools import count
353
- from typing import Deque, Dict, Optional, Tuple, Union
354
-
355
- from aioquic.quic.configuration import QuicConfiguration
356
- from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset, ConnectionTerminated
357
-
358
-
359
370
  class RawQuicClient(QuicConnectionProtocol):
360
371
 
361
372
  SYS_RATIO_NUM = 9 # SYS 9/10
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GNServer
3
- Version: 0.0.0.0.28
3
+ Version: 0.0.0.0.30
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=lP2YEChUHDWB8Ig3711hgsccwKTko8a3nlgT2EFmpwY,32494
4
+ GNServer/_client.py,sha256=7D4JVgjjUqFN7RVzcOltMN_KyqV6Zfhe7F0Hz3OCIPk,30182
5
+ gnserver-0.0.0.0.30.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
6
+ gnserver-0.0.0.0.30.dist-info/METADATA,sha256=8KCKYQXhaFF2d_P8Y-QK1dFDLjnus723FehM0b4N4r8,833
7
+ gnserver-0.0.0.0.30.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ gnserver-0.0.0.0.30.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
9
+ gnserver-0.0.0.0.30.dist-info/RECORD,,
@@ -1,9 +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=CZQ1EM-m0FsMTOVyjNIMeDvS0B1MtZMsGV0O1deMyTc,30778
4
- GNServer/_client.py,sha256=uF5h5pu0noJ1uNWSdC-kxGvBUwUUmyyAQTt_altNJ_g,29861
5
- gnserver-0.0.0.0.28.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
6
- gnserver-0.0.0.0.28.dist-info/METADATA,sha256=lrvZv_aAc4ggrW0gIWvQerVUexDwivGvyVsNWoDr-cQ,833
7
- gnserver-0.0.0.0.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- gnserver-0.0.0.0.28.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
9
- gnserver-0.0.0.0.28.dist-info/RECORD,,