to.sparks.mtgox.net.HTTPAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for to.sparks.mtgox.net.HTTPAuthenticator.java

Source

/*
 * The MtGox-Java API is free software: you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The MtGox-Java API is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Lesser GNU General Public License for more details.
 *
 * You should have received a copy of the Lesser GNU General Public License
 * along with the MtGox-Java API .  If not, see <http://www.gnu.org/licenses/>.
 */
package to.sparks.mtgox.net;

import biz.source_code.base64Coder.Base64Coder;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.lang.StringUtils;

/**
 * A simple implementation of an authenticated client for the MtGox HTTP API
 *
 * @author SparksG
 */
public class HTTPAuthenticator {

    private String apiKey;
    private String secret;
    protected static Logger logger;
    private int readTimout = 600000;
    private int connectTimeout = 10000;
    private int killTimeout = 600000;

    public HTTPAuthenticator(final Logger logger, String apiKey, String secret) {
        this.apiKey = apiKey;
        this.secret = secret;

        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }
        } };

        try {

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {

            logger.log(Level.SEVERE, null, e);
        }

    }

    /*
     * This function is based on an original idea by github user christopherobin
     * See https://gist.github.com/2396722
     */
    protected InputStream getMtGoxHTTPInputStream(String path, HashMap<String, String> args)
            throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        HttpURLConnection connection;

        args.put("nonce", String.valueOf(System.nanoTime()));
        String post_data = buildQueryString(args);

        System.setProperty("jsse.enableSNIExtension", "false");

        URL queryUrl = new URL(path);
        connection = (HttpURLConnection) queryUrl.openConnection();
        connection.setDoOutput(true);
        connection.setConnectTimeout(connectTimeout);
        connection.setReadTimeout(readTimout);
        connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; mtgox-java client)");
        new Thread(new InterruptThread(Thread.currentThread(), connection)).start(); // Kill the connection on timeout

        if (StringUtils.isNotBlank(this.secret) && !this.secret.equalsIgnoreCase("${api.secret}")) {
            Mac mac = Mac.getInstance("HmacSHA512");
            SecretKeySpec secret_spec = new SecretKeySpec(Base64Coder.decode(this.secret), "HmacSHA512");
            mac.init(secret_spec);
            String signature = new String(Base64Coder.encode(mac.doFinal(post_data.getBytes()))).replaceAll("\n",
                    "");
            connection.setRequestProperty("Rest-Key", apiKey);
            connection.setRequestProperty("Rest-Sign", signature);
        }

        connection.getOutputStream().write(post_data.getBytes());
        return connection.getInputStream();
    }

    protected InputStream getMtGoxHTTPInputStream(String path)
            throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        return getMtGoxHTTPInputStream(path, new HashMap<String, String>());
    }

    private static String buildQueryString(HashMap<String, String> args) throws UnsupportedEncodingException {
        String result = new String();
        for (String hashkey : args.keySet()) {
            if (result.length() > 0) {
                result += '&';
            }
            result += URLEncoder.encode(hashkey, "UTF-8") + "=" + URLEncoder.encode(args.get(hashkey), "UTF-8");

        }
        return result;
    }

    public int getReadTimout() {
        return readTimout;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public void setReadTimout(int readTimout) {
        this.readTimout = readTimout;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
    /*
     * http://thushw.blogspot.hu/2010/10/java-urlconnection-provides-no-fail.html
     */

    class InterruptThread implements Runnable {

        Thread parent;
        HttpURLConnection con;

        public InterruptThread(Thread parent, HttpURLConnection con) {
            this.parent = parent;
            this.con = con;
        }

        public void run() {
            try {
                Thread.sleep(killTimeout);
                if (con != null) {
                    con.disconnect();
                }
            } catch (InterruptedException | NullPointerException e) {
            }

        }
    }
}