package nl.knaw.huygens.security.client; import com.google.common.base.Splitter; import com.google.common.collect.LinkedListMultimap; import com.google.common.escape.Escaper; import com.google.common.net.UrlEscapers; import java.net.URI; import java.util.List; import java.util.Map; public class HttpRequest { public final String method; private String path; public final LinkedListMultimap<String, String> headers; public final String body; public final String server; public final LinkedListMultimap<String, String> queryParameters; public HttpRequest( String method, String url, LinkedListMultimap<String, String> headers, String body, String server, LinkedListMultimap<String, String> queryParameters ) { if (url != null) { URI uri = URI.create(url); if (uri.isOpaque()) { throw new IllegalArgumentException("Should be a URL, not a URI"); } this.path = uri.getPath(); if (uri.isAbsolute() && server == null) { this.server = uri.getScheme() + "://" + uri.getRawAuthority(); } else { this.server = server; } //if you have query parameters in the base url _and_ separate query parameters then the result is a concatenation if (uri.getRawQuery() != null) { this.queryParameters = LinkedListMultimap.create(); for (String querySegment : Splitter.on("&").split(uri.getRawQuery())) { int equalsLocation = querySegment.indexOf('='); String key = querySegment.substring(0, equalsLocation); String value = querySegment.substring(equalsLocation + 1); this.queryParameters.put(key, value); } if (queryParameters != null) { this.queryParameters.putAll(queryParameters); } } else { this.queryParameters = queryParameters; } } else { this.server = server; this.path = ""; this.queryParameters = queryParameters; } this.method = method; this.headers = headers; this.body = body; } public HttpRequest(String method, String url) { this(method, url, LinkedListMultimap.create(), null, null, LinkedListMultimap.create()); } public HttpRequest(String method, String url, String body) { this(method, url, LinkedListMultimap.create(), body, null, LinkedListMultimap.create()); } public HttpRequest withHeader(String key, String value) { headers.put(key, value); return this; } public HttpRequest withExtraPath(String path) { if (path == null || path.equals("")) { return this; } if (!this.path.endsWith("/")) { this.path += "/"; } if (path.charAt(0) == '/') { path = path.substring(1); } this.path += path; return this; } public HttpRequest withHeaders(List<? extends Map.Entry<String, String>> headers) { headers.forEach(entry -> this.headers.put(entry.getKey(), entry.getValue())); return this; } public HttpRequest withQueryParam(String key, String value) { queryParameters.put(key, value); return this; } public HttpRequest withQueryParams(List<? extends Map.Entry<String, String>> params) { params.forEach(entry -> this.queryParameters.put(entry.getKey(), entry.getValue())); return this; } public String getPath() { return this.path; } public String getPathAndQuery() { String url = this.path; boolean isFirst = true; for (Map.Entry<String, String> queryParameter : this.queryParameters.entries()) { if (isFirst) { url += "?"; isFirst = false; } else { url += "&"; } Escaper escaper = UrlEscapers.urlFormParameterEscaper(); url += escaper.escape(queryParameter.getKey()) + "=" + escaper.escape(queryParameter.getValue()); } return url; } public String getUrl() { String path = getPathAndQuery(); if (path.charAt(0) == '/') { return server + path; } else { return server + "/" + path; } } }