Search in sources :

Example 1 with NoResponseException

use of com.predic8.membrane.core.transport.http.NoResponseException in project service-proxy by membrane.

the class Response method parseStartLine.

@Override
public void parseStartLine(InputStream in) throws IOException, EndOfStreamException {
    String line;
    try {
        line = HttpUtil.readLine(in);
    } catch (EOFWhileReadingLineException e) {
        if (e.getLineSoFar().length() == 0)
            throw new NoResponseException(e);
        throw new EOFWhileReadingFirstLineException(e.getLineSoFar());
    }
    Matcher matcher = pattern.matcher(line);
    boolean find = matcher.find();
    if (!find) {
        throw new RuntimeException("Invalid server response: " + line);
    }
    version = matcher.group(1);
    statusCode = Integer.parseInt(matcher.group(2));
    statusMessage = matcher.group(4);
}
Also used : Matcher(java.util.regex.Matcher) EOFWhileReadingFirstLineException(com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException) NoResponseException(com.predic8.membrane.core.transport.http.NoResponseException) EOFWhileReadingLineException(com.predic8.membrane.core.transport.http.EOFWhileReadingLineException)

Example 2 with NoResponseException

use of com.predic8.membrane.core.transport.http.NoResponseException in project service-proxy by membrane.

the class HttpClient method call.

public Exchange call(Exchange exc, boolean adjustHostHeader, boolean failOverOn5XX) throws Exception {
    if (exc.getDestinations().isEmpty())
        throw new IllegalStateException("List of destinations is empty. Please specify at least one destination.");
    int counter = 0;
    Exception exception = null;
    Object trackNodeStatusObj = exc.getProperty(Exchange.TRACK_NODE_STATUS);
    boolean trackNodeStatus = trackNodeStatusObj != null && trackNodeStatusObj instanceof Boolean && (Boolean) trackNodeStatusObj;
    disableStreamingForRetries(exc);
    while (counter < maxRetries) {
        Connection con = null;
        String dest = getDestination(exc, counter);
        HostColonPort target = null;
        try {
            log.debug("try # " + counter + " to " + dest);
            target = init(exc, dest, adjustHostHeader);
            if (counter == 0) {
                con = exc.getTargetConnection();
                if (con != null) {
                    if (!con.isSame(target.host, target.port)) {
                        con.close();
                        con = null;
                    } else {
                        con.setKeepAttachedToExchange(true);
                    }
                }
            }
            SSLProvider sslProvider = getOutboundSSLProvider(exc, target);
            if (con == null) {
                con = conMgr.getConnection(target.host, target.port, localAddr, sslProvider, connectTimeout, getSNIServerName(exc), proxy, proxySSLContext);
                con.setKeepAttachedToExchange(exc.getRequest().isBindTargetConnectionToIncoming());
                exc.setTargetConnection(con);
            }
            if (proxy != null && sslProvider == null)
                // if we use a proxy for a plain HTTP (=non-HTTPS) request, attach the proxy credentials.
                exc.getRequest().getHeader().setProxyAutorization(proxy.getCredentials());
            Response response;
            String newProtocol = null;
            if (exc.getRequest().isCONNECTRequest()) {
                handleConnectRequest(exc, con);
                response = Response.ok().build();
                newProtocol = "CONNECT";
            } else {
                response = doCall(exc, con);
                if (trackNodeStatus)
                    exc.setNodeStatusCode(counter, response.getStatusCode());
                if (exc.getProperty(Exchange.ALLOW_WEBSOCKET) == Boolean.TRUE && isUpgradeToResponse(response, "websocket")) {
                    log.debug("Upgrading to WebSocket protocol.");
                    newProtocol = "WebSocket";
                }
                if (exc.getProperty(Exchange.ALLOW_TCP) == Boolean.TRUE && isUpgradeToResponse(response, "tcp")) {
                    log.debug("Upgrading to TCP protocol.");
                    newProtocol = "TCP";
                }
                if (exc.getProperty(Exchange.ALLOW_SPDY) == Boolean.TRUE && isUpgradeToResponse(response, "SPDY/3.1")) {
                    log.debug("Upgrading to SPDY/3.1 protocol.");
                    newProtocol = "SPDY/3.1";
                }
            }
            if (newProtocol != null) {
                setupConnectionForwarding(exc, con, newProtocol, streamPumpStats);
                exc.getDestinations().clear();
                exc.getDestinations().add(dest);
                con.setExchange(exc);
                exc.setResponse(response);
                return exc;
            }
            boolean is5XX = 500 <= response.getStatusCode() && response.getStatusCode() < 600;
            if (!failOverOn5XX || !is5XX || counter == maxRetries - 1) {
                applyKeepAliveHeader(response, con);
                exc.getDestinations().clear();
                exc.getDestinations().add(dest);
                con.setExchange(exc);
                response.addObserver(con);
                exc.setResponse(response);
                return exc;
            }
        // java.net.SocketException: Software caused connection abort: socket write error
        } catch (ConnectException e) {
            exception = e;
            log.info("Connection to " + (target == null ? dest : target) + " refused.");
        } catch (SocketException e) {
            if (e.getMessage().contains("Software caused connection abort")) {
                log.info("Connection to " + dest + " was aborted externally. Maybe by the server or the OS Membrane is running on.");
            } else if (e.getMessage().contains("Connection reset")) {
                log.info("Connection to " + dest + " was reset externally. Maybe by the server or the OS Membrane is running on.");
            } else {
                logException(exc, counter, e);
            }
            exception = e;
        } catch (UnknownHostException e) {
            log.warn("Unknown host: " + (target == null ? dest : target));
            exception = e;
            if (exc.getDestinations().size() < 2) {
                // don't retry this host, it's useless. (it's very unlikely that it will work after timeBetweenTriesMs)
                break;
            }
        } catch (EOFWhileReadingFirstLineException e) {
            log.debug("Server connection to " + dest + " terminated before line was read. Line so far: " + e.getLineSoFar());
            exception = e;
        } catch (NoResponseException e) {
            throw e;
        } catch (Exception e) {
            logException(exc, counter, e);
            exception = e;
        } finally {
            if (trackNodeStatus) {
                if (exception != null) {
                    exc.setNodeException(counter, exception);
                }
            }
        }
        counter++;
        if (exc.getDestinations().size() == 1) {
            // as documented above, the sleep timeout is only applied between successive calls to the same destination.
            Thread.sleep(timeBetweenTriesMs);
        }
    }
    throw exception;
}
Also used : IOException(java.io.IOException) EndOfStreamException(com.predic8.membrane.core.util.EndOfStreamException) SSLProvider(com.predic8.membrane.core.transport.ssl.SSLProvider)

