001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.client;
018
019import java.io.*;
020
021/**
022 * SPI for pluggable HTTP transports.
023 *
024 * <p>
025 * An {@link HttpTransport} is responsible for executing a fully-resolved {@link TransportRequest} and returning a
026 * {@link TransportResponse}.  Implementations include:
027 * <ul>
028 *    <li>{@code ApacheHc45Transport} (module {@code juneau-rest-client-apache-httpclient-45})
029 *    <li>{@code ApacheHc5Transport} (module {@code juneau-rest-client-apache-httpclient-50})
030 *    <li>{@code JavaHttpTransport} (module {@code juneau-rest-client-java-httpclient})
031 *    <li>{@code OkHttpTransport} (module {@code juneau-rest-client-okhttp})
032 *    <li>{@code JettyHttpTransport} (module {@code juneau-rest-client-jetty})
033 *    <li>{@code MockHttpTransport} (module {@code juneau-rest-mock})
034 * </ul>
035 *
036 * <p>
037 * Implementations are discovered automatically via {@link HttpTransportProvider} using {@link java.util.ServiceLoader},
038 * or set explicitly via {@code RestClient.Builder#transport(HttpTransport)}.
039 *
040 * <h5 class='section'>See Also:</h5><ul>
041 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a>
042 * </ul>
043 *
044 * @since 9.2.1
045 */
046public interface HttpTransport extends Closeable {
047
048   /**
049    * Executes the given request and returns the response.
050    *
051    * <p>
052    * The caller is responsible for closing the returned {@link TransportResponse} after consuming the body.
053    *
054    * @param request The fully-resolved request. Must not be <jk>null</jk>.
055    * @return The response. Never <jk>null</jk>.
056    * @throws TransportException If a network-level error occurs.
057    */
058   TransportResponse execute(TransportRequest request) throws TransportException;
059
060   /**
061    * Returns {@code true} if this transport can honor the SSRF guardrail's connect-time contract for a
062    * policy-covered request ({@link TransportRequest#isSsrfGuardActive()}): pin-on-connect to a resolved address
063    * that has passed the deny-private policy, and Juneau-controlled redirect revalidation (no fallback to the
064    * transport's own auto-follow).
065    *
066    * <p>
067    * The default implementation returns {@code false} (fail closed): an unknown/caller-supplied transport that
068    * has not affirmatively opted in is presumed unable to honor the contract, so
069    * {@code RestRequest#run()} rejects policy-covered requests against it rather than silently connecting without
070    * the guardrail. First-party transports that construct and fully control their own underlying HTTP client
071    * override this to return {@code true}.
072    *
073    * @return {@code true} if this transport supports pin-on-connect + redirect revalidation for policy-covered requests.
074    */
075   default boolean supportsUrlPolicy() {
076      return false;
077   }
078
079   /**
080    * Releases resources held by this transport (connection pools, threads, etc.).
081    *
082    * <p>
083    * The default implementation is a no-op.
084    */
085   @Override
086   default void close() throws IOException {
087      // no-op by default
088   }
089}