mirror of
https://github.com/apache/olingo-odata4.git
synced 2025-03-06 16:49:09 +00:00
[OLINGO-472] Absolute Uris are not longer allowed
Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
parent
520acbce85
commit
297950a8d0
@ -42,6 +42,7 @@ import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.client.api.uri.UriFormat;
|
||||
import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
||||
import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
@ -65,6 +66,7 @@ public class BatchClientITCase extends AbstractTestITCase {
|
||||
@Before
|
||||
public void setup() {
|
||||
client.getConfiguration().setContinueOnError(false);
|
||||
client.getConfiguration().setBatchUriFormat(UriFormat.RELATIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -162,7 +164,6 @@ public class BatchClientITCase extends AbstractTestITCase {
|
||||
@Test
|
||||
public void testErrorWithContinueOnErrorPreferHeader() {
|
||||
client.getConfiguration().setContinueOnError(true);
|
||||
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
|
||||
request.setAccept(ACCEPT);
|
||||
|
||||
@ -446,7 +447,7 @@ public class BatchClientITCase extends AbstractTestITCase {
|
||||
}
|
||||
|
||||
private void appendGetRequest(final BatchManager manager, final String segment, final Object key) {
|
||||
URIBuilder targetURI = client.newURIBuilder(SERVICE_URI);
|
||||
URIBuilder targetURI = client.newBatchURIBuilder(SERVICE_URI);
|
||||
targetURI.appendEntitySetSegment(segment).appendKeySegment(key);
|
||||
|
||||
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
|
@ -53,6 +53,8 @@ public interface CommonODataClient<UT extends CommonUpdateType> {
|
||||
|
||||
CommonURIBuilder<?> newURIBuilder(String serviceRoot);
|
||||
|
||||
CommonURIBuilder<?> newBatchURIBuilder(String serviceRoot);
|
||||
|
||||
CommonFilterFactory getFilterFactory();
|
||||
|
||||
ODataSerializer getSerializer(ODataFormat format);
|
||||
|
@ -22,6 +22,7 @@ import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.apache.olingo.client.api.http.HttpClientFactory;
|
||||
import org.apache.olingo.client.api.http.HttpUriRequestFactory;
|
||||
import org.apache.olingo.client.api.uri.UriFormat;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
|
||||
@ -270,4 +271,17 @@ public interface Configuration {
|
||||
*/
|
||||
void setExecutor(ExecutorService executorService);
|
||||
|
||||
/**
|
||||
* Returns the current URI format
|
||||
*
|
||||
* @return current URI format
|
||||
*/
|
||||
UriFormat getUriFormat();
|
||||
|
||||
/**
|
||||
* Sets the current URI format
|
||||
*
|
||||
* @param format new URI format
|
||||
*/
|
||||
void setBatchUriFormat(UriFormat format);
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.client.api.uri;
|
||||
|
||||
/**
|
||||
* Determines if absolute or relative URIs are used
|
||||
*/
|
||||
public enum UriFormat {
|
||||
/**
|
||||
* Relative URI
|
||||
*
|
||||
* Example People(1)
|
||||
*/
|
||||
RELATIVE,
|
||||
|
||||
/**
|
||||
* Absolute URI
|
||||
*
|
||||
* Example https://host:1234/path/service/People(1)
|
||||
*/
|
||||
ABSOLUTE;
|
||||
}
|
@ -45,6 +45,9 @@ public interface ODataClient extends CommonODataClient<UpdateType> {
|
||||
@Override
|
||||
URIBuilder newURIBuilder(String serviceRoot);
|
||||
|
||||
@Override
|
||||
URIBuilder newBatchURIBuilder(String serviceRoot);
|
||||
|
||||
@Override
|
||||
FilterFactory getFilterFactory();
|
||||
|
||||
|
@ -47,6 +47,9 @@ public interface ODataClient extends CommonODataClient<UpdateType> {
|
||||
@Override
|
||||
URIBuilder newURIBuilder(String serviceRoot);
|
||||
|
||||
@Override
|
||||
URIBuilder newBatchURIBuilder(String serviceRoot);
|
||||
|
||||
@Override
|
||||
FilterFactory getFilterFactory();
|
||||
|
||||
|
@ -26,6 +26,7 @@ import java.util.concurrent.Executors;
|
||||
import org.apache.olingo.client.api.Configuration;
|
||||
import org.apache.olingo.client.api.http.HttpClientFactory;
|
||||
import org.apache.olingo.client.api.http.HttpUriRequestFactory;
|
||||
import org.apache.olingo.client.api.uri.UriFormat;
|
||||
import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
|
||||
import org.apache.olingo.client.core.http.DefaultHttpUriRequestFactory;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
@ -59,6 +60,8 @@ public class ConfigurationImpl implements Configuration {
|
||||
|
||||
private static final String CONTINUE_ON_ERROR = "continueOnError";
|
||||
|
||||
private static final String BATCH_URI_FORMAT = "batchUriFormat";
|
||||
|
||||
private final Map<String, Object> CONF = new HashMap<String, Object>();
|
||||
|
||||
private transient ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||
@ -230,4 +233,14 @@ public class ConfigurationImpl implements Configuration {
|
||||
public void setExecutor(final ExecutorService executorService) {
|
||||
executor = executorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriFormat getUriFormat() {
|
||||
return (UriFormat) getProperty(BATCH_URI_FORMAT, UriFormat.ABSOLUTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBatchUriFormat(UriFormat format) {
|
||||
setProperty(BATCH_URI_FORMAT, format);
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
@ -94,6 +95,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
||||
|
||||
this.version = version;
|
||||
this.configuration = configuration;
|
||||
|
||||
segments.add(new Segment(SegmentType.SERVICEROOT, serviceRoot));
|
||||
}
|
||||
|
||||
@ -268,6 +270,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
||||
@Override
|
||||
public URI build() {
|
||||
final StringBuilder segmentsBuilder = new StringBuilder();
|
||||
|
||||
for (Segment seg : segments) {
|
||||
if (segmentsBuilder.length() > 0 && seg.getType() != SegmentType.KEY) {
|
||||
switch (seg.getType()) {
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.client.core.uri.v3;
|
||||
|
||||
import org.apache.olingo.client.api.Configuration;
|
||||
import org.apache.olingo.client.api.uri.UriFormat;
|
||||
import org.apache.olingo.client.api.uri.v3.URIBuilder;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
public class BatchURIBuilderImpl extends URIBuilderImpl implements URIBuilder {
|
||||
|
||||
public BatchURIBuilderImpl(ODataServiceVersion version, Configuration configuration, String serviceRoot) {
|
||||
super(version, configuration, serviceRoot);
|
||||
|
||||
if (configuration.getUriFormat() == UriFormat.RELATIVE && segments.size() >= 0) {
|
||||
segments.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.olingo.client.core.uri.v4;
|
||||
|
||||
import org.apache.olingo.client.api.Configuration;
|
||||
import org.apache.olingo.client.api.uri.UriFormat;
|
||||
import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
public class BatchURIBuilderImpl extends URIBuilderImpl implements URIBuilder {
|
||||
|
||||
public BatchURIBuilderImpl(ODataServiceVersion version, Configuration configuration, String serviceRoot) {
|
||||
super(version, configuration, serviceRoot);
|
||||
|
||||
if(configuration.getUriFormat() == UriFormat.RELATIVE && segments.size() >= 0) {
|
||||
segments.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -40,6 +40,7 @@ import org.apache.olingo.client.core.communication.request.retrieve.v3.RetrieveR
|
||||
import org.apache.olingo.client.core.serialization.v3.ODataBinderImpl;
|
||||
import org.apache.olingo.client.core.serialization.v3.ODataDeserializerImpl;
|
||||
import org.apache.olingo.client.core.serialization.v3.ODataReaderImpl;
|
||||
import org.apache.olingo.client.core.uri.v3.BatchURIBuilderImpl;
|
||||
import org.apache.olingo.client.core.uri.v3.FilterFactoryImpl;
|
||||
import org.apache.olingo.client.core.uri.v3.URIBuilderImpl;
|
||||
import org.apache.olingo.commons.api.domain.v3.ODataObjectFactory;
|
||||
@ -87,6 +88,11 @@ public class ODataClientImpl extends AbstractODataClient<UpdateType> implements
|
||||
return new URIBuilderImpl(getServiceVersion(), configuration, serviceRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder newBatchURIBuilder(String serviceRoot) {
|
||||
return new BatchURIBuilderImpl(getServiceVersion(), getConfiguration(), serviceRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterFactory getFilterFactory() {
|
||||
return filterFactory;
|
||||
|
@ -43,6 +43,7 @@ import org.apache.olingo.client.core.communication.request.v4.AsyncRequestFactor
|
||||
import org.apache.olingo.client.core.serialization.v4.ODataBinderImpl;
|
||||
import org.apache.olingo.client.core.serialization.v4.ODataDeserializerImpl;
|
||||
import org.apache.olingo.client.core.serialization.v4.ODataReaderImpl;
|
||||
import org.apache.olingo.client.core.uri.v4.BatchURIBuilderImpl;
|
||||
import org.apache.olingo.client.core.uri.v4.FilterFactoryImpl;
|
||||
import org.apache.olingo.client.core.uri.v4.URIBuilderImpl;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataObjectFactory;
|
||||
@ -93,6 +94,11 @@ public class ODataClientImpl extends AbstractODataClient<UpdateType> implements
|
||||
return new URIBuilderImpl(getServiceVersion(), getConfiguration(), serviceRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder newBatchURIBuilder(String serviceRoot) {
|
||||
return new BatchURIBuilderImpl(getServiceVersion(), getConfiguration(), serviceRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterFactory getFilterFactory() {
|
||||
return filterFactory;
|
||||
|
@ -39,7 +39,8 @@ public class BatchDeserializerException extends BatchException {
|
||||
MISSING_CONTENT_TRANSFER_ENCODING,
|
||||
MISSING_CONTENT_TYPE,
|
||||
MISSING_MANDATORY_HEADER,
|
||||
FORBIDDEN_HEADER;
|
||||
FORBIDDEN_HEADER,
|
||||
FORBIDDEN_ABSOLUTE_URI;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
|
@ -29,8 +29,8 @@ import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException.MessageKeys;
|
||||
import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
|
||||
import org.apache.olingo.server.core.deserializer.batch.HttpRequestStatusLine.ODataURI;
|
||||
|
||||
public class BatchReferenceRewriter {
|
||||
private static final String REG_EX_REFERENCE = "\\$(.*)(/.*)?";
|
||||
@ -78,8 +78,7 @@ public class BatchReferenceRewriter {
|
||||
if (request.getMethod() == HttpMethod.POST) {
|
||||
// Create entity
|
||||
// The URI of the new resource will be generated by the server and published in the location header
|
||||
ODataURI uri = new ODataURI(response.getHeaders().get(HttpHeader.LOCATION), request.getRawBaseUri());
|
||||
resourceUri = uri.getRawODataPath();
|
||||
resourceUri = parseODataPath(response.getHeaders().get(HttpHeader.LOCATION), request.getRawBaseUri());
|
||||
} else {
|
||||
// Update, Upsert (PUT, PATCH, Delete)
|
||||
// These methods still addresses a given resource, so we use the URI given by the request
|
||||
@ -89,6 +88,16 @@ public class BatchReferenceRewriter {
|
||||
return resourceUri;
|
||||
}
|
||||
|
||||
private String parseODataPath(String uri, String rawBaseUri) throws BatchDeserializerException {
|
||||
int index = uri.indexOf(rawBaseUri);
|
||||
|
||||
if(index == 0) {
|
||||
return uri.substring(rawBaseUri.length());
|
||||
} else {
|
||||
throw new BatchDeserializerException("Invalid base uri or uri", MessageKeys.INVALID_URI, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private String removeSlash(String rawODataPath, boolean first) {
|
||||
final int indexOfSlash = rawODataPath.indexOf("/");
|
||||
if (first) {
|
||||
|
@ -30,7 +30,6 @@ import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException.MessageKeys;
|
||||
import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
|
||||
import org.apache.olingo.server.core.deserializer.batch.HttpRequestStatusLine.ODataURI;
|
||||
|
||||
public class BatchRequestTransformator {
|
||||
private final String baseUri;
|
||||
@ -101,10 +100,8 @@ public class BatchRequestTransformator {
|
||||
final boolean isChangeSet)
|
||||
throws BatchDeserializerException {
|
||||
final HttpRequestStatusLine statusLine =
|
||||
new HttpRequestStatusLine(operation.getHttpStatusLine(), baseUri, rawServiceResolutionUri, operation
|
||||
.getHeaders());
|
||||
new HttpRequestStatusLine(operation.getHttpStatusLine(), baseUri, rawServiceResolutionUri);
|
||||
statusLine.validateHttpMethod(isChangeSet);
|
||||
final ODataURI uri = statusLine.getUri();
|
||||
|
||||
validateBody(statusLine, operation);
|
||||
InputStream bodyStrean = getBodyStream(operation, statusLine);
|
||||
@ -114,11 +111,11 @@ public class BatchRequestTransformator {
|
||||
final ODataRequest request = new ODataRequest();
|
||||
request.setBody(bodyStrean);
|
||||
request.setMethod(statusLine.getMethod());
|
||||
request.setRawBaseUri(uri.getRawBaseUri());
|
||||
request.setRawODataPath(uri.getRawODataPath());
|
||||
request.setRawQueryPath(uri.getRawQueryPath());
|
||||
request.setRawRequestUri(uri.getRawRequestUri());
|
||||
request.setRawServiceResolutionUri(uri.getRawServiceResolutionUri());
|
||||
request.setRawBaseUri(statusLine.getRawBaseUri());
|
||||
request.setRawODataPath(statusLine.getRawODataPath());
|
||||
request.setRawQueryPath(statusLine.getRawQueryPath());
|
||||
request.setRawRequestUri(statusLine.getRawRequestUri());
|
||||
request.setRawServiceResolutionUri(statusLine.getRawServiceResolutionUri());
|
||||
|
||||
for (final HeaderField field : operation.getHeaders()) {
|
||||
request.addHeader(field.getFieldName(), field.getValues());
|
||||
|
@ -18,23 +18,20 @@
|
||||
*/
|
||||
package org.apache.olingo.server.core.deserializer.batch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException;
|
||||
import org.apache.olingo.server.api.batch.exception.BatchDeserializerException.MessageKeys;
|
||||
|
||||
public class HttpRequestStatusLine {
|
||||
private static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(?:\\?(.*))?");
|
||||
private static final Pattern PATTERN_ABSOLUTE_URI_WITH_HOST = Pattern.compile("(/[^?]*)(?:\\?(.*))?");
|
||||
private static final Pattern PATTERN_ABSOLUTE_URI = Pattern.compile("(http[s]?://[^?]*)(?:\\?(.*))?");
|
||||
|
||||
private static final Set<String> HTTP_BATCH_METHODS = new HashSet<String>(Arrays.asList(new String[] { "GET" }));
|
||||
private static final Set<String> HTTP_CHANGE_SET_METHODS = new HashSet<String>(Arrays.asList(new String[] { "POST",
|
||||
@ -46,15 +43,16 @@ public class HttpRequestStatusLine {
|
||||
|
||||
private HttpMethod method;
|
||||
private String httpVersion;
|
||||
private Header header;
|
||||
private ODataURI uri;
|
||||
private String rawServiceResolutionUri;
|
||||
private String rawQueryPath;
|
||||
private String rawODataPath;
|
||||
private String rawBaseUri;
|
||||
private String rawRequestUri;
|
||||
|
||||
public HttpRequestStatusLine(final Line httpStatusLine, final String baseUri, final String serviceResolutionUri,
|
||||
final Header requestHeader)
|
||||
public HttpRequestStatusLine(final Line httpStatusLine, final String baseUri, final String serviceResolutionUrir)
|
||||
throws BatchDeserializerException {
|
||||
statusLine = httpStatusLine;
|
||||
requestBaseUri = baseUri;
|
||||
header = requestHeader;
|
||||
|
||||
parse();
|
||||
}
|
||||
@ -64,7 +62,8 @@ public class HttpRequestStatusLine {
|
||||
|
||||
if (parts.length == 3) {
|
||||
method = parseMethod(parts[0]);
|
||||
uri = new ODataURI(parts[1], requestBaseUri, statusLine.getLineNumber(), header.getHeaders(HttpHeader.HOST));
|
||||
// uri = new ODataURI(parts[1], requestBaseUri, statusLine.getLineNumber(), header.getHeaders(HttpHeader.HOST));
|
||||
parseUri(parts[1], requestBaseUri);
|
||||
httpVersion = parseHttpVersion(parts[2]);
|
||||
} else {
|
||||
throw new BatchDeserializerException("Invalid status line", MessageKeys.INVALID_STATUS_LINE, statusLine
|
||||
@ -72,6 +71,40 @@ public class HttpRequestStatusLine {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseUri(String rawUri, String baseUrl) throws BatchDeserializerException {
|
||||
try {
|
||||
final URI uri = new URI(rawUri);
|
||||
|
||||
if (uri.isAbsolute()) {
|
||||
throw new BatchDeserializerException("Forbidden absolute uri", MessageKeys.FORBIDDEN_ABSOLUTE_URI, statusLine
|
||||
.getLineNumber());
|
||||
} else {
|
||||
final Matcher relativeUriMatcher = PATTERN_RELATIVE_URI.matcher(rawUri);
|
||||
|
||||
if (relativeUriMatcher.matches()) {
|
||||
buildUri(relativeUriMatcher.group(1), relativeUriMatcher.group(2));
|
||||
} else {
|
||||
throw new BatchDeserializerException("Malformed uri", MessageKeys.INVALID_URI, statusLine.getLineNumber());
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new BatchDeserializerException("Malformed uri", MessageKeys.INVALID_URI, statusLine.getLineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
private void buildUri(final String oDataPath, final String queryOptions) throws BatchDeserializerException {
|
||||
rawBaseUri = requestBaseUri;
|
||||
rawODataPath = "/" + oDataPath;
|
||||
rawRequestUri = requestBaseUri + rawODataPath;
|
||||
|
||||
if (queryOptions != null) {
|
||||
rawRequestUri += "?" + queryOptions;
|
||||
rawQueryPath = queryOptions;
|
||||
} else {
|
||||
rawQueryPath = "";
|
||||
}
|
||||
}
|
||||
|
||||
private HttpMethod parseMethod(final String method) throws BatchDeserializerException {
|
||||
try {
|
||||
return HttpMethod.valueOf(method.trim());
|
||||
@ -96,8 +129,7 @@ public class HttpRequestStatusLine {
|
||||
if (!validMethods.contains(getMethod().toString())) {
|
||||
if (isChangeSet) {
|
||||
throw new BatchDeserializerException("Invalid change set method", MessageKeys.INVALID_CHANGESET_METHOD,
|
||||
statusLine
|
||||
.getLineNumber());
|
||||
statusLine.getLineNumber());
|
||||
} else {
|
||||
throw new BatchDeserializerException("Invalid query operation method",
|
||||
MessageKeys.INVALID_QUERY_OPERATION_METHOD,
|
||||
@ -118,114 +150,27 @@ public class HttpRequestStatusLine {
|
||||
return statusLine.getLineNumber();
|
||||
}
|
||||
|
||||
public ODataURI getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static class ODataURI {
|
||||
private String rawServiceResolutionUri;
|
||||
private String rawQueryPath;
|
||||
private String rawODataPath;
|
||||
private String rawBaseUri;
|
||||
private String rawRequestUri;
|
||||
private final String requestBaseUri;
|
||||
private final int lineNumber;
|
||||
|
||||
public ODataURI(final String rawUri, final String requestBaseUri) throws BatchDeserializerException {
|
||||
this(rawUri, requestBaseUri, 0, new ArrayList<String>());
|
||||
}
|
||||
|
||||
public ODataURI(final String rawUri, final String requestBaseUri, final int lineNumber,
|
||||
final List<String> hostHeader)
|
||||
throws BatchDeserializerException {
|
||||
this.lineNumber = lineNumber;
|
||||
this.requestBaseUri = requestBaseUri;
|
||||
|
||||
final Matcher absoluteUriMatcher = PATTERN_ABSOLUTE_URI.matcher(rawUri);
|
||||
final Matcher absoluteUriWtithHostMatcher = PATTERN_ABSOLUTE_URI_WITH_HOST.matcher(rawUri);
|
||||
final Matcher relativeUriMatcher = PATTERN_RELATIVE_URI.matcher(rawUri);
|
||||
|
||||
if (absoluteUriMatcher.matches()) {
|
||||
buildUri(absoluteUriMatcher.group(1), absoluteUriMatcher.group(2));
|
||||
|
||||
} else if (absoluteUriWtithHostMatcher.matches()) {
|
||||
if (hostHeader != null && hostHeader.size() == 1) {
|
||||
buildUri(hostHeader.get(0) + absoluteUriWtithHostMatcher.group(1), absoluteUriWtithHostMatcher.group(2));
|
||||
} else {
|
||||
throw new BatchDeserializerException("Exactly one host header is required",
|
||||
MessageKeys.MISSING_MANDATORY_HEADER,
|
||||
lineNumber);
|
||||
}
|
||||
|
||||
} else if (relativeUriMatcher.matches()) {
|
||||
buildUri(requestBaseUri + "/" + relativeUriMatcher.group(1), relativeUriMatcher.group(2));
|
||||
|
||||
} else {
|
||||
throw new BatchDeserializerException("Invalid uri", MessageKeys.INVALID_URI, lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildUri(final String resourceUri, final String queryOptions) throws BatchDeserializerException {
|
||||
if (!resourceUri.startsWith(requestBaseUri)) {
|
||||
throw new BatchDeserializerException("Host do not match", MessageKeys.INVALID_URI, lineNumber);
|
||||
}
|
||||
|
||||
final int oDataPathIndex = resourceUri.indexOf(requestBaseUri);
|
||||
|
||||
rawBaseUri = requestBaseUri;
|
||||
rawODataPath = resourceUri.substring(oDataPathIndex + requestBaseUri.length());
|
||||
rawRequestUri = requestBaseUri + rawODataPath;
|
||||
|
||||
if (queryOptions != null) {
|
||||
rawRequestUri += "?" + queryOptions;
|
||||
rawQueryPath = queryOptions;
|
||||
} else {
|
||||
rawQueryPath = "";
|
||||
}
|
||||
public String getRequestBaseUri() {
|
||||
return requestBaseUri;
|
||||
}
|
||||
|
||||
public String getRawServiceResolutionUri() {
|
||||
return rawServiceResolutionUri;
|
||||
}
|
||||
|
||||
public void setRawServiceResolutionUri(final String rawServiceResolutionUri) {
|
||||
this.rawServiceResolutionUri = rawServiceResolutionUri;
|
||||
}
|
||||
|
||||
public String getRawQueryPath() {
|
||||
return rawQueryPath;
|
||||
}
|
||||
|
||||
public void setRawQueryPath(final String rawQueryPath) {
|
||||
this.rawQueryPath = rawQueryPath;
|
||||
}
|
||||
|
||||
public String getRawODataPath() {
|
||||
return rawODataPath;
|
||||
}
|
||||
|
||||
public void setRawODataPath(final String rawODataPath) {
|
||||
this.rawODataPath = rawODataPath;
|
||||
}
|
||||
|
||||
public String getRawBaseUri() {
|
||||
return rawBaseUri;
|
||||
}
|
||||
|
||||
public void setRawBaseUri(final String rawBaseUri) {
|
||||
this.rawBaseUri = rawBaseUri;
|
||||
}
|
||||
|
||||
public String getRawRequestUri() {
|
||||
return rawRequestUri;
|
||||
}
|
||||
|
||||
public void setRawRequestUri(final String rawRequestUri) {
|
||||
this.rawRequestUri = rawRequestUri;
|
||||
}
|
||||
|
||||
public String getRequestBaseUri() {
|
||||
return requestBaseUri;
|
||||
}
|
||||
}
|
||||
}
|
@ -116,5 +116,6 @@ BatchDeserializerException.MISSING_CONTENT_ID=Missing content-id at line '%1$s'.
|
||||
BatchDeserializerException.MISSING_CONTENT_TRANSFER_ENCODING=Missing content transfer encoding at line '%1$s'.
|
||||
BatchDeserializerException.MISSING_CONTENT_TYPE=Missing content-type at line '%1$s'.
|
||||
BatchDeserializerException.MISSING_MANDATORY_HEADER=Missing mandatory header at line '%1$s'.
|
||||
BatchDeserializerException.FORBIDDEN_ABSOLUTE_URI=Forbidden absolute request URI at line '%1$s'.
|
||||
|
||||
BatchSerializerExecption.MISSING_CONTENT_ID=Each request within a change set required exactly one content id.
|
@ -89,7 +89,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 3" + CRLF
|
||||
+ CRLF
|
||||
+ "PUT ESAllPrim(1) HTTP/1.1" + CRLF // Relative URI
|
||||
+ "PUT ESAllPrim(1) HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -98,8 +98,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 4" + CRLF
|
||||
+ CRLF
|
||||
+ "PUT /$3/PropertyInt32 HTTP/1.1" + CRLF // Absolute URI with separate Host header and ref.
|
||||
+ "Host: http://localhost:8080/odata" + CRLF
|
||||
+ "PUT $3/PropertyInt32 HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -108,7 +107,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 1" + CRLF
|
||||
+ CRLF
|
||||
+ "POST http://localhost:8080/odata/ESAllPrim HTTP/1.1" + CRLF // Absolute URI
|
||||
+ "POST ESAllPrim HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -117,7 +116,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 5" + CRLF
|
||||
+ CRLF
|
||||
+ "POST http://localhost:8080/odata/$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF // Absolute URI with ref.
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -126,7 +125,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 2" + CRLF
|
||||
+ CRLF
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF // Relative URI with ref.
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -135,8 +134,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 6" + CRLF
|
||||
+ CRLF
|
||||
+ "PUT /ESAllPrim(1) HTTP/1.1" + CRLF // Absolute URI with separate Host header
|
||||
+ "Host: http://localhost:8080/odata"
|
||||
+ "PUT ESAllPrim(1) HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -264,8 +262,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 2" + CRLF
|
||||
+ CRLF
|
||||
+ "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Host: http://localhost:8080/odata" + CRLF
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -288,8 +285,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 2" + CRLF
|
||||
+ CRLF
|
||||
+ "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Host: http://localhost:8080/odata" + CRLF
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
@ -390,8 +386,7 @@ public class MockedBatchHandlerTest {
|
||||
+ "Content-Transfer-Encoding: binary" + CRLF
|
||||
+ "Content-Id: 2" + CRLF
|
||||
+ CRLF
|
||||
+ "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Host: http://localhost:8080/odata" + CRLF
|
||||
+ "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
|
||||
+ "Content-Type: application/json;odata=verbose" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
|
@ -602,7 +602,7 @@ public class BatchRequestParserTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidUri() throws Exception {
|
||||
public void testAbsoluteUri() throws Exception {
|
||||
final String batch = ""
|
||||
+ "--batch_8194-cf13-1f56" + CRLF
|
||||
+ MIME_HEADERS
|
||||
@ -612,7 +612,7 @@ public class BatchRequestParserTest {
|
||||
+ CRLF
|
||||
+ "--batch_8194-cf13-1f56--";
|
||||
|
||||
parseInvalidBatchBody(batch, BatchDeserializerException.MessageKeys.INVALID_URI);
|
||||
parseInvalidBatchBody(batch, BatchDeserializerException.MessageKeys.FORBIDDEN_ABSOLUTE_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -627,17 +627,7 @@ public class BatchRequestParserTest {
|
||||
+ CRLF
|
||||
+ "--batch_8194-cf13-1f56--";
|
||||
|
||||
final List<BatchRequestPart> parts = parse(batch);
|
||||
assertEquals(1, parts.size());
|
||||
|
||||
final BatchRequestPart part = parts.get(0);
|
||||
assertEquals(1, part.getRequests().size());
|
||||
final ODataRequest request = part.getRequests().get(0);
|
||||
|
||||
assertEquals("http://localhost/odata/Employees('1')/EmployeeName", request.getRawRequestUri());
|
||||
assertEquals("http://localhost/odata", request.getRawBaseUri());
|
||||
assertEquals("/Employees('1')/EmployeeName", request.getRawODataPath());
|
||||
assertEquals("", request.getRawQueryPath());
|
||||
parseInvalidBatchBody(batch, BatchDeserializerException.MessageKeys.INVALID_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -651,23 +641,7 @@ public class BatchRequestParserTest {
|
||||
+ CRLF
|
||||
+ "--batch_8194-cf13-1f56--";
|
||||
|
||||
parseInvalidBatchBody(batch, MessageKeys.MISSING_MANDATORY_HEADER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriWithAbsolutePathMissingHostDulpicatedHeader() throws Exception {
|
||||
final String batch = ""
|
||||
+ "--batch_8194-cf13-1f56" + CRLF
|
||||
+ MIME_HEADERS
|
||||
+ CRLF
|
||||
+ "GET /odata/Employees('1')/EmployeeName HTTP/1.1" + CRLF
|
||||
+ "Host: http://localhost" + CRLF
|
||||
+ "Host: http://localhost/odata" + CRLF
|
||||
+ CRLF
|
||||
+ CRLF
|
||||
+ "--batch_8194-cf13-1f56--";
|
||||
|
||||
parseInvalidBatchBody(batch, MessageKeys.MISSING_MANDATORY_HEADER);
|
||||
parseInvalidBatchBody(batch, MessageKeys.INVALID_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2,7 +2,7 @@
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
GET http://localhost/odata/Employees('2')/EmployeeName?$format=json HTTP/1.1
|
||||
GET Employees('2')/EmployeeName?$format=json HTTP/1.1
|
||||
Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
|
||||
Accept-Language:en-US,en;q=0.7,en-UK;q=0.9
|
||||
MaxDataServiceVersion: 2.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user