WFSProxy.java

/*
 * Copyright (C) 2023 B3Partners B.V.
 *
 * SPDX-License-Identifier: MIT
 */
package org.tailormap.api.geotools.wfs;

import static org.springframework.http.HttpHeaders.REFERER;
import static org.tailormap.api.util.HttpProxyUtil.addForwardedForRequestHeaders;
import static org.tailormap.api.util.HttpProxyUtil.configureProxyRequestBuilderForUri;
import static org.tailormap.api.util.HttpProxyUtil.passthroughRequestHeaders;
import static org.tailormap.api.util.HttpProxyUtil.setHttpBasicAuthenticationHeader;

import jakarta.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Set;

public class WFSProxy {
  private final HttpClient httpClient;

  public WFSProxy() {
    final HttpClient.Builder builder = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL);
    this.httpClient = builder.build();
  }

  public HttpResponse<InputStream> proxyWfsRequest(
      URI wfsRequest, String username, String password, HttpServletRequest request) throws Exception {

    HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
    configureProxyRequestBuilderForUri(requestBuilder, wfsRequest, request);
    addForwardedForRequestHeaders(requestBuilder, request);
    // Just a few headers for logging, conditional or range requests not likely to be supported by a
    // WFS
    passthroughRequestHeaders(requestBuilder, request, Set.of(REFERER, "User-Agent"));
    setHttpBasicAuthenticationHeader(requestBuilder, username, password);

    return httpClient.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofInputStream());
  }
}