public static URI resolve(
            final URI originalURI,
            final HttpHost target,
            final List<URI> redirects) throws URISyntaxException {
        Args.notNull(originalURI, "Request URI");
        final URIBuilder uribuilder;
        if (redirects == null || redirects.isEmpty()) {
            uribuilder = new URIBuilder(originalURI);
        } else {
            uribuilder = new URIBuilder(redirects.get(redirects.size() - 1));
            String frag = uribuilder.getFragment();
            // read interpreted fragment identifier from redirect locations
            for (int i = redirects.size() - 1; frag == null && i >= 0; i--) {
                frag = redirects.get(i).getFragment();
            }
            uribuilder.setFragment(frag);
        }
        // read interpreted fragment identifier from original request
        if (uribuilder.getFragment() == null) {
            uribuilder.setFragment(originalURI.getFragment());
        }
        // last target origin
        if (target != null && !uribuilder.isAbsolute()) {
            uribuilder.setScheme(target.getSchemeName());
            uribuilder.setHost(target.getHostName());
            uribuilder.setPort(target.getPort());
        }
        return uribuilder.build();
    }
Derives the interpreted (absolute) URI that was used to generate the last
request. This is done by extracting the request-uri and target origin for
the last request and scanning all the redirect locations for the last
fragment identifier, then combining the result into a {@link URI}.

@param originalURI
           original request before any redirects
@param target
           if the last URI is relative, it is resolved against this target,
           or {@code null} if not available.
@param redirects
           collection of redirect locations since the original request
           or {@code null} if not available.
@return interpreted (absolute) URI
ngrinder-runtime/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java