You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/10/14 14:00:24 UTC
git commit: [OLINGO-436] Fix: Validate request HTTP version
Repository: olingo-odata2
Updated Branches:
refs/heads/master e7e44471c -> 86c4ddc42
[OLINGO-436] Fix: Validate request HTTP version
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/86c4ddc4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/86c4ddc4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/86c4ddc4
Branch: refs/heads/master
Commit: 86c4ddc4205aa29d744ec8b3047fae15541a1493
Parents: e7e4447
Author: Christian Holzer <c....@sap.com>
Authored: Tue Oct 14 13:04:58 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Tue Oct 14 13:59:48 2014 +0200
----------------------------------------------------------------------
.../odata2/api/batch/BatchParserResult.java | 6 +
.../odata2/core/batch/v2/BatchParserCommon.java | 103 ++--------
.../batch/v2/BatchRequestTransformator.java | 75 ++------
.../batch/v2/BatchResponseTransformator.java | 34 +---
.../core/batch/v2/BatchTransformatorCommon.java | 188 ++++++++++++++++++-
.../core/batch/BatchRequestParserTest.java | 92 +++++++--
.../odata2/core/batch/BatchRequestTest.java | 1 -
.../BufferedReaderIncludingLineEndingsTest.java | 13 +-
8 files changed, 322 insertions(+), 190 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
index 1e2054f..842933d 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
@@ -18,6 +18,12 @@
******************************************************************************/
package org.apache.olingo.odata2.api.batch;
+/**
+ * A BatchParserResult
+ *
+ * <p> BatchParserResult represents a BatchRequestPart or a BatchResponse part.
+ *
+ */
public interface BatchParserResult {
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index cac340e..62f03c2 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -20,8 +20,6 @@ package org.apache.olingo.odata2.core.batch.v2;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -35,10 +33,6 @@ import java.util.regex.Pattern;
import org.apache.olingo.odata2.api.batch.BatchException;
import org.apache.olingo.odata2.api.commons.HttpContentType;
import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.apache.olingo.odata2.api.uri.PathSegment;
-import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
-import org.apache.olingo.odata2.core.PathInfoImpl;
import org.apache.olingo.odata2.core.batch.AcceptParser;
import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.odata2.core.commons.Decoder;
@@ -58,16 +52,16 @@ public class BatchParserCommon {
public static final Pattern PATTERN_HEADER_LINE = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*");
public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile(REG_EX_APPLICATION_HTTP,
Pattern.CASE_INSENSITIVE);
- private static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(\\?.*)?");
+ public static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(\\?.*)?");
public static String trimLineListToLength(final List<Line> list, final int length) {
- final String message = stringListToString(list);
+ final String message = lineListToString(list);
final int lastIndex = Math.min(length, message.length());
return (lastIndex > 0) ? message.substring(0, lastIndex) : "";
}
- public static String stringListToString(final List<Line> list) {
+ public static String lineListToString(final List<Line> list) {
StringBuilder builder = new StringBuilder();
for (Line currentLine : list) {
@@ -77,16 +71,16 @@ public class BatchParserCommon {
return builder.toString();
}
- public static InputStream convertMessageToInputStream(final List<Line> messageList, final int contentLength)
+ public static InputStream convertLineListToInputStream(final List<Line> messageList, final int contentLength)
throws BatchException {
final String message = trimLineListToLength(messageList, contentLength);
return new ByteArrayInputStream(message.getBytes());
}
- public static InputStream convertMessageToInputStream(final List<Line> messageList)
+ public static InputStream convertLineListToInputStream(final List<Line> messageList)
throws BatchException {
- final String message = stringListToString(messageList);
+ final String message = lineListToString(messageList);
return new ByteArrayInputStream(message.getBytes());
}
@@ -158,14 +152,14 @@ public class BatchParserCommon {
}
public static Header consumeHeaders(final List<Line> remainingMessage) throws BatchException {
- final int lineNumberOfHeader = remainingMessage.size() != 0 ? remainingMessage.get(0).getLineNumber() : 0;
- final Header headers = new Header(lineNumberOfHeader);
- boolean isHeader = true;
+ final int headerLineNumber = remainingMessage.size() != 0 ? remainingMessage.get(0).getLineNumber() : 0;
+ final Header headers = new Header(headerLineNumber);
final Iterator<Line> iter = remainingMessage.iterator();
final AcceptParser acceptParser = new AcceptParser();
Line currentLine;
int acceptLineNumber = 0;
int acceptLanguageLineNumber = 0;
+ boolean isHeader = true;
while (iter.hasNext() && isHeader) {
currentLine = iter.next();
@@ -224,6 +218,14 @@ public class BatchParserCommon {
}
}
+ private static String trimQuota(String boundary) {
+ if (boundary.matches("\".*\"")) {
+ boundary = boundary.replace("\"", "");
+ }
+
+ return boundary;
+ }
+
public static Map<String, List<String>> parseQueryParameter(final Line httpRequest) {
Map<String, List<String>> queryParameter = new HashMap<String, List<String>>();
@@ -254,75 +256,4 @@ public class BatchParserCommon {
return queryParameter;
}
-
- public static PathInfo parseRequestUri(final Line httpStatusLine, final PathInfo batchRequestPathInfo,
- final String baseUri, final int line)
- throws BatchException {
-
- final String odataPathSegmentsAsString;
- final String queryParametersAsString;
-
- PathInfoImpl pathInfo = new PathInfoImpl();
- pathInfo.setServiceRoot(batchRequestPathInfo.getServiceRoot());
- pathInfo.setPrecedingPathSegment(batchRequestPathInfo.getPrecedingSegments());
-
- String[] requestParts = httpStatusLine.toString().split(" ");
- if (requestParts.length == 3) {
- String uri = requestParts[1];
- Pattern regexRequestUri;
-
- try {
- URI uriObject = new URI(uri);
- if (uriObject.isAbsolute()) {
- regexRequestUri = Pattern.compile(baseUri + "/([^/][^?]*)(\\?.*)?");
- } else {
- regexRequestUri = PATTERN_RELATIVE_URI;
-
- }
-
- Matcher uriParts = regexRequestUri.matcher(uri);
-
- if (uriParts.lookingAt() && uriParts.groupCount() == 2) {
- odataPathSegmentsAsString = uriParts.group(1);
- queryParametersAsString = uriParts.group(2) != null ? uriParts.group(2) : "";
-
- pathInfo.setODataPathSegment(parseODataPathSegments(odataPathSegmentsAsString));
- if (!odataPathSegmentsAsString.startsWith("$")) {
- String requestUri = baseUri + "/" + odataPathSegmentsAsString + queryParametersAsString;
- pathInfo.setRequestUri(new URI(requestUri));
- }
-
- } else {
- throw new BatchException(BatchException.INVALID_URI.addContent(httpStatusLine.getLineNumber()));
- }
-
- } catch (URISyntaxException e) {
- throw new BatchException(BatchException.INVALID_URI.addContent(line), e);
- }
- } else {
- throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpStatusLine.toString())
- .addContent(line));
- }
-
- return pathInfo;
- }
-
- public static List<PathSegment> parseODataPathSegments(final String odataPathSegmentsAsString) {
- final List<PathSegment> odataPathSegments = new ArrayList<PathSegment>();
- final String[] pathParts = odataPathSegmentsAsString.split("/");
-
- for (final String pathSegment : pathParts) {
- odataPathSegments.add(new ODataPathSegmentImpl(pathSegment, null));
- }
-
- return odataPathSegments;
- }
-
- private static String trimQuota(String boundary) {
- if (boundary.matches("\".*\"")) {
- boundary = boundary.replace("\"", "");
- }
-
- return boundary;
- }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
index 4faac22..66600b5 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -21,12 +21,9 @@ package org.apache.olingo.odata2.core.batch.v2;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
-import java.util.Set;
import org.apache.olingo.odata2.api.batch.BatchException;
import org.apache.olingo.odata2.api.batch.BatchParserResult;
@@ -37,15 +34,11 @@ import org.apache.olingo.odata2.api.processor.ODataRequest.ODataRequestBuilder;
import org.apache.olingo.odata2.api.uri.PathInfo;
import org.apache.olingo.odata2.core.batch.BatchHelper;
import org.apache.olingo.odata2.core.batch.BatchRequestPartImpl;
-import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
+import org.apache.olingo.odata2.core.batch.v2.BatchTransformatorCommon.HttpRequestStatusLine;
import org.apache.olingo.odata2.core.batch.v2.Header.HeaderField;
public class BatchRequestTransformator implements BatchTransformator {
- 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",
- "PUT", "DELETE", "MERGE", "PATCH" }));
-
@Override
public List<BatchParserResult> transform(final BatchBodyPart bodyPart, final PathInfo pathInfo, final String baseUri)
throws BatchException {
@@ -89,19 +82,21 @@ public class BatchRequestTransformator implements BatchTransformator {
private ODataRequest createRequest(final BatchQueryOperation operation, final Header headers,
final PathInfo pathInfo, final String baseUri, final boolean isChangeSet) throws BatchException {
- final int httpLineNumber = operation.getHttpStatusLine().getLineNumber();
- ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpStatusLine());
- validateHttpMethod(httpMethod, isChangeSet, httpLineNumber);
- validateBody(httpMethod, operation, httpLineNumber);
- InputStream bodyStrean = getBodyStream(operation, headers, httpMethod);
+ final HttpRequestStatusLine statusLine = new HttpRequestStatusLine( operation.getHttpStatusLine(),
+ baseUri,
+ pathInfo);
+ statusLine.validateHttpMethod(isChangeSet);
+
+ validateBody(statusLine, operation);
+ InputStream bodyStrean = getBodyStream(operation, headers, statusLine);
- ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
+ ODataRequestBuilder requestBuilder = ODataRequest.method(statusLine.getMethod())
.acceptableLanguages(getAcceptLanguageHeaders(headers))
.acceptHeaders(headers.getHeaders(HttpHeaders.ACCEPT))
.allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpStatusLine()))
.body(bodyStrean)
.requestHeaders(headers.toMultiMap())
- .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpStatusLine(), pathInfo, baseUri, 0));
+ .pathInfo(statusLine.getPathInfo());
final String contentType = headers.getHeader(HttpHeaders.CONTENT_TYPE);
if (contentType != null) {
@@ -111,30 +106,32 @@ public class BatchRequestTransformator implements BatchTransformator {
return requestBuilder.build();
}
- private void validateBody(final ODataHttpMethod httpStatusLine, final BatchQueryOperation operation, final int line)
+ private void validateBody(final HttpRequestStatusLine httpStatusLine, final BatchQueryOperation operation)
throws BatchException {
- if (HTTP_BATCH_METHODS.contains(httpStatusLine.toString()) && isUnvalidGetRequestBody(operation)) {
- throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpStatusLine).addContent(line));
+ if (httpStatusLine.getMethod().equals(ODataHttpMethod.GET) && isUnvalidGetRequestBody(operation)) {
+ throw new BatchException(BatchException.INVALID_REQUEST_LINE
+ .addContent(httpStatusLine.getMethod())
+ .addContent(httpStatusLine.getLineNumber()));
}
}
private boolean isUnvalidGetRequestBody(final BatchQueryOperation operation) {
return (operation.getBody().size() > 1)
- || (operation.getBody().size() == 1 && !operation.getBody().get(0).toString().trim().equals(""));
+ || (operation.getBody().size() == 1 && !"".equals(operation.getBody().get(0).toString().trim()));
}
private InputStream getBodyStream(final BatchQueryOperation operation, final Header headers,
- final ODataHttpMethod httpMethod) throws BatchException {
+ final HttpRequestStatusLine httpStatusLine) throws BatchException {
- if (HTTP_BATCH_METHODS.contains(httpMethod.toString())) {
+ if (httpStatusLine.getMethod().equals(ODataHttpMethod.GET)) {
return new ByteArrayInputStream(new byte[0]);
} else {
int contentLength = BatchTransformatorCommon.getContentLength(headers);
if (contentLength == -1) {
- return BatchParserCommon.convertMessageToInputStream(operation.getBody());
+ return BatchParserCommon.convertLineListToInputStream(operation.getBody());
} else {
- return BatchParserCommon.convertMessageToInputStream(operation.getBody(), contentLength);
+ return BatchParserCommon.convertLineListToInputStream(operation.getBody(), contentLength);
}
}
}
@@ -157,19 +154,6 @@ public class BatchRequestTransformator implements BatchTransformator {
return headers;
}
- private void validateHttpMethod(final ODataHttpMethod httpMethod, final boolean isChangeSet, final int line)
- throws BatchException {
- Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
-
- if (!validMethods.contains(httpMethod.toString())) {
- if (isChangeSet) {
- throw new BatchException(BatchException.INVALID_CHANGESET_METHOD.addContent(line));
- } else {
- throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD.addContent(line));
- }
- }
- }
-
private List<Locale> getAcceptLanguageHeaders(final Header headers) {
final List<String> acceptLanguageValues = headers.getHeaders(HttpHeaders.ACCEPT_LANGUAGE);
List<Locale> acceptLanguages = new ArrayList<Locale>();
@@ -188,23 +172,4 @@ public class BatchRequestTransformator implements BatchTransformator {
return acceptLanguages;
}
- private ODataHttpMethod getHttpMethod(final Line httpRequest) throws BatchException {
- ODataHttpMethod result = null;
-
- String[] parts = httpRequest.toString().split(" ");
-
- if (parts.length == 3) {
- try {
- result = ODataHttpMethod.valueOf(parts[0]);
- } catch (IllegalArgumentException e) {
- throw new BatchException(BatchException.MISSING_METHOD.addContent(httpRequest.getLineNumber()), e);
- }
- } else {
- throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpRequest.toString()).addContent(
- httpRequest.getLineNumber()));
- }
-
- return result;
- }
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
index e800673..5e4198c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
@@ -20,8 +20,6 @@ package org.apache.olingo.odata2.core.batch.v2;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.olingo.odata2.api.batch.BatchException;
import org.apache.olingo.odata2.api.batch.BatchParserResult;
@@ -29,12 +27,10 @@ import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
import org.apache.olingo.odata2.api.uri.PathInfo;
import org.apache.olingo.odata2.core.batch.BatchHelper;
import org.apache.olingo.odata2.core.batch.BatchSingleResponseImpl;
-import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
+import org.apache.olingo.odata2.core.batch.v2.BatchTransformatorCommon.HttpResponsetStatusLine;
public class BatchResponseTransformator implements BatchTransformator {
- private static final String REG_EX_STATUS_LINE = "(?:HTTP/[0-9]\\.[0-9])\\s([0-9]{3})\\s([\\S ]+)\\s*";
-
public BatchResponseTransformator() {}
@Override
@@ -81,46 +77,26 @@ public class BatchResponseTransformator implements BatchTransformator {
private BatchSingleResponse transformQueryOperation(final BatchQueryOperation operation, final String contentId)
throws BatchException {
- final Matcher statusMatcher = prepareStatusLineMatcher(operation.getHttpStatusLine());
+ final HttpResponsetStatusLine statusLine = new HttpResponsetStatusLine(operation.getHttpStatusLine());
BatchSingleResponseImpl response = new BatchSingleResponseImpl();
response.setContentId(contentId);
response.setHeaders(operation.getHeaders().toSingleMap());
- response.setStatusCode(getStatusCode(statusMatcher));
- response.setStatusInfo(getStatusInfo(statusMatcher));
+ response.setStatusCode(statusLine.getStatusCode());
+ response.setStatusInfo(statusLine.getStatusInfo());
response.setBody(getBody(operation));
return response;
}
- private Matcher prepareStatusLineMatcher(final Line httpStatusLine) throws BatchException {
- final Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
- final Matcher matcher = regexPattern.matcher(httpStatusLine.toString());
-
- if (matcher.find()) {
- return matcher;
- } else {
- throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(httpStatusLine.toString())
- .addContent(httpStatusLine.getLineNumber()));
- }
- }
-
private String getBody(final BatchQueryOperation operation) throws BatchException {
int contentLength = BatchTransformatorCommon.getContentLength(operation.getHeaders());
if (contentLength == -1) {
- return BatchParserCommon.stringListToString(operation.getBody());
+ return BatchParserCommon.lineListToString(operation.getBody());
} else {
return BatchParserCommon.trimLineListToLength(operation.getBody(), contentLength);
}
}
- private String getStatusCode(final Matcher matcher) throws BatchException {
- return matcher.group(1);
- }
-
- private String getStatusInfo(final Matcher matcher) throws BatchException {
- return matcher.group(2);
- }
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
index 521b4e1..c07c06f 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -18,16 +18,29 @@
******************************************************************************/
package org.apache.olingo.odata2.core.batch.v2;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+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.odata2.api.batch.BatchException;
import org.apache.olingo.odata2.api.commons.HttpContentType;
import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
+import org.apache.olingo.odata2.core.PathInfoImpl;
import org.apache.olingo.odata2.core.batch.BatchHelper;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.odata2.core.batch.v2.Header.HeaderField;
public class BatchTransformatorCommon {
-
public static void validateContentType(final Header headers) throws BatchException {
List<String> contentTypes = headers.getHeaders(HttpHeaders.CONTENT_TYPE);
@@ -87,4 +100,177 @@ public class BatchTransformatorCommon {
return -1;
}
+
+ public static class HttpResponsetStatusLine {
+ private static final String REG_EX_STATUS_LINE = "(?:HTTP/[0-9]\\.[0-9])\\s([0-9]{3})\\s([\\S ]+)\\s*";
+ private Line httpStatusLine;
+ private String statusCode;
+ private String statusInfo;
+
+ public HttpResponsetStatusLine(final Line httpStatusLine) throws BatchException {
+ this.httpStatusLine = httpStatusLine;
+ parse();
+ }
+
+ private void parse() throws BatchException {
+ final Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
+ final Matcher matcher = regexPattern.matcher(httpStatusLine.toString());
+
+ if (matcher.find()) {
+ statusCode = matcher.group(1);
+ statusInfo = matcher.group(2);
+ } else {
+ throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(httpStatusLine.toString())
+ .addContent(httpStatusLine.getLineNumber()));
+ }
+ }
+
+ public String getStatusCode() {
+ return statusCode;
+ }
+
+ public String getStatusInfo() {
+ return statusInfo;
+ }
+ }
+
+ public static class HttpRequestStatusLine {
+ 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",
+ "PUT", "DELETE", "MERGE", "PATCH" }));
+ private static final String HTTP_VERSION = "HTTP/1.1";
+
+ final private Line statusLine;
+ final String requestBaseUri;
+ final PathInfo batchRequestPathInfo;
+
+ private ODataHttpMethod method;
+ private PathInfo pathInfo;
+ private String httpVersion;
+
+ public HttpRequestStatusLine(final Line httpStatusLine, final String baseUri, final PathInfo pathInfo)
+ throws BatchException {
+ statusLine = httpStatusLine;
+ requestBaseUri = baseUri;
+ batchRequestPathInfo = pathInfo;
+
+ parse();
+ }
+
+ private void parse() throws BatchException {
+ final String[] parts = statusLine.toString().split(" ");
+
+ if (parts.length == 3) {
+ try {
+ method = parseMethod(parts[0]);
+ pathInfo = parseUri(parts[1]);
+ httpVersion = parseHttpVersion(parts[2]);
+ } catch (IllegalArgumentException e) {
+ throw new BatchException(BatchException.MISSING_METHOD.addContent(statusLine.getLineNumber()), e);
+ }
+ } else {
+ throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(statusLine.toString())
+ .addContent(statusLine.getLineNumber()));
+ }
+ }
+
+ private ODataHttpMethod parseMethod(final String method) throws BatchException {
+ try {
+ return ODataHttpMethod.valueOf(method.trim());
+ } catch (IllegalArgumentException e) {
+ throw new BatchException(BatchException.MISSING_METHOD.addContent(statusLine.getLineNumber()), e);
+ }
+ }
+
+ private PathInfo parseUri(final String uri)
+ throws BatchException {
+ final PathInfoImpl pathInfo = new PathInfoImpl();
+ final String odataPathSegmentsAsString;
+ final String queryParametersAsString;
+ Pattern regexRequestUri;
+
+ pathInfo.setServiceRoot(batchRequestPathInfo.getServiceRoot());
+ pathInfo.setPrecedingPathSegment(batchRequestPathInfo.getPrecedingSegments());
+
+ try {
+ URI uriObject = new URI(uri);
+ if (uriObject.isAbsolute()) {
+ regexRequestUri = Pattern.compile(requestBaseUri + "/([^/][^?]*)(\\?.*)?");
+ } else {
+ regexRequestUri = BatchParserCommon.PATTERN_RELATIVE_URI;
+
+ }
+
+ Matcher uriParts = regexRequestUri.matcher(uri);
+
+ if (uriParts.lookingAt() && uriParts.groupCount() == 2) {
+ odataPathSegmentsAsString = uriParts.group(1);
+ queryParametersAsString = uriParts.group(2) != null ? uriParts.group(2) : "";
+
+ pathInfo.setODataPathSegment(parseODataPathSegments(odataPathSegmentsAsString));
+ if (!odataPathSegmentsAsString.startsWith("$")) {
+ String requestUri = requestBaseUri + "/" + odataPathSegmentsAsString + queryParametersAsString;
+ pathInfo.setRequestUri(new URI(requestUri));
+ }
+
+ } else {
+ throw new BatchException(BatchException.INVALID_URI.addContent(statusLine.getLineNumber()));
+ }
+ } catch (URISyntaxException e) {
+ throw new BatchException(BatchException.INVALID_URI.addContent(statusLine.getLineNumber()), e);
+ }
+
+ return pathInfo;
+ }
+
+ private List<PathSegment> parseODataPathSegments(final String odataPathSegmentsAsString) {
+ final List<PathSegment> odataPathSegments = new ArrayList<PathSegment>();
+ final String[] pathParts = odataPathSegmentsAsString.split("/");
+
+ for (final String pathSegment : pathParts) {
+ odataPathSegments.add(new ODataPathSegmentImpl(pathSegment, null));
+ }
+
+ return odataPathSegments;
+ }
+
+ private String parseHttpVersion(final String httpVersion) throws BatchException {
+ if (!HTTP_VERSION.equals(httpVersion.trim())) {
+ throw new BatchException(BatchException.INVALID_REQUEST_LINE
+ .addContent(statusLine.toString())
+ .addContent(statusLine.getLineNumber()));
+ } else {
+ return HTTP_VERSION;
+ }
+ }
+
+ public void validateHttpMethod(boolean isChangeSet) throws BatchException {
+ Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
+
+ if (!validMethods.contains(getMethod().toString())) {
+ if (isChangeSet) {
+ throw new BatchException(BatchException.INVALID_CHANGESET_METHOD.addContent(statusLine.getLineNumber()));
+ } else {
+ throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD
+ .addContent(statusLine.getLineNumber()));
+ }
+ }
+ }
+
+ public ODataHttpMethod getMethod() {
+ return method;
+ }
+
+ public PathInfo getPathInfo() {
+ return pathInfo;
+ }
+
+ public String getHttpVersion() {
+ return httpVersion;
+ }
+
+ public int getLineNumber() {
+ return statusLine.getLineNumber();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index 52550fb..1a374a5 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -41,7 +41,6 @@ import org.apache.olingo.odata2.core.PathInfoImpl;
import org.apache.olingo.odata2.core.batch.v2.BatchParser;
import org.apache.olingo.odata2.testutil.helper.StringHelper;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
public class BatchRequestParserTest {
@@ -119,7 +118,7 @@ public class BatchRequestParserTest {
}
}
}
-
+
@Test
public void testImageInContent() throws IOException, BatchException, URISyntaxException {
String fileName = "/batchWithContent.batch";
@@ -271,6 +270,51 @@ public class BatchRequestParserTest {
parseInvalidBatchBody(batch);
}
+ @Test(expected=BatchException.class)
+ public void testMissingHttpVersion() throws BatchException {
+ String batch = ""
+ + "--batch_8194-cf13-1f56" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding:binary" + CRLF
+ + CRLF
+ + "GET Employees?$format=json" + CRLF
+ + "Host: localhost:8080" + CRLF
+ + CRLF
+ + "--batch_8194-cf13-1f56--";
+
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected=BatchException.class)
+ public void testMissingHttpVersion2() throws BatchException {
+ String batch = ""
+ + "--batch_8194-cf13-1f56" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding:binary" + CRLF
+ + CRLF
+ + "GET Employees?$format=json " + CRLF
+ + "Host: localhost:8080" + CRLF
+ + CRLF
+ + "--batch_8194-cf13-1f56--";
+
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected=BatchException.class)
+ public void testMissingHttpVersion3() throws BatchException {
+ String batch = ""
+ + "--batch_8194-cf13-1f56" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding:binary" + CRLF
+ + CRLF
+ + "GET Employees?$format=json SMTP:3.1" + CRLF
+ + "Host: localhost:8080" + CRLF
+ + CRLF
+ + "--batch_8194-cf13-1f56--";
+
+ parseInvalidBatchBody(batch);
+ }
+
@Test(expected = BatchException.class)
public void testBoundaryWithoutHyphen() throws BatchException {
String batch = "--batch_8194-cf13-1f56" + CRLF
@@ -347,19 +391,6 @@ public class BatchRequestParserTest {
}
@Test(expected = BatchException.class)
- @Ignore("What should here throw an exception")
- public void testMimeHeaderContentId() throws BatchException {
- String batch = "--batch_8194-cf13-1f56" + CRLF
- + MIME_HEADERS
- + "Content-ID: 1" + CRLF
- + CRLF
- + "GET Employees('1')/EmployeeName HTTP/1.1" + CRLF
- + CRLF
- + "--batch_8194-cf13-1f56--";
- parseInvalidBatchBody(batch);
- }
-
- @Test(expected = BatchException.class)
public void testInvalidMethodForBatch() throws BatchException {
String batch = "--batch_8194-cf13-1f56" + CRLF
+ MIME_HEADERS
@@ -413,7 +444,7 @@ public class BatchRequestParserTest {
parseInvalidBatchBody(batch);
}
- @Test(expected = BatchException.class)
+ @Test(expected=BatchException.class)
public void testInvalidChangeSetBoundary() throws BatchException {
String batch = "--batch_8194-cf13-1f56" + CRLF
+ "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
@@ -425,10 +456,37 @@ public class BatchRequestParserTest {
+ "Content-Type: application/json;odata=verbose" + CRLF
+ "MaxDataServiceVersion: 2.0" + CRLF
+ CRLF
+ + "--changeset_f980-1cb6-94dd--" + CRLF
+ + CRLF
+ "--batch_8194-cf13-1f56--";
parseInvalidBatchBody(batch);
}
-
+
+ @Test(expected=BatchException.class)
+ public void testNestedChangeset() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + CRLF
+ + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
+ + CRLF
+ + "--changeset_f980-1cb6-94dd" + CRLF
+ + MIME_HEADERS
+ + CRLF
+ + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd2" + CRLF
+ + CRLF
+ + "--changeset_f980-1cb6-94dd2" + CRLF
+ + MIME_HEADERS
+ + CRLF
+ + "POST Employees('2') HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + "MaxDataServiceVersion: 2.0" + CRLF
+ + CRLF
+ + "--changeset_f980-1cb6-94dd--" + CRLF
+ + CRLF
+ + "--changeset_f980-1cb6-94dd--" + CRLF
+ + CRLF
+ + "--batch_8194-cf13-1f56--";
+ parse(batch);
+ }
+
@Test(expected = BatchException.class)
public void testMissingContentTransferEncoding() throws BatchException {
String batch = "--batch_8194-cf13-1f56" + CRLF
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
index bcf13e4..116bfd7 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
@@ -132,7 +132,6 @@ public class BatchRequestTest {
}
@Test
- // TODO
/*
* --batch_123
* Content-Type: application/http
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/86c4ddc4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
index 1161530..69b546f 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
@@ -378,7 +378,18 @@ public class BufferedReaderIncludingLineEndingsTest {
assertEquals(null, reader.readLine());
assertEquals(-1, reader.read());
}
-
+
+ @Test
+ public void testLineEqualsAndHashCode() {
+ Line l1 = new Line("The first line", 1);
+ Line l2 = new Line("The first line", 1);
+ Line l3 = new Line("The second line", 2);
+
+ assertEquals(l1, l2);
+ assertFalse(l1.equals(l3));
+ assertTrue(l1.hashCode() != l3.hashCode());
+ }
+
@Test(expected = IllegalArgumentException.class)
public void testSkipNegative() throws IOException {
BufferedReaderIncludingLineEndings reader = create("123");