Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion config/local/gateway-service.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
spring.profiles.include: diag
apiml:
service:
allowEncodedSlashes: true
hostname: localhost
ipAddress: 127.0.0.1
port: 10010
Expand Down
2 changes: 1 addition & 1 deletion config/zowe-api-dev/alternative_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ _BPX_JOBNAME=${ZOWE_PREFIX}${GATEWAY_CODE} java -Xms32m -Xmx256m -Xquickstart -X
-Dapiml.service.port=${GATEWAY_PORT} \
-Dapiml.service.discoveryServiceUrls=https://${ZOWE_EXPLORER_HOST}:${DISCOVERY_PORT}/eureka/ \
-Dapiml.service.preferIpAddress=false \
-Dapiml.service.allowEncodedSlashes=false \
-Dapiml.service.allowEncodedSlashes=true \
-Dapiml.cache.storage.location=${WORKSPACE_DIR}/api-mediation/ \
-Denvironment.ipAddress=${ZOWE_IP_ADDRESS} \
-Dapiml.gateway.timeoutMillis=30000 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.*;

/**
* This filter should run on all requests for services, which do not have enabled encoded characters in URL
*
* Special characters encoding is enabled on Tomcat and Spring Firewall so this filter takes over responsibility
* for filtering them.
* Encoded characters in URL are allowed only for services that have it explicitly configured on the metadata.
*
* This filter should run on all requests for services, which do not have enabled encoded characters in URL
* <p>
* Special characters encoding is enabled on Tomcat and Spring Firewall so this filter takes over responsibility
* for filtering them.
* Encoded characters in URL are allowed by default.
*/

@RequiredArgsConstructor
Expand Down Expand Up @@ -68,7 +67,8 @@ public boolean shouldFilter() {

List<Map<String, String>> enabledList = instanceList.stream()
.map(ServiceInstance::getMetadata)
.filter( metadata -> String.valueOf(true).equalsIgnoreCase(metadata.get(METADATA_KEY)) )
.filter(metadata -> metadata.get(METADATA_KEY) == null
|| String.valueOf(true).equalsIgnoreCase(metadata.get(METADATA_KEY)))
.collect(Collectors.toList());

if (enabledList.size() == instanceList.size()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class TomcatFilter implements Filter {
private final MessageService messageService;
private final ObjectMapper mapper;

@Value("${apiml.service.allowEncodedSlashes:#{false}}")
@Value("${apiml.service.allowEncodedSlashes:#{true}}")
private boolean allowEncodedSlashes;

@InjectApimlLogger
Expand Down
1 change: 0 additions & 1 deletion gateway-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ apiml:
ipAddress: 127.0.0.1 # IP address that is advertised in Eureka. Default is valid only for localhost
scheme: https # "https" or "http"
preferIpAddress: false
allowEncodedSlashes: false
ignoredHeadersWhenCorsEnabled: Access-Control-Request-Method,Access-Control-Request-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Credentials,Origin

gateway:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ class EncodedCharactersFilterTest {
private final String METADATA_KEY = EncodedCharactersFilter.METADATA_KEY;
private final String SERVICE_ID = "serviceid";

private final DefaultServiceInstance serviceInstanceWithConfiguration = new DefaultServiceInstance("INSTANCE1", SERVICE_ID ,"",0,true, new HashMap<String, String>());
private final DefaultServiceInstance serviceInstanceWithoutConfiguration = new DefaultServiceInstance("INSTANCE2", SERVICE_ID ,"",0,true, new HashMap<String, String>());
private final DefaultServiceInstance serviceInstanceWithTrueConfiguration = new DefaultServiceInstance("INSTANCE1", SERVICE_ID ,"",0,true, new HashMap<String, String>());
private final DefaultServiceInstance serviceInstanceWithFalseConfiguration = new DefaultServiceInstance("INSTANCE2", SERVICE_ID ,"",0,true, new HashMap<String, String>());
private final DefaultServiceInstance serviceInstanceWithNoConfiguration = new DefaultServiceInstance("INSTANCE3", SERVICE_ID ,"",0,true, new HashMap<String, String>());

private static MessageService messageService;

Expand All @@ -63,8 +64,8 @@ static void initMessageService() {
@BeforeEach
void setup() {
filter = new EncodedCharactersFilter(discoveryClient, messageService);
serviceInstanceWithConfiguration.getMetadata().put(METADATA_KEY, "true");
serviceInstanceWithoutConfiguration.getMetadata().put(METADATA_KEY, "false");
serviceInstanceWithTrueConfiguration.getMetadata().put(METADATA_KEY, "true");
serviceInstanceWithFalseConfiguration.getMetadata().put(METADATA_KEY, "false");
RequestContext ctx = RequestContext.getCurrentContext();
ctx.clear();
ctx.set(PROXY_KEY, "api/v1/" + SERVICE_ID);
Expand All @@ -73,18 +74,27 @@ void setup() {
}

@Test
void givenSingleInstance_WhenNotConfigured_ShouldFilter() {
void givenSingleInstance_WhenConfiguredFalse_ShouldFilter() {
List<ServiceInstance> instanceList = new ArrayList<>();
instanceList.add(serviceInstanceWithoutConfiguration);
instanceList.add(serviceInstanceWithFalseConfiguration);
when(discoveryClient.getInstances(SERVICE_ID)).thenReturn(instanceList);

assertThat(filter.shouldFilter(), is(equalTo(true)));
}

@Test
void givenSingleInstance_WhenConfigured_ShouldNotFilter() {
void givenSingleInstance_WhenConfiguredTrue_ShouldNotFilter() {
List<ServiceInstance> instanceList = new ArrayList<>();
instanceList.add(serviceInstanceWithConfiguration);
instanceList.add(serviceInstanceWithTrueConfiguration);
when(discoveryClient.getInstances(SERVICE_ID)).thenReturn(instanceList);

assertThat(filter.shouldFilter(), is(equalTo(false)));
}

@Test
void givenSingleInstance_WhenNotConfigured_ShouldNotFilter() {
List<ServiceInstance> instanceList = new ArrayList<>();
instanceList.add(serviceInstanceWithNoConfiguration);
when(discoveryClient.getInstances(SERVICE_ID)).thenReturn(instanceList);

assertThat(filter.shouldFilter(), is(equalTo(false)));
Expand All @@ -103,10 +113,10 @@ void shouldReturnFilterOrder() {
}

@Test
void givenMultipleInstances_WhenMixedSetup_ShouldBePesimistic() {
void givenMultipleInstances_WhenMixedSetup_ShouldBePessimistic() {
List<ServiceInstance> instanceList = new ArrayList<>();
instanceList.add(serviceInstanceWithoutConfiguration);
instanceList.add(serviceInstanceWithConfiguration);
instanceList.add(serviceInstanceWithFalseConfiguration);
instanceList.add(serviceInstanceWithTrueConfiguration);
when(discoveryClient.getInstances(SERVICE_ID)).thenReturn(instanceList);

assertThat(filter.shouldFilter(), is(equalTo(true)));
Expand Down
2 changes: 1 addition & 1 deletion gateway-service/src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ apiml:
ipAddress: 127.0.0.1 # IP address that is advertised in Eureka. Default is valid only for localhost
scheme: https # "https" or "http"
preferIpAddress: false
allowEncodedSlashes: false
allowEncodedSlashes: true
discoveryServiceUrls: https://localhost:10011/eureka/
corsEnabled: true
gateway:
Expand Down
2 changes: 1 addition & 1 deletion gateway-service/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ apiml:
ipAddress: 127.0.0.1 # IP address that is advertised in Eureka. Default is valid only for localhost
scheme: https # "https" or "http"
preferIpAddress: false
allowEncodedSlashes: false
allowEncodedSlashes: true
discoveryServiceUrls: https://localhost:10011/eureka/
ignoredHeadersWhenCorsEnabled: Access-Control-Request-Method,Access-Control-Request-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Credentials,Origin
gateway:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import org.zowe.apiml.util.config.GatewayServiceConfiguration;

import static io.restassured.RestAssured.given;
import static org.apache.http.HttpStatus.SC_BAD_REQUEST;
import static org.apache.http.HttpStatus.SC_OK;
import static org.apache.http.HttpStatus.*;
import static org.hamcrest.Matchers.is;

public class EncodedCharactersTest {
Expand Down Expand Up @@ -82,4 +81,29 @@ void shouldCallServiceWithGatewayNotAllowingAndReject() {
.then()
.statusCode(is(SC_BAD_REQUEST));
}

@Test
void shouldCallServiceWithGatewayAllowingAndAllow() {
final String encodedURI = "/api/v1/apicatalog/gf%2fd/testcall";

given()
.contentType(ContentType.JSON)
.urlEncodingEnabled(true)
.when()
.get(String.format("%s://%s:%s%s", scheme, host, port, encodedURI))
.then()
.statusCode(is(SC_NOT_FOUND)); //Means not a bad request. Route doesn't actually exist so NOT_FOUND is expected
}

@Test
void shouldCallServiceWithGatewayNotSetAndAllow() {
final String encodedURI = "/api/v1/apicatalog/gf%2fd/testcall";

given()
.contentType(ContentType.JSON)
.when()
.get(String.format("%s://%s:%s%s", scheme, host, port, encodedURI))
.then()
.statusCode(is(SC_NOT_FOUND)); //Means not a bad request. Route doesn't actually exist so NOT_FOUND is expected
}
}
2 changes: 1 addition & 1 deletion zowe-install/src/main/resources/component-scripts/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ _BPX_JOBNAME=${ZOWE_PREFIX}${GATEWAY_CODE} java -Xms32m -Xmx256m -Xquickstart \
-Dapiml.service.port=${GATEWAY_PORT} \
-Dapiml.service.discoveryServiceUrls=https://${ZOWE_EXPLORER_HOST}:${DISCOVERY_PORT}/eureka/ \
-Dapiml.service.preferIpAddress=true \
-Dapiml.service.allowEncodedSlashes=false \
-Dapiml.service.allowEncodedSlashes=true \
-Dapiml.service.corsEnabled=false \
-Dapiml.cache.storage.location=${WORKSPACE_DIR}/api-mediation/ \
-Denvironment.ipAddress=${ZOWE_IP_ADDRESS} \
Expand Down