fixxxy
4dd3a32 · gmorell · 2026-05-25 16:17
Files changed
modified
lib/git_gud_web/controllers/runner_controller.ex
+14
−9
@@ -421,15 +421,20 @@ defmodule GitGudWeb.RunnerController do
| 421 | 421 | |
| 422 | 422 | step = job && Workflows.ensure_log_step(job) |
| 423 | 423 | |
| 424 | − # Connect-Go decodes empty unary bodies as "method not | |
| 425 | − # implemented" and surfaces it as "unimplemented: 404 Not | |
| 426 | − # Found" — which corrupts the HTTP/1.1 keepalive stream when | |
| 427 | − # the actual content-length disagrees with what was written. | |
| 428 | − # `ack_index = 0` would encode to 0 bytes (proto3 omits default | |
| 429 | − # ints), so we always advertise at least 1 acked row when the | |
| 430 | − # request itself was non-zero — matches Forgejo's behavior of | |
| 431 | − # echoing back the high-water mark. | |
| 432 | − ack_index = max(index + length(rows), 1) | |
| 424 | + # The runner's `ReportLog` slices its local buffer with | |
| 425 | + # | |
| 426 | + # r.logRows = r.logRows[ack-r.logOffset:] | |
| 427 | + # | |
| 428 | + # If we lie about `ack_index` (claim more rows than the runner | |
| 429 | + # sent), the slice runs past `len(r.logRows)` and the runner | |
| 430 | + # PANICS with `goPanicSliceB`. So `ack_index` MUST be exactly | |
| 431 | + # `index + length(rows)` — never floor or bump. | |
| 432 | + # | |
| 433 | + # The original concern that motivated a floor here — empty | |
| 434 | + # response bodies confusing Connect-Go / breaking HTTP/1.1 | |
| 435 | + # keepalive framing — is handled by the `Connection: close` | |
| 436 | + # we set in `respond/2`, so this can be honest. | |
| 437 | + ack_index = index + length(rows) | |
| 433 | 438 | |
| 434 | 439 | cond do |
| 435 | 440 | is_nil(step) -> |
Parents: 5195c69