com.jayway.restassured.config.HttpClientConfig.java Source code

Java tutorial

Introduction

Here is the source code for com.jayway.restassured.config.HttpClientConfig.java

Source

/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed 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 com.jayway.restassured.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.cookie.params.CookieSpecPNames;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.impl.client.DefaultHttpClient;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static com.jayway.restassured.internal.assertion.AssertParameter.notNull;
import static java.util.Arrays.asList;

/**
 * Configure the Apache HTTP Client parameters.
 * <p>Note that you can't configure the redirect settings from this config. Please use {@link RedirectConfig} for this purpose.</p>
 * <p/>
 * The following parameters are applied per default:
 * <table border=1>
 * <tr>
 * <th>Parameter name</th><th>Parameter value</th><th>Description</th>
 * </tr>
 * <tr>
 * <td>{@link ClientPNames#COOKIE_POLICY}</td><td>{@link CookiePolicy#IGNORE_COOKIES}</td><td>Don't automatically set response cookies in subsequent requests.</td>
 * </tr>
 * <tr>
 * <td>{@link CookieSpecPNames#DATE_PATTERNS}</td><td>[EEE, dd-MMM-yyyy HH:mm:ss z, EEE, dd MMM yyyy HH:mm:ss z]</td><td>Defines valid date patterns to be used for parsing non-standard
 * <code>expires</code> attribute.</td>
 * <p/>
 * </tr>
 * </table>
 * <p>
 * You can also specify a http client factory that is used to create the http client instances that REST Assured uses ({@link #httpClientFactory(com.jayway.restassured.config.HttpClientConfig.HttpClientFactory)}).
 * By default the {@link DefaultHttpClient} is used. It's also possible to specify whether or not this instance should be reused in multiple requests. By default the http client instance is not reused.
 * </p>
 *
 * @see org.apache.http.client.params.ClientPNames
 * @see org.apache.http.client.params.CookiePolicy
 * @see org.apache.http.params.CoreProtocolPNames
 */
public class HttpClientConfig implements Config {

    private static final boolean SHOULD_REUSE_HTTP_CLIENT_INSTANCE_BY_DEFAULT = false;
    private static final HttpClient NO_HTTP_CLIENT = null;

    private final boolean shouldReuseHttpClientInstance;
    private final Map<String, ?> httpClientParams;
    private final HttpMultipartMode httpMultipartMode;
    private final HttpClientFactory httpClientFactory;
    private final boolean isUserConfigured;
    private volatile HttpClient httpClient;

    /**
     * Creates a new  HttpClientConfig instance with the <code>{@value org.apache.http.client.params.ClientPNames#COOKIE_POLICY}</code> parameter set to <code>{@value org.apache.http.client.params.CookiePolicy#IGNORE_COOKIES}</code>.
     */
    public HttpClientConfig() {
        this.httpClientFactory = defaultHttpClientFactory();

        this.httpClientParams = new HashMap<String, Object>() {
            {
                put(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);
                put(CookieSpecPNames.DATE_PATTERNS,
                        asList("EEE, dd-MMM-yyyy HH:mm:ss z", "EEE, dd MMM yyyy HH:mm:ss z"));
            }
        };
        this.httpMultipartMode = HttpMultipartMode.STRICT;
        this.shouldReuseHttpClientInstance = SHOULD_REUSE_HTTP_CLIENT_INSTANCE_BY_DEFAULT;
        this.httpClient = null;
        this.isUserConfigured = false;
    }

    private HttpClientConfig(HttpClientFactory httpClientFactory, Map<String, ?> httpClientParams,
            HttpMultipartMode httpMultipartMode, boolean shouldReuseHttpClientInstance,
            HttpClient abstractHttpClient, boolean isUserConfigured) {
        notNull(httpClientParams, "httpClientParams");
        notNull(httpMultipartMode, "httpMultipartMode");
        notNull(httpClientFactory, "Http Client factory");
        this.shouldReuseHttpClientInstance = shouldReuseHttpClientInstance;
        this.httpClientFactory = httpClientFactory;
        this.httpClientParams = new HashMap<String, Object>(httpClientParams);
        this.httpMultipartMode = httpMultipartMode;
        this.httpClient = abstractHttpClient;
        this.isUserConfigured = isUserConfigured;
    }

    /**
     * Creates a new  HttpClientConfig instance with the parameters defined by the <code>httpClientParams</code>.
     */
    public HttpClientConfig(Map<String, ?> httpClientParams) {
        this(defaultHttpClientFactory(), httpClientParams, HttpMultipartMode.STRICT,
                SHOULD_REUSE_HTTP_CLIENT_INSTANCE_BY_DEFAULT, NO_HTTP_CLIENT, true);
    }

    /**
     * @return The configured parameters
     */
    public Map<String, ?> params() {
        return Collections.unmodifiableMap(httpClientParams);
    }

    /**
     * @return The same HttpClientConfig instance. Only here for syntactic sugar.
     */
    public HttpClientConfig and() {
        return this;
    }

    /**
     * Instruct REST Assured to reuse the configured http client instance for multiple requests. By default REST Assured
     * will create a new {@link org.apache.http.client.HttpClient} instance for each request. Note that for this to work
     * the configuration must be defined statically, for example:
     * <p/>
     * <pre>
     * RestAssured.config = newConfig().httpClient(httpClientConfig().reuseHttpClientInstance());
     * </pre>
     *
     * @return An updated HttpClientConfig
     * @see #httpClientFactory(com.jayway.restassured.config.HttpClientConfig.HttpClientFactory)
     */
    public HttpClientConfig reuseHttpClientInstance() {
        return new HttpClientConfig(httpClientFactory, httpClientParams, httpMultipartMode, true, httpClient, true);
    }

    /**
     * Instruct REST Assured <i>not</i> to reuse the configured http client instance for multiple requests. This is the default behavior.
     *
     * @return An updated HttpClientConfig
     * @see #reuseHttpClientInstance()
     */
    public HttpClientConfig dontReuseHttpClientInstance() {
        return new HttpClientConfig(httpClientFactory, httpClientParams, httpMultipartMode, false, NO_HTTP_CLIENT,
                true);
    }

    /**
     * If this method returns <code>true</code> then REST Assured will reuse the same {@link org.apache.http.client.HttpClient} instance created
     * by the {@link #httpClientInstance()} method for all requests. If <code>false</code> is returned then REST Assured creates a new instance for each request.
     * <p>
     * By default <code>false</code> is returned.
     * </p>
     * Note that for this to work the configuration must be defined statically, for example:
     * <pre>
     * RestAssured.config = newConfig().httpClient(httpClientConfig().reuseHttpClientInstance());
     * </pre>
     *
     * @return <code>true</code> if the same HTTP Client instance should be reused between several requests, <code>false</code> otherwise.
     */
    public boolean isConfiguredToReuseTheSameHttpClientInstance() {
        return shouldReuseHttpClientInstance;
    }

    /**
     * Set a http client parameter.
     *
     * @param parameterName  The name of the parameter
     * @param parameterValue The value of the parameter (may be null)
     * @param <T>            The parameter type
     * @return An updated HttpClientConfig
     */
    public <T> HttpClientConfig setParam(String parameterName, T parameterValue) {
        notNull(parameterName, "Parameter name");
        final Map<String, Object> newParams = new HashMap<String, Object>(httpClientParams);
        newParams.put(parameterName, parameterValue);
        return new HttpClientConfig(newParams);
    }

    /**
     * Replaces the currently configured parameters with the ones supplied by <code>httpClientParams</code>. This method is the same as {@link #setParams(java.util.Map)}.
     *
     * @param httpClientParams The parameters to set.
     * @return An updated HttpClientConfig
     */
    public HttpClientConfig withParams(Map<String, ?> httpClientParams) {
        return new HttpClientConfig(httpClientParams);
    }

    /**
     * Replaces the currently configured parameters with the ones supplied by <code>httpClientParams</code>. This method is the same as {@link #withParams(java.util.Map)}.
     *
     * @param httpClientParams The parameters to set.
     * @return An updated HttpClientConfig
     */
    public HttpClientConfig setParams(Map<String, ?> httpClientParams) {
        return withParams(httpClientParams);
    }

    /**
     * Add the given parameters to an already configured number of parameters.
     *
     * @param httpClientParams The parameters.
     * @return An updated HttpClientConfig
     */
    public HttpClientConfig addParams(Map<String, ?> httpClientParams) {
        notNull(httpClientParams, "httpClientParams");
        final Map<String, Object> newParams = new HashMap<String, Object>(httpClientParams);
        newParams.putAll(httpClientParams);
        return new HttpClientConfig(newParams);
    }

    /**
     * Set the http client factory that Rest Assured should use when making request. For each request REST Assured will invoke the factory to get the a the HttpClient instance.
     *
     * @param httpClientFactory The http client factory to use.
     * @return An updated HttpClientConfig
     */
    public HttpClientConfig httpClientFactory(HttpClientFactory httpClientFactory) {
        return new HttpClientConfig(httpClientFactory, httpClientParams, httpMultipartMode,
                shouldReuseHttpClientInstance, NO_HTTP_CLIENT, true);
    }

    /**
     * @return The configured http client that will create an {@link org.apache.http.client.HttpClient} instances that's used by REST Assured when making a request.
     */
    public HttpClient httpClientInstance() {
        if (isConfiguredToReuseTheSameHttpClientInstance()) {
            if (httpClient == NO_HTTP_CLIENT) {
                httpClient = httpClientFactory.createHttpClient();
            }
            return httpClient;
        }
        return httpClientFactory.createHttpClient();
    }

    /**
     * Specify the HTTP Multipart mode when sending multi-part data.
     *
     * @param httpMultipartMode The multi-part mode to set.
     * @return An updated HttpClientConfig
     */
    public HttpClientConfig httpMultipartMode(HttpMultipartMode httpMultipartMode) {
        return new HttpClientConfig(httpClientFactory, httpClientParams, httpMultipartMode,
                shouldReuseHttpClientInstance, httpClient, true);
    }

    /**
     * @return A static way to create a new HttpClientConfig instance without calling "new" explicitly. Mainly for syntactic sugar.
     */
    public static HttpClientConfig httpClientConfig() {
        return new HttpClientConfig();
    }

    /**
     * @return The http multi-part mode.
     */
    public HttpMultipartMode httpMultipartMode() {
        return httpMultipartMode;
    }

    private static HttpClientFactory defaultHttpClientFactory() {
        return new HttpClientFactory() {
            public HttpClient createHttpClient() {
                return new DefaultHttpClient();
            }
        };
    }

    public boolean isUserConfigured() {
        return isUserConfigured;
    }

    /**
     * A factory for creating and configuring a custom http client instance that will be used by REST Assured.
     */
    public interface HttpClientFactory {
        /**
         * Create an instance of {@link HttpClient} that'll be used by REST Assured when making requests. By default
         * REST Assured creates a {@link DefaultHttpClient}.
         * <p>
         * <b>Important: Version 1.9.0 of REST Assured ONLY supports instances of {@link org.apache.http.impl.client.AbstractHttpClient}</b>. The API is
         * how ever prepared for future upgrades.
         * </p>
         *
         * @return An instance of {@link HttpClient}.
         */
        HttpClient createHttpClient();
    }
}