/* * Copyright (c) 2013-2014 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.werval.controllers; import com.jayway.restassured.response.Response; import io.werval.runtime.routes.RoutesParserProvider; import io.werval.test.WervalHttpRule; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import org.junit.ClassRule; import org.junit.Test; import static com.jayway.restassured.RestAssured.expect; import static org.hamcrest.Matchers.either; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; public class ClasspathTest { @ClassRule public static final WervalHttpRule WERVAL = new WervalHttpRule( new RoutesParserProvider( "GET /*path Classpath.metainf( String path )" ) ); @Test public void givenNonExistentResourceWhenRequestingExpectNotFound() { expect(). statusCode( 404 ). when(). get( "/werval/donotexists.yet" ); } @Test public void givenResourceSmallerThanOneChunkWhenRequestingExpectCorrectResult() throws Exception { Response response = expect(). statusCode( 200 ). header( "Transfer-Encoding", "chunked" ). header( "Content-Type", "application/octet-stream" ). // Trailers are not accessible in HttpClient API // See http://httpcomponents.10934.n7.nabble.com/HTTP-Trailers-in-HttpClient-4-0-1-td15030.html // header( "X-Werval-Content-Length", "666" ). when(). get( "/werval/666B" ); assertThat( response.asByteArray().length, equalTo( 666 ) ); } @Test public void givenResourceSpanningSeveralCompleteChunksWhenRequestingExpectCorrectResult() throws Exception { Response response = expect(). statusCode( 200 ). header( "Transfer-Encoding", "chunked" ). header( "Content-Type", "application/octet-stream" ). // Trailers are not accessible in HttpClient API // See http://httpcomponents.10934.n7.nabble.com/HTTP-Trailers-in-HttpClient-4-0-1-td15030.html // header( "X-Werval-Content-Length", "32768" ). when(). get( "/werval/32KB" ); assertThat( response.asByteArray().length, equalTo( 32768 ) ); } @Test public void givenResourceSpanningOneChunkAndABitMoreWhenRequestingExpectCorrectResult() throws Exception { Response response = expect(). statusCode( 200 ). header( "Transfer-Encoding", "chunked" ). header( "Content-Type", "application/octet-stream" ). // Trailers are not accessible in HttpClient API // See http://httpcomponents.10934.n7.nabble.com/HTTP-Trailers-in-HttpClient-4-0-1-td15030.html // header( "X-Werval-Content-Length", "32768" ). when(). get( "/werval/8858B" ); assertThat( response.asByteArray().length, equalTo( 8858 ) ); } @Test public void indexFiles() { int expectedLength = new BigDecimal( new File( "src/test/resources/META-INF/resources/werval/index.html" ).length() ).intValueExact(); Response response = expect() .statusCode( 200 ) .when() .get( "/werval/index.html" ); assertThat( response.body().asByteArray().length, equalTo( expectedLength ) ); response = expect() .statusCode( 200 ) .when() .get( "/werval" ); assertThat( response.body().asByteArray().length, equalTo( expectedLength ) ); } @Test public void givenDirectoryTraversalAttemptsWhenProcessingExpectBadRequest() throws Exception { // Simple directory traversal assertDirectoryTraversalAttemptFailed( "/werval/../../../shadow" ); assertDirectoryTraversalAttemptFailed( "/../shadow" ); // URI encoded directory traversal assertDirectoryTraversalAttemptFailed( "/%2e%2e%2fshadow" ); assertDirectoryTraversalAttemptFailed( "/%2e%2e%5cshadow" ); assertDirectoryTraversalAttemptFailed( "/%2e%2e/shadow" ); assertDirectoryTraversalAttemptFailed( "/%2e./shadow" ); assertDirectoryTraversalAttemptFailed( "/.%2e/shadow" ); assertDirectoryTraversalAttemptFailed( "/..%2fshadow" ); assertDirectoryTraversalAttemptFailed( "/..%5cshadow" ); // Unicode / UTF-8 encoded directory traversal assertDirectoryTraversalAttemptFailed( "/\u002e\u002e\u002fshadow" ); assertDirectoryTraversalAttemptFailed( "/\u002e.\u002fshadow" ); assertDirectoryTraversalAttemptFailed( "/.\u002e\u002fshadow" ); assertDirectoryTraversalAttemptFailed( "/..\u002fshadow" ); assertDirectoryTraversalAttemptFailed( "/\u002e\u002e/shadow" ); } private void assertDirectoryTraversalAttemptFailed( String path ) throws IOException { expect(). statusCode( either( is( 400 ) ).or( is( 404 ) ) ). when(). get( path ); } }