Java tutorial
/*----------------------------------------------------------------------------+ *| | *| Android's Hooker | *| | *+---------------------------------------------------------------------------+ *| Copyright (C) 2011 Georges Bossert and Dimitri Kirchner | *| 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/>. | *+---------------------------------------------------------------------------+ *| @url : http://www.amossys.fr | *| @contact : android-hooker@amossys.fr | *| @sponsors : Amossys, http://www.amossys.fr | *+---------------------------------------------------------------------------+ */ package com.amossys.hooker.reporting; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.Locale; import java.util.Queue; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import com.amossys.hooker.SubstrateMain; import com.amossys.hooker.common.InterceptEvent; /** * @author Georges Bossert * */ public class NetworkEventSenderThread implements Runnable { private static final int VERY_LONG_SLEEP_TIME = 2000; /** * Long sleep time (when connection fails with remote server) */ private static final int LONG_SLEEP_TIME = 1000; /** * Short sleep time (when no event is available) */ private static final int SHORT_SLEEP_TIME = 300; // Events to send private Queue<InterceptEvent> events; // The HttpClient private HttpClient httpClient; // Target URI private URI targetURI; // Flag to raise if you want this thread to stop private boolean finish; private int nbErrors = 0; private String esIndex; private String esDoctype; private String host; private int port; public NetworkEventSenderThread(String host, int port, String esIndex, String esDoctype, Queue<InterceptEvent> events) { this.events = events; this.host = host; this.port = port; this.esIndex = esIndex; this.esDoctype = esDoctype; this.httpClient = new DefaultHttpClient(); this.finish = false; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { if (this.events == null) { SubstrateMain.log("EventSenderThread (" + Thread.currentThread().getPriority() + ") fails to start since no Queue is available. "); return; } SubstrateMain.log("EventSenderThread (" + Thread.currentThread().getPriority() + ") has started."); int sleepTime; while (!this.isFinish()) { sleepTime = 0; // !!! // This may cause a problem when we launch from Snapshot. We have to be careful that snapshot // doesn't have any IDXP // Retrieves the current id XP //this.idXP = fetchIDXPFromSdcard(); InterceptEvent eventToSend = this.events.poll(); if (eventToSend != null) { if (!this.send(eventToSend)) { this.events.add(eventToSend); sleepTime = LONG_SLEEP_TIME; nbErrors++; } } else { sleepTime = SHORT_SLEEP_TIME; } if ((nbErrors > 10) && (nbErrors % 5 == 0)) { SubstrateMain.log("[E] Too many network errors, we stop the thread..."); sleepTime = VERY_LONG_SLEEP_TIME; } if (sleepTime > 0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { SubstrateMain.log("[E] Error while sleeping the EventSenderThread", e); } } } } public void stopThread() { this.finish = true; } public boolean send(InterceptEvent event) { try { this.targetURI = new URI("http://" + host + ":" + port + "/" + this.esIndex.toLowerCase() + "/" + this.esDoctype.toLowerCase() + "?parent=" + event.getIDXP() + "&op_type=create"); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } SubstrateMain.log("Sending Event to " + this.targetURI); boolean result = false; StringEntity se; try { se = new StringEntity(event.toJson()); HttpPost httpPost = new HttpPost(this.targetURI); httpPost.setEntity(se); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); // Executes POST request to the given URL HttpResponse httpResponse = this.httpClient.execute(httpPost); // Receives response as inputStream InputStream inputStream = httpResponse.getEntity().getContent(); // Converts inputStream to string // TODO: we should parse the elasticsearch result result = inputStream != null; SubstrateMain.log("Event succesfully sent !"); if (inputStream != null) { inputStream.close(); } } catch (UnsupportedEncodingException e) { SubstrateMain.log( "Impossible to send data to remote database due to encoding issues (" + e.getMessage() + ")", e); } catch (IOException e) { SubstrateMain.log( "Impossible to connect to the remote database, check the connectivity (" + e.getMessage() + ")", e); } return result; } /** * @return the finish */ public boolean isFinish() { return finish; } }