Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client should verify response content-type #679

Merged
merged 2 commits into from
Feb 8, 2024

Conversation

jhump
Copy link
Member

@jhump jhump commented Feb 7, 2024

@smaye81 found some more bugs with new conformance test cases.

The client is not verifying that the response has the correct content-type. So this change adds that verification.

Some tests, that had simple handlers that weren't setting a valid content-type, had to be updated. Sorry for the large diff stats, but it's not as bad as it looks. This PR adds three new table-driven tests that account for 75% of the lines of code.

@@ -511,6 +511,21 @@ func (cc *connectUnaryClientConn) validateResponse(response *http.Response) *Err
}
cc.responseTrailer[strings.TrimPrefix(k, connectUnaryTrailerPrefix)] = v
}
err := connectValidateUnaryResponseContentType(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be moved into the validate response function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Do you mean inlined? I had made it a separate function to make it easier to test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry misread, thought the method on the duplexcall was due to it not being part of this function, but thats for the request params.

@jhump jhump merged commit 2290ed2 into main Feb 8, 2024
11 checks passed
@jhump jhump deleted the jh/check-response-content-type branch February 8, 2024 18:17
response.Status,
getHeaderCanonical(response.Header, headerContentType),
)
if err != nil {
Copy link
Member

@akshayjshah akshayjshah Feb 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we scope err to the if block? It's visually a little ugly, but the functions in this portion of the code are long enough that I'd love to minimize scope where possible. Same below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had not done so just because I find it a bit hard to read when the if keyword is far from the actual condition. But if that's accepted style, and even preferred in this case, I'll change it.

jhump added a commit that referenced this pull request Feb 8, 2024
This also formats the grpc version of the check so it is consistent with
the other two.

Addresses comment in prior PR:
#679 (comment)
@jhump jhump added the bug Something isn't working label Feb 16, 2024
@jhump jhump mentioned this pull request Feb 16, 2024
simonswine added a commit to simonswine/pyroscope that referenced this pull request Jun 19, 2024
The query-frontend accidentally leaked content-type and content-encoding
information from the underlying connectgrpc implementation, which is
used to schedule queries on to the workers (queriers).

This will filter those out, so they won't be passed on through the
frontend.

This could be observed by errors like this:

```
$ profilecli query series
level=info msg="query series from querier" url=http://localhost:8080 from=2024-06-18T15:46:19.932471+01:00 to=2024-06-18T16:46:19.932472+01:00 labelNames=[]
error: failed to query: unknown: invalid content-type: "application/grpc,application/proto"; expecting "application/grpc"
exit status 1
```

Which themselves were produced only because envoy (involved on our GC
ingress), converted headers from this:

```
content-type: application/grpc
content-type: application/proto
```

to

```
content-type: application/grpc,application/proto
```

This then triggered a validation recently added to connect-go:

connectrpc/connect-go#679
simonswine added a commit to simonswine/pyroscope that referenced this pull request Jun 19, 2024
The query-frontend accidentally leaked content-type and content-encoding
information from the underlying connectgrpc implementation, which is
used to schedule queries on to the workers (queriers).

This will filter those out, so they won't be passed on through the
frontend.

This could be observed by errors like this:

```
$ profilecli query series
level=info msg="query series from querier" url=http://localhost:8080 from=2024-06-18T15:46:19.932471+01:00 to=2024-06-18T16:46:19.932472+01:00 labelNames=[]
error: failed to query: unknown: invalid content-type: "application/grpc,application/proto"; expecting "application/grpc"
exit status 1
```

Which themselves were produced only because envoy (involved on our GC
ingress), converted headers from this:

```
content-type: application/grpc
content-type: application/proto
```

to

```
content-type: application/grpc,application/proto
```

This then triggered a validation recently added to connect-go:

connectrpc/connect-go#679
simonswine added a commit to grafana/pyroscope that referenced this pull request Jun 19, 2024
The query-frontend accidentally leaked content-type and content-encoding
information from the underlying connectgrpc implementation, which is
used to schedule queries on to the workers (queriers).

This will filter those out, so they won't be passed on through the
frontend.

This could be observed by errors like this:

```
$ profilecli query series
level=info msg="query series from querier" url=http://localhost:8080 from=2024-06-18T15:46:19.932471+01:00 to=2024-06-18T16:46:19.932472+01:00 labelNames=[]
error: failed to query: unknown: invalid content-type: "application/grpc,application/proto"; expecting "application/grpc"
exit status 1
```

Which themselves were produced only because envoy (involved on our GC
ingress), converted headers from this:

```
content-type: application/grpc
content-type: application/proto
```

to

```
content-type: application/grpc,application/proto
```

This then triggered a validation recently added to connect-go:

connectrpc/connect-go#679
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants