Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.solr.servlet;
import static org.apache.solr.common.params.CommonParams.PATH;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.invoke.MethodHandles;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import org.apache.commons.io.input.CloseShieldInputStream;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.api.V2HttpCall;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MultiMapSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.CommandOperation;
import org.apache.solr.common.util.ContentStream;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.FastInputStream;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.RequestHandlers;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryRequestBase;
import org.apache.solr.util.RTimerTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SolrRequestParsers {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
// Should these constants be in a more public place?
public static final String MULTIPART = "multipart";
public static final String FORMDATA = "formdata";
public static final String RAW = "raw";
public static final String SIMPLE = "simple";
public static final String STANDARD = "standard";
private static final Charset CHARSET_US_ASCII = StandardCharsets.US_ASCII;
public static final String INPUT_ENCODING_KEY = "ie";
private static final byte[] INPUT_ENCODING_BYTES = INPUT_ENCODING_KEY.getBytes(CHARSET_US_ASCII);
public static final String REQUEST_TIMER_SERVLET_ATTRIBUTE = "org.apache.solr.RequestTimer";
private final HashMap parsers = new HashMap<>();
private final boolean enableRemoteStreams;
private final boolean enableStreamBody;
private StandardRequestParser standard;
private boolean handleSelect = true;
private boolean addHttpRequestToContext;
/**
* Default instance for e.g. admin requests. Limits to 2 MB uploads and does not allow remote
* streams.
*/
public static final SolrRequestParsers DEFAULT = new SolrRequestParsers();
/**
* Pass in an xml configuration. A null configuration will enable everything with maximum values.
*/
public SolrRequestParsers(SolrConfig globalConfig) {
final int multipartUploadLimitKB, formUploadLimitKB;
if (globalConfig == null) {
multipartUploadLimitKB = formUploadLimitKB = Integer.MAX_VALUE;
enableRemoteStreams = false;
enableStreamBody = false;
handleSelect = false;
addHttpRequestToContext = false;
} else {
multipartUploadLimitKB = globalConfig.getMultipartUploadLimitKB();
formUploadLimitKB = globalConfig.getFormUploadLimitKB();
// security risks; disabled by default
enableRemoteStreams = Boolean.getBoolean("solr.enableRemoteStreaming");
enableStreamBody = Boolean.getBoolean("solr.enableStreamBody");
// Let this filter take care of /select?xxx format
handleSelect = globalConfig.isHandleSelect();
addHttpRequestToContext = globalConfig.isAddHttpRequestToContext();
}
init(multipartUploadLimitKB, formUploadLimitKB);
}
private SolrRequestParsers() {
enableRemoteStreams = false;
enableStreamBody = false;
handleSelect = false;
addHttpRequestToContext = false;
init(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
private void init(int multipartUploadLimitKB, int formUploadLimitKB) {
MultipartRequestParser multi = new MultipartRequestParser(multipartUploadLimitKB);
RawRequestParser raw = new RawRequestParser();
FormDataRequestParser formdata = new FormDataRequestParser(formUploadLimitKB);
standard = new StandardRequestParser(multi, raw, formdata);
// I don't see a need to have this publicly configured just yet
// adding it is trivial
parsers.put(MULTIPART, multi);
parsers.put(FORMDATA, formdata);
parsers.put(RAW, raw);
parsers.put(SIMPLE, new SimpleRequestParser());
parsers.put(STANDARD, standard);
parsers.put("", standard);
}
private static RTimerTree getRequestTimer(HttpServletRequest req) {
final Object reqTimer = req.getAttribute(REQUEST_TIMER_SERVLET_ATTRIBUTE);
if (reqTimer != null && reqTimer instanceof RTimerTree) {
return ((RTimerTree) reqTimer);
}
return new RTimerTree();
}
public SolrQueryRequest parse(SolrCore core, String path, HttpServletRequest req)
throws Exception {
SolrRequestParser parser = standard;
// TODO -- in the future, we could pick a different parser based on the request
// Pick the parser from the request...
ArrayList streams = new ArrayList<>(1);
SolrParams params = parser.parseParamsAndFillStreams(req, streams);
SolrQueryRequest sreq = buildRequestFrom(core, params, streams, getRequestTimer(req), req);
// Handlers and login will want to know the path. If it contains a ':'
// the handler could use it for RESTful URLs
sreq.getContext().put(PATH, RequestHandlers.normalize(path));
sreq.getContext().put("httpMethod", req.getMethod());
if (addHttpRequestToContext) {
sreq.getContext().put("httpRequest", req);
}
return sreq;
}
/** For embedded Solr use; not related to HTTP. */
public SolrQueryRequest buildRequestFrom(
SolrCore core, SolrParams params, Collection streams) throws Exception {
return buildRequestFrom(core, params, streams, new RTimerTree(), null);
}
private SolrQueryRequest buildRequestFrom(
SolrCore core,
SolrParams params,
Collection streams,
RTimerTree requestTimer,
final HttpServletRequest req)
throws Exception {
// The content type will be applied to all streaming content
String contentType = params.get(CommonParams.STREAM_CONTENTTYPE);
// Handle anything with a remoteURL
String[] strs = params.getParams(CommonParams.STREAM_URL);
if (strs != null) {
if (!enableRemoteStreams) {
throw new SolrException(ErrorCode.BAD_REQUEST, "Remote Streaming is disabled.");
}
for (final String url : strs) {
ContentStreamBase stream = new ContentStreamBase.URLStream(new URL(url));
if (contentType != null) {
stream.setContentType(contentType);
}
streams.add(stream);
}
}
// Handle streaming files
strs = params.getParams(CommonParams.STREAM_FILE);
if (strs != null) {
if (!enableRemoteStreams) {
throw new SolrException(
ErrorCode.BAD_REQUEST,
"Remote Streaming is disabled. See https://solr.apache.org/guide/solr/latest/configuration-guide/requestdispatcher.html for help");
}
for (final String file : strs) {
ContentStreamBase stream = new ContentStreamBase.FileStream(new File(file));
if (contentType != null) {
stream.setContentType(contentType);
}
streams.add(stream);
}
}
// Check for streams in the request parameters
strs = params.getParams(CommonParams.STREAM_BODY);
if (strs != null) {
if (!enableStreamBody) {
throw new SolrException(
ErrorCode.BAD_REQUEST,
"Stream Body is disabled. See https://solr.apache.org/guide/solr/latest/configuration-guide/requestdispatcher.html for help");
}
for (final String body : strs) {
ContentStreamBase stream = new ContentStreamBase.StringStream(body);
if (contentType != null) {
stream.setContentType(contentType);
}
streams.add(stream);
}
}
final HttpSolrCall httpSolrCall =
req == null ? null : (HttpSolrCall) req.getAttribute(HttpSolrCall.class.getName());
SolrQueryRequestBase q =
new SolrQueryRequestBase(core, params, requestTimer) {
@Override
public Principal getUserPrincipal() {
return req == null ? null : req.getUserPrincipal();
}
@Override
public CoreContainer getCoreContainer() {
return httpSolrCall != null ? httpSolrCall.cores : super.getCoreContainer();
}
@Override
public List getCommands(boolean validateInput) {
if (httpSolrCall != null) {
return httpSolrCall.getCommands(validateInput);
}
return super.getCommands(validateInput);
}
@Override
public Map getPathTemplateValues() {
if (httpSolrCall != null && httpSolrCall instanceof V2HttpCall) {
return ((V2HttpCall) httpSolrCall).getUrlParts();
}
return super.getPathTemplateValues();
}
@Override
public HttpSolrCall getHttpSolrCall() {
return httpSolrCall;
}
};
if (streams != null && streams.size() > 0) {
q.setContentStreams(streams);
}
return q;
}
private static HttpSolrCall getHttpSolrCall(HttpServletRequest req) {
return req == null ? null : (HttpSolrCall) req.getAttribute(HttpSolrCall.class.getName());
}
/** Given a url-encoded query string (UTF-8), map it into solr params */
public static MultiMapSolrParams parseQueryString(String queryString) {
Map map = new HashMap<>();
parseQueryString(queryString, map);
return new MultiMapSolrParams(map);
}
/**
* Given a url-encoded query string (UTF-8), map it into the given map
*
* @param queryString as given from URL
* @param map place all parameters in this map
*/
static void parseQueryString(final String queryString, final Map map) {
if (queryString != null && queryString.length() > 0) {
try {
final int len = queryString.length();
// this input stream emulates to get the raw bytes from the URL as passed to servlet
// container, it disallows any byte > 127 and enforces to %-escape them:
final InputStream in =
new InputStream() {
int pos = 0;
@Override
public int read() {
if (pos < len) {
final char ch = queryString.charAt(pos);
if (ch > 127) {
throw new SolrException(
ErrorCode.BAD_REQUEST,
"URLDecoder: The query string contains a not-%-escaped byte > 127 at position "
+ pos);
}
pos++;
return ch;
} else {
return -1;
}
}
};
parseFormDataContent(in, Long.MAX_VALUE, StandardCharsets.UTF_8, map, true);
} catch (IOException ioe) {
throw new SolrException(ErrorCode.BAD_REQUEST, ioe);
}
}
}
/**
* Given a url-encoded form from POST content (as InputStream), map it into the given map. The
* given InputStream should be buffered!
*
* @param postContent to be parsed
* @param charset to be used to decode resulting bytes after %-decoding
* @param map place all parameters in this map
*/
@SuppressWarnings({"fallthrough", "resource"})
static long parseFormDataContent(
final InputStream postContent,
final long maxLen,
Charset charset,
final Map map,
boolean supportCharsetParam)
throws IOException {
CharsetDecoder charsetDecoder = supportCharsetParam ? null : getCharsetDecoder(charset);
final List