wisp-python 0.4.2__tar.gz → 0.5.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wisp-python
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: An implementation of a Wisp proxy server in Python
5
5
  Author: ading2210
6
6
  Project-URL: Homepage, https://github.com/MercuryWorkshop/wisp-server-python
@@ -38,8 +38,9 @@ pip3 install wisp-python
38
38
  To start the server, run `python3 -m wisp.server`. The program accepts the following arguments:
39
39
  ```
40
40
  usage: wisp-server-python [-h] [--host HOST] [--port PORT] [--static STATIC] [--limits] [--bandwidth BANDWIDTH] [--connections CONNECTIONS] [--window WINDOW] [--allow-loopback] [--allow-private]
41
+ [--log-level LOG_LEVEL]
41
42
 
42
- A Wisp server implementation, written in Python (v0.4.1)
43
+ A Wisp server implementation, written in Python (v0.5.0)
43
44
 
44
45
  options:
45
46
  -h, --help show this help message and exit
@@ -54,6 +55,8 @@ options:
54
55
  --window WINDOW Fixed window length for rate limits, in seconds.
55
56
  --allow-loopback Allow connections to loopback IP addresses.
56
57
  --allow-private Allow connections to private IP addresses.
58
+ --log-level LOG_LEVEL
59
+ The log level (either debug, info, warning, error, or critical).
57
60
  ```
58
61
 
59
62
  ## Roadmap:
@@ -21,8 +21,9 @@ pip3 install wisp-python
21
21
  To start the server, run `python3 -m wisp.server`. The program accepts the following arguments:
22
22
  ```
23
23
  usage: wisp-server-python [-h] [--host HOST] [--port PORT] [--static STATIC] [--limits] [--bandwidth BANDWIDTH] [--connections CONNECTIONS] [--window WINDOW] [--allow-loopback] [--allow-private]
24
+ [--log-level LOG_LEVEL]
24
25
 
25
- A Wisp server implementation, written in Python (v0.4.1)
26
+ A Wisp server implementation, written in Python (v0.5.0)
26
27
 
27
28
  options:
28
29
  -h, --help show this help message and exit
@@ -37,6 +38,8 @@ options:
37
38
  --window WINDOW Fixed window length for rate limits, in seconds.
38
39
  --allow-loopback Allow connections to loopback IP addresses.
39
40
  --allow-private Allow connections to private IP addresses.
41
+ --log-level LOG_LEVEL
42
+ The log level (either debug, info, warning, error, or critical).
40
43
  ```
41
44
 
42
45
  ## Roadmap:
@@ -11,7 +11,7 @@ package-dir = {"" = "src"}
11
11
 
12
12
  [project]
13
13
  name = "wisp-python"
14
- version = "0.4.2"
14
+ version = "0.5.0"
15
15
  authors = [
16
16
  {name="ading2210"},
17
17
  ]
@@ -1,3 +1,2 @@
1
1
  from wisp import server
2
-
3
- version = "0.4.2"
2
+ version = "0.5.0"
@@ -1,5 +1,7 @@
1
1
  import argparse
2
2
  import asyncio
3
+ import logging
4
+
3
5
  try:
4
6
  import uvloop
5
7
  use_uvloop = True
@@ -24,10 +26,17 @@ if __name__ == "__main__":
24
26
  parser.add_argument("--window", default=60, help="Fixed window length for rate limits, in seconds.")
25
27
  parser.add_argument("--allow-loopback", action="store_true",help="Allow connections to loopback IP addresses.")
26
28
  parser.add_argument("--allow-private", action="store_true", help="Allow connections to private IP addresses.")
29
+ parser.add_argument("--log-level", default="info", help="The log level (either debug, info, warning, error, or critical).")
27
30
  args = parser.parse_args()
28
31
 
32
+ logging.basicConfig(
33
+ format="[%(asctime)s] %(levelname)-8s %(message)s",
34
+ level=getattr(logging, args.log_level.upper()),
35
+ datefmt="%Y/%m/%d - %H:%M:%S"
36
+ )
37
+
29
38
  if use_uvloop:
30
39
  uvloop.run(wisp.server.http.main(args))
31
40
  else:
32
- print("Warning: Importing uvloop failed. Falling back to asyncio, which is slower.")
41
+ logging.error("Importing uvloop failed. Falling back to asyncio, which is slower.")
33
42
  asyncio.run(wisp.server.http.main(args))
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import struct
3
3
  import os
4
+ import logging
4
5
 
5
6
  from websockets.exceptions import ConnectionClosed
6
7
 
@@ -32,7 +33,7 @@ class WSProxyConnection:
32
33
  self.conn = net.TCPConnection(self.tcp_host, self.tcp_port)
33
34
  await self.conn.connect()
34
35
  except Exception as e:
35
- print(f"Creating a WSProxy stream to {self.tcp_host}:{self.tcp_port} failed: {e}")
36
+ logging.info(f"Creating a WSProxy stream to {self.tcp_host}:{self.tcp_port} failed: {e}")
36
37
  await self.ws.close()
37
38
 
38
39
  async def handle_ws(self):
@@ -59,11 +60,12 @@ class WSProxyConnection:
59
60
  await self.ws.close()
60
61
 
61
62
  class WispConnection:
62
- def __init__(self, ws, path, client_ip):
63
+ def __init__(self, ws, path, client_ip, id=None):
63
64
  self.ws = ws
64
65
  self.path = path
65
66
  self.active_streams = {}
66
67
  self.client_ip = client_ip
68
+ self.id = id
67
69
 
68
70
  #send the initial CONTINUE packet
69
71
  async def setup(self):
@@ -74,6 +76,7 @@ class WispConnection:
74
76
  async def new_stream(self, stream_id, payload):
75
77
  stream_type, destination_port = struct.unpack(connect_format, payload[:3])
76
78
  hostname = payload[3:].decode()
79
+ logging.debug(f"({self.id}) Creating a new stream to {hostname}:{destination_port}")
77
80
 
78
81
  #rate limited
79
82
  stream_count = ratelimit.get_client_attr(self.client_ip, "streams")
@@ -94,7 +97,7 @@ class WispConnection:
94
97
  await connection.connect()
95
98
 
96
99
  except Exception as e:
97
- print(f"Creating a new stream to {hostname}:{destination_port} failed: {e}")
100
+ logging.warn(f"({self.id}) Creating a new stream to {hostname}:{destination_port} failed: {e}")
98
101
  await self.send_close_packet(stream_id, 0x42)
99
102
  self.close_stream(stream_id)
100
103
  return
@@ -112,7 +115,7 @@ class WispConnection:
112
115
  await target_func(*args, **kwargs)
113
116
  except asyncio.CancelledError as e:
114
117
  raise e
115
-
118
+
116
119
  async def stream_ws_to_tcp(self, stream_id):
117
120
  #this infinite loop should get killed by the task.cancel call later on
118
121
  while True:
@@ -137,7 +140,7 @@ class WispConnection:
137
140
  try:
138
141
  data = await stream["conn"].recv()
139
142
  except Exception as e:
140
- print(f"Receiving data from stream failed: {e}")
143
+ logging.warn(f"({self.id}) Receiving data from stream failed: {e}")
141
144
  await self.send_close_packet(stream_id, 0x03)
142
145
  self.close_stream(stream_id)
143
146
  return
@@ -163,7 +166,8 @@ class WispConnection:
163
166
  if not stream_id in self.active_streams:
164
167
  return #stream already closed
165
168
  stream = self.active_streams[stream_id]
166
- stream["conn"].close()
169
+ if stream["conn"]:
170
+ stream["conn"].close()
167
171
 
168
172
  #kill the running tasks associated with this stream
169
173
  if not stream["connect_task"].done():
@@ -181,6 +185,12 @@ class WispConnection:
181
185
  data = await self.ws.recv()
182
186
  except ConnectionClosed:
183
187
  break
188
+ except Exception as e:
189
+ logging.warn(f"({self.id}) Receiving data from websocket failed: {e}")
190
+ break
191
+
192
+ if not isinstance(data, bytes):
193
+ continue #ignore non binary frames
184
194
 
185
195
  #implement bandwidth limits
186
196
  await ratelimit.limit_client_bandwidth(self.client_ip, len(data), "ws")
@@ -1,6 +1,8 @@
1
1
  import asyncio
2
2
  import pathlib
3
3
  import mimetypes
4
+ import logging
5
+ import random
4
6
 
5
7
  from websockets.server import serve
6
8
 
@@ -14,11 +16,12 @@ async def connection_handler(websocket, path):
14
16
  if client_ip == "127.0.0.1" and "X-Real-IP" in websocket.request_headers:
15
17
  client_ip = websocket.request_headers["X-Real-IP"]
16
18
 
17
- print(f"incoming connection on {path} from {client_ip}")
19
+ conn_id = "".join(random.choices("1234567890abcdef", k=8))
20
+ logging.info(f"({conn_id}) incoming connection on {path} from {client_ip}")
18
21
  ratelimit.inc_client_attr(client_ip, "streams")
19
22
 
20
23
  if path.endswith("/"):
21
- wisp_conn = connection.WispConnection(websocket, path, client_ip)
24
+ wisp_conn = connection.WispConnection(websocket, path, client_ip, conn_id)
22
25
  await wisp_conn.setup()
23
26
  ws_handler = asyncio.create_task(wisp_conn.handle_ws())
24
27
  await asyncio.gather(ws_handler)
@@ -57,18 +60,18 @@ async def static_handler(path, request_headers):
57
60
 
58
61
  async def main(args):
59
62
  global static_path
60
- print(f"running wisp-server-python v{wisp.version}")
63
+ logging.info(f"running wisp-server-python v{wisp.version}")
61
64
 
62
65
  if args.static:
63
66
  static_path = pathlib.Path(args.static).resolve()
64
67
  request_handler = static_handler
65
68
  mimetypes.init()
66
- print(f"serving static files from {static_path}")
69
+ logging.info(f"serving static files from {static_path}")
67
70
  else:
68
71
  request_handler = None
69
72
 
70
73
  if args.limits:
71
- print("enabled rate limits")
74
+ logging.info("enabled rate limits")
72
75
  ratelimit.enabled = True
73
76
  ratelimit.connections_limit = int(args.connections)
74
77
  ratelimit.bandwidth_limit = float(args.bandwidth)
@@ -78,6 +81,10 @@ async def main(args):
78
81
  net.block_private = not args.allow_private
79
82
 
80
83
  limit_task = asyncio.create_task(ratelimit.reset_limits_timer())
81
- print(f"listening on {args.host}:{args.port}")
84
+ logging.info(f"listening on {args.host}:{args.port}")
85
+
86
+ ws_logger = logging.getLogger("websockets")
87
+ ws_logger.setLevel(logging.WARN)
88
+
82
89
  async with serve(connection_handler, args.host, int(args.port), process_request=request_handler, compression=None):
83
90
  await asyncio.Future()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wisp-python
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: An implementation of a Wisp proxy server in Python
5
5
  Author: ading2210
6
6
  Project-URL: Homepage, https://github.com/MercuryWorkshop/wisp-server-python
@@ -38,8 +38,9 @@ pip3 install wisp-python
38
38
  To start the server, run `python3 -m wisp.server`. The program accepts the following arguments:
39
39
  ```
40
40
  usage: wisp-server-python [-h] [--host HOST] [--port PORT] [--static STATIC] [--limits] [--bandwidth BANDWIDTH] [--connections CONNECTIONS] [--window WINDOW] [--allow-loopback] [--allow-private]
41
+ [--log-level LOG_LEVEL]
41
42
 
42
- A Wisp server implementation, written in Python (v0.4.1)
43
+ A Wisp server implementation, written in Python (v0.5.0)
43
44
 
44
45
  options:
45
46
  -h, --help show this help message and exit
@@ -54,6 +55,8 @@ options:
54
55
  --window WINDOW Fixed window length for rate limits, in seconds.
55
56
  --allow-loopback Allow connections to loopback IP addresses.
56
57
  --allow-private Allow connections to private IP addresses.
58
+ --log-level LOG_LEVEL
59
+ The log level (either debug, info, warning, error, or critical).
57
60
  ```
58
61
 
59
62
  ## Roadmap:
File without changes
File without changes