Search in sources :

Example 1 with CountingInputReader

use of org.xel.util.CountingInputReader 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 CountingInputReader

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

the class PeerServlet method process.

/**
 * Process the peer request
 *
 * @param   peer                Peer
 * @param   inputReader         Input reader
 * @return                      JSON response
 */
private JSONStreamAware process(PeerImpl peer, Reader inputReader) {
    // 
    if (peer.isBlacklisted()) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("error", Errors.BLACKLISTED);
        jsonObject.put("cause", peer.getBlacklistingCause());
        return jsonObject;
    }
    Peers.addPeer(peer);
    // 
    try (CountingInputReader cr = new CountingInputReader(inputReader, Peers.MAX_REQUEST_SIZE)) {
        JSONObject request = (JSONObject) JSONValue.parseWithException(cr);
        peer.updateDownloadedVolume(cr.getCount());
        if (request.get("protocol") == null || ((Number) request.get("protocol")).intValue() != 1) {
            Logger.logDebugMessage("Unsupported protocol " + request.get("protocol"));
            return UNSUPPORTED_PROTOCOL;
        }
        PeerRequestHandler peerRequestHandler = peerRequestHandlers.get((String) request.get("requestType"));
        if (peerRequestHandler == null) {
            return UNSUPPORTED_REQUEST_TYPE;
        }
        if (peer.getState() == Peer.State.DISCONNECTED) {
            peer.setState(Peer.State.CONNECTED);
        }
        if (peer.getVersion() == null && !"getInfo".equals(request.get("requestType"))) {
            return SEQUENCE_ERROR;
        }
        if (!peer.isInbound()) {
            if (Peers.hasTooManyInboundPeers()) {
                return MAX_INBOUND_CONNECTIONS;
            }
            Peers.notifyListeners(peer, Peers.Event.ADD_INBOUND);
        }
        peer.setLastInboundRequest(Nxt.getEpochTime());
        if (peerRequestHandler.rejectWhileDownloading()) {
            if (blockchainProcessor.isDownloading()) {
                return DOWNLOADING;
            }
            if (Constants.isLightClient) {
                return LIGHT_CLIENT;
            }
        }
        return peerRequestHandler.processRequest(request, peer);
    } catch (RuntimeException | ParseException | IOException e) {
        Logger.logDebugMessage("Error processing POST request: " + e.toString());
        peer.blacklist(e);
        return error(e);
    }
}
Also used : JSONObject(org.json.simple.JSONObject) CountingInputReader(org.xel.util.CountingInputReader) ParseException(org.json.simple.parser.ParseException) IOException(java.io.IOException)

Aggregations

IOException (java.io.IOException)2 JSONObject (org.json.simple.JSONObject)2 ParseException (org.json.simple.parser.ParseException)2 CountingInputReader (org.xel.util.CountingInputReader)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 NxtException (org.xel.NxtException)1