Java tutorial
package online.privacy; /** * HTTPS API communication class. * * Talks to the Privacy Online API over HTTPS using JSON payloads. * Used to verify user credentials and obtain available VPN location node lists. * * Copyright 2016, privacy.online * All rights reserved. * * This file is part of Privacy Online for Android. * * Privacy Online for Android 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. * * Privacy Online for Android 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 Privacy Online for Android. If not, see <http://www.gnu.org/licenses/>. * * @author James Ronan <jim@dev.uk2.net> */ import android.content.Context; import android.util.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import javax.net.ssl.HttpsURLConnection; public class PrivacyOnlineApiRequest { private static final String LOG_TAG = "p.o.api.request"; private Context context; public static final int VERIFY_FAIL = 0; public static final int VERIFY_OK = 1; public static final int VERIFY_ERROR = 2; PrivacyOnlineApiRequest(Context context) { this.context = context; } /** * Uses HTTPS to verify the supplied credentials against the Privacy Online user account * API. Returns true/false indicating whether or not the supplied credentials are valid. * * @param username Username for account. * @param password Password for account. * @return int Validity of account credentials. */ public int verifyUserAccount(String username, String password) { JSONObject responseData; try { JSONObject requestData = new JSONObject(); requestData.put("username", username); requestData.put("password", password); responseData = makeAPIRequest("PUT", "/user/verify", requestData.toString()); Log.e(LOG_TAG, responseData.toString()); if (responseData.has("success")) { return VERIFY_OK; } else if (responseData.has("error")) { JSONObject errorObject = responseData.getJSONObject("error"); if (errorObject.has("authentication")) { JSONObject authenticationError = errorObject.getJSONObject("authentication"); if (authenticationError.has("user")) { return VERIFY_FAIL; } } return VERIFY_ERROR; } } catch (JSONException je) { Log.e(LOG_TAG, je.toString()); return VERIFY_ERROR; } catch (IOException ioe) { Log.e(LOG_TAG, ioe.toString()); return VERIFY_ERROR; } return VERIFY_ERROR; } /** * Retrieves a list of the currently available VPN locations from the Privacy Online API. * * *Not Currently Used* * TODO - update the error handling when this is eventually used. * * @return ArrayList of VPNLocations */ public ArrayList<VPNLocation> getLocationList() { JSONObject responseData; ArrayList<VPNLocation> locationList; try { responseData = makeAPIRequest("GET", "/location", ""); JSONArray locations = responseData.getJSONArray("location"); locationList = new ArrayList<>(locations.length()); for (int i = 0; i < locations.length(); i++) { JSONObject locationIterator = locations.getJSONObject(i); locationList.add(new VPNLocation(locationIterator.getString("label"), locationIterator.getString("hostname"))); } return locationList; } catch (JSONException je) { Log.e(LOG_TAG, je.toString()); return null; } catch (IOException ioe) { Log.e(LOG_TAG, ioe.toString()); return null; } } // Private worker method that actually communicates with the Privacy Online API. private JSONObject makeAPIRequest(String method, String endPoint, String jsonPayload) throws IOException, JSONException { InputStream inputStream = null; OutputStream outputStream = null; String apiUrl = "https://api.privacy.online"; String apiKey = this.context.getString(R.string.privacy_online_api_key); String keyString = "?key=" + apiKey; int payloadSize = jsonPayload.length(); try { URL url = new URL(apiUrl + endPoint + keyString); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); // Sec 5 second connect/read timeouts connection.setReadTimeout(5000); connection.setConnectTimeout(5000); connection.setRequestMethod(method); connection.setRequestProperty("Content-Type", "application/json"); if (payloadSize > 0) { connection.setDoInput(true); connection.setDoOutput(true); connection.setFixedLengthStreamingMode(payloadSize); } // Initiate the connection connection.connect(); // Write the payload if there is one. if (payloadSize > 0) { outputStream = connection.getOutputStream(); outputStream.write(jsonPayload.getBytes("UTF-8")); } // Get the response code ... int responseCode = connection.getResponseCode(); Log.e(LOG_TAG, "Response code: " + responseCode); switch (responseCode) { case HttpsURLConnection.HTTP_OK: inputStream = connection.getInputStream(); break; case HttpsURLConnection.HTTP_FORBIDDEN: inputStream = connection.getErrorStream(); break; case HttpURLConnection.HTTP_NOT_FOUND: inputStream = connection.getErrorStream(); break; case HttpsURLConnection.HTTP_UNAUTHORIZED: inputStream = connection.getErrorStream(); break; default: inputStream = connection.getInputStream(); break; } String responseContent = "{}"; // Default to an empty object. if (inputStream != null) { responseContent = readInputStream(inputStream, connection.getContentLength()); } JSONObject responseObject = new JSONObject(responseContent); responseObject.put("code", responseCode); return responseObject; } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } // Util method for reading the IO stream in a buffered manner. private String readInputStream(InputStream inputStream, int contentLength) throws IOException { Reader reader = new InputStreamReader(inputStream, "UTF-8"); char[] buffer = new char[contentLength]; reader.read(buffer); return new String(buffer); } }