package org.github.flytreeleft.nexus3.keycloak.plugin.internal.http; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicNameValuePair; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; public class HttpMethod<R> { private final HttpClient httpClient; private final ClientAuthenticator authenticator; private final RequestBuilder builder; private final HashMap<String, String> params; public HttpMethod(HttpClient httpClient, ClientAuthenticator authenticator, RequestBuilder builder) { this(httpClient, authenticator, builder, new HashMap<>()); } public HttpMethod( HttpClient httpClient, ClientAuthenticator authenticator, RequestBuilder builder, HashMap<String, String> params ) { this.httpClient = httpClient; this.authenticator = authenticator; this.builder = builder; this.params = params != null ? new HashMap<>(params) : new HashMap<>(); } public void execute() { execute((InputStream inputStream) -> null); } public R execute(HttpResponseProcessor<R> responseProcessor) { InputStream inputStream = null; try { preExecute(this.builder); HttpResponse response = this.httpClient.execute(this.builder.build()); HttpEntity entity = response.getEntity(); if (entity != null) { inputStream = entity.getContent(); } StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); if (statusCode == 404) { return null; } else if (statusCode < 200 || statusCode >= 300) { throw new HttpResponseException( "Unexpected response from server: " + statusCode + " / " + statusLine.getReasonPhrase(), statusCode, statusLine.getReasonPhrase()); } if (inputStream == null) { return null; } else { return responseProcessor.process(inputStream); } } catch (HttpResponseException e) { throw e; } catch (Exception e) { throw new RuntimeException("Error executing http method [" + this.builder + "].", e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { } } } } protected void preExecute(RequestBuilder builder) { for (Map.Entry<String, String> param : this.params.entrySet()) { builder.addParameter(param.getKey(), param.getValue()); } } public HttpMethod<R> authorizationBearer(String bearer) { String prefix = "Bearer "; if (!bearer.startsWith(prefix)) { bearer = prefix + bearer; } header("Authorization", bearer); return this; } public HttpMethod<R> authorizationBasic(String basic) { String prefix = "Basic "; if (!basic.startsWith(prefix)) { basic = prefix + basic; } header("Authorization", basic); return this; } public HttpMethod<R> authorizationBasic(String username, String password) { StringBuilder sb = new StringBuilder(username); sb.append(':').append(password); try { String basic = Base64.getEncoder().encodeToString(sb.toString().getBytes("UTF-8")); authorizationBasic(basic); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } return this; } public HttpMethodResponse<R> response() { return new HttpMethodResponse<R>(this); } public HttpMethod<R> authentication() { if (this.authenticator != null) { this.authenticator.configure(this); } return this; } public HttpMethod<R> param(String name, String value) { this.params.put(name, value); return this; } public HttpMethod<R> header(String name, String value) { this.builder.addHeader(name, value); return this; } public HttpMethod<R> json(byte[] entity) { header("Content-Type", "application/json"); this.builder.setEntity(new ByteArrayEntity(entity)); return this; } public HttpMethod<R> form() { return new HttpMethod<R>(this.httpClient, authenticator, this.builder, this.params) { @Override protected void preExecute(RequestBuilder builder) { List<NameValuePair> formParams = new ArrayList<>(); for (Map.Entry<String, String> param : getParams().entrySet()) { formParams.add(new BasicNameValuePair(param.getKey(), param.getValue())); } if (!formParams.isEmpty()) { try { builder.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Error creating form parameters"); } } } }; } protected Map<String, String> getParams() { return this.params; } }