bug(sdk/go): http client generates invalid header values
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 219
- PR merge metrics
- No merged PRs in 30d
Description
Sending a `select_rows` command with a placeholder with a binary value leads to a `net/http: invalid header field value for "X-Yt-Parameters"` error.
It seems YSON text encoder does not escape some characters considered by HTTP as control.
Reproducer
```go
package internal_test
import (
"context"
"fmt"
"testing"
"go.uber.org/zap/zaptest"
ytzap "go.ytsaurus.tech/library/go/core/log/zap"
"go.ytsaurus.tech/yt/go/yson"
"go.ytsaurus.tech/yt/go/yt"
"go.ytsaurus.tech/yt/go/yt/ythttp"
)
// placeholderSet is a simple wrapper to encode placeholder values.
//
// See https://github.com/ytsaurus/ytsaurus/blob/bbaedcf016db5e599563bb3f3b5ba87b047b4faa/yt/yt/library/query/base/query_preparer.cpp#L2461.
type placeholderSet struct {
values []any
}
func (p placeholderSet) MarshalYSON(w *yson.Writer) error {
w.BeginMap()
for i, v := range p.values {
w.MapKeyString(fmt.Sprintf("placeholder%d", i))
w.Any(v)
}
w.EndMap()
return nil
}
func TestPlaceholders(t *testing.T) {
ctx := context.Background()
log := zaptest.NewLogger(t)
yc, err := ythttp.NewClient(&yt.Config{
Logger: &ytzap.Logger{L: log},
})
if err != nil {
t.Fatal(err)
}
var (
id = [16]byte{
0x1f, 0x1f, 0x1f, 0x1f, // <- 0x1f is a control character (unit separator)
0x1f, 0x1f, 0x1f, 0x1f,
0x1f, 0x1f, 0x1f, 0x1f,
0x1f, 0x1f, 0x1f, 0x1f,
}
// Table schema does not matter, since query does not actually reach the proxy.
query = "* from [//table] where uuid = {placeholder0}"
placeholders = placeholderSet{
values: []any{id[:]},
}
)
r, err := yc.SelectRows(ctx, query, &yt.SelectRowsOptions{
PlaceholderValues: placeholders,
})
if err != nil {
t.Fatal(err)
}
defer r.Close()
}
```
Logs
```
2023-06-01T21:28:18.836+0300 DEBUG request started {"call_id": "f4d2888d-b94c52bc-7541d52f-5e7febcf", "method": "select_rows", "query": "* from [//table] where uuid = {placeholder0}"}
2023-06-01T21:28:18.836+0300 DEBUG sending HTTP request {"call_id": "f4d2888d-b94c52bc-7541d52f-5e7febcf", "proxy": "localhost:8000"}
2023-06-01T21:28:18.836+0300 WARN retrying heavy read request {"call_id": "f4d2888d-b94c52bc-7541d52f-5e7febcf", "backoff": "2.012342203s", "error": "Get \"http://localhost:8000/api/v4/select_rows\": net/http: invalid header field value for \"X-Yt-Parameters\""}
```
Contributor guide
Assessment
This issue has not been assessed yet.