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

FailFast if Content-Length header value is greater than configured max request size #59

Merged
merged 1 commit into from
Jun 3, 2017

Conversation

rabeyta
Copy link
Contributor

@rabeyta rabeyta commented May 31, 2017

Per #37 , Configured validation in RoutingHandler to fail fast if the content-length header is set and greater than the configured max request size once we know the endpoint for the request

This was put into the RoutingHandler instead of RequestInfoSetterHandler as we do not know the endpoint yet until after the RoutingHandler figures it out, which is necessary to process an endpoint's override of the global limit.

I also refactored a couple of the requestSize methods into HttpUtils to enable both handlers to share the code of determining the max size and if it is disabled.

@codecov-io
Copy link

codecov-io commented May 31, 2017

Codecov Report

Merging #59 into master will increase coverage by 0.18%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master      #59      +/-   ##
============================================
+ Coverage      90.2%   90.39%   +0.18%     
- Complexity     1947     1955       +8     
============================================
  Files           141      141              
  Lines          5790     5797       +7     
  Branches        765      767       +2     
============================================
+ Hits           5223     5240      +17     
+ Misses          387      378       -9     
+ Partials        180      179       -1
Impacted Files Coverage Δ Complexity Δ
...poste/server/handler/RequestInfoSetterHandler.java 100% <100%> (ø) 15 <0> (-5) ⬇️
...server/channelpipeline/HttpChannelInitializer.java 100% <100%> (ø) 29 <0> (ø) ⬇️
...src/main/java/com/nike/riposte/util/HttpUtils.java 100% <100%> (ø) 45 <5> (+5) ⬆️
...om/nike/riposte/server/handler/RoutingHandler.java 100% <100%> (ø) 17 <7> (+4) ⬆️
...ient/asynchttp/netty/StreamingAsyncHttpClient.java 73.42% <0%> (+0.46%) 38% <0%> (+1%) ⬆️
...mpipeline/DownstreamIdleChannelTimeoutHandler.java 90% <0%> (+5%) 5% <0%> (+1%) ⬆️
...oste/server/handler/IdleChannelTimeoutHandler.java 92.3% <0%> (+53.84%) 4% <0%> (+2%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2e57e93...ed19ec4. Read the comment docs.


maxRequestSizeInBytes = 10;
httpHeaders.set(CONTENT_LENGTH, 100);
httpHeaders.set(CONTENT_TYPE, APPLICATION_JSON);
Copy link
Member

Choose a reason for hiding this comment

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

Is the content-type header necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, i'll remove them as they are not necessary for the testing of this functionality. i added them just for typical use case even though they are ignored.

// given
doReturn(null).when(endpointMock).maxRequestSizeInBytesOverride();

maxRequestSizeInBytes = 10;
Copy link
Member

@nicmunroe nicmunroe Jun 1, 2017

Choose a reason for hiding this comment

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

Do you need to specify maxRequestSizeInBytes and create your own handlerSpy? Isn't this how handlerSpy is already setup?

Edit: I guess you're probably doing this for clarity vs. the other similar methods. That's fine.

Copy link
Contributor Author

@rabeyta rabeyta Jun 1, 2017

Choose a reason for hiding this comment

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

your edit is spot on. i kept it there for clarity. if you think of a way that is more clear let me know and i'll change it.

// given
doReturn(100).when(endpointMock).maxRequestSizeInBytesOverride();

maxRequestSizeInBytes = 99;
Copy link
Member

Choose a reason for hiding this comment

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

Should probably test when the global is above and below the endpoint override (to prove that the override is used no matter what). I'd recommend using a @DataProvider to set maxRequestSizeInBytes to 99 and 101 - the rest of the test should still work as-is I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call. i need to start using @dataProvider more often, i see the benefit.

done!

}

@Test
public void doChannelRead_HttpRequest_transfer_encoding_chunked_processed() {
Copy link
Member

Choose a reason for hiding this comment

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

Confusing test name. Recommend: doChannelRead_HttpRequest_does_not_throw_TooLongFrameException_if_content_length_header_is_missing(). I'd also suggest making it a @DataProvider test with a boolean isChunkedTransferEncoding argument to test when transfer-encoding is chunked or when all relevant headers are just missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

renamed and made suggested updates.

}

@Test
public void doChannelRead_HttpRequest_request_size_validation_endpoint_overridden_processed_message() {
Copy link
Member

Choose a reason for hiding this comment

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

Another confusing test name. Recommend: doChannelRead_HttpRequest_does_not_throw_TooLongFrameException_if_content_length_is_less_than_endpoint_overridden_value(). Also recommend making this a @DataProvider test with content-length set below the endpoint override as well as exactly the endpoint override value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for the names. renamed and updated with dataprovider

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I tend to just mix & match the given/when/then bits to come up with the test names. [target_method/code]_[does_thing_i_want/expect]_[given_some_scenario]. Thanks for humoring me.

@nicmunroe
Copy link
Member

The last thing I think this PR needs is some adjustments to VerifyRequestSizeValidationComponentTest to make sure we're covering both the content-length-exists cases (global and override) where we get the fail-fast behavior in RoutingHandler, and the content-length-missing cases (global and override) where we get the per-chunk-payload-size-checking behavior in RequestInfoSetterHandler.

I'm not sure how to get RestAssured to not automatically put in content-length header for the latter tests - if you can't figure out a way with RestAssured (does RestAssured let you do chunked transfer encoding? Maybe with the .body(InputStream) method?) then you'll have to do a raw Netty client again.

…ength header is set and greater than the configured max request size once we know the endpoint for the request
@rabeyta
Copy link
Contributor Author

rabeyta commented Jun 2, 2017

@nicmunroe That is a good call. I took those tests and duplicated them using the Netty client and transfer-encoding header instead of content-length like RestAssured does due to the underlining Apache client. This should then cover both of the scenarios we care about and enable a nice regression in case this logic needs to change.

If you had other ideas on the implementation let me know and i'll make the necessary updates.

@nicmunroe
Copy link
Member

Looks great, thank you!

@nicmunroe nicmunroe merged commit cf034a1 into Nike-Inc:master Jun 3, 2017
@rabeyta rabeyta deleted the failFastRequestTooBig branch June 5, 2017 15:34
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.

3 participants