下面列出了org.apache.http.HttpEntity#isRepeatable ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void sign(HttpRequestBase req) throws IOException {
String payload = null;
Charset charset = Charset.defaultCharset();
if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(req.getClass())) {
HttpEntityEnclosingRequestBase requestBase = (HttpEntityEnclosingRequestBase) req;
HttpEntity entity = requestBase.getEntity();
if (entity.getContentLength() > 0) {
if (!entity.isRepeatable()) {
throw new IOException(
"The signer needs to read the request payload but the input stream of this request cannot be read multiple times. Please provide the payload using a separate argument or ensure that the entity is repeatable.");
}
ContentType contentType = ContentType.get(entity);
charset = contentType.getCharset();
payload = EntityUtils.toString(entity, contentType.getCharset());
}
}
String authHeader = OAuth.getAuthorizationHeader(req.getURI(), req.getMethod(), payload, charset, consumerKey, signingKey);
req.setHeader(OAuth.AUTHORIZATION_HEADER_NAME, authHeader);
}
/**
* Get delay time before next retry.
*
* @param method The current HTTP method being executed.
* @param exception The client/service exception from the failed request.
* @param attempt The number of times the current request has been attempted.
* @param retryPolicy The retryPolicy being used.
* @return The deley time before next retry.
*/
protected long getDelayBeforeNextRetryInMillis(HttpRequestBase method, BceClientException exception, int attempt,
RetryPolicy retryPolicy) {
int retries = attempt - 1;
int maxErrorRetry = retryPolicy.getMaxErrorRetry();
// Immediately fails when it has exceeds the max retry count.
if (retries >= maxErrorRetry) {
return -1;
}
// Never retry on requests containing non-repeatable entity
if (method instanceof HttpEntityEnclosingRequest) {
HttpEntity entity = ((HttpEntityEnclosingRequest) method).getEntity();
if (entity != null && !entity.isRepeatable()) {
logger.debug("Entity not repeatable, stop retrying");
return -1;
}
}
return Math.min(retryPolicy.getMaxDelayInMillis(),
retryPolicy.getDelayBeforeNextRetryInMillis(exception, retries));
}
private byte[] serializeContent(HttpRequest request) {
if (!(request instanceof HttpEntityEnclosingRequest)) {
return new byte[]{};
}
final HttpEntityEnclosingRequest entityWithRequest = (HttpEntityEnclosingRequest) request;
HttpEntity entity = entityWithRequest.getEntity();
if (entity == null) {
return new byte[]{};
}
try {
// Buffer non-repeatable entities
if (!entity.isRepeatable()) {
entityWithRequest.setEntity(new BufferedHttpEntity(entity));
}
return EntityUtils.toByteArray(entityWithRequest.getEntity());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
@Nullable
public Span createClientSpan(String method, String endpoint, @Nullable HttpEntity httpEntity) {
final AbstractSpan<?> activeSpan = tracer.getActive();
if (activeSpan == null) {
return null;
}
Span span = activeSpan.createExitSpan();
// Don't record nested spans. In 5.x clients the instrumented sync method is calling the instrumented async method
if (span == null) {
return null;
}
span.withType(SPAN_TYPE)
.withSubtype(ELASTICSEARCH)
.withAction(SPAN_ACTION)
.appendToName("Elasticsearch: ").appendToName(method).appendToName(" ").appendToName(endpoint);
span.getContext().getDb().withType(ELASTICSEARCH);
span.activate();
if (span.isSampled()) {
span.getContext().getHttp().withMethod(method);
if (WildcardMatcher.isAnyMatch(QUERY_WILDCARD_MATCHERS, endpoint)) {
if (httpEntity != null && httpEntity.isRepeatable()) {
try {
IOUtils.readUtf8Stream(httpEntity.getContent(), span.getContext().getDb().withStatementBuffer());
} catch (IOException e) {
logger.error("Failed to read Elasticsearch client query from request body", e);
}
}
}
span.getContext().getDestination().getService().withName(ELASTICSEARCH).withResource(ELASTICSEARCH).withType(SPAN_TYPE);
}
return span;
}
public CappedBufferHttpEntity( final HttpEntity entity, int bufferSize ) throws IOException {
super( entity );
this.wrappedStream = null;
this.replayWriteIndex = -1;
if( !entity.isRepeatable() ) {
this.replayBuffer = new byte[ bufferSize ];
this.replayWriteLimit = bufferSize-1;
} else {
this.replayBuffer = null;
}
}
public PartiallyRepeatableHttpEntity(final HttpEntity entity, int bufferSize) throws IOException {
super( entity );
this.wrappedStream = null;
this.finalStream = null;
this.replayWriteIndex = -1;
if( !entity.isRepeatable() ) {
this.replayBuffer = new byte[ bufferSize ];
this.replayWriteLimit = bufferSize-1;
} else {
this.replayBuffer = null;
}
}
/**
* Builds a string from given request.
*
* @param message
* @return a string from given request.
*/
private String buildRequestLogString(HttpRequest message) {
if (message == null) {
return "<null>";
}
StringBuilder result = new StringBuilder();
if (message.getRequestLine() != null) {
result.append(message.getRequestLine().toString()).append("\n");
}
if (message.getAllHeaders() != null) {
for (Header header : message.getAllHeaders()) {
result.append(header.toString()).append("\n");
}
}
if (message instanceof HttpEntityEnclosingRequest) {
HttpEntity entity = ((HttpEntityEnclosingRequest) message).getEntity();
if (entity != null) {
if (entity.isRepeatable()) {
try {
ByteArrayOutputStream entityBytes = new ByteArrayOutputStream();
entity.writeTo(entityBytes);
result.append(new String(entityBytes.toByteArray(), entity.getContentEncoding() == null ? charsetToUse : entity.getContentEncoding().getValue()));
} catch (IOException e) {
// ignore
}
} else {
result.append("\n<content not repeatable>\n");
}
}
}
return result.toString();
}
/**
* Builds a string from given request.
*
* @param message
* @return a string from given request.
*/
private String buildResponseLogString(HttpResponse message) {
if (message == null) {
return "<null>";
}
StringBuilder result = new StringBuilder();
if (message.getStatusLine() != null) {
result.append(message.getStatusLine().toString()).append("\n");
}
if (message.getAllHeaders() != null) {
for (Header header : message.getAllHeaders()) {
result.append(header.toString()).append("\n");
}
}
if (message instanceof BasicHttpResponse) {
HttpEntity entity = ((BasicHttpResponse) message).getEntity();
if (entity != null) {
if (entity.isRepeatable()) {
try {
ByteArrayOutputStream entityBytes = new ByteArrayOutputStream();
entity.writeTo(entityBytes);
result.append(new String(entityBytes.toByteArray(), entity.getContentEncoding() == null ? charsetToUse : entity.getContentEncoding().getValue()));
} catch (IOException e) {
// ignore
}
} else {
result.append("\n<content not repeatable>\n");
}
}
}
return result.toString();
}
private Response applyInternal(final HttpRequest request)
throws IOException {
Objects.requireNonNull(request, "request");
final HttpEntity entity = request instanceof HttpEntityEnclosingRequest
? ((HttpEntityEnclosingRequest) request).getEntity() : null;
final Request r = new Request(
request.getRequestLine().getMethod(),
request.getRequestLine().getUri());
r.setEntity(entity);
final Response response = restClient.performRequest(r);
final String payload = entity != null && entity.isRepeatable()
? EntityUtils.toString(entity) : "<empty>";
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
final String error = EntityUtils.toString(response.getEntity());
final String message = String.format(Locale.ROOT,
"Error while querying Elastic (on %s/%s) status: %s\nPayload:\n%s\nError:\n%s\n",
response.getHost(), response.getRequestLine(),
response.getStatusLine(), payload, error);
throw new RuntimeException(message);
}
return response;
}
@Override
public String getEntity(HttpRequest httpRequest) {
if (httpRequest instanceof HttpEntityEnclosingRequest) {
final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) httpRequest;
try {
final HttpEntity entity = entityRequest.getEntity();
if (entity != null && entity.isRepeatable() && entity.getContentLength() > 0) {
return entityUtilsToString(entity, Charsets.UTF_8_NAME, 1024);
}
} catch (Exception e) {
logger.debug("Failed to get entity. httpRequest={}", httpRequest, e);
}
}
return null;
}
protected final String getResponseBody(CloseableHttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";
}
/**
* Returns true if a failed request should be retried.
*
* @param params Params for the individual request being executed.
* @param exception The client/service exception from the failed request.
* @return True if the failed request should be retried.
*/
private boolean shouldRetry(ExecOneRequestParams params, SdkBaseException exception) {
final int retriesAttempted = params.requestCount - 1;
final HttpRequestBase method = params.apacheRequest;
// Never retry on requests containing non-repeatable entity
if (method instanceof HttpEntityEnclosingRequest) {
HttpEntity entity = ((HttpEntityEnclosingRequest) method).getEntity();
if (entity != null && !entity.isRepeatable()) {
if (log.isDebugEnabled()) {
log.debug("Entity not repeatable");
}
return false;
}
}
RetryPolicyContext context = RetryPolicyContext.builder()
.request(request)
.originalRequest(requestConfig.getOriginalRequest())
.exception(exception)
.retriesAttempted(retriesAttempted)
.httpStatusCode(params.getStatusCode())
.build();
// Do not use retry capacity for throttling exceptions
if (!RetryUtils.isThrottlingException(exception)) {
// See if we have enough available retry capacity to be able to execute
// this retry attempt.
if (!retryCapacity.acquire(THROTTLED_RETRY_COST)) {
awsRequestMetrics.incrementCounter(ThrottledRetryCount);
reportMaxRetriesExceededIfRetryable(context);
return false;
}
executionContext.markRetryCapacityConsumed();
}
// Finally, pass all the context information to the RetryCondition and let it
// decide whether it should be retried.
if (!retryPolicy.shouldRetry(context)) {
// If the retry policy fails we immediately return consumed capacity to the pool.
if (executionContext.retryCapacityConsumed()) {
retryCapacity.release(THROTTLED_RETRY_COST);
}
reportMaxRetriesExceededIfRetryable(context);
return false;
}
return true;
}
/**
* Generates a cURL command equivalent to the given request.
*/
private static String toCurl(HttpUriRequest request, boolean logAuthToken) throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("curl ");
for (Header header: request.getAllHeaders()) {
if (!logAuthToken
&& (header.getName().equals("Authorization") ||
header.getName().equals("Cookie"))) {
continue;
}
builder.append("--header \"");
builder.append(header.toString().trim());
builder.append("\" ");
}
URI uri = request.getURI();
// If this is a wrapped request, use the URI from the original
// request instead. getURI() on the wrapper seems to return a
// relative URI. We want an absolute URI.
if (request instanceof RequestWrapper) {
HttpRequest original = ((RequestWrapper) request).getOriginal();
if (original instanceof HttpUriRequest) {
uri = ((HttpUriRequest) original).getURI();
}
}
builder.append("\"");
builder.append(uri);
builder.append("\"");
if (request instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest entityRequest =
(HttpEntityEnclosingRequest) request;
HttpEntity entity = entityRequest.getEntity();
if (entity != null && entity.isRepeatable()) {
if (entity.getContentLength() < 1024) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
entity.writeTo(stream);
String entityString = stream.toString();
// TODO: Check the content type, too.
builder.append(" --data-ascii \"")
.append(entityString)
.append("\"");
} else {
builder.append(" [TOO MUCH DATA TO INCLUDE]");
}
}
}
return builder.toString();
}
/**
* Generates a cURL command equivalent to the given request.
*/
private static String toCurl(HttpUriRequest request, boolean logAuthToken) throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("curl ");
for (Header header: request.getAllHeaders()) {
if (!logAuthToken
&& (header.getName().equals("Authorization") ||
header.getName().equals("Cookie"))) {
continue;
}
builder.append("--header \"");
builder.append(header.toString().trim());
builder.append("\" ");
}
URI uri = request.getURI();
// If this is a wrapped request, use the URI from the original
// request instead. getURI() on the wrapper seems to return a
// relative URI. We want an absolute URI.
if (request instanceof RequestWrapper) {
HttpRequest original = ((RequestWrapper) request).getOriginal();
if (original instanceof HttpUriRequest) {
uri = ((HttpUriRequest) original).getURI();
}
}
builder.append("\"");
builder.append(uri);
builder.append("\"");
if (request instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest entityRequest =
(HttpEntityEnclosingRequest) request;
HttpEntity entity = entityRequest.getEntity();
if (entity != null && entity.isRepeatable()) {
if (entity.getContentLength() < 1024) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
entity.writeTo(stream);
String entityString = stream.toString();
// TODO: Check the content type, too.
builder.append(" --data-ascii \"")
.append(entityString)
.append("\"");
} else {
builder.append(" [TOO MUCH DATA TO INCLUDE]");
}
}
}
return builder.toString();
}
/**
* Generates a cURL command equivalent to the given request.
*/
private static String toCurl(HttpUriRequest request, boolean logAuthToken)
throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("curl ");
for (Header header : request.getAllHeaders()) {
if (!logAuthToken
&& (header.getName().equals("Authorization") || header
.getName().equals("Cookie"))) {
continue;
}
builder.append("--header \"");
builder.append(header.toString().trim());
builder.append("\" ");
}
URI uri = request.getURI();
// If this is a wrapped request, use the URI from the original
// request instead. getURI() on the wrapper seems to return a
// relative URI. We want an absolute URI.
if (request instanceof RequestWrapper) {
HttpRequest original = ((RequestWrapper) request).getOriginal();
if (original instanceof HttpUriRequest) {
uri = ((HttpUriRequest) original).getURI();
}
}
builder.append("\"");
builder.append(uri);
builder.append("\"");
if (request instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
HttpEntity entity = entityRequest.getEntity();
if (entity != null && entity.isRepeatable()) {
if (entity.getContentLength() < 1024) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
entity.writeTo(stream);
String entityString = stream.toString();
// TODO: Check the content type, too.
builder.append(" --data-ascii \"").append(entityString)
.append("\"");
} else {
builder.append(" [TOO MUCH DATA TO INCLUDE]");
}
}
}
return builder.toString();
}
Response.Body toFeignBody(HttpResponse httpResponse) {
final HttpEntity entity = httpResponse.getEntity();
if (entity == null) {
return null;
}
return new Response.Body() {
@Override
public Integer length() {
return entity.getContentLength() >= 0 && entity.getContentLength() <= Integer.MAX_VALUE
? (int) entity.getContentLength()
: null;
}
@Override
public boolean isRepeatable() {
return entity.isRepeatable();
}
@Override
public InputStream asInputStream() throws IOException {
return entity.getContent();
}
@SuppressWarnings("deprecation")
@Override
public Reader asReader() throws IOException {
return new InputStreamReader(asInputStream(), UTF_8);
}
@Override
public Reader asReader(Charset charset) throws IOException {
Util.checkNotNull(charset, "charset should not be null");
return new InputStreamReader(asInputStream(), charset);
}
@Override
public void close() throws IOException {
EntityUtils.consume(entity);
}
};
}