DHT Race crash fix
This commit is contained in:
parent
2b7f44b2d7
commit
1472fb7cfd
@ -2218,6 +2218,7 @@ func (d *DHT) queryNodesParallel(candidates []*Node, targetID NodeID, queryType
|
|||||||
|
|
||||||
resultChan := make(chan queryResult, len(candidates))
|
resultChan := make(chan queryResult, len(candidates))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
var queriedMutex sync.Mutex
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
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)
|
key := fmt.Sprintf("%s:%d", node.Addr.IP, node.Addr.Port)
|
||||||
|
queriedMutex.Lock()
|
||||||
queried[key] = true
|
queried[key] = true
|
||||||
|
queriedMutex.Unlock()
|
||||||
|
|
||||||
var discoveredNodes []*Node
|
var discoveredNodes []*Node
|
||||||
|
|
||||||
|
@ -1374,22 +1374,23 @@
|
|||||||
|
|
||||||
const baseUrl = window.location.origin;
|
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 = {
|
const links = {
|
||||||
direct: `${baseUrl}/api/download/${hash}`,
|
direct: `${baseUrl}/api/download/${hash}`,
|
||||||
torrent: `${baseUrl}/api/torrent/${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
|
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);
|
showShareModal(file, links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1400,26 +1401,43 @@
|
|||||||
|
|
||||||
fileName.textContent = file.name;
|
fileName.textContent = file.name;
|
||||||
|
|
||||||
|
// Escape HTML attributes properly and validate links
|
||||||
|
function escapeHtml(unsafe) {
|
||||||
|
return unsafe
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.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 = `
|
let linksHTML = `
|
||||||
<div class="share-link">
|
<div class="share-link">
|
||||||
<label>Direct Download:</label>
|
<label>Direct Download:</label>
|
||||||
<div class="link-row">
|
<div class="link-row">
|
||||||
<input type="text" value="${links.direct}" readonly onclick="this.select()">
|
<input type="text" value="${escapeHtml(safeLinks.direct)}" readonly onclick="this.select()">
|
||||||
<button onclick="copyToClipboard('${links.direct}')">Copy</button>
|
<button onclick="copyToClipboard(\`${escapeHtml(safeLinks.direct)}\`)">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="share-link">
|
<div class="share-link">
|
||||||
<label>Torrent File:</label>
|
<label>Torrent File:</label>
|
||||||
<div class="link-row">
|
<div class="link-row">
|
||||||
<input type="text" value="${links.torrent}" readonly onclick="this.select()">
|
<input type="text" value="${escapeHtml(safeLinks.torrent)}" readonly onclick="this.select()">
|
||||||
<button onclick="copyToClipboard('${links.torrent}')">Copy</button>
|
<button onclick="copyToClipboard(\`${escapeHtml(safeLinks.torrent)}\`)">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="share-link">
|
<div class="share-link">
|
||||||
<label>Magnet Link:</label>
|
<label>Magnet Link:</label>
|
||||||
<div class="link-row">
|
<div class="link-row">
|
||||||
<input type="text" value="${links.magnet}" readonly onclick="this.select()">
|
<input type="text" value="${escapeHtml(safeLinks.magnet)}" readonly onclick="this.select()">
|
||||||
<button onclick="copyToClipboard('${links.magnet}')">Copy</button>
|
<button onclick="copyToClipboard(\`${escapeHtml(safeLinks.magnet)}\`)">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -614,15 +614,6 @@ class GatewayUI {
|
|||||||
|
|
||||||
const baseUrl = window.location.origin;
|
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 = {
|
const links = {
|
||||||
direct: `${baseUrl}/api/download/${hash}`
|
direct: `${baseUrl}/api/download/${hash}`
|
||||||
};
|
};
|
||||||
@ -630,7 +621,17 @@ class GatewayUI {
|
|||||||
// Only add torrent/magnet links for torrent storage type
|
// Only add torrent/magnet links for torrent storage type
|
||||||
if (fileData && fileData.storage_type === 'torrent') {
|
if (fileData && fileData.storage_type === 'torrent') {
|
||||||
links.torrent = `${baseUrl}/api/torrent/${hash}`;
|
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
|
// Add NIP-71 Nostr link for torrents if available
|
||||||
if (fileData.nip71_share_link) {
|
if (fileData.nip71_share_link) {
|
||||||
@ -686,17 +687,30 @@ class GatewayUI {
|
|||||||
{ key: 'nostr', label: 'Share on Nostr', icon: '⚡' }
|
{ 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, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
linksContainer.innerHTML = linkTypes
|
linksContainer.innerHTML = linkTypes
|
||||||
.filter(type => links[type.key])
|
.filter(type => links[type.key])
|
||||||
.map(type => {
|
.map(type => {
|
||||||
|
const linkValue = links[type.key] || '';
|
||||||
|
const escapedLink = escapeHtml(linkValue);
|
||||||
|
|
||||||
if (type.key === 'nostr') {
|
if (type.key === 'nostr') {
|
||||||
return `
|
return `
|
||||||
<div class="share-link nostr-link">
|
<div class="share-link nostr-link">
|
||||||
<label>${type.icon} ${type.label}</label>
|
<label>${type.icon} ${type.label}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" value="${links[type.key]}" readonly>
|
<input type="text" value="${escapedLink}" readonly>
|
||||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
<button onclick="copyToClipboard(\`${escapeHtml(linkValue)}\`)" class="copy-btn">Copy</button>
|
||||||
<button onclick="window.open('https://njump.me/${links[type.key]}', '_blank')" class="open-btn">Open</button>
|
<button onclick="window.open('https://njump.me/${escapeHtml(linkValue)}', '_blank')" class="open-btn">Open</button>
|
||||||
</div>
|
</div>
|
||||||
<small>Opens in Nostr clients or web viewer</small>
|
<small>Opens in Nostr clients or web viewer</small>
|
||||||
</div>
|
</div>
|
||||||
@ -706,8 +720,8 @@ class GatewayUI {
|
|||||||
<div class="share-link">
|
<div class="share-link">
|
||||||
<label>${type.icon} ${type.label}</label>
|
<label>${type.icon} ${type.label}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" value="${links[type.key]}" readonly>
|
<input type="text" value="${escapedLink}" readonly>
|
||||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
<button onclick="copyToClipboard(\`${escapeHtml(linkValue)}\`)" class="copy-btn">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
BIN
torrent-gateway
BIN
torrent-gateway
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user