hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [10/17] httpcomponents-client git commit: Moved classes and renamed packages (no functional changes)
Date Sat, 02 Sep 2017 15:28:10 GMT
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ContentCompressionExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ContentCompressionExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ContentCompressionExec.java
deleted file mode 100644
index df6638c..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ContentCompressionExec.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.entity.DecompressingEntity;
-import org.apache.hc.client5.http.entity.DeflateInputStreamFactory;
-import org.apache.hc.client5.http.entity.GZIPInputStreamFactory;
-import org.apache.hc.client5.http.entity.InputStreamFactory;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.ExecChain;
-import org.apache.hc.client5.http.sync.ExecChainHandler;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HeaderElement;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.config.Lookup;
-import org.apache.hc.core5.http.config.RegistryBuilder;
-import org.apache.hc.core5.http.message.BasicHeaderValueParser;
-import org.apache.hc.core5.http.message.ParserCursor;
-import org.apache.hc.core5.util.Args;
-
-/**
- * Request executor in the request execution chain that is responsible
- * for automatic response content decompression.
- * <p>
- * Further responsibilities such as communication with the opposite
- * endpoint is delegated to the next executor in the request execution
- * chain.
- * </p>
- *
- * @since 5.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public final class ContentCompressionExec implements ExecChainHandler {
-
-    private final List<String> acceptEncoding;
-    private final Lookup<InputStreamFactory> decoderRegistry;
-    private final boolean ignoreUnknown;
-
-    public ContentCompressionExec(
-            final List<String> acceptEncoding,
-            final Lookup<InputStreamFactory> decoderRegistry,
-            final boolean ignoreUnknown) {
-        this.acceptEncoding = acceptEncoding != null ? acceptEncoding : Arrays.asList("gzip", "x-gzip", "deflate");
-        this.decoderRegistry = decoderRegistry != null ? decoderRegistry :
-                RegistryBuilder.<InputStreamFactory>create()
-                        .register("gzip", GZIPInputStreamFactory.getInstance())
-                        .register("x-gzip", GZIPInputStreamFactory.getInstance())
-                        .register("deflate", DeflateInputStreamFactory.getInstance())
-                        .build();
-        this.ignoreUnknown = ignoreUnknown;
-    }
-
-    public ContentCompressionExec(final boolean ignoreUnknown) {
-        this(null, null, ignoreUnknown);
-    }
-
-    /**
-     * Handles {@code gzip} and {@code deflate} compressed entities by using the following
-     * decoders:
-     * <ul>
-     * <li>gzip - see {@link java.util.zip.GZIPInputStream}</li>
-     * <li>deflate - see {@link org.apache.hc.client5.http.entity.DeflateInputStream}</li>
-     * </ul>
-     */
-    public ContentCompressionExec() {
-        this(null, null, true);
-    }
-
-
-    @Override
-    public ClassicHttpResponse execute(
-            final ClassicHttpRequest request,
-            final ExecChain.Scope scope,
-            final ExecChain chain) throws IOException, HttpException {
-        Args.notNull(request, "HTTP request");
-        Args.notNull(scope, "Scope");
-
-        final HttpClientContext clientContext = scope.clientContext;
-        final RequestConfig requestConfig = clientContext.getRequestConfig();
-
-        /* Signal support for Accept-Encoding transfer encodings. */
-        if (!request.containsHeader(HttpHeaders.ACCEPT_ENCODING) && requestConfig.isContentCompressionEnabled()) {
-            request.addHeader(HttpHeaders.ACCEPT_ENCODING, acceptEncoding);
-        }
-
-        final ClassicHttpResponse response = chain.proceed(request, scope);
-
-        final HttpEntity entity = response.getEntity();
-        // entity can be null in case of 304 Not Modified, 204 No Content or similar
-        // check for zero length entity.
-        if (requestConfig.isContentCompressionEnabled() && entity != null && entity.getContentLength() != 0) {
-            final String contentEncoding = entity.getContentEncoding();
-            if (contentEncoding != null) {
-                final ParserCursor cursor = new ParserCursor(0, contentEncoding.length());
-                final HeaderElement[] codecs = BasicHeaderValueParser.INSTANCE.parseElements(contentEncoding, cursor);
-                for (final HeaderElement codec : codecs) {
-                    final String codecname = codec.getName().toLowerCase(Locale.ROOT);
-                    final InputStreamFactory decoderFactory = decoderRegistry.lookup(codecname);
-                    if (decoderFactory != null) {
-                        response.setEntity(new DecompressingEntity(response.getEntity(), decoderFactory));
-                        response.removeHeaders(HttpHeaders.CONTENT_LENGTH);
-                        response.removeHeaders(HttpHeaders.CONTENT_ENCODING);
-                        response.removeHeaders(HttpHeaders.CONTENT_MD5);
-                    } else {
-                        if (!"identity".equals(codecname) && !ignoreUnknown) {
-                            throw new HttpException("Unsupported Content-Encoding: " + codec.getName());
-                        }
-                    }
-                }
-            }
-        }
-        return response;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CookieSpecRegistries.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CookieSpecRegistries.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CookieSpecRegistries.java
deleted file mode 100644
index e7d1b56..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CookieSpecRegistries.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import org.apache.hc.client5.http.config.CookieSpecs;
-import org.apache.hc.client5.http.cookie.CookieSpecProvider;
-import org.apache.hc.client5.http.impl.cookie.IgnoreSpecProvider;
-import org.apache.hc.client5.http.impl.cookie.RFC6265CookieSpecProvider;
-import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
-import org.apache.hc.client5.http.psl.PublicSuffixMatcherLoader;
-import org.apache.hc.core5.http.config.Lookup;
-import org.apache.hc.core5.http.config.RegistryBuilder;
-
-/**
- * @since 4.5
- */
-public final class CookieSpecRegistries {
-
-    /**
-     * Creates a builder containing the default registry entries, using the provided public suffix matcher.
-     */
-    public static RegistryBuilder<CookieSpecProvider> createDefaultBuilder(final PublicSuffixMatcher publicSuffixMatcher) {
-        final CookieSpecProvider laxStandardProvider = new RFC6265CookieSpecProvider(
-                RFC6265CookieSpecProvider.CompatibilityLevel.RELAXED, publicSuffixMatcher);
-        final CookieSpecProvider strictStandardProvider = new RFC6265CookieSpecProvider(
-                RFC6265CookieSpecProvider.CompatibilityLevel.STRICT, publicSuffixMatcher);
-        return RegistryBuilder.<CookieSpecProvider>create()
-                .register(CookieSpecs.DEFAULT, laxStandardProvider)
-                .register(CookieSpecs.STANDARD, laxStandardProvider)
-                .register(CookieSpecs.STANDARD_STRICT, strictStandardProvider)
-                .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecProvider());
-    }
-
-    /**
-     * Creates a builder containing the default registry entries with the default public suffix matcher.
-     */
-    public static RegistryBuilder<CookieSpecProvider> createDefaultBuilder() {
-        return createDefaultBuilder(PublicSuffixMatcherLoader.getDefault());
-    }
-
-    /**
-     * Creates the default registry, using the default public suffix matcher.
-     */
-    public static Lookup<CookieSpecProvider> createDefault() {
-        return createDefault(PublicSuffixMatcherLoader.getDefault());
-    }
-
-    /**
-     * Creates the default registry with the provided public suffix matcher
-     */
-    public static Lookup<CookieSpecProvider> createDefault(final PublicSuffixMatcher publicSuffixMatcher) {
-        return createDefaultBuilder(publicSuffixMatcher).build();
-    }
-
-    private CookieSpecRegistries() {}
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultBackoffStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultBackoffStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultBackoffStrategy.java
deleted file mode 100644
index a968cd7..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultBackoffStrategy.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.sync;
-
-import java.net.ConnectException;
-import java.net.SocketTimeoutException;
-
-import org.apache.hc.client5.http.sync.ConnectionBackoffStrategy;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
-
-/**
- * This {@link ConnectionBackoffStrategy} backs off either for a raw
- * network socket or connection timeout or if the server explicitly
- * sends a 503 (Service Unavailable) response.
- *
- * @since 4.2
- */
-public class DefaultBackoffStrategy implements ConnectionBackoffStrategy {
-
-    @Override
-    public boolean shouldBackoff(final Throwable t) {
-        return (t instanceof SocketTimeoutException
-                || t instanceof ConnectException);
-    }
-
-    @Override
-    public boolean shouldBackoff(final HttpResponse resp) {
-        return (resp.getCode() == HttpStatus.SC_SERVICE_UNAVAILABLE);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java
deleted file mode 100644
index e23f024..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultHttpRequestRetryHandler.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.ConnectException;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.net.ssl.SSLException;
-
-import org.apache.hc.client5.http.sync.HttpRequestRetryHandler;
-import org.apache.hc.client5.http.sync.methods.HttpUriRequestBase;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-
-/**
- * The default {@link HttpRequestRetryHandler} used by request executors.
- *
- * @since 4.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler {
-
-    public static final DefaultHttpRequestRetryHandler INSTANCE = new DefaultHttpRequestRetryHandler();
-
-    /** the number of times a method will be retried */
-    private final int retryCount;
-
-    private final Map<String, Boolean> idempotentMethods;
-    private final Set<Class<? extends IOException>> nonRetriableClasses;
-
-    /**
-     * Create the request retry handler using the specified IOException classes
-     *
-     * @param retryCount how many times to retry; 0 means no retries
-     * @param requestSentRetryEnabled true if it's OK to retry requests that have been sent
-     * @param clazzes the IOException types that should not be retried
-     * @since 4.3
-     */
-    protected DefaultHttpRequestRetryHandler(
-            final int retryCount,
-            final boolean requestSentRetryEnabled,
-            final Collection<Class<? extends IOException>> clazzes) {
-        super();
-        this.retryCount = retryCount;
-        this.idempotentMethods = new ConcurrentHashMap<>();
-        this.idempotentMethods.put("GET", Boolean.TRUE);
-        this.idempotentMethods.put("HEAD", Boolean.TRUE);
-        this.idempotentMethods.put("PUT", Boolean.TRUE);
-        this.idempotentMethods.put("DELETE", Boolean.TRUE);
-        this.idempotentMethods.put("OPTIONS", Boolean.TRUE);
-        this.idempotentMethods.put("TRACE", Boolean.TRUE);
-        this.nonRetriableClasses = new HashSet<>();
-        for (final Class<? extends IOException> clazz: clazzes) {
-            this.nonRetriableClasses.add(clazz);
-        }
-    }
-
-    /**
-     * Create the request retry handler using the following list of
-     * non-retriable IOException classes: <br>
-     * <ul>
-     * <li>InterruptedIOException</li>
-     * <li>UnknownHostException</li>
-     * <li>ConnectException</li>
-     * <li>SSLException</li>
-     * </ul>
-     * @param retryCount how many times to retry; 0 means no retries
-     * @param requestSentRetryEnabled true if it's OK to retry non-idempotent requests that have been sent
-     */
-    @SuppressWarnings("unchecked")
-    public DefaultHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) {
-        this(retryCount, requestSentRetryEnabled, Arrays.asList(
-                InterruptedIOException.class,
-                UnknownHostException.class,
-                ConnectException.class,
-                SSLException.class));
-    }
-
-    /**
-     * Create the request retry handler with a retry count of 3, requestSentRetryEnabled false
-     * and using the following list of non-retriable IOException classes: <br>
-     * <ul>
-     * <li>InterruptedIOException</li>
-     * <li>UnknownHostException</li>
-     * <li>ConnectException</li>
-     * <li>SSLException</li>
-     * </ul>
-     */
-    public DefaultHttpRequestRetryHandler() {
-        this(3, false);
-    }
-
-    /**
-     * Used {@code retryCount} and {@code requestSentRetryEnabled} to determine
-     * if the given method should be retried.
-     */
-    @Override
-    public boolean retryRequest(
-            final HttpRequest request,
-            final IOException exception,
-            final int executionCount,
-            final HttpContext context) {
-        Args.notNull(request, "HTTP request");
-        Args.notNull(exception, "I/O exception");
-
-        if (executionCount > this.retryCount) {
-            // Do not retry if over max retry count
-            return false;
-        }
-        if (this.nonRetriableClasses.contains(exception.getClass())) {
-            return false;
-        } else {
-            for (final Class<? extends IOException> rejectException : this.nonRetriableClasses) {
-                if (rejectException.isInstance(exception)) {
-                    return false;
-                }
-            }
-        }
-        if (request instanceof HttpUriRequestBase && ((HttpUriRequestBase)request).isAborted()) {
-            return false;
-        }
-        if (handleAsIdempotent(request)) {
-            // Retry if the request is considered idempotent
-            return true;
-        }
-        // otherwise do not retry
-        return false;
-    }
-
-    /**
-     * @return the maximum number of times a method will be retried
-     */
-    public int getRetryCount() {
-        return retryCount;
-    }
-
-    /**
-     * @since 4.2
-     */
-    protected boolean handleAsIdempotent(final HttpRequest request) {
-        final String method = request.getMethod().toUpperCase(Locale.ROOT);
-        final Boolean b = this.idempotentMethods.get(method);
-        return b != null && b.booleanValue();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultServiceUnavailableRetryStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultServiceUnavailableRetryStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultServiceUnavailableRetryStrategy.java
deleted file mode 100644
index 13d4e5b..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/DefaultServiceUnavailableRetryStrategy.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import java.util.Date;
-
-import org.apache.hc.client5.http.sync.ServiceUnavailableRetryStrategy;
-import org.apache.hc.client5.http.utils.DateUtils;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.util.Args;
-
-/**
- * Default implementation of the {@link ServiceUnavailableRetryStrategy} interface.
- * that retries {@code 503} (Service Unavailable) responses for a fixed number of times
- * at a fixed interval.
- *
- * @since 4.2
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class DefaultServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy {
-
-    /**
-     * Maximum number of allowed retries if the server responds with a HTTP code
-     * in our retry code list. Default value is 1.
-     */
-    private final int maxRetries;
-
-    /**
-     * Retry interval between subsequent requests, in milliseconds. Default
-     * value is 1 second.
-     */
-    private final long defaultRetryInterval;
-
-    public DefaultServiceUnavailableRetryStrategy(final int maxRetries, final int defaultRetryInterval) {
-        super();
-        Args.positive(maxRetries, "Max retries");
-        Args.positive(defaultRetryInterval, "Retry interval");
-        this.maxRetries = maxRetries;
-        this.defaultRetryInterval = defaultRetryInterval;
-    }
-
-    public DefaultServiceUnavailableRetryStrategy() {
-        this(1, 1000);
-    }
-
-    @Override
-    public boolean retryRequest(final HttpResponse response, final int executionCount, final HttpContext context) {
-        return executionCount <= maxRetries && response.getCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
-    }
-
-    @Override
-    public long getRetryInterval(final HttpResponse response, final HttpContext context) {
-        final Header header = response.getFirstHeader(HttpHeaders.RETRY_AFTER);
-        if (header != null) {
-            final String value = header.getValue();
-            try {
-                return Long.parseLong(value) * 1000;
-            } catch (final NumberFormatException ignore) {
-                final Date date = DateUtils.parseDate(value);
-                if (date != null) {
-                    final long n = date.getTime() - System.currentTimeMillis();
-                    return n > 0 ? n : 0;
-                }
-            }
-        }
-        return this.defaultRetryInterval;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java
deleted file mode 100644
index c5a2638..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecChainElement.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-
-import org.apache.hc.client5.http.sync.ExecChain;
-import org.apache.hc.client5.http.sync.ExecChainHandler;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpException;
-
-class ExecChainElement {
-
-    private final ExecChainHandler handler;
-    private final ExecChainElement next;
-
-    ExecChainElement(final ExecChainHandler handler, final ExecChainElement next) {
-        this.handler = handler;
-        this.next = next;
-    }
-
-    public ClassicHttpResponse execute(
-            final ClassicHttpRequest request,
-            final ExecChain.Scope scope) throws IOException, HttpException {
-        return handler.execute(request, scope, new ExecChain() {
-
-            @Override
-            public ClassicHttpResponse proceed(
-                    final ClassicHttpRequest request,
-                    final Scope scope) throws IOException, HttpException {
-                return next.execute(request, scope);
-            }
-
-        });
-    }
-
-    @Override
-    public String toString() {
-        return "{" +
-                "handler=" + handler.getClass() +
-                ", next=" + (next != null ? next.handler.getClass() : "null") +
-                '}';
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
deleted file mode 100644
index e80956f..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ExecRuntimeImpl.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.hc.client5.http.CancellableAware;
-import org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.io.ConnectionEndpoint;
-import org.apache.hc.client5.http.io.HttpClientConnectionManager;
-import org.apache.hc.client5.http.io.LeaseRequest;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.ExecRuntime;
-import org.apache.hc.core5.concurrent.Cancellable;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
-import org.apache.hc.core5.io.ShutdownType;
-import org.apache.hc.core5.util.Args;
-import org.apache.hc.core5.util.TimeValue;
-import org.apache.logging.log4j.Logger;
-
-class ExecRuntimeImpl implements ExecRuntime, Cancellable {
-
-    private final Logger log;
-
-    private final HttpClientConnectionManager manager;
-    private final HttpRequestExecutor requestExecutor;
-    private final CancellableAware cancellableAware;
-    private final AtomicReference<ConnectionEndpoint> endpointRef;
-
-    private volatile boolean reusable;
-    private volatile Object state;
-    private volatile TimeValue validDuration;
-
-    ExecRuntimeImpl(
-            final Logger log,
-            final HttpClientConnectionManager manager,
-            final HttpRequestExecutor requestExecutor,
-            final CancellableAware cancellableAware) {
-        super();
-        this.log = log;
-        this.manager = manager;
-        this.requestExecutor = requestExecutor;
-        this.cancellableAware = cancellableAware;
-        this.endpointRef = new AtomicReference<>(null);
-        this.validDuration = TimeValue.NEG_ONE_MILLISECONDS;
-    }
-
-    @Override
-    public boolean isExecutionAborted() {
-        return cancellableAware != null && cancellableAware.isCancelled();
-    }
-
-    @Override
-    public boolean isConnectionAcquired() {
-        return endpointRef.get() != null;
-    }
-
-    @Override
-    public void acquireConnection(final HttpRoute route, final Object object, final HttpClientContext context) throws IOException {
-        Args.notNull(route, "Route");
-        if (endpointRef.get() == null) {
-            final LeaseRequest connRequest = manager.lease(route, object);
-            state = object;
-            if (cancellableAware != null) {
-                if (cancellableAware.isCancelled()) {
-                    connRequest.cancel();
-                    throw new RequestFailedException("Request aborted");
-                }
-                cancellableAware.setCancellable(connRequest);
-            }
-            try {
-                final RequestConfig requestConfig = context.getRequestConfig();
-                final TimeValue timeout = requestConfig.getConnectionRequestTimeout();
-                final ConnectionEndpoint connectionEndpoint = connRequest.get(timeout.getDuration(), timeout.getTimeUnit());
-                endpointRef.set(connectionEndpoint);
-                reusable = connectionEndpoint.isConnected();
-                if (cancellableAware != null) {
-                    cancellableAware.setCancellable(this);
-                }
-            } catch(final TimeoutException ex) {
-                throw new ConnectionRequestTimeoutException(ex.getMessage());
-            } catch(final InterruptedException interrupted) {
-                Thread.currentThread().interrupt();
-                throw new RequestFailedException("Request aborted", interrupted);
-            } catch(final ExecutionException ex) {
-                Throwable cause = ex.getCause();
-                if (cause == null) {
-                    cause = ex;
-                }
-                throw new RequestFailedException("Request execution failed", cause);
-            }
-        } else {
-            throw new IllegalStateException("Endpoint already acquired");
-        }
-    }
-
-    ConnectionEndpoint ensureValid() {
-        final ConnectionEndpoint endpoint = endpointRef.get();
-        if (endpoint == null) {
-            throw new IllegalStateException("Endpoint not acquired / already released");
-        }
-        return endpoint;
-    }
-
-    @Override
-    public boolean isConnected() {
-        final ConnectionEndpoint endpoint = endpointRef.get();
-        return endpoint != null && endpoint.isConnected();
-    }
-
-    private void connectEndpoint(final ConnectionEndpoint endpoint, final HttpClientContext context) throws IOException {
-        if (cancellableAware != null) {
-            if (cancellableAware.isCancelled()) {
-                throw new RequestFailedException("Request aborted");
-            }
-        }
-        final RequestConfig requestConfig = context.getRequestConfig();
-        final TimeValue connectTimeout = requestConfig.getConnectTimeout();
-        manager.connect(endpoint, connectTimeout, context);
-        final TimeValue socketTimeout = requestConfig.getSocketTimeout();
-        if (socketTimeout.getDuration() >= 0) {
-            endpoint.setSocketTimeout(socketTimeout.toMillisIntBound());
-        }
-    }
-
-    @Override
-    public void connect(final HttpClientContext context) throws IOException {
-        final ConnectionEndpoint endpoint = ensureValid();
-        if (!endpoint.isConnected()) {
-            connectEndpoint(endpoint, context);
-        }
-    }
-
-    @Override
-    public void disconnect() throws IOException {
-        final ConnectionEndpoint endpoint = endpointRef.get();
-        if (endpoint != null) {
-            endpoint.close();
-            log.debug("Disconnected");
-        }
-    }
-
-    @Override
-    public void upgradeTls(final HttpClientContext context) throws IOException {
-        final ConnectionEndpoint endpoint = ensureValid();
-        manager.upgrade(endpoint, context);
-    }
-
-    @Override
-    public ClassicHttpResponse execute(final ClassicHttpRequest request, final HttpClientContext context) throws IOException, HttpException {
-        final ConnectionEndpoint endpoint = ensureValid();
-        if (!endpoint.isConnected()) {
-            connectEndpoint(endpoint, context);
-        }
-        return endpoint.execute(request, requestExecutor, context);
-    }
-
-    @Override
-    public boolean isConnectionReusable() {
-        return reusable;
-    }
-
-    @Override
-    public void markConnectionReusable() {
-        reusable = true;
-    }
-
-    @Override
-    public void markConnectionNonReusable() {
-        reusable = false;
-    }
-
-    @Override
-    public void setConnectionState(final Object state) {
-        this.state = state;
-    }
-
-    @Override
-    public void setConnectionValidFor(final TimeValue duration) {
-        validDuration = duration;
-    }
-
-    @Override
-    public void releaseConnection() {
-        final ConnectionEndpoint endpoint = endpointRef.getAndSet(null);
-        if (endpoint != null) {
-            if (reusable) {
-                manager.release(endpoint, state, validDuration);
-            } else {
-                try {
-                    endpoint.close();
-                    log.debug("Connection discarded");
-                } catch (final IOException ex) {
-                    if (log.isDebugEnabled()) {
-                        log.debug(ex.getMessage(), ex);
-                    }
-                } finally {
-                    manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void discardConnection() {
-        final ConnectionEndpoint endpoint = endpointRef.getAndSet(null);
-        if (endpoint != null) {
-            try {
-                endpoint.shutdown(ShutdownType.IMMEDIATE);
-                log.debug("Connection discarded");
-            } finally {
-                manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS);
-            }
-        }
-    }
-
-    @Override
-    public boolean cancel() {
-        final boolean alreadyReleased = endpointRef.get() == null;
-        log.debug("Cancelling request execution");
-        discardConnection();
-        return !alreadyReleased;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionMetrics.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionMetrics.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionMetrics.java
deleted file mode 100644
index f348c23..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionMetrics.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.sync;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Collection of different counters used to gather metrics for {@link FutureRequestExecutionService}.
- */
-public final class FutureRequestExecutionMetrics {
-
-    private final AtomicLong activeConnections = new AtomicLong();
-    private final AtomicLong scheduledConnections = new AtomicLong();
-    private final DurationCounter successfulConnections = new DurationCounter();
-    private final DurationCounter failedConnections = new DurationCounter();
-    private final DurationCounter requests = new DurationCounter();
-    private final DurationCounter tasks = new DurationCounter();
-
-    FutureRequestExecutionMetrics() {
-    }
-
-    AtomicLong getActiveConnections() {
-        return activeConnections;
-    }
-
-    AtomicLong getScheduledConnections() {
-        return scheduledConnections;
-    }
-
-    DurationCounter getSuccessfulConnections() {
-        return successfulConnections;
-    }
-
-    DurationCounter getFailedConnections() {
-        return failedConnections;
-    }
-
-    DurationCounter getRequests() {
-        return requests;
-    }
-
-    DurationCounter getTasks() {
-        return tasks;
-    }
-
-    public long getActiveConnectionCount() {
-        return activeConnections.get();
-    }
-
-    public long getScheduledConnectionCount() {
-        return scheduledConnections.get();
-    }
-
-    public long getSuccessfulConnectionCount() {
-        return successfulConnections.count();
-    }
-
-    public long getSuccessfulConnectionAverageDuration() {
-        return successfulConnections.averageDuration();
-    }
-
-    public long getFailedConnectionCount() {
-        return failedConnections.count();
-    }
-
-    public long getFailedConnectionAverageDuration() {
-        return failedConnections.averageDuration();
-    }
-
-    public long getRequestCount() {
-        return requests.count();
-    }
-
-    public long getRequestAverageDuration() {
-        return requests.averageDuration();
-    }
-
-    public long getTaskCount() {
-        return tasks.count();
-    }
-
-    public long getTaskAverageDuration() {
-        return tasks.averageDuration();
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("[activeConnections=").append(activeConnections)
-                .append(", scheduledConnections=").append(scheduledConnections)
-                .append(", successfulConnections=").append(successfulConnections)
-                .append(", failedConnections=").append(failedConnections)
-                .append(", requests=").append(requests)
-                .append(", tasks=").append(tasks)
-                .append("]");
-        return builder.toString();
-    }
-
-    /**
-     * A counter that can measure duration and number of events.
-     */
-    static class DurationCounter {
-
-        private final AtomicLong count = new AtomicLong(0);
-        private final AtomicLong cumulativeDuration = new AtomicLong(0);
-
-        public void increment(final long startTime) {
-            count.incrementAndGet();
-            cumulativeDuration.addAndGet(System.currentTimeMillis() - startTime);
-        }
-
-        public long count() {
-            return count.get();
-        }
-
-        public long averageDuration() {
-            final long counter = count.get();
-            return counter > 0 ? cumulativeDuration.get() / counter : 0;
-        }
-
-        @Override
-        public String toString() {
-            final StringBuilder builder = new StringBuilder();
-            builder.append("[count=").append(count())
-                    .append(", averageDuration=").append(averageDuration())
-                    .append("]");
-            return builder.toString();
-        }
-
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
deleted file mode 100644
index acd3f49..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.sync;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.hc.client5.http.sync.HttpClient;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.protocol.HttpContext;
-
-/**
- * HttpAsyncClientWithFuture wraps calls to execute with a {@link HttpRequestFutureTask}
- * and schedules them using the provided executor service. Scheduled calls may be cancelled.
- */
-@Contract(threading = ThreadingBehavior.SAFE_CONDITIONAL)
-public class FutureRequestExecutionService implements Closeable {
-
-    private final HttpClient httpclient;
-    private final ExecutorService executorService;
-    private final FutureRequestExecutionMetrics metrics = new FutureRequestExecutionMetrics();
-    private final AtomicBoolean closed = new AtomicBoolean(false);
-
-    /**
-     * Create a new FutureRequestExecutionService.
-     *
-     * @param httpclient
-     *            you should tune your httpclient instance to match your needs. You should
-     *            align the max number of connections in the pool and the number of threads
-     *            in the executor; it doesn't make sense to have more threads than connections
-     *            and if you have less connections than threads, the threads will just end up
-     *            blocking on getting a connection from the pool.
-     * @param executorService
-     *            any executorService will do here. E.g.
-     *            {@link java.util.concurrent.Executors#newFixedThreadPool(int)}
-     */
-    public FutureRequestExecutionService(
-            final HttpClient httpclient,
-            final ExecutorService executorService) {
-        this.httpclient = httpclient;
-        this.executorService = executorService;
-    }
-
-    /**
-     * Schedule a request for execution.
-     *
-     * @param <T>
-     *
-     * @param request
-     *            request to execute
-     * @param HttpClientResponseHandler
-     *            handler that will process the response.
-     * @return HttpAsyncClientFutureTask for the scheduled request.
-     */
-    public <T> HttpRequestFutureTask<T> execute(
-            final ClassicHttpRequest request,
-            final HttpContext context,
-            final HttpClientResponseHandler<T> HttpClientResponseHandler) {
-        return execute(request, context, HttpClientResponseHandler, null);
-    }
-
-    /**
-     * Schedule a request for execution.
-     *
-     * @param <T>
-     *
-     * @param request
-     *            request to execute
-     * @param context
-     *            optional context; use null if not needed.
-     * @param HttpClientResponseHandler
-     *            handler that will process the response.
-     * @param callback
-     *            callback handler that will be called when the request is scheduled,
-     *            started, completed, failed, or cancelled.
-     * @return HttpAsyncClientFutureTask for the scheduled request.
-     */
-    public <T> HttpRequestFutureTask<T> execute(
-            final ClassicHttpRequest request,
-            final HttpContext context,
-            final HttpClientResponseHandler<T> HttpClientResponseHandler,
-            final FutureCallback<T> callback) {
-        if(closed.get()) {
-            throw new IllegalStateException("Close has been called on this httpclient instance.");
-        }
-        metrics.getScheduledConnections().incrementAndGet();
-        final HttpRequestTaskCallable<T> callable = new HttpRequestTaskCallable<>(
-                httpclient, request, context, HttpClientResponseHandler, callback, metrics);
-        final HttpRequestFutureTask<T> httpRequestFutureTask = new HttpRequestFutureTask<>(
-                request, callable);
-        executorService.execute(httpRequestFutureTask);
-
-        return httpRequestFutureTask;
-    }
-
-    /**
-     * @return metrics gathered for this instance.
-     * @see FutureRequestExecutionMetrics
-     */
-    public FutureRequestExecutionMetrics metrics() {
-        return metrics;
-    }
-
-    @Override
-    public void close() throws IOException {
-        closed.set(true);
-        executorService.shutdownNow();
-        if (httpclient instanceof Closeable) {
-            ((Closeable) httpclient).close();
-        }
-    }
-}


Mime
View raw message