/* MonkeyTalk - a cross-platform functional testing tool
Copyright (C) 2012 Gorilla Logic, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package com.gorillalogic.monkeytalk.sender;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Helper class to send HTTP messages via a HTTP POST.
*/
public class Sender {
public static final String MIME_JSON = "application/json";
private static final int TIMEOUT_CONNECT = 10000;
private static final int TIMEOUT_READ = 30000;
/**
* Send a JSON message to the given url.
*
* @param url
* the target url
* @param json
* the JSON message body
* @return the response
*/
public Response sendJSON(URL url, String json) {
return send(url, json, MIME_JSON);
}
/**
* Send a JSON message to the given url.
*
* @param url
* the target url
* @param json
* the JSON message body as a {@link JSONObject} object
* @return the response
*/
public Response sendJSON(URL url, JSONObject json) {
return send(url, json.toString(), MIME_JSON);
}
/**
* Send a message to the given url.
*
* @param url
* the target url
* @param message
* the message body
* @param contentType
* the HTTP content type (ex: {@code application/json})
* @return the response
*/
public Response send(URL url, String message, String contentType) {
HttpURLConnection conn = null;
if (message == null) {
message = "";
}
int readTimeout = TIMEOUT_READ;
try {
JSONObject json = new JSONObject(message);
JSONObject modifiers = json.getJSONObject("modifiers");
String timeout = modifiers.optString("timeout");
String thinktime = modifiers.optString("thinktime");
if (timeout != null && timeout.length() > 0) {
readTimeout += Integer.parseInt(timeout);
}
if (thinktime != null && thinktime.length() > 0) {
readTimeout += Integer.parseInt(thinktime);
}
} catch (JSONException ex) {
readTimeout = TIMEOUT_READ;
}
try {
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(TIMEOUT_CONNECT);
conn.setReadTimeout(readTimeout);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", contentType);
conn.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
out.write(message);
out.close();
String resp = null;
try {
resp = readFromStream(conn.getInputStream());
} catch (IOException ex) {
resp = readFromStream(conn.getErrorStream());
}
return new Response(conn.getResponseCode(), resp);
} catch (SocketTimeoutException ex) {
return new Response(0, "{result: \"ERROR\", message: \"Timeout connecting to " + url
+ ": " + ex.getMessage().replaceAll("\"", "'") + "\"}");
} catch (Exception ex) {
return new Response(0,
"{result: \"ERROR\", message: \"Unable to send command to "
+ url
+ ": "
+ (ex.getMessage() != null ? ex.getMessage().replaceAll("\"", "'")
+ "\"}" : ""));
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private String readFromStream(InputStream in) throws UnsupportedEncodingException, IOException {
if (in == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuilder sb = new StringBuilder();
try {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} finally {
reader.close();
}
return (sb.length() > 0 ? sb.substring(0, sb.length() - 1) : "");
}
}