diff --git a/internal/dht/node.go b/internal/dht/node.go index 16de262..95a7caf 100644 --- a/internal/dht/node.go +++ b/internal/dht/node.go @@ -2218,6 +2218,7 @@ func (d *DHT) queryNodesParallel(candidates []*Node, targetID NodeID, queryType resultChan := make(chan queryResult, len(candidates)) var wg sync.WaitGroup + var queriedMutex sync.Mutex ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -2233,7 +2234,9 @@ func (d *DHT) queryNodesParallel(candidates []*Node, targetID NodeID, queryType }() key := fmt.Sprintf("%s:%d", node.Addr.IP, node.Addr.Port) + queriedMutex.Lock() queried[key] = true + queriedMutex.Unlock() var discoveredNodes []*Node diff --git a/internal/web/index.html b/internal/web/index.html index 2b6c992..2d3925c 100644 --- a/internal/web/index.html +++ b/internal/web/index.html @@ -1374,22 +1374,23 @@ const baseUrl = window.location.origin; - // Use torrent info hash for magnet if available, otherwise use file hash - let magnetHash = hash; - if (file.torrent_info_hash) { - magnetHash = file.torrent_info_hash; - console.log('Using torrent InfoHash for magnet:', magnetHash); - } else { - console.log('No torrent InfoHash found, using file hash:', magnetHash); - } - const links = { direct: `${baseUrl}/api/download/${hash}`, torrent: `${baseUrl}/api/torrent/${hash}`, - magnet: `magnet:?xt=urn:btih:${magnetHash}&dn=${encodeURIComponent(file.name)}`, stream: file.name.match(/\.(mp4|mkv|avi|mov)$/i) ? `${baseUrl}/api/stream/${hash}` : null }; + // Use the correct magnet link from file data, or fallback to constructed one + if (file.magnet_link) { + links.magnet = file.magnet_link; + console.log('Using API magnet link:', file.magnet_link); + } else { + // Fallback: Use torrent info hash if available, otherwise use file hash + let magnetHash = file.torrent_info_hash || hash; + links.magnet = `magnet:?xt=urn:btih:${magnetHash}&dn=${encodeURIComponent(file.name)}`; + console.log('Using fallback magnet with hash:', magnetHash); + } + showShareModal(file, links); } @@ -1400,26 +1401,43 @@ fileName.textContent = file.name; + // Escape HTML attributes properly and validate links + function escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } + + // Ensure all links are defined + const safeLinks = { + direct: links.direct || '', + torrent: links.torrent || '', + magnet: links.magnet || '' + }; + let linksHTML = `
`; diff --git a/internal/web/static/upload.js b/internal/web/static/upload.js index 7588b29..7421726 100644 --- a/internal/web/static/upload.js +++ b/internal/web/static/upload.js @@ -614,15 +614,6 @@ class GatewayUI { const baseUrl = window.location.origin; - // Use torrent info hash for magnet link if available, otherwise use file hash - let magnetHash = hash; - if (fileData && fileData.torrent_hash) { - magnetHash = fileData.torrent_hash; - console.log('Using torrent InfoHash for magnet:', magnetHash); - } else { - console.log('No torrent InfoHash found, using file hash:', magnetHash); - } - const links = { direct: `${baseUrl}/api/download/${hash}` }; @@ -630,7 +621,17 @@ class GatewayUI { // Only add torrent/magnet links for torrent storage type if (fileData && fileData.storage_type === 'torrent') { links.torrent = `${baseUrl}/api/torrent/${hash}`; - links.magnet = `magnet:?xt=urn:btih:${magnetHash}&dn=${encodeURIComponent(name)}`; + + // Use the correct magnet link from API response, or fallback to constructed one + if (fileData.magnet_link) { + links.magnet = fileData.magnet_link; + console.log('Using API magnet link:', fileData.magnet_link); + } else { + // Fallback: Use torrent info hash if available, otherwise use file hash + let magnetHash = fileData.torrent_hash || hash; + links.magnet = `magnet:?xt=urn:btih:${magnetHash}&dn=${encodeURIComponent(name)}`; + console.log('Using fallback magnet with hash:', magnetHash); + } // Add NIP-71 Nostr link for torrents if available if (fileData.nip71_share_link) { @@ -686,17 +687,30 @@ class GatewayUI { { key: 'nostr', label: 'Share on Nostr', icon: '⚡' } ]; + // Escape HTML attributes properly for Firefox compatibility + function escapeHtml(unsafe) { + return (unsafe || '') + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } + linksContainer.innerHTML = linkTypes .filter(type => links[type.key]) .map(type => { + const linkValue = links[type.key] || ''; + const escapedLink = escapeHtml(linkValue); + if (type.key === 'nostr') { return ` @@ -706,8 +720,8 @@ class GatewayUI { `; diff --git a/torrent-gateway b/torrent-gateway index 2f40dd0..f5cb047 100755 Binary files a/torrent-gateway and b/torrent-gateway differ