in solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java [535:729]
protected NamedList<Object> executeMethod(
HttpRequestBase method,
Principal userPrincipal,
final ResponseParser processor,
final boolean isV2Api)
throws SolrServerException {
method.addHeader("User-Agent", USER_AGENT);
org.apache.http.client.config.RequestConfig.Builder requestConfigBuilder =
HttpClientUtil.createDefaultRequestConfigBuilder();
requestConfigBuilder.setSocketTimeout(soTimeout);
requestConfigBuilder.setConnectTimeout(connectionTimeout);
if (followRedirects != null) {
requestConfigBuilder.setRedirectsEnabled(followRedirects);
}
method.setConfig(requestConfigBuilder.build());
HttpEntity entity = null;
InputStream respBody = null;
boolean shouldClose = true;
try {
// Execute the method.
HttpClientContext httpClientRequestContext =
HttpClientUtil.createNewHttpClientRequestContext();
if (userPrincipal != null) {
// Normally the context contains a static userToken to enable reuse resources. However, if a
// personal Principal object exists, we use that instead, also as a means to transfer
// authentication information to Auth plugins that wish to intercept the request later
httpClientRequestContext.setUserToken(userPrincipal);
}
final HttpResponse response = httpClient.execute(method, httpClientRequestContext);
int httpStatus = response.getStatusLine().getStatusCode();
// Read the contents
entity = response.getEntity();
respBody = entity.getContent();
String mimeType = null;
Charset charset = null;
String charsetName = null;
ContentType contentType = ContentType.get(entity);
if (contentType != null) {
mimeType = contentType.getMimeType().trim().toLowerCase(Locale.ROOT);
charset = contentType.getCharset();
if (charset != null) {
charsetName = charset.name();
}
}
// handle some http level checks before trying to parse the response
switch (httpStatus) {
case HttpStatus.SC_OK:
case HttpStatus.SC_BAD_REQUEST:
case HttpStatus.SC_CONFLICT: // 409
break;
case HttpStatus.SC_MOVED_PERMANENTLY:
case HttpStatus.SC_MOVED_TEMPORARILY:
if (!followRedirects) {
throw new SolrServerException(
"Server at " + getBaseURL() + " sent back a redirect (" + httpStatus + ").");
}
break;
default:
if (processor == null || contentType == null) {
throw new SolrClient.RemoteSolrException(
baseUrl,
httpStatus,
"non ok status: "
+ httpStatus
+ ", message:"
+ response.getStatusLine().getReasonPhrase(),
null);
}
}
if (processor == null || processor instanceof InputStreamResponseParser) {
// no processor specified, return raw stream
final var rsp =
InputStreamResponseParser.createInputStreamNamedList(
response.getStatusLine().getStatusCode(), respBody);
rsp.add("closeableResponse", response);
// Only case where stream should not be closed
shouldClose = false;
return rsp;
}
final Collection<String> processorSupportedContentTypes = processor.getContentTypes();
if (!processorSupportedContentTypes.isEmpty()) {
final Collection<String> processorMimeTypes =
processorSupportedContentTypes.stream()
.map(ct -> ContentType.parse(ct).getMimeType().trim().toLowerCase(Locale.ROOT))
.collect(Collectors.toSet());
if (!processorMimeTypes.contains(mimeType)) {
if (isUnmatchedErrorCode(mimeType, httpStatus)) {
throw new SolrClient.RemoteSolrException(
baseUrl,
httpStatus,
"non ok status: "
+ httpStatus
+ ", message:"
+ response.getStatusLine().getReasonPhrase(),
null);
}
// unexpected mime type
final String combinedMimeTypes = String.join(", ", processorMimeTypes);
String prefix =
"Expected mime type in [" + combinedMimeTypes + "] but got " + mimeType + ". ";
Charset exceptionCharset = charset != null ? charset : FALLBACK_CHARSET;
try {
ByteArrayOutputStream body = new ByteArrayOutputStream();
respBody.transferTo(body);
throw new SolrClient.RemoteSolrException(
baseUrl, httpStatus, prefix + body.toString(exceptionCharset), null);
} catch (IOException e) {
throw new SolrClient.RemoteSolrException(
baseUrl,
httpStatus,
"Could not parse response with encoding " + exceptionCharset,
e);
}
}
}
NamedList<Object> rsp = null;
try {
rsp = processor.processResponse(respBody, charsetName);
} catch (Exception e) {
throw new SolrClient.RemoteSolrException(baseUrl, httpStatus, e.getMessage(), e);
}
Object error = rsp == null ? null : rsp.get("error");
if (error != null
&& (isV2Api
|| String.valueOf(getObjectByPath(error, true, errPath))
.endsWith("ExceptionWithErrObject"))) {
throw RemoteExecutionException.create(baseUrl, rsp);
}
if (httpStatus != HttpStatus.SC_OK && !isV2Api) {
NamedList<String> metadata = null;
String reason = null;
try {
if (error != null) {
reason = (String) Utils.getObjectByPath(error, false, Collections.singletonList("msg"));
if (reason == null) {
reason =
(String) Utils.getObjectByPath(error, false, Collections.singletonList("trace"));
}
Object metadataObj =
Utils.getObjectByPath(error, false, Collections.singletonList("metadata"));
if (metadataObj instanceof NamedList) {
metadata = (NamedList<String>) metadataObj;
} else if (metadataObj instanceof List) {
// NamedList parsed as List convert to NamedList again
List<Object> list = (List<Object>) metadataObj;
metadata = new NamedList<>(list.size() / 2);
for (int i = 0; i < list.size(); i += 2) {
metadata.add((String) list.get(i), (String) list.get(i + 1));
}
} else if (metadataObj instanceof Map) {
metadata = new NamedList((Map) metadataObj);
}
}
} catch (Exception ex) {
}
if (reason == null) {
StringBuilder msg = new StringBuilder();
msg.append(response.getStatusLine().getReasonPhrase())
.append("\n\n")
.append("request: ")
.append(method.getURI());
reason = java.net.URLDecoder.decode(msg.toString(), FALLBACK_CHARSET);
}
SolrClient.RemoteSolrException rss =
new SolrClient.RemoteSolrException(baseUrl, httpStatus, reason, null);
if (metadata != null) rss.setMetadata(metadata);
throw rss;
}
return rsp;
} catch (ConnectException e) {
throw new SolrServerException("Server refused connection at: " + getBaseURL(), e);
} catch (SocketTimeoutException e) {
throw new SolrServerException(
"Timeout occurred while waiting response from server at: " + getBaseURL(), e);
} catch (IOException e) {
throw new SolrServerException(
"IOException occurred when talking to server at: " + getBaseURL(), e);
} finally {
if (shouldClose) {
Utils.consumeFully(entity);
}
}
}