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

com.budjb.httprequests.AbstractHttpClient Maven / Gradle / Ivy

/*
 * Copyright 2016-2018 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.budjb.httprequests;

import com.budjb.httprequests.converter.EntityConverterManager;
import com.budjb.httprequests.exception.HttpClientException;
import com.budjb.httprequests.exception.UnsupportedConversionException;
import com.budjb.httprequests.filter.HttpClientFilterProcessor;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

/**
 * A base class for HTTP clients that implements most of the functionality of the {@link HttpClient} interface.
 * 

* Individual HTTP client library implementations should extend this class. */ public abstract class AbstractHttpClient implements HttpClient { /** * Converter manager. */ private final EntityConverterManager converterManager; /** * Constructor. * * @param entityConverterManager Converter manager. */ protected AbstractHttpClient(EntityConverterManager entityConverterManager) { this.converterManager = entityConverterManager; } /** * Implements the logic to make an actual request with an HTTP client library. * * @param context HTTP request context. * @param httpEntity An HTTP entity. May be {@code null} if no request entity is required. * @param filterProcessor Filter processor. * @return A {@link HttpResponse} object containing the properties of the server response. * @throws IOException When an underlying IO exception occurs. * @throws URISyntaxException When a problem parsing a URI occurs. * @throws GeneralSecurityException When an issue with SSL configuration occurs. */ protected abstract HttpResponse execute(HttpContext context, HttpEntity httpEntity, HttpClientFilterProcessor filterProcessor) throws IOException, URISyntaxException, GeneralSecurityException; /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, HttpRequest request) throws IOException { return run(method, request, null); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, String uri) throws URISyntaxException, IOException { return execute(method, new HttpRequest(uri)); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, HttpRequest request, InputStream inputStream) throws IOException { return execute(method, request, new HttpEntity(inputStream)); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(method, new HttpRequest(uri), inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(method, request, converterManager.write(entity, null, null)); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, String uri, Object entity) throws IOException, URISyntaxException, UnsupportedConversionException { return execute(method, new HttpRequest(uri), entity); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, HttpRequest request, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException { return execute(method, request, converterManager.write(entity)); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, String uri, ConvertingHttpEntity entity) throws IOException, URISyntaxException, UnsupportedConversionException { return execute(method, new HttpRequest(uri), entity); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, HttpRequest request, HttpEntity entity) throws IOException { return run(method, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse execute(HttpMethod method, String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(method, new HttpRequest(uri), entity); } /** * {@inheritDoc} */ @Override public HttpResponse get(HttpRequest request) throws IOException { return execute(HttpMethod.GET, request); } /** * {@inheritDoc} */ @Override public HttpResponse get(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.GET, uri); } /** * {@inheritDoc} */ @Override public HttpResponse post(HttpRequest request) throws IOException { return execute(HttpMethod.POST, request); } /** * {@inheritDoc} */ @Override public HttpResponse post(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.POST, uri); } /** * {@inheritDoc} */ @Override public HttpResponse post(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.POST, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse post(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.POST, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse post(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.POST, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse post(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.POST, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse post(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.POST, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse post(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.POST, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse post(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.POST, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse post(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.POST, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(HttpRequest request) throws IOException { return execute(HttpMethod.PUT, request); } /** * {@inheritDoc} */ @Override public HttpResponse put(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.PUT, uri); } /** * {@inheritDoc} */ @Override public HttpResponse put(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.PUT, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.PUT, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.PUT, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse put(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.PUT, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse put(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.PUT, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.PUT, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.PUT, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse put(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.PUT, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(HttpRequest request) throws IOException { return execute(HttpMethod.DELETE, request); } /** * {@inheritDoc} */ @Override public HttpResponse delete(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.DELETE, uri); } /** * {@inheritDoc} */ @Override public HttpResponse delete(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.DELETE, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.DELETE, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.DELETE, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse delete(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.DELETE, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse delete(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.DELETE, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.DELETE, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.DELETE, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse delete(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.DELETE, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(HttpRequest request) throws IOException { return execute(HttpMethod.OPTIONS, request); } /** * {@inheritDoc} */ @Override public HttpResponse options(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.OPTIONS, uri); } /** * {@inheritDoc} */ @Override public HttpResponse options(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.OPTIONS, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.OPTIONS, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.OPTIONS, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse options(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.OPTIONS, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse options(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.OPTIONS, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.OPTIONS, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.OPTIONS, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse options(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.OPTIONS, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(HttpRequest request) throws IOException { return execute(HttpMethod.HEAD, request); } /** * {@inheritDoc} */ @Override public HttpResponse head(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.HEAD, uri); } /** * {@inheritDoc} */ @Override public HttpResponse head(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.HEAD, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.HEAD, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.HEAD, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse head(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.HEAD, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse head(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.HEAD, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.HEAD, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.HEAD, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse head(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.HEAD, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse trace(HttpRequest request) throws IOException { return execute(HttpMethod.TRACE, request); } /** * {@inheritDoc} */ @Override public HttpResponse trace(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.TRACE, uri); } /** * {@inheritDoc} */ @Override public HttpResponse patch(HttpRequest request) throws IOException { return execute(HttpMethod.PATCH, request); } /** * {@inheritDoc} */ @Override public HttpResponse patch(String uri) throws IOException, URISyntaxException { return execute(HttpMethod.PATCH, uri); } /** * {@inheritDoc} */ @Override public HttpResponse patch(HttpRequest request, HttpEntity entity) throws IOException { return execute(HttpMethod.PATCH, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse patch(String uri, HttpEntity entity) throws IOException, URISyntaxException { return execute(HttpMethod.PATCH, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse patch(HttpRequest request, InputStream inputStream) throws IOException { return execute(HttpMethod.PATCH, request, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse patch(String uri, InputStream inputStream) throws IOException, URISyntaxException { return execute(HttpMethod.PATCH, uri, inputStream); } /** * {@inheritDoc} */ @Override public HttpResponse patch(HttpRequest request, Object entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.PATCH, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse patch(String uri, Object entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.PATCH, uri, entity); } /** * {@inheritDoc} */ @Override public HttpResponse patch(HttpRequest request, ConvertingHttpEntity entity) throws IOException, UnsupportedConversionException { return execute(HttpMethod.PATCH, request, entity); } /** * {@inheritDoc} */ @Override public HttpResponse patch(String uri, ConvertingHttpEntity entity) throws UnsupportedConversionException, IOException, URISyntaxException { return execute(HttpMethod.PATCH, uri, entity); } /** * {@inheritDoc} */ @Override public EntityConverterManager getConverterManager() { return converterManager; } /** * Orchestrates making the HTTP request. Fires appropriate filter events and hands off to the implementation * to perform the actual HTTP request. * * @param method HTTP request method. * @param request {@link HttpRequest} object to configure the request. * @param entity Request entity. * @return A {@link HttpResponse} object containing the properties of the server response. */ private HttpResponse run(HttpMethod method, HttpRequest request, HttpEntity entity) throws IOException { HttpContext context = new HttpContext(); HttpClientFilterProcessor filterProcessor = new HttpClientFilterProcessor(request.getFilters()); try { filterProcessor.onStart(context); context.setMethod(method); HttpEntity originalEntity = null; boolean hasRetryFilters = filterProcessor.hasRetryFilters(); // Requests whose client contains a retry filter must have their entity buffered. // If it is not, the retried request will either throw an error due to the entity // input stream being closed, or the entity will not actually transmit. So, requests // that could potentially be retried are automatically buffered so we can copy their // entities multiple times. if (entity != null && hasRetryFilters) { originalEntity = entity; originalEntity.buffer(); } while (true) { if (entity != null && originalEntity != null) { entity = new HttpEntity(originalEntity.getInputStream(), originalEntity.getContentType(), originalEntity.getCharSet()); } HttpRequest newRequest; try { newRequest = (HttpRequest) request.clone(); } catch (CloneNotSupportedException e) { throw new HttpClientException(e); } context.setRequest(newRequest); context.setResponse(null); filterProcessor.filterHttpRequest(newRequest); filterProcessor.onRequest(context); // Note that OutputStreamFilter#filter should be called by the client implementation, // and will occur during the execution started below. HttpResponse response; try { response = execute(context, entity, filterProcessor); } catch (IOException e) { throw e; } catch (Exception e) { throw new HttpClientException(e); } context.setResponse(response); filterProcessor.filterHttpResponse(response); filterProcessor.onResponse(context); if (!filterProcessor.isRetryRequired(context)) { filterProcessor.onComplete(context); return context.getResponse(); } context.incrementRetries(); } } finally { filterProcessor.close(); } } /** * Create and return an all-trusting TLS {@link SSLContext}. * * @return An all-trusting TLS {@link SSLContext}. * @throws GeneralSecurityException When an issue with SSL configuration occurs. */ protected SSLContext createTrustingSSLContext() throws GeneralSecurityException { TrustManager[] certs = {new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } }}; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, certs, new SecureRandom()); return sslContext; } /** * Create and return an all-trusting {@link HostnameVerifier}. * * @return An all-trusting {@link HostnameVerifier}. */ protected HostnameVerifier createTrustingHostnameVerifier() { return (hostname, session) -> true; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy