diff --git a/internal/server/handlers_panel_stat.go b/internal/server/handlers_panel_stat.go index 42d8575..fc6cc17 100644 --- a/internal/server/handlers_panel_stat.go +++ b/internal/server/handlers_panel_stat.go @@ -298,18 +298,23 @@ func (s *Server) handleSpeedRelayOpen(w http.ResponseWriter, r *http.Request) { } // POST /api/panel/agents/{id}/speed/down - a piece of the browser's upload, -// passed on to the agent. 410 once the agent has stopped reading. +// passed on to the agent. 204 asks for the next piece, 200 says the agent has +// stopped reading. func (s *Server) handleSpeedRelayFeed(w http.ResponseWriter, r *http.Request) { + body := http.MaxBytesReader(w, r.Body, speedUpCap) rl := s.relays.get(r.PathValue("id")) - if rl == nil { - http.Error(w, "gone", http.StatusGone) - return + if rl != nil { + if _, err := io.Copy(rl.downW, body); err == nil { + w.WriteHeader(http.StatusNoContent) + return + } } - if _, err := io.Copy(rl.downW, http.MaxBytesReader(w, r.Body, speedUpCap)); err != nil { - http.Error(w, "gone", http.StatusGone) - return - } - w.WriteHeader(http.StatusNoContent) + // Take the rest of the piece before answering: an answer sent over an + // unread body makes Go drop the connection, which a proxy in front turns + // into a 502. + _, _ = io.Copy(io.Discard, body) + w.Header().Set("Cache-Control", "no-store") + _, _ = io.WriteString(w, "done") } // GET /api/panel/agents/{id}/speed/up - the agent's upload, for the browser to diff --git a/internal/server/web/templates/status.html b/internal/server/web/templates/status.html index 4aee3fb..6a0954c 100644 --- a/internal/server/web/templates/status.html +++ b/internal/server/web/templates/status.html @@ -167,7 +167,7 @@ for (var i = 0; i < n; i++) parts.push(block); return fetch(base + '/speed/down', {method: 'POST', body: new Blob(parts), credentials: 'same-origin', signal: stop.signal}) .then(function (r) { - if (!r.ok) return; + if (r.status !== 204) return; if (performance.now() - t < 500 && n < 256) n *= 2; return one(); });