blob: 74b67cba6e97aa5767ffeb1ee2e0c4141f4f8d0b [file] [log] [blame]
/*
* 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.server.core.deserializer.batch;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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 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", "PATCH" }));
private static final String HTTP_VERSION = "HTTP/1.1";
final private Line statusLine;
final String requestBaseUri;
private HttpMethod method;
private String httpVersion;
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)
throws BatchDeserializerException {
statusLine = httpStatusLine;
requestBaseUri = baseUri;
rawServiceResolutionUri = serviceResolutionUri;
parse();
}
private void parse() throws BatchDeserializerException {
final String[] parts = statusLine.toString().split(" ");
if (parts.length == 3) {
method = parseMethod(parts[0]);
// 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
.getLineNumber());
}
}
private void parseUri(String rawUri, String baseUri) throws BatchDeserializerException {
try {
final URI uri = new URI(rawUri);
if (uri.isAbsolute()) {
parseAbsoluteUri(rawUri, baseUri);
} else {
parseRelativeUri(rawUri);
}
} catch (URISyntaxException e) {
throw new BatchDeserializerException("Malformed uri", MessageKeys.INVALID_URI, statusLine.getLineNumber());
}
}
private void parseAbsoluteUri(String rawUri, String baseUri) throws BatchDeserializerException {
if (rawUri.startsWith(baseUri)) {
final String relativeUri = removeLeadingSlash(rawUri.substring(baseUri.length()));
parseRelativeUri(relativeUri);
} else {
throw new BatchDeserializerException("Base uri do not match", MessageKeys.INVALID_BASE_URI, statusLine
.getLineNumber());
}
}
private String removeLeadingSlash(String value) {
return (value.length() > 0 && value.charAt(0) == '/') ? value.substring(1) : value;
}
private void parseRelativeUri(String rawUri) throws BatchDeserializerException {
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());
}
}
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());
} catch (IllegalArgumentException e) {
throw new BatchDeserializerException("Illegal http method", MessageKeys.INVALID_METHOD, statusLine
.getLineNumber());
}
}
private String parseHttpVersion(final String httpVersion) throws BatchDeserializerException {
if (!HTTP_VERSION.equals(httpVersion.trim())) {
throw new BatchDeserializerException("Invalid http version", MessageKeys.INVALID_HTTP_VERSION, statusLine
.getLineNumber());
} else {
return HTTP_VERSION;
}
}
public void validateHttpMethod(final boolean isChangeSet) throws BatchDeserializerException {
Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
if (!validMethods.contains(getMethod().toString())) {
if (isChangeSet) {
throw new BatchDeserializerException("Invalid change set method", MessageKeys.INVALID_CHANGESET_METHOD,
statusLine.getLineNumber());
} else {
throw new BatchDeserializerException("Invalid query operation method",
MessageKeys.INVALID_QUERY_OPERATION_METHOD,
statusLine.getLineNumber());
}
}
}
public HttpMethod getMethod() {
return method;
}
public String getHttpVersion() {
return httpVersion;
}
public int getLineNumber() {
return statusLine.getLineNumber();
}
public String getRequestBaseUri() {
return requestBaseUri;
}
public String getRawServiceResolutionUri() {
return rawServiceResolutionUri;
}
public String getRawQueryPath() {
return rawQueryPath;
}
public String getRawODataPath() {
return rawODataPath;
}
public String getRawBaseUri() {
return rawBaseUri;
}
public String getRawRequestUri() {
return rawRequestUri;
}
}