io.nitor.api.backend.util.Helpers.java Source code

Java tutorial

Introduction

Here is the source code for io.nitor.api.backend.util.Helpers.java

Source

/**
 * Copyright 2018-2019 Nitor Creations Oy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.nitor.api.backend.util;

import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.regex.Pattern;

import static io.netty.handler.codec.http.HttpHeaderNames.USER_AGENT;
import static java.lang.Math.min;
import static java.net.URLEncoder.encode;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Locale.ROOT;
import static java.util.regex.Pattern.compile;

public class Helpers {
    private static final Logger logger = LogManager.getLogger(Helpers.class);
    private static final Pattern NUMERIC = compile("[0-9]+");
    public static final String REMOTE_ADDRESS = "remoteAddress";
    private static Region DEFAULT_REGION = null;
    static final boolean praseForwardedHeader = false;

    public static String urlEncode(String raw) {
        try {
            return encode(raw, UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("Never happends", e);
        }
    }

    public static String cleanUserAgent(HttpServerRequest request) {
        String userAgent = request.getHeader(USER_AGENT);
        if (userAgent == null) {
            return null;
        }
        return NUMERIC.matcher(userAgent).replaceAll("0");
    }

    public static String getRemoteAddress(RoutingContext context) {
        String remote = context.get(REMOTE_ADDRESS);
        if (remote != null) {
            return remote;
        }
        return context.request().remoteAddress().host();
    }

    public static String parseForwardedHeaders(MultiMap headers) {
        String host = null;
        if (praseForwardedHeader) {
            host = parseForwarded(headers);
        }
        if (host == null) {
            host = parseXForwardedHost(headers);
        }
        return host;
    }

    private static String parseForwarded(MultiMap headers) {
        List<String> values = headers.getAll("forwarded");
        if (values.isEmpty()) {
            return null;
        }
        String forwarded = values.get(values.size() - 1).toLowerCase(ROOT);
        int start = forwarded.lastIndexOf("for=");
        if (start == -1) {
            return null;
        }
        start += 4;
        int end;
        if (forwarded.charAt(start) == '"') {
            start++;
            end = forwarded.indexOf('"', start);
        } else {
            end = forwarded.indexOf(';');
            if (end == -1) {
                end = forwarded.length();
            }
            int end2 = forwarded.indexOf(',');
            if (end2 == -1) {
                end2 = forwarded.length();
            }
            end = min(end, end2);
        }
        forwarded = forwarded.substring(start, end).trim();
        return forwarded;
    }

    private static String parseXForwardedHost(MultiMap headers) {
        List<String> values = headers.getAll("x-forwarded-for");
        if (values.isEmpty()) {
            return null;
        }
        String forwardedHost = values.get(values.size() - 1);
        int lastPart = forwardedHost.lastIndexOf(',') + 1;
        forwardedHost = forwardedHost.substring(lastPart).trim();
        return forwardedHost;
    }

    public static String getUriHostNamePort(String uri) {
        if (uri == null) {
            return null;
        }
        if (uri.startsWith("http")) {
            uri = uri.substring(uri.indexOf("://") + 3);
        }
        int pathIdx = uri.indexOf('/');
        if (pathIdx >= 0) {
            uri = uri.substring(0, pathIdx);
        }
        return uri.toLowerCase(ROOT);
    }

    public static String getUriHostName(String uri) {
        if (uri == null) {
            return null;
        }
        uri = getUriHostNamePort(uri);
        int idx = uri.indexOf(':');
        if (idx >= 0) {
            uri = uri.substring(0, idx);
        }
        return uri;
    }

    public static String replaceHost(String publicURI, String host) {
        return replaceHost(publicURI, host, false);
    }

    public static String replaceHostAndPort(String publicURI, String host) {
        return replaceHost(publicURI, host, true);
    }

    private static String replaceHost(String publicURI, String host, boolean replacePort) {
        int begin = publicURI.indexOf("://") + 3;
        int end = publicURI.indexOf('/', begin);
        int end2 = replacePort ? -1 : publicURI.indexOf(':', begin);
        if (end == -1) {
            end = publicURI.length();
        }
        if (end2 == -1) {
            end2 = publicURI.length();
        }
        return publicURI.substring(0, begin) + host + publicURI.substring(min(end, end2));
    }

    public static String forceHttps(String host) {
        return host.startsWith("http:") ? "https:" + host.substring(5) : host;
    }

    public static Region resolveRegion(JsonObject conf) {
        String regionStr = conf.getString("region");
        if (regionStr != null) {
            return Region.of(regionStr);
        } else {
            if (DEFAULT_REGION == null) {
                DEFAULT_REGION = new DefaultAwsRegionProviderChain().getRegion();
            }
            return DEFAULT_REGION;
        }
    }

    public static AwsCredentialsProvider resolveCredentialsProvider(JsonObject conf) {
        AwsCredentialsProvider secretsProvider;
        String accessKey = conf.getString("accessKey");
        String secretKey = conf.getString("secretKey");
        if (accessKey != null && secretKey != null) {
            AwsBasicCredentials creds = AwsBasicCredentials.create(accessKey, secretKey);
            secretsProvider = () -> creds;
        } else {
            secretsProvider = DefaultCredentialsProvider.builder().build();
        }
        return secretsProvider;
    }

    public static byte[] toBytes(InputStream in) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = in.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        return buffer.toByteArray();
    }
}