All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.catools.ws.model.CHttpClient Maven / Gradle / Ivy

package org.catools.ws.model;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.catools.common.executor.CRetry;
import org.catools.common.logger.CLogger;
import org.catools.ws.enums.CHttpStatusCode;
import org.catools.ws.exceptions.CInvalidRedirectTarget;

import javax.ws.rs.core.UriBuilder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.catools.ws.session.CSession.*;

/**
 * Http Client to perform Delete / Get / Post / Put against target application using apache http client.
 */
public class CHttpClient {
    /**
     * Process Delete request and return the response
     *
     * @param logger  logger to be used during request processing
     * @param request {@link CHttpRequest} or {@link CHttpsRequest} request to be process
     * @return {@link CHttpResponse} with the execution result
     */
    public static CHttpResponse delete(CLogger logger, CHttpRequest request) {
        try {
            UriBuilder builder = buildUri(logger, request);
            HttpDelete httpHttpDelete = new HttpDelete(builder.build().normalize());
            return processRequestWith302(logger, httpHttpDelete, request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Process Get request and return the response
     *
     * @param logger  logger to be used during request processing
     * @param request {@link CHttpRequest} or {@link CHttpsRequest} request to be process
     * @return {@link CHttpResponse} with the execution result
     */
    public static CHttpResponse get(CLogger logger, CHttpRequest request) {
        try {
            UriBuilder builder = buildUri(logger, request);
            HttpGet httpGet = new HttpGet(builder.build().normalize());
            return processRequestWith302(logger, httpGet, request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Process Post request and return the response
     *
     * @param logger  logger to be used during request processing
     * @param request {@link CHttpRequest} or {@link CHttpsRequest} request to be process
     * @return {@link CHttpResponse} with the execution result
     */
    public static CHttpResponse post(CLogger logger, CHttpRequest request) {
        try {
            UriBuilder builder = buildUri(logger, request);
            HttpPost httpPost = new HttpPost(builder.build().normalize());
            if (request.getEntity() != null) {
                httpPost.setEntity(request.getEntity());
            }
            return processRequestWith302(logger, httpPost, request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Process Put request and return the response
     *
     * @param logger  logger to be used during request processing
     * @param request {@link CHttpRequest} or {@link CHttpsRequest} request to be process
     * @return {@link CHttpResponse} with the execution result
     */
    public static CHttpResponse put(CLogger logger, CHttpRequest request) {
        try {
            UriBuilder builder = buildUri(logger, request);
            HttpPut httpPut = new HttpPut(builder.build().normalize());
            if (request.getEntity() != null) {
                httpPut.setEntity(request.getEntity());
            }

            return processRequestWith302(logger, httpPut, request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static UriBuilder buildUri(CLogger logger, CHttpRequest request) {
        logger.trace("Processing Request: \n" + request);
        UriBuilder builder = UriBuilder.fromUri(request.getTargetURL());
        if (request.getQueryParameters() != null) {
            request.getQueryParameters().forEach(kv -> builder.queryParam(kv.getName(), kv.getValue()));
        }
        return builder;
    }

    private static CHttpResponse processRequestWith302(CLogger logger, HttpUriRequest uriRequest, CHttpRequest request) {
        CHttpResponse response = processRequest(logger, uriRequest, request);
        if (response.StatusCode.equals(CHttpStatusCode.MOVED_TEMP_302)) {
            return get(logger, new CHttpRequest(request.getSession(), getRedirectUrl(request, response)));
        }
        return response;
    }

    private static CHttpResponse processRequest(CLogger logger, HttpUriRequest request, CHttpRequest cHttpRequest) {
        HttpClientBuilder clientBuilder = HttpClients.custom();
        if (cHttpRequest.getSession() != null && cHttpRequest.getSession().getCookieStore() != null) {
            clientBuilder.setDefaultCookieStore(cHttpRequest.getSession().getCookieStore());
        }

        if (cHttpRequest instanceof CHttpsRequest) {
            if (((CHttpsRequest) cHttpRequest).getSSLConnectionSocketFactory() != null) {
                clientBuilder.setSSLSocketFactory(((CHttpsRequest) cHttpRequest).getSSLConnectionSocketFactory());
            }

            if (((CHttpsRequest) cHttpRequest).getSSLContext() != null) {
                clientBuilder.setSSLContext(((CHttpsRequest) cHttpRequest).getSSLContext());
            }
        }

        if (cHttpRequest.getSession() != null && cHttpRequest.getSession().getHeaders() != null) {
            cHttpRequest.getSession().getHeaders().forEach((k, v) -> request.addHeader(k, v));
        }

        CloseableHttpClient build = clientBuilder.build();
        logger.trace("Request ::> " + cHttpRequest);

        CHttpResponse response = CRetry.retry(integer -> {
            try {
                return new CHttpResponse(cHttpRequest.getSession(), build.execute(request));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, 10, 5000, null);

        if (cHttpRequest.getSession() != null) {
            cHttpRequest.getSession().copyFromResponse(JSESSIONID, response);
            cHttpRequest.getSession().copyFromResponse(CSRFTOKEN, response);
            cHttpRequest.getSession().copyFromResponse(X_CSRF, response);
        }
        logger.trace("Response ::> " + response);
        return response;
    }

    private static String getRedirectUrl(CHttpRequest request, CHttpResponse response) {
        String content = response.Content.getValue();
        if (content.trim().isEmpty()) {
            CResponseHeader http = response.Headers.getFirstOrNull(k -> k.Name.startsWith("http"));
            if (http != null) {
                return http.Value.getValue();
            }
            else {
                CResponseHeader location = response.Headers.getFirstOrNull(k -> k.Name.equals("Location"));
                if (location != null) {
                    String locationValue = location.Value.getValue();

                    if (locationValue.toLowerCase().startsWith("http")) {
                        return locationValue;
                    }

                    // If location is a relative path then we should have host in header otherwise it is not possible to know where exactly we should redirect to
                    String host = request.getHeaders().get("Host");
                    if (StringUtils.isBlank(host)) {
                        throw new CInvalidRedirectTarget("Potential Relative Redirect URL found but could not find any host in request header. Url: " +
                                locationValue);
                    }

                    if (host.toLowerCase().startsWith("http")) {
                        return host.replaceAll("http(s)?://", "") + locationValue;
                    }

                    if (request.getTargetURL().toString().startsWith("model")) {
                        return "model://" + host + locationValue;
                    }
                    return "http://" + host + locationValue;
                }
            }
        }
        else {
            Pattern pattern = Pattern.compile("(.*?)");
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
                return matcher.group(1).replaceAll("&", "&");
            }
        }
        throw new RuntimeException("Redirect url not found in " + response.toString());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy