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

Support OPTIONS requests #3885

Merged
merged 6 commits into from
Mar 16, 2018
Merged

Conversation

eddsteel
Copy link
Contributor

  • register endpoints with supported methods
  • support OPTIONS requests, indicating supported methods
  • extract method validation (error 405) out of individual endpoints
  • on 405 where multiple methods are allowed, create a single Allow
    header with comma-separated values, not multiple Allow headers.

This is based on #1957 and fixes #865 (and anything else that expects OPTIONS to work).

I made the allowed methods a parameter of wrap so that they wouldn't need to be looked up in the map for every call of wrap, but it does change the signature and makes some tests a bit uglier. LMK if you'd prefer wrap to look it up instead, or any other improvements.

- register endpoints with supported methods
- support OPTIONS requests, indicating supported methods
- extract method validation (error 405) from individual endpoints
- on 405 where multiple methods are allowed, create a single Allow
  header with comma-separated values, not multiple Allow headers.
Copy link
Member

@preetapan preetapan left a comment

Choose a reason for hiding this comment

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

Looks solid given how much surface area this is touching. I had one suggestion.

agent/http.go Outdated
if endpoints == nil {
endpoints = make(map[string]unboundEndpoint)
}
if endpoints[pattern] != nil {
if allowedMethods == nil {
Copy link
Member

Choose a reason for hiding this comment

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

Move creating the map to the init function, rather than a lazy initialization of this map here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved this here. Did I understand you correctly? Should endpoints move too?

} else if optionsStr != "OPTIONS,GET,POST" {
t.Fatalf("options method should set 'Allow' header correctly")
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you change this and TestMethodNotAllowed to loop through all the endpoints in allowedMethods and check their response codes/headers (instead of just the query/kv ones)?

Copy link
Contributor Author

@eddsteel eddsteel Feb 18, 2018

Choose a reason for hiding this comment

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

I realised from your comments that existing tests existed in http_oss_test.go so I moved my testing there.

This exposed an issue with specific prepared queries, since OPTIONS should return different methods if the path ends /execute or /explain. I got around that by allowing endpoints to register with no methods if they want to handle OPTIONS/NotFoundErrors themselves (this commit). I'm open to other solutions if this isn't the cleanest way.

@eddsteel
Copy link
Contributor Author

Thanks, I don't have much go experience so I'm grateful for all pointers. I'll update with these suggestions in the next couple of days.

a.Agent.LogWriter = logger.NewLogWriter(512)
defer a.Shutdown()

for _, tt := range expectedEndpoints {
Copy link
Member

Choose a reason for hiding this comment

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

Given that allowedMethods is package local and visible to this test there's no need to create another map. instead, you could loop over the keys and values in allowedMethods making the same OPTIONS call and verifying the list of options returned matches the values in allowedMethods.

Copy link
Contributor Author

@eddsteel eddsteel Feb 21, 2018

Choose a reason for hiding this comment

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

The problem with that is that

 {"OPTIONS,GET", "/v1/query/xxx/execute"},
 {"OPTIONS,GET", "/v1/query/xxx/explain"},

won't be tested, and it won't actually check that allowedMethods was correctly defined. Is that OK?

Copy link
Member

Choose a reason for hiding this comment

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

Good point. However this test method also relies on expectedEndpoints being comprehensively defined, so won't catch things that we forget to add here as we add more end points.

I suggest explicitly adding test cases for the special cases like /execute/ and /explain in this method after looping through allowedMethods. Also add a comment line for it explaining why the special case lines exist.

Any future end points (not special cased) added to the http server will be tested automatically without us having to maintain two lists.

@pearkes pearkes added this to the 1.0.7 milestone Mar 14, 2018
@eddsteel
Copy link
Contributor Author

Hi all, any more requested changes?

@preetapan preetapan merged commit c87699a into hashicorp:master Mar 16, 2018
@preetapan
Copy link
Member

thanks @eddsteel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CORS requests fail with a 405 method not allow for OPTIONS
4 participants