Package nodebox.function

Source Code of nodebox.function.NetworkFunctions$Response

package nodebox.function;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.jayway.jsonpath.JsonPath;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class NetworkFunctions {

    public static final Map<Integer, Response> responseCache = new HashMap<Integer, Response>();
    public static final FunctionLibrary LIBRARY;

    static {
        LIBRARY = JavaLibrary.ofClass("network", NetworkFunctions.class,
                "httpGet", "queryJSON", "encodeURL");
    }

    public static synchronized Map<String, Object> httpGet(final String url, final String username, final String password, final long refreshTimeSeconds) {
        Integer cacheKey = Objects.hashCode(url, username, password);
        if (responseCache.containsKey(cacheKey)) {
            Response r = responseCache.get(cacheKey);
            long timeNow = nowSeconds();
            long timeFetched = r.timeFetched;
            if ((timeNow - timeFetched) <= refreshTimeSeconds) {
                return r.response;
            }
        }
        Map<String, Object> r = _httpGet(url, username, password);
        Response res = new Response(nowSeconds(), r);
        responseCache.put(cacheKey, res);
        return r;
    }

    public static Iterable<?> queryJSON(final Object json, final String query) {
        if (json instanceof Map) {
            Map<?, ?> requestMap = (Map<?, ?>) json;
            if (requestMap.containsKey("body")) {
                return queryJSON(requestMap.get("body"), query);
            } else {
                throw new IllegalArgumentException("Cannot parse JSON input.");
            }
        } else if (json instanceof String) {
            Object results = JsonPath.read((String) json, query);
            if (!(results instanceof Iterable)) {
                return ImmutableList.of(results);
            } else {
                return (Iterable<?>) results;
            }
        } else {
            throw new IllegalArgumentException("Cannot parse JSON input.");
        }
    }

    public static String encodeURL(final String s) {
        try {
            return URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return s;
        }
    }

    private static Map<String, Object> _httpGet(final String url, final String username, final String password) {
        HttpGet request = new HttpGet(url);

        if (username != null && !username.trim().isEmpty()) {
            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
            BasicScheme scheme = new BasicScheme();
            Header authorizationHeader;
            try {
                authorizationHeader = scheme.authenticate(credentials, request, new BasicHttpContext());
            } catch (AuthenticationException e) {
                throw new RuntimeException(e);
            }
            request.addHeader(authorizationHeader);
        }

        try {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpResponse response = client.execute(request);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String body = EntityUtils.toString(entity);
                HashMap<String, String> m = new HashMap<String, String>();
                for (Header h : response.getAllHeaders()) {
                    m.put(h.getName(), h.getValue());
                }

                Map<String, String> headers = ImmutableMap.copyOf(m);
                return ImmutableMap.of(
                        "body", body,
                        "statusCode", response.getStatusLine().getStatusCode(),
                        "headers", headers);
            } else {
                // 204 No Content
                return emptyResponse(204);
            }
        } catch (IllegalStateException e) {
            if (e.getMessage().startsWith("Target host must not be null")) {
                throw new RuntimeException("URL should start with \"http://\" or \"https://\".");
            } else {
                throw e;
            }
        } catch (IOException e) {
            // We return status code 408 (Request Timeout) here since we always want to return a valid response.
            // However, the exception signifies an IO error, so maybe the network connection is down.
            // This has no valid HTTP response (since there is NO response).
            return emptyResponse(408);
        }
    }

    private static Map<String, Object> emptyResponse(int statusCode) {
        return ImmutableMap.<String, Object>of(
                "body", "",
                "statusCode", statusCode
        );
    }

    private static long nowSeconds() {
        return System.currentTimeMillis() / 1000;
    }

    private static class Response {
        private final long timeFetched;
        private final Map<String, Object> response;

        private Response(long timeFetched, Map<String, Object> response) {
            this.timeFetched = timeFetched;
            this.response = response;
        }
    }

}
TOP

Related Classes of nodebox.function.NetworkFunctions$Response

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.