Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

handle gzipped graphql requests#14391

Merged
chrispine merged 4 commits into
mainfrom
cp/gzip-http-requests
Oct 12, 2020
Merged

handle gzipped graphql requests#14391
chrispine merged 4 commits into
mainfrom
cp/gzip-http-requests

Conversation

@chrispine

@chrispine chrispine commented Oct 2, 2020

Copy link
Copy Markdown

This allows the backend to handle gzipped GraphQL requests. But perhaps this is not the right place to do this? I'm curious to know your thoughts.

This partially fixes #12840.

@mrnugget mrnugget left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Regarding location: I'm thinking that maybe we don't need your snippet of code and can instead use the gziphandler middlware we use for the extensions endpoint already:

https://github.com/sourcegraph/sourcegraph/blob/23091f79f8250306969b9f88b4643643add3f02e/cmd/frontend/internal/app/app.go#L66

And here's where I'd wrap the GraphQL handler:

https://github.com/sourcegraph/sourcegraph/blob/23091f79f8250306969b9f88b4643643add3f02e/cmd/frontend/internal/httpapi/httpapi.go#L62

The advantage of the gzip handler would be that it encodes/decodes request and response bodies.

Comment thread cmd/frontend/internal/httpapi/graphql.go Outdated
@eseliger

eseliger commented Oct 5, 2020

Copy link
Copy Markdown
Member

Cool @mrnugget, I didn't know that helper existed.

I think what Chris and I asked ourselves initially when hacking on this was: Do we want to allow that encoding on the entire GraphQL API? It probably won't hurt, but also won't make things necessarily easier to understand.
But, if we don't want to go down that avenue, we'd have to have a separate endpoint, like codeintel has for LSIF dumps, which are ingested using plain HTTP. So, it felt to be okay, but we definitely wanted to raise it for discussion.

@mrnugget

mrnugget commented Oct 5, 2020

Copy link
Copy Markdown
Contributor

but also won't make things necessarily easier to understand.

Why?

@eseliger

eseliger commented Oct 5, 2020

Copy link
Copy Markdown
Member

Just because it adds some more complexity, nothing in particular.

@mrnugget

mrnugget commented Oct 5, 2020

Copy link
Copy Markdown
Contributor

Yeah, but where? I think I'm missing something. Do you mean the complexity in code, as in: adding the handler? Or do you mean complexity of usage?

@eseliger

eseliger commented Oct 5, 2020

Copy link
Copy Markdown
Member

I mean complexity as in

  • When is GraphQL
  • And when this certain header is set
  • And when you encode the json body using gzip

then this path is triggered. Especially because we only use it for one thing but it lives in some global piece of code. But I think it is okay.

@mrnugget

mrnugget commented Oct 5, 2020

Copy link
Copy Markdown
Contributor

I see. We should ask @sourcegraph/cloud whether this is okay, but I agree, I think it's okay.

@felixfbecker

Copy link
Copy Markdown
Contributor

Stumbled across this PR and ❤️ it, my 2ct: I think this would be great to support and is pretty standard with HTTP. There are all well-defined mechanisms in HTTP for announcing what a client or server supports and what a message is using, and they are commonly used (gzip in particular). As long as we respect/use those I think this is great. If anything it can be frustrating to think "oh, this body is large, so I'm going to send a gzipped body with the appropiate standard HTTP headers" only to discover our backend rejects it.

return err
}

r.Body = reader

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we need to be careful regarding Closing the original reader. According to the docs the underlying reader won't be closed, only the gzip reader.

https://golang.org/pkg/compress/gzip/#Reader.Close

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't remember we need to close the underlying reader ourselves while using net/http? 🤔

The other problem I'm seeing though, is that we should close the gzip reader with reader.Close(), otherwise it's a resource leak. Not sure if this is what you intended to say?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Well, now I'm confused. 😄

First, I can confirm that the gzip reader is not being closed. (And if it was closed, it wouldn't close the underlying reader-formerly-known-as-r.Body.) I can wrap the gzip reader so that, if closed, it will close the underlying reader. (But is unknwon saying I don't need to do that at all?)

It sounds like, however, I do need to find a place to close the gzip reader. I assume it's safe to do this after the called to ServeHTTP()?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(But is unknwon saying I don't need to do that at all?)

I believe so: https://github.com/golang/go/blob/9449a125e8b25d21c0d522435be44a4a6e7af2d3/src/net/http/request.go#L174-L178

It sounds like, however, I do need to find a place to close the gzip reader. I assume it's safe to do this after the called to ServeHTTP()?

Yes, that's what I'm thinking of.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

OK, it now closes the gzip reader in the latest commit. Thanks!

@codecov

codecov Bot commented Oct 12, 2020

Copy link
Copy Markdown

Codecov Report

Merging #14391 into main will decrease coverage by 0.00%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##             main   #14391      +/-   ##
==========================================
- Coverage   51.87%   51.87%   -0.01%     
==========================================
  Files        1535     1535              
  Lines       78120    78126       +6     
  Branches     7085     7085              
==========================================
+ Hits        40526    40527       +1     
- Misses      33935    33941       +6     
+ Partials     3659     3658       -1     
Flag Coverage Δ *Carryforward flag
#go 52.10% <0.00%> (-0.01%) ⬇️
#integration 30.31% <ø> (ø) Carriedforward from 09cf6af
#storybook 18.06% <ø> (ø) Carriedforward from 09cf6af
#typescript 51.31% <ø> (ø) Carriedforward from 09cf6af
#unit 33.91% <ø> (ø) Carriedforward from 09cf6af

*This pull request uses carry forward flags. Click here to find out more.

Impacted Files Coverage Δ
cmd/frontend/internal/httpapi/graphql.go 3.44% <0.00%> (-0.90%) ⬇️
internal/db/helpers.go 100.00% <0.00%> (ø)
internal/gosrc/stdlib.go 100.00% <0.00%> (ø)
internal/conf/platform.go 100.00% <0.00%> (ø)
internal/routevar/util.go 100.00% <0.00%> (ø)
internal/timeutil/week.go 100.00% <0.00%> (ø)
internal/vcs/git/mocks.go 100.00% <0.00%> (ø)
internal/db/query/query.go 100.00% <0.00%> (ø)
internal/highlight/mocks.go 100.00% <0.00%> (ø)
internal/routevar/regexp.go 100.00% <0.00%> (ø)
... and 749 more

@chrispine chrispine merged commit b01d304 into main Oct 12, 2020
@chrispine chrispine deleted the cp/gzip-http-requests branch October 12, 2020 20:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

campaigns: large changesets can result in 413 errors

8 participants