com.sandklef.coachapp.http.HttpAccess.java Source code

Java tutorial

Introduction

Here is the source code for com.sandklef.coachapp.http.HttpAccess.java

Source

/******************************************************************************
 *      Copyright (c) 2015 - 2016 Henrik Sandklef
 *
 *  This file is part of Coach Assistant
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

package com.sandklef.coachapp.http;

import com.sandklef.coachapp.Session.CoachAppSession;
import com.sandklef.coachapp.misc.*;
import com.sandklef.coachapp.storage.LocalStorage;
import com.sandklef.coachapp.storage.Storage;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;

import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;

import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.net.MalformedURLException;
import java.security.acl.LastOwnerException;

public class HttpAccess {

    private final static String LOG_TAG = HttpAccess.class.getSimpleName();

    private static int maxBufferSize = 1 * 1024 * 1024;

    private String urlBase;
    //  private String serverUrl;
    private String serverUrlShort;
    //    private String clubUri;

    public HttpAccess(String baseUrl) throws HttpAccessException {
        if (baseUrl == null) {
            throw new HttpAccessException("NULL pointer passed to constructor (" + baseUrl + ")",
                    HttpAccessException.NETWORK_ERROR);
        }
        this.urlBase = baseUrl;
        //    this.clubUri   = "";
        //    this.serverUrl = urlBase + HttpSettings.CLUB_PATH + HttpSettings.PATH_SEPARATOR ;
    }

    private String sendHttpPost(String token, StringEntity data, String header, String path)
            throws HttpAccessException {
        HttpClient client = new DefaultHttpClient();
        String url = urlBase + path;
        HttpResponse resp = null;
        String response = null;
        Log.d(LOG_TAG, "sendHttpPost()  url:     " + urlBase);
        Log.d(LOG_TAG, "sendHttpPost()  path:    " + path);
        Log.d(LOG_TAG, "sendHttpPost()  url:     " + url);
        Log.d(LOG_TAG, "sendHttpPost()  club:    " + LocalStorage.getInstance().getCurrentClub());
        Log.d(LOG_TAG, "sendHttpPost()  header: " + header);
        try {
            Log.d(LOG_TAG, "sendHttpPost()  data:   " + data.getContent().toString());
        } catch (Exception e) {
            ;
        }

        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setHeader(HttpSettings.CONTENT_STATUS, header);
            httpPost.setEntity(data);
            if (token != null) {
                httpPost.setHeader("X-Token", token);
                httpPost.setHeader("X-instance", LocalStorage.getInstance().getCurrentClub());
                Log.d(LOG_TAG, "Using token: " + token);
            } else {
                Log.d(LOG_TAG, "Not using token");
            }
            resp = client.execute(httpPost);
            Log.d(LOG_TAG, resp + "  <==  sendHttpPost");
            Log.d(LOG_TAG, resp.getStatusLine().getStatusCode() + "  <==  sendHttpPost");
            if (HttpSettings.isResponseOk(resp.getStatusLine().getStatusCode())) {
                Log.d(LOG_TAG, " server response ok, returning data");
                response = EntityUtils.toString(resp.getEntity());
            } else {
                Log.d(LOG_TAG, "Server response OK but bad password");
                HttpAccessException e = new HttpAccessException("sendHttpPost failed",
                        HttpAccessException.ACCESS_ERROR);
                Log.d(LOG_TAG, "Will throw: " + e.getMode());
                throw e;
            }
        } catch (IOException e) {
            throw new HttpAccessException("sendHttpPost failed", e, HttpAccessException.NETWORK_ERROR);
        }

        try {
            Log.d(LOG_TAG, " consuming entity");
            if (resp.getEntity() != null) {
                resp.getEntity().consumeContent();
            }
        } catch (IOException ex) {
            throw new HttpAccessException("sendHttpPost failed", ex, HttpAccessException.NETWORK_ERROR);
        }

        return response;
    }

    private String getFromServer(String token, String path, String clubUri) throws HttpAccessException {
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();

        String url = urlBase + HttpSettings.API_VERSION + path;
        if (clubUri == null) {
            url = urlBase + path;
        }

        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("X-Token", token);
        if (clubUri != null) {
            Log.d(LOG_TAG, "Server instance: " + clubUri + " ");
            httpGet.addHeader("X-Instance", clubUri);
        } else {
            Log.d(LOG_TAG, "Server instance not set in header");
        }
        Log.d(LOG_TAG, "Server url:   " + url + "  in getFromServer()");
        Log.d(LOG_TAG, "Server token: " + token + " ");

        Log.d(LOG_TAG, "Headers:");
        for (Header h : httpGet.getAllHeaders()) {
            Log.d(LOG_TAG, " * header: " + h);
        }

        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (HttpSettings.isResponseOk(statusCode)) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.d(LOG_TAG, "Failed to download file");
                Log.d(LOG_TAG, " * " + response.getStatusLine().getStatusCode());
                Log.d(LOG_TAG, " * " + response.getStatusLine());
                Log.d(LOG_TAG, "Failed to download file" + response);
                Log.w("Failed reading data from server", "Failed to download: " + path);
                throw new HttpAccessException("readEntireCoachServer failed", HttpAccessException.ACCESS_ERROR);
            }
        } catch (ClientProtocolException e) {
            throw new HttpAccessException("readEntireCoachServer failed", e, HttpAccessException.NETWORK_ERROR);
        } catch (IOException e) {
            throw new HttpAccessException("readEntireCoachServer failed", e, HttpAccessException.NETWORK_ERROR);
        }
        return builder.toString();
    }

    public String readEntireCoachServer(String token, String clubUri) throws HttpAccessException {
        return getFromServer(token, HttpSettings.PATH_SEPARATOR + HttpSettings.COMPOSITE_PATH, clubUri);
    }

    public String getUserInfo(String token) throws HttpAccessException {
        return getFromServer(token, HttpSettings.USER_PATH, null);
    }

    public String getToken(String header, String data) throws HttpAccessException {
        HttpResponse resp = null;
        // POST /api/login { "user": "my_email@example.com", "password": "my_password" }
        try {
            Log.d(LOG_TAG, "getToken(" + data + ", " + header + ")");
            return sendHttpPost(null, new StringEntity(data), header,
                    HttpSettings.PATH_SEPARATOR + HttpSettings.LOGIN_PATH);
        } catch (UnsupportedEncodingException e) {
            throw new HttpAccessException("Failed encoding", e, HttpAccessException.NETWORK_ERROR);
        }
    }

    public String createVideo(String token, String clubUri, String data, String header) throws HttpAccessException {
        HttpResponse resp = null;
        //$ curl --data "{ \"trainingPhaseUuid\": \"$TRAINING_PHASE_UUID\" }" --header "Content-Type: application/json" --request POST localhost:3000/0.0.0/clubs/$CLUB_UUID/videos
        try {
            Log.d(LOG_TAG, "createVideo(" + data + ", " + header + ")");
            return sendHttpPost(token, new StringEntity(data), header,
                    HttpSettings.API_VERSION + HttpSettings.VIDEO_URL_PATH);
            //            return sendHttpPost(token, new StringEntity(data), header, HttpSettings.API_VERSION + HttpSettings.CLUB_PATH + HttpSettings.PATH_SEPARATOR + clubUri + HttpSettings.PATH_SEPARATOR + HttpSettings.PATH_SEPARATOR + HttpSettings.VIDEO_URL_PATH);
        } catch (UnsupportedEncodingException e) {
            throw new HttpAccessException("Failed encoding", e, HttpAccessException.NETWORK_ERROR);
        }
    }

    public void uploadTrainingPhaseVideo(String clubUri, String videoUuid, String fileName)
            throws HttpAccessException, IOException {

        HttpURLConnection connection = null;
        DataOutputStream outputStream = null;
        DataInputStream inputStream = null;

        String pathToOurFile = fileName;
        String urlServer = urlBase + HttpSettings.API_VERSION + HttpSettings.PATH_SEPARATOR
                + HttpSettings.VIDEO_URL_PATH + HttpSettings.UUID_PATH + videoUuid + HttpSettings.PATH_SEPARATOR
                + HttpSettings.UPLOAD_PATH;

        Log.d(LOG_TAG, "Upload server url: " + urlServer);
        Log.d(LOG_TAG, "Upload file:       " + fileName);

        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;

        FileInputStream fileInputStream = new FileInputStream(new File(pathToOurFile));

        URL url = new URL(urlServer);
        connection = (HttpURLConnection) url.openConnection();

        Log.d(LOG_TAG, "connection: " + connection + "  uploading data to video: " + videoUuid);

        // Allow Inputs & Outputs
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod(HttpSettings.HTTP_POST);

        //
        int timeout = LocalStorage.getInstance().getnetworkTimeout();
        Log.d(LOG_TAG, "timeout: " + timeout);
        connection.setConnectTimeout(timeout);
        connection.setReadTimeout(timeout);

        connection.setRequestProperty("X-Token", LocalStorage.getInstance().getLatestUserToken());
        connection.addRequestProperty("X-Instance", LocalStorage.getInstance().getCurrentClub());
        connection.setRequestProperty("Connection", "close");

        Log.d(LOG_TAG, " upload propoerties: " + connection.getRequestProperties());

        outputStream = new DataOutputStream(connection.getOutputStream());
        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];

        // Read file
        bytesRead = fileInputStream.read(buffer, 0, bufferSize);

        while (bytesRead > 0) {
            Log.d(LOG_TAG, " writing data to stream  (" + bytesRead + " / " + bytesAvailable + ")");
            outputStream.write(buffer, 0, bufferSize);
            Log.d(LOG_TAG, " writing data to stream  -");
            bytesAvailable = fileInputStream.available();
            Log.d(LOG_TAG, " writing data to stream  -");
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }
        outputStream.flush();
        outputStream.close();

        // Responses from the server (code and message)
        fileInputStream.close();

        int serverResponseCode = 0;

        long before = System.currentTimeMillis();
        try {
            Log.d(LOG_TAG, " ... writing done, getting response code");
            serverResponseCode = connection.getResponseCode();
            Log.d(LOG_TAG, " ... writing done, getting response message");
            String serverResponseMessage = connection.getResponseMessage();
            Log.d(LOG_TAG, "ServerCode:" + serverResponseCode);
            Log.d(LOG_TAG, "serverResponseMessage:" + serverResponseMessage);
        } catch (java.net.SocketTimeoutException e) {
            Log.d(LOG_TAG, " ... getting response code, got an exception, print stacktrace");
            e.printStackTrace();
            throw new HttpAccessException("Network timeout reached", e, HttpAccessException.NETWORK_SLOW);
        }
        long after = System.currentTimeMillis();
        long diff = after - before;
        Log.d(LOG_TAG, "diff: " + diff + "ms   " + diff / 1000 + "s");

        if (diff > LocalStorage.getInstance().getnetworkTimeout()) {
            throw new HttpAccessException("Network timeout reached", HttpAccessException.NETWORK_SLOW);
        }

        if (serverResponseCode >= 409) {
            throw new HttpAccessException("Failed uploading trainingphase video, access denied",
                    HttpAccessException.CONFLICT_ERROR);
        }

        if (serverResponseCode < 500 && serverResponseCode >= 400) {
            throw new HttpAccessException("Failed uploading trainingphase video, access denied",
                    HttpAccessException.ACCESS_ERROR);
        }

        try {
            Log.d(LOG_TAG, " ... disconnecting");
            connection.disconnect();
        } catch (Exception e) {
            Log.d(LOG_TAG, " ... disconnecting, got an exception, print stacktrace");
            e.printStackTrace();
        }
    }

    public void downloadVideo(String clubUri, String file, String videoUuid) throws HttpAccessException {
        try {
            //$ GET http://localhost:3000/v0.0.0/clubs/<ID>/videos/uuid/<ID>/download
            //            String file = LocalStorage.getInstance().getDownloadMediaDir() + "/" + videoUuid + SERVER_VIDEO_SUFFIX;
            int TIMEOUT_CONNECTION = 5000;//5sec
            int TIMEOUT_SOCKET = 30000;//30sec
            String urlServer = urlBase + HttpSettings.API_VERSION + HttpSettings.PATH_SEPARATOR
                    + HttpSettings.VIDEO_URL_PATH + HttpSettings.UUID_PATH + videoUuid + HttpSettings.PATH_SEPARATOR
                    + HttpSettings.DOWNLOAD_PATH;
            /*            String urlServer = urlBase + HttpSettings.API_VERSION + HttpSettings.CLUB_PATH + HttpSettings.PATH_SEPARATOR + clubUri + HttpSettings.PATH_SEPARATOR + HttpSettings.VIDEO_URL_PATH +
                HttpSettings.UUID_PATH  + videoUuid +
                HttpSettings.PATH_SEPARATOR + HttpSettings.DOWNLOAD_PATH ;
            */
            URL url = new URL(urlServer);
            long startTime = System.currentTimeMillis();
            Log.i(LOG_TAG, "video download beginning: " + urlServer);

            //Open a connection to that URL.
            HttpURLConnection ucon = (HttpURLConnection) url.openConnection();

            ucon.setRequestProperty("X-Token", LocalStorage.getInstance().getLatestUserToken());
            ucon.addRequestProperty("X-Instance", LocalStorage.getInstance().getCurrentClub());
            ucon.setRequestMethod(HttpSettings.HTTP_GET);

            //this timeout affects how long it takes for the app to realize there's a connection problem
            ucon.setReadTimeout(TIMEOUT_CONNECTION);
            ucon.setConnectTimeout(TIMEOUT_SOCKET);

            Log.d(LOG_TAG, " and now to ...1");

            //Define InputStreams to read from the HttpURLConnection
            // uses 3KB download buffer
            InputStream is = ucon.getInputStream();
            Log.d(LOG_TAG, " and now to ...1");
            BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
            Log.d(LOG_TAG, " and now to ...2 to file: " + file);
            FileOutputStream outStream = new FileOutputStream(file);
            Log.d(LOG_TAG, " and now to ..31");
            byte[] buff = new byte[5 * 1024];

            System.err.println("For those about to ... file: " + file);
            //Read bytes (and store them) until there is nothing more to read(-1)
            int len;
            while ((len = inStream.read(buff)) != -1) {
                outStream.write(buff, 0, len);
            }

            Log.d(LOG_TAG, "response code: " + ucon.getResponseCode());

            //clean up
            outStream.flush();
            outStream.close();
            inStream.close();

            Log.d(LOG_TAG, "For those about to ...");

            Log.d(LOG_TAG, "download completed in " + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
            if (!HttpSettings.isResponseOk(ucon.getResponseCode())) {
                throw new HttpAccessException(
                        "Failed downloading video, response from server " + ucon.getResponseCode(),
                        HttpAccessException.ACCESS_ERROR);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new HttpAccessException("Failed downloading video", e, HttpAccessException.FILE_NOT_FOUND);
        } catch (Exception e) {
            e.printStackTrace();
            throw new HttpAccessException("Failed downloading video", e, HttpAccessException.NETWORK_ERROR);
        }
    }
}