fix dns media downlaod timeouts and video play in android

This commit is contained in:
Sarto
2026-05-02 00:37:47 +03:30
parent ace8ce8627
commit ad1196173a
3 changed files with 37 additions and 19 deletions
+8 -4
View File
@@ -41,16 +41,18 @@ func (e *ghRateLimitError) Error() string {
// bionic libc → netd → the device's actual DNS, the same path any other
// Android app uses. On desktop the OS resolver is similarly fine.
var relayHTTPClient = &http.Client{
Timeout: 30 * time.Second,
// Per-request budget — large enough to cover multi-MB downloads
// over a slow link without hugging short-circuit timeouts.
Timeout: 5 * time.Minute,
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 10 * time.Second,
Timeout: 15 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 10,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
TLSHandshakeTimeout: 15 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
@@ -131,7 +133,9 @@ func (s *Server) serveFromGitHubRelay(w http.ResponseWriter, r *http.Request, si
return false
}
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
// Long enough to cover a multi-MB GitHub fetch over a slow link, plus
// a multi-block DNS-tunneled relay-info lookup if the cache is empty.
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Minute)
defer cancel()
info, err := rc.get(ctx, fetcher)
+19 -10
View File
@@ -3374,12 +3374,17 @@
await selectChannel(1); return
}
if (data && typeof data === 'object' && data.type === 'no_changes') {
// Only show the toast if the user is still viewing the channel
// that reported no changes — silently drop it if they switched.
if (data.channel === selectedChannel) showToast(t('no_new_messages'));
// Only show the toast if the user explicitly asked for this
// refresh AND is still on the same channel. Channel-open and
// auto-refresh ticks stay silent.
if (data.channel === manualRefreshChannel && data.channel === selectedChannel) {
showToast(t('no_new_messages'));
}
if (data.channel === manualRefreshChannel) manualRefreshChannel = 0;
if (snapChannel > 0) { delete refreshingChannels[snapChannel]; var fb = document.getElementById('prog-fetch-ch-' + snapChannel); if (fb) fb.remove() }
} else if (data && typeof data === 'object' && data.channel) {
delete refreshingChannels[data.channel]; var fb2 = document.getElementById('prog-fetch-ch-' + data.channel); if (fb2) fb2.remove();
if (data.channel === manualRefreshChannel) manualRefreshChannel = 0;
// Only re-render if the user is STILL on that channel right now —
// selectedChannel may have changed during the awaited loadChannels.
if (data.channel === selectedChannel) await loadMessages(data.channel)
@@ -4921,6 +4926,10 @@
showImageLightbox(entry.url, mediaTagLabel(tag));
return;
}
if (mediaIsPlayableTag(tag)) {
showMediaPlayer(entry, tag);
return;
}
if (androidBridge && androidBridge.openMedia) {
var fname = mediaFilenameFor(msgID, tag, entry.mime);
try {
@@ -4929,13 +4938,6 @@
} catch (e) { }
return;
}
// Browser path: play video/audio inline in a lightbox instead of
// opening a blob URL in a new tab — some browsers refuse to render
// blob:video and download it as a hash-named file with no extension.
if (mediaIsPlayableTag(tag)) {
showMediaPlayer(entry, tag);
return;
}
try {
var a = document.createElement('a');
a.href = entry.url;
@@ -5596,6 +5598,12 @@
}
tick(); nextFetchInterval = setInterval(tick, 1000);
}
// Channel number for which the user explicitly clicked Refresh.
// The "no new messages" toast fires only for that channel; auto-
// refresh ticks and channel-open refreshes leave it at 0 so the
// toast stays silent.
var manualRefreshChannel = 0;
async function doRefreshUI() {
var btn = document.getElementById('refreshBtn');
btn.style.animation = 'spin .8s linear';
@@ -5605,6 +5613,7 @@
var name = (ch && (ch.Name || ch.name)) || 'Channel ' + selectedChannel;
showChannelFetchProgress(selectedChannel, name);
refreshingChannels[selectedChannel] = true;
manualRefreshChannel = selectedChannel;
}
doRefresh(false);
setTimeout(function () { btn.style.animation = '' }, 800);
+10 -5
View File
@@ -319,11 +319,16 @@ func (s *Server) Run() error {
}
srv := &http.Server{
Addr: addr,
Handler: handler,
ReadTimeout: 30 * time.Second,
WriteTimeout: 60 * time.Second,
IdleTimeout: 120 * time.Second,
Addr: addr,
Handler: handler,
// ReadHeaderTimeout protects against slow-loris on the request
// header. The body itself can be large (Telegram send-message
// uploads), and the response can be slow (DNS-tunneled media
// streams take many minutes for multi-block files in censored
// networks). So zero out ReadTimeout/WriteTimeout and bound the
// idle period on the connection itself.
ReadHeaderTimeout: 30 * time.Second,
IdleTimeout: 30 * time.Minute,
}
return srv.ListenAndServe()
}