Example 3 with NoResponseException

use of com.predic8.membrane.core.transport.http.NoResponseException in project service-proxy by membrane.

the class HttpServerHandler method run.

public void run() {
    // see Request.isBindTargetConnectionToIncoming()
    Connection boundConnection = null;
    try {
        updateThreadName(true);
        setup();
        while (true) {
            srcReq = new Request();
            endpointListener.setIdleStatus(sourceSocket, true);
            try {
                srcIn.mark(2);
                if (srcIn.read() == -1)
                    break;
                srcIn.reset();
            } finally {
                endpointListener.setIdleStatus(sourceSocket, false);
            }
            if (boundConnection != null) {
                exchange.setTargetConnection(boundConnection);
                boundConnection = null;
            }
            srcReq.read(srcIn, true);
            exchange.received();
            if (srcReq.getHeader().getProxyConnection() != null) {
                srcReq.getHeader().add(Header.CONNECTION, srcReq.getHeader().getProxyConnection());
                srcReq.getHeader().removeFields(Header.PROXY_CONNECTION);
            }
            process();
            if (srcReq.isCONNECTRequest()) {
                log.debug("stopping HTTP Server Thread after establishing an HTTP connect");
                return;
            }
            boundConnection = exchange.getTargetConnection();
            exchange.setTargetConnection(null);
            if (!exchange.canKeepConnectionAlive())
                break;
            if (exchange.getResponse().isRedirect()) {
                break;
            }
            exchange.detach();
            exchange = new Exchange(this);
        }
    } catch (SocketTimeoutException e) {
        log.debug("Socket of thread " + counter + " timed out");
    } catch (SocketException se) {
        log.debug("client socket closed");
    } catch (SSLException s) {
        if (showSSLExceptions) {
            if (s.getCause() instanceof SSLException)
                s = (SSLException) s.getCause();
            if (s.getCause() instanceof SocketException)
                log.debug("ssl socket closed");
            else
                log.error("", s);
        }
    } catch (IOException e) {
        log.error("", e);
    } catch (EndOfStreamException e) {
        log.debug("stream closed");
    } catch (AbortException e) {
        log.debug("exchange aborted.");
    } catch (NoMoreRequestsException e) {
    // happens at the end of a keep-alive connection
    } catch (NoResponseException e) {
        log.debug("No response received. Maybe increase the keep-alive timeout on the server.");
    } catch (EOFWhileReadingFirstLineException e) {
        log.debug("Client connection terminated before line was read. Line so far: (" + e.getLineSoFar() + ")");
    } catch (Exception e) {
        log.error("", e);
    } finally {
        endpointListener.setOpenStatus(sourceSocket, false);
        if (boundConnection != null)
            try {
                boundConnection.close();
            } catch (IOException e) {
                log.debug("Closing bound connection.", e);
            }
        closeConnections();
        exchange.detach();
        updateThreadName(false);
    }
}
Also used : SocketException(java.net.SocketException) EndOfStreamException(com.predic8.membrane.core.util.EndOfStreamException) Request(com.predic8.membrane.core.http.Request) IOException(java.io.IOException) SSLException(javax.net.ssl.SSLException) IOException(java.io.IOException) EndOfStreamException(com.predic8.membrane.core.util.EndOfStreamException) SocketException(java.net.SocketException) SSLException(javax.net.ssl.SSLException) SocketTimeoutException(java.net.SocketTimeoutException) Exchange(com.predic8.membrane.core.exchange.Exchange) SocketTimeoutException(java.net.SocketTimeoutException)

Aggregations

EndOfStreamException (com.predic8.membrane.core.util.EndOfStreamException)2 IOException (java.io.IOException)2 Exchange (com.predic8.membrane.core.exchange.Exchange)1 Request (com.predic8.membrane.core.http.Request)1 EOFWhileReadingFirstLineException (com.predic8.membrane.core.transport.http.EOFWhileReadingFirstLineException)1 EOFWhileReadingLineException (com.predic8.membrane.core.transport.http.EOFWhileReadingLineException)1 NoResponseException (com.predic8.membrane.core.transport.http.NoResponseException)1 SSLProvider (com.predic8.membrane.core.transport.ssl.SSLProvider)1 SocketException (java.net.SocketException)1 SocketTimeoutException (java.net.SocketTimeoutException)1 Matcher (java.util.regex.Matcher)1 SSLException (javax.net.ssl.SSLException)1