• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zalando / skipper / 39278377840
81%

Build:
DEFAULT BRANCH: master
Ran 19 Oct 2026 03:51PM UTC
Jobs 1
Files 333
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

19 Oct 2026 03:29PM UTC coverage: 81.037% (-0.01%) from 81.051%
39278377840

push

github

web-flow
fix: headerToQuery clears the query param when the header is missing (#4348)

## Symptom

`headerToQuery` changes the query even when the request doesn't have the
header:

```
r: * -> headerToQuery("X-Foo-Header", "foo-query-param") -> "http://backend"
```

| Request (no `X-Foo-Header`) | query sent to the backend on master |
expected |
| --- | --- | --- |
| `/` | `?foo-query-param=` | no query |
| `/?foo-query-param=baz` | `?foo-query-param=` | `?foo-query-param=baz`
|
| `/?b=2&a=1` | `?a=1&b=2&foo-query-param=` | `?b=2&a=1` |

The second row is the worst one: a value the client sent in the query is
replaced with an empty string just because the header is absent.

## Cause

`Request` always calls `params.Set(f.queryParamName,
req.Header.Get(f.headerName))` and re-encodes the query. `Header.Get`
returns `""` for a missing header, so the param is set to an empty
value.

`queryToHeader`, the reverse filter, already returns early when the
query param is missing.

## Change

- Return without touching the query when the request has no values for
the header (`len(req.Header.Values(name)) == 0`). A header that is
present, even with an empty value, is still copied as before.
- One sentence in `docs/reference/filters.md` saying the query is left
unchanged without the header.

## Tests

New `TestHeaderToQueryFilter_RequestWithoutHeader` covers the three rows
above. On master it fails:

```
headertoquery_test.go:50: request without the header: got https://example.org?foo-query-param=, want https://example.org unchanged
headertoquery_test.go:50: request without the header: got https://example.org?foo-query-param=, want https://example.org?foo-query-param=baz unchanged
headertoquery_test.go:50: request without the header: got https://example.org?a=1&b=2&foo-query-param=, want https://example.org?b=2&a=1 unchanged
```

With the change, `go test ./filters/builtin/` passes, and `gofmt` and
`go vet` are clean.

This change was prepared with AI assistance and reviewed/... (continued)

4 of 4 new or added lines in 1 file covered. (100.0%)

10 existing lines in 5 files now uncovered.

27713 of 34198 relevant lines covered (81.04%)

73803.49 hits per line

Coverage Regressions

Lines Coverage ∆ File
3
94.39
-1.53% filters/tee/tee.go
3
68.77
0.0% skipper.go
2
84.68
-0.56% net/httpclient.go
1
96.88
-1.04% eskipfile/watch.go
1
82.41
-0.23% routing/datasource.go
Jobs
ID Job ID Ran Files Coverage
1 39278377840.1 19 Oct 2026 03:51PM UTC 333
81.04
GitHub Action Run
Source Files on build 39278377840
  • Tree
  • List 333
  • Changed 7
  • Source Changed 1
  • Coverage Changed 7
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #39278377840
  • 29360aa4 on github
  • Prev Build on master (#39277283251)
  • Next Build on master (#39279299108)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc