[OLINGO-752] Support for + sign as a separator

This commit is contained in:
Archana Rai 2017-08-09 13:37:27 +05:30
parent f7e5a5c716
commit 38f77daa5c
3 changed files with 128 additions and 2 deletions

View File

@ -19,6 +19,7 @@
package org.apache.olingo.fit.tecsvc.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@ -288,4 +289,107 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
assertTrue(content.contains("\"AdditionalPropString\":null"));
assertTrue(content.contains("\"@odata.type\":\"#olingo.odata.test1.CTBase\""));
}
@Test
public void testFilterWithSpaceFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16%20eq%201&odata-accept-forms-encoding=true");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertNotNull(content);
}
@Test
public void testFilterWithSpaceNoFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16%20eq%201");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertNotNull(content);
}
@Test
public void testFilterWithFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16+eq+1&odata-accept-forms-encoding=true");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertNotNull(content);
}
@Test
public void testFilterWithFormEncodingOrderChange() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?odata-accept-forms-encoding=true&$filter=PropertyInt16+eq+1");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertNotNull(content);
}
@Test
public void testFilterWithFalseFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16+eq+1&odata-accept-forms-encoding=false");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
}
@Test
public void testFilterWithNoFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16+eq+1");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
}
@Test
public void testFilterWithInvalidFormEncoding() throws Exception {
URL url = new URL(SERVICE_URI +
"ESAllPrim?$filter=PropertyInt16+eq+1&odata-accept-forms-encoding=qwer");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
connection.connect();
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
}
}

View File

@ -95,7 +95,7 @@ public class Parser {
throws UriParserException, UriValidationException {
UriInfoImpl contextUriInfo = new UriInfoImpl();
// Read the query options (system and custom options).
// This is done before parsing the resource path because the aliases have to be available there.
// System query options that can only be parsed with context from the resource path will be post-processed later.
@ -103,8 +103,12 @@ public class Parser {
query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
for (final QueryOption option : options) {
final String optionName = option.getName();
String value = option.getText();
if(UriDecoder.isFormEncoding()){
value = getFormEncodedValue(value);
}
// Parse the untyped option and retrieve a system-option or alias-option instance (or null for a custom option).
final QueryOption parsedOption = parseOption(optionName, option.getText());
final QueryOption parsedOption = parseOption(optionName, value);
try {
contextUriInfo.setQueryOption(parsedOption == null ? option : parsedOption);
} catch (final ODataRuntimeException e) {
@ -290,6 +294,13 @@ public class Parser {
return contextUriInfo;
}
private String getFormEncodedValue(String value) {
if(value.contains("+")){
value = value.replaceAll("\\+", " ");
}
return value;
}
private QueryOption parseOption(final String optionName, final String optionValue)
throws UriParserException, UriValidationException {
if (optionName.startsWith(DOLLAR)) {

View File

@ -28,6 +28,13 @@ import org.apache.olingo.server.core.uri.queryoption.CustomQueryOptionImpl;
public class UriDecoder {
private static final String ACCEPT_FORM_ENCODING = "odata-accept-forms-encoding";
private static boolean formEncoding = false;
public static boolean isFormEncoding() {
return formEncoding;
}
/** Splits the path string at '/' characters and percent-decodes the resulting path segments. */
protected static List<String> splitAndDecodePath(final String path) throws UriParserSyntaxException {
List<String> pathSegmentsDecoded = new ArrayList<String>();
@ -45,11 +52,15 @@ public class UriDecoder {
protected static List<QueryOption> splitAndDecodeOptions(final String queryOptionString)
throws UriParserSyntaxException {
List<QueryOption> queryOptions = new ArrayList<QueryOption>();
formEncoding = false;
for (final String option : split(queryOptionString, '&')) {
final int pos = option.indexOf('=');
final String name = pos >= 0 ? option.substring(0, pos) : option;
final String text = pos >= 0 ? option.substring(pos + 1) : "";
//OLINGO-846 We trim the query option text to be more lenient to wrong uri constructors
if(ACCEPT_FORM_ENCODING.equals(name)){
formEncoding = Boolean.parseBoolean(text);
}
queryOptions.add(new CustomQueryOptionImpl()
.setName(decode(name).trim())
.setText(decode(text).trim()));