Background
deviceshifuhttp proxies HTTP requests from the cluster to a device-side host server. When the host server returns a non-2xx response (e.g. 500 from a failed device probe), the proxy should forward the original status code to the caller.
Root Cause
In pkg/deviceshifu/deviceshifuhttp/deviceshifuhttp.go, the GET/POST instruction handler copies response headers and streams the body, but never calls w.WriteHeader before io.Copy:
// ~line 217
utils.CopyHeader(w.Header(), resp.Header)
_, err := io.Copy(w, resp.Body) // w.WriteHeader never called
Go's net/http implicitly writes 200 OK the first time the ResponseWriter is written to. As a result, any non-2xx status from the upstream host server is silently translated to 200 OK before reaching the caller.
The HTTPCommandline handler in the same file (around line 371) already does this correctly:
utils.CopyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode) // present here
_, err = io.Copy(w, resp.Body)
How to Trigger
- Deploy a device via deviceshifu whose host server returns non-2xx on some endpoint (e.g. a
/healthz that probes the physical device and returns 500 when the device is unreachable).
- Invoke that endpoint through the deviceshifu ClusterIP service.
- Observe: the response status is always
200 OK regardless of what the host server actually returned. The body is forwarded correctly, so a caller checking only the status code will incorrectly conclude the device is healthy.
Impact
Any staleness-detection or health-check mechanism that relies on HTTP status codes from deviceshifu endpoints will not work as expected for HTTP-based device drivers. The body may contain {"ok": false} but the status is 200, which is a semantic contradiction that breaks status-code-based probing.
Fix
Add one line before the io.Copy call in the GET/POST handler:
utils.CopyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode) // add this
_, err := io.Copy(w, resp.Body)
Background
deviceshifuhttpproxies HTTP requests from the cluster to a device-side host server. When the host server returns a non-2xx response (e.g. 500 from a failed device probe), the proxy should forward the original status code to the caller.Root Cause
In
pkg/deviceshifu/deviceshifuhttp/deviceshifuhttp.go, the GET/POST instruction handler copies response headers and streams the body, but never callsw.WriteHeaderbeforeio.Copy:Go's
net/httpimplicitly writes200 OKthe first time theResponseWriteris written to. As a result, any non-2xx status from the upstream host server is silently translated to200 OKbefore reaching the caller.The
HTTPCommandlinehandler in the same file (around line 371) already does this correctly:How to Trigger
/healthzthat probes the physical device and returns500when the device is unreachable).200 OKregardless of what the host server actually returned. The body is forwarded correctly, so a caller checking only the status code will incorrectly conclude the device is healthy.Impact
Any staleness-detection or health-check mechanism that relies on HTTP status codes from deviceshifu endpoints will not work as expected for HTTP-based device drivers. The body may contain
{"ok": false}but the status is200, which is a semantic contradiction that breaks status-code-based probing.Fix
Add one line before the
io.Copycall in the GET/POST handler: