use of org.xel.util.CountingInputStream in project elastic-core-maven by OrdinaryDude.
the class PeerImpl method send.
@Override
public JSONObject send(final JSONStreamAware request, int maxResponseSize) {
JSONObject response = null;
String log = null;
boolean showLog = false;
HttpURLConnection connection = null;
int communicationLoggingMask = Peers.communicationLoggingMask;
try {
//
if (useWebSocket && !webSocket.isOpen())
useWebSocket = webSocket.startClient(URI.create("ws://" + host + ":" + getPort() + "/nxt"));
//
if (useWebSocket) {
//
// Send the request using the WebSocket session
//
StringWriter wsWriter = new StringWriter(1000);
request.writeJSONString(wsWriter);
String wsRequest = wsWriter.toString();
if (communicationLoggingMask != 0)
log = "WebSocket " + host + ": " + wsRequest;
String wsResponse = webSocket.doPost(wsRequest);
updateUploadedVolume(wsRequest.length());
if (maxResponseSize > 0) {
if ((communicationLoggingMask & Peers.LOGGING_MASK_200_RESPONSES) != 0) {
log += " >>> " + wsResponse;
showLog = true;
}
if (wsResponse.length() > maxResponseSize)
throw new NxtException.NxtIOException("Maximum size exceeded: " + wsResponse.length());
response = (JSONObject) JSONValue.parseWithException(wsResponse);
updateDownloadedVolume(wsResponse.length());
}
} else {
//
// Send the request using HTTP
//
URL url = new URL("http://" + host + ":" + getPort() + "/nxt");
if (communicationLoggingMask != 0)
log = "\"" + url.toString() + "\": " + JSON.toString(request);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setConnectTimeout(Peers.connectTimeout);
connection.setReadTimeout(Peers.readTimeout);
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setRequestProperty("Content-Type", "text/plain; charset=UTF-8");
try (Writer writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"))) {
CountingOutputWriter cow = new CountingOutputWriter(writer);
request.writeJSONString(cow);
updateUploadedVolume(cow.getCount());
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
if (maxResponseSize > 0) {
if ((communicationLoggingMask & Peers.LOGGING_MASK_200_RESPONSES) != 0) {
CountingInputStream cis = new CountingInputStream(connection.getInputStream(), maxResponseSize);
InputStream responseStream = cis;
if ("gzip".equals(connection.getHeaderField("Content-Encoding")))
responseStream = new GZIPInputStream(cis);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int numberOfBytes;
try (InputStream inputStream = responseStream) {
while ((numberOfBytes = inputStream.read(buffer, 0, buffer.length)) > 0) byteArrayOutputStream.write(buffer, 0, numberOfBytes);
}
String responseValue = byteArrayOutputStream.toString("UTF-8");
if (responseValue.length() > 0 && responseStream instanceof GZIPInputStream)
log += String.format("[length: %d, compression ratio: %.2f]", cis.getCount(), (double) cis.getCount() / (double) responseValue.length());
log += " >>> " + responseValue;
showLog = true;
response = (JSONObject) JSONValue.parseWithException(responseValue);
updateDownloadedVolume(responseValue.length());
} else {
InputStream responseStream = connection.getInputStream();
if ("gzip".equals(connection.getHeaderField("Content-Encoding")))
responseStream = new GZIPInputStream(responseStream);
try (Reader reader = new BufferedReader(new InputStreamReader(responseStream, "UTF-8"))) {
CountingInputReader cir = new CountingInputReader(reader, maxResponseSize);
response = (JSONObject) JSONValue.parseWithException(cir);
updateDownloadedVolume(cir.getCount());
}
}
}
} else {
if ((communicationLoggingMask & Peers.LOGGING_MASK_NON200_RESPONSES) != 0) {
log += " >>> Peer responded with HTTP " + connection.getResponseCode() + " code!";
showLog = true;
}
Logger.logDebugMessage("Peer " + host + " responded with HTTP " + connection.getResponseCode());
deactivate();
connection.disconnect();
}
}
//
if (response != null && response.get("error") != null) {
deactivate();
if (Errors.SEQUENCE_ERROR.equals(response.get("error")) && request != Peers.getMyPeerInfoRequest()) {
Logger.logDebugMessage("Sequence error, reconnecting to " + host);
connect();
} else {
Logger.logDebugMessage("Peer " + host + " version " + version + " returned error: " + response.toJSONString() + ", request was: " + JSON.toString(request) + ", disconnecting");
if (connection != null) {
connection.disconnect();
}
}
}
} catch (NxtException.NxtIOException e) {
blacklist(e);
if (connection != null) {
connection.disconnect();
}
} catch (RuntimeException | ParseException | IOException e) {
if (!(e instanceof UnknownHostException || e instanceof SocketTimeoutException || e instanceof SocketException || Errors.END_OF_FILE.equals(e.getMessage()))) {
Logger.logDebugMessage(String.format("Error sending request to peer %s: %s", host, e.getMessage() != null ? e.getMessage() : e.toString()));
}
if ((communicationLoggingMask & Peers.LOGGING_MASK_EXCEPTIONS) != 0) {
log += " >>> " + e.toString();
showLog = true;
}
deactivate();
if (connection != null) {
connection.disconnect();
}
}
if (showLog) {
Logger.logMessage(log + "\n");
}
return response;
}
Aggregations