Search in sources :

Example 1 with CountingOutputWriter

use of org.xel.util.CountingOutputWriter 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;
}
Also used : SocketException(java.net.SocketException) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) CountingInputReader(org.xel.util.CountingInputReader) BufferedReader(java.io.BufferedReader) URL(java.net.URL) BufferedWriter(java.io.BufferedWriter) GZIPInputStream(java.util.zip.GZIPInputStream) HttpURLConnection(java.net.HttpURLConnection) StringWriter(java.io.StringWriter) InputStreamReader(java.io.InputStreamReader) UnknownHostException(java.net.UnknownHostException) GZIPInputStream(java.util.zip.GZIPInputStream) CountingInputStream(org.xel.util.CountingInputStream) InputStream(java.io.InputStream) CountingInputStream(org.xel.util.CountingInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) JSONObject(org.json.simple.JSONObject) CountingInputReader(org.xel.util.CountingInputReader) NxtException(org.xel.NxtException) BufferedReader(java.io.BufferedReader) OutputStreamWriter(java.io.OutputStreamWriter) ParseException(org.json.simple.parser.ParseException) CountingOutputWriter(org.xel.util.CountingOutputWriter) OutputStreamWriter(java.io.OutputStreamWriter) BufferedWriter(java.io.BufferedWriter) StringWriter(java.io.StringWriter) CountingOutputWriter(org.xel.util.CountingOutputWriter) Writer(java.io.Writer)

Example 2 with CountingOutputWriter

use of org.xel.util.CountingOutputWriter in project elastic-core-maven by OrdinaryDude.

the class PeerServlet method doPost.

/**
 * Process HTTP POST request
 *
 * @param   req                 HTTP request
 * @param   resp                HTTP response
 * @throws  ServletException    Servlet processing error
 * @throws  IOException         I/O error
 */
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    JSONStreamAware jsonResponse;
    // 
    // Process the peer request
    // 
    PeerImpl peer = Peers.findOrCreatePeer(req.getRemoteAddr());
    if (peer == null) {
        jsonResponse = UNKNOWN_PEER;
    } else {
        jsonResponse = process(peer, req.getReader());
    }
    // 
    // Return the response
    // 
    resp.setContentType("text/plain; charset=UTF-8");
    try (CountingOutputWriter writer = new CountingOutputWriter(resp.getWriter())) {
        JSON.writeJSONString(jsonResponse, writer);
        if (peer != null) {
            peer.updateUploadedVolume(writer.getCount());
        }
    } catch (RuntimeException | IOException e) {
        if (peer != null) {
            if ((Peers.communicationLoggingMask & Peers.LOGGING_MASK_EXCEPTIONS) != 0) {
                if (e instanceof RuntimeException) {
                    Logger.logDebugMessage("Error sending response to peer " + peer.getHost(), e);
                } else {
                    Logger.logDebugMessage(String.format("Error sending response to peer %s: %s", peer.getHost(), e.getMessage() != null ? e.getMessage() : e.toString()));
                }
            }
            peer.blacklist(e);
        }
        throw e;
    }
}
Also used : IOException(java.io.IOException) JSONStreamAware(org.json.simple.JSONStreamAware) CountingOutputWriter(org.xel.util.CountingOutputWriter)

Aggregations

IOException (java.io.IOException)2 CountingOutputWriter (org.xel.util.CountingOutputWriter)2 BufferedReader (java.io.BufferedReader)1 BufferedWriter (java.io.BufferedWriter)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 OutputStreamWriter (java.io.OutputStreamWriter)1 Reader (java.io.Reader)1 StringWriter (java.io.StringWriter)1 Writer (java.io.Writer)1 HttpURLConnection (java.net.HttpURLConnection)1 SocketException (java.net.SocketException)1 SocketTimeoutException (java.net.SocketTimeoutException)1 URL (java.net.URL)1 UnknownHostException (java.net.UnknownHostException)1 GZIPInputStream (java.util.zip.GZIPInputStream)1 JSONObject (org.json.simple.JSONObject)1 JSONStreamAware (org.json.simple.JSONStreamAware)1 ParseException (org.json.simple.parser.ParseException)1