-
Notifications
You must be signed in to change notification settings - Fork 97
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
Robust Header Check #13
Conversation
… 'application/octet-stream' we don't want to add another
@bradleyfalzon any chance you could take a look at this? My company is using the fork in production now and we don't want to do that for to long. |
Sorry for the delay on this one. I'm confused, we need to send the And therefore you're choosing to not send As I'm thinking that instead of adding another accept header, we check if one exists and append to that header? |
The behavior I'm seeing is regardless of authentication type when trying to download a single asset from the GitHub API (documentation) you can only have a single accept header I was able to verify this behavior just making a curl command with a personal oauth token. My solution is if we detect the |
At a high level, this makes sense to me. 👍 I hope the implementation can be made simpler though. @bradleyfalzon See a relevant issue google/go-github#870 if you’d like more context. |
@shurcooL Agreed on the implementation, I wasn't sure if there was a more elegant want to handle it. I'd be happy to change it if we can find something better. |
OK, so I see, it's working around a suspected bug on GitHub's side. So essentially, if the request already has an Accept header, and it's equal to I like the cleaner google/go-github#870 implementation because it just disables the header for that one endpoint. If it's only one particular URL that's causing the issue. Then it's clearer what bug we're working around? |
That's right.
I don't think it's a bug, I think it's working correctly. The documentation for https://developer.github.com/v3/repos/releases/#get-a-single-release-asset endpoint says:
Basically, that endpoint can respond either with a JSON payload, or binary data, depending on what the client prefers. If you read the documentation at https://developer.github.com/v3/media/ and https://developer.github.com/v3/previews/:
It becomes more clear how to parse the following Accept header value:
It means to use "machine-man-preview" preview version, and since So, when both |
transport.go
Outdated
) | ||
|
||
//Used to detect if a single asset request is being made. https://developer.github.com/v3/repos/releases/#get-a-single-release-asset | ||
var assetPathRegex = regexp.MustCompile("/repos/.+/.+/releases/assets/\\d+") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gosimple: should use raw string (...
) with regexp.MustCompile to avoid having to escape twice (S1007)
@bradleyfalzon I refactored the code to specifically look for the case to download a single asset. |
I would suggest you consider this more general approach:
What do you think? |
@shurcooL I like that idea, little confused on how I can tell if it's asking for JSON. Would it be as simple as checking the |
Yes, you'd have to check the
Please wait to hear back from @bradleyfalzon as he's the owner here. He should read my comments following his, because I think that the original analysis was not accurate, and I tried to provide helpful information to improve it. I don't think the same fix as in go-github is applicable here. |
I do think this is the best method, although I am concerned about the breaking implications of this for some users not setting that header, and not using @shurcooL from my understanding, |
Isn't this package for GitHub? How can users not be using
That's right. The GitHub REST API v3 expects the media type to be provided in order to control the format of the data to be received. See https://developer.github.com/v3/media/. You can confirm that |
It's for GitHub, but it doesn't necessarily require users to use the I question this because https://developer.github.com/v3/#schema mentions:
Although, just previous to that is https://developer.github.com/v3/#current-version
So, similar to RFC guidelines of the term I'm then OK with the simpler approach by @shurcooL #13 (comment)
@cpheps will this be satisfactory for you also? |
@bradleyfalzon That seems appropriate for me, I'll try and get a modification in later today. |
…. If either cases is true append machine-man-preview+json accpet header
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny nits, but can you review my alternate implementation?
appsTransport.go
Outdated
|
||
resp, err := t.tr.RoundTrip(req) | ||
return resp, err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can you remove this extra newline?
transport.go
Outdated
@@ -134,3 +135,22 @@ func (t *Transport) refreshToken() error { | |||
|
|||
return nil | |||
} | |||
|
|||
func addAcceptHeader(req *http.Request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be slightly rewritten to return early when possible, what's your thoughts on this? I haven't tested it at all.
// addAcceptIfJSON adds the preview accept headers if the request does not already specify an
// accept header, or if it's already specifying acceptance of json type as defined by
// https://developer.github.com/v3/media/.
func addAcceptIfJSON(headers http.Header) {
if headers.Get("Accept") == "" {
headers.Set("Accept", acceptHeader)
return
}
for _, header := range headers["Accept"] {
if strings.HasSuffix(header, "json") {
headers.Add("Accept", acceptHeader)
return
}
}
}
Just accepting a http.Header
also simplifies some of the tests, as the function just requires what it checks and modifies, nothing more. But again, I haven't tested this at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bradleyfalzon Made the changes
transport.go
Outdated
return | ||
} | ||
|
||
//Need to loop through all Accept headers incase there is more than one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor style issue. Since this is a normal comment for humans rather than for the compiler, it should have a space after //
, like so:
// Need to ...
See https://dmitri.shuralyov.com/idiomatic-go#comments-for-humans-always-have-a-single-space-after-the-slashes for rationale.
Also, “incase” should be two words I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpheps Did you see this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed the second one, just pushed a fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the first part? I still see some comments that don't have a space after //
.
transport.go
Outdated
|
||
//Need to loop through all Accept headers incase there is more than one. | ||
for _, header := range headers["Accept"] { | ||
//Looks as though all media types (https://developer.github.com/v3/media/) that can accept json end with "json". Only doing a suffix check to see if a json header already exists. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here as well:
// Looks as though ...
You might also want to wrap the line at around 80-100 columns, so it’s more comfortable to read.
@bradleyfalzon Fixed those issues a few days ago any other requests? |
@bradleyfalzon Just wanted to check on this and see if there was anything blocking the merge still? |
transport.go
Outdated
@@ -134,3 +135,20 @@ func (t *Transport) refreshToken() error { | |||
|
|||
return nil | |||
} | |||
|
|||
func addAcceptHeader(headers http.Header) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to document what the function does. Perhaps something like this:
// addAcceptHeader adds acceptHeader value to "Accept" header, but only
// if the current "Accept" header is not set, or if it already accepts JSON.
func addAcceptHeader(headers http.Header) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied it directly (seemed like a good description) and pushed.
@shurcooL @bradleyfalzon any more requests, would like to get this merged if it looks good to you guys. |
I still see 3 lines of comments in |
@bradleyfalzon I don't mean to be annoying on this but it's been open a while without any movement. |
@bradleyfalzon Checking in again seeing if we can get this merged. |
Sorry for the delays in this, I've had another look through, and tentatively it looks OK to me. I'd like someone else to confirm before I merge though. |
Added a robust check when adding the
Accept
Header, if anAccept
header already exists with the valueapplication/octet-stream
then don't add the additionalAccept
header.Resolves #12