weed-cli 1.1.2__tar.gz → 1.1.4__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.4
2
2
  Name: weed-cli
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel
5
5
  License: MIT
6
6
  Keywords: p2p,video,censorship-resistant,discovery,dht,kademlia,nat-traversal
@@ -197,6 +197,29 @@ def load_leaves(archive_dir, root_hash):
197
197
  return json.load(f)
198
198
 
199
199
 
200
+ def _graceful_close(sock):
201
+ """Plain sock.close() on an SSL-wrapped socket tears down the TCP
202
+ connection without ever sending a TLS close_notify -- fine for the
203
+ plaintext direct-connect path, but every tunneled connection here is
204
+ TLS all the way to Fly's edge (fly.tunnel-relay.toml terminates TLS
205
+ there, handlers = ["tls"]), and Fly's proxy logs that abrupt cutoff as
206
+ 'fly-proxy-p2p/tls/tcp-backhaul: unexpected end of file' even though
207
+ the app-level protocol already got every byte it needed by then.
208
+ unwrap() sends the close_notify so the edge sees a clean shutdown
209
+ instead of a truncation."""
210
+ if isinstance(sock, ssl.SSLSocket):
211
+ try:
212
+ # unwrap() blocks waiting for the peer's own close_notify --
213
+ # cap that wait so a peer that's already gone can't leak this
214
+ # thread forever, same reasoning as the timeouts already used
215
+ # for connect_via_tunnel/_connect_tunnel_socket
216
+ sock.settimeout(5)
217
+ sock = sock.unwrap()
218
+ except (OSError, ssl.SSLError, ValueError):
219
+ pass
220
+ sock.close()
221
+
222
+
200
223
  def serve_session(conn, entries_by_hash, default_hash, price):
201
224
  """Handle every command on one connection, not just one — a download
202
225
  needs INFO + LEAVES + one FETCH per chunk (thousands, for a real
@@ -213,7 +236,7 @@ def serve_session(conn, entries_by_hash, default_hash, price):
213
236
  tunnel path (already scoped to one file before this function runs)
214
237
  keep working unchanged."""
215
238
  selected = default_hash
216
- with conn:
239
+ try:
217
240
  while True:
218
241
  line = recv_line(conn)
219
242
  if not line:
@@ -256,6 +279,8 @@ def serve_session(conn, entries_by_hash, default_hash, price):
256
279
  conn.sendall((f'DATA {base64.b64encode(data).decode()}\n').encode())
257
280
  elif parts[0] == 'PRICE':
258
281
  conn.sendall(f'PRICE {price}\n'.encode())
282
+ finally:
283
+ _graceful_close(conn)
259
284
 
260
285
 
261
286
  def run_host_server(archive_dir, file_name, port, bind_host='0.0.0.0', quiet=False, price=0):
@@ -409,7 +434,7 @@ class HostConnection:
409
434
  return recv_line(self.sock)
410
435
 
411
436
  def close(self):
412
- self.sock.close()
437
+ _graceful_close(self.sock)
413
438
 
414
439
  def __enter__(self):
415
440
  return self
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weed-cli"
7
- version = "1.1.2"
7
+ version = "1.1.4"
8
8
  description = "Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -128,7 +128,8 @@ def _rehydrate_jobs_from_library():
128
128
  _jobs[rec['job_id']] = {
129
129
  'status': 'done', 'idx': 0, 'n_chunks': None,
130
130
  'content_hash': content_hash, 'path': rec['path'],
131
- 'title': rec.get('title'), 'error': None,
131
+ 'title': rec.get('title'), 'size': rec.get('size'), 'bps': rec.get('bps'),
132
+ 'error': None,
132
133
  }
133
134
  _lan_url = None # set once in run_web_ui() -- the base URL a phone on the
134
135
  # same LAN can actually reach this server at, or None if
@@ -208,14 +209,18 @@ def _run_download_job(job_id, content_hash, relay_urls, out_path, k, use_lightni
208
209
  _jobs[job_id].update(idx=idx, n_chunks=n_chunks)
209
210
 
210
211
  try:
212
+ t0 = time.time()
211
213
  with _quiet():
212
214
  path = node.download_with_auction(content_hash, relay_urls, out_path=out_path, k=k,
213
215
  use_lightning=use_lightning, on_progress=on_progress)
216
+ elapsed = time.time() - t0
217
+ size = os.path.getsize(path)
218
+ bps = size / elapsed if elapsed > 0 else None
214
219
  with _lock:
215
- _jobs[job_id].update(status='done', path=path)
220
+ _jobs[job_id].update(status='done', path=path, size=size, bps=bps)
216
221
  _library['downloads'][content_hash] = {
217
222
  'content_hash': content_hash, 'job_id': job_id, 'path': path,
218
- 'title': title, 'downloaded_at': time.time(),
223
+ 'title': title, 'downloaded_at': time.time(), 'size': size, 'bps': bps,
219
224
  }
220
225
  _save_library()
221
226
  except SystemExit as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weed-cli
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel
5
5
  License: MIT
6
6
  Keywords: p2p,video,censorship-resistant,discovery,dht,kademlia,nat-traversal
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes