Search in sources :

Example 61 with Exchange

use of com.predic8.membrane.core.exchange.Exchange in project service-proxy by membrane.

the class ClusterNotificationInterceptor method handleRequest.

@Override
public Outcome handleRequest(Exchange exc) throws Exception {
    log.debug(exc.getOriginalRequestUri());
    Matcher m = urlPattern.matcher(exc.getOriginalRequestUri());
    if (!m.matches())
        return Outcome.CONTINUE;
    log.debug("request received: " + m.group(1));
    if (validateSignature && !getParams(exc).containsKey("data")) {
        exc.setResponse(Response.forbidden().build());
        return Outcome.ABORT;
    }
    Map<String, String> params = validateSignature ? getDecryptedParams(getParams(exc).get("data")) : getParams(exc);
    if (isTimedout(params)) {
        exc.setResponse(Response.forbidden().build());
        return Outcome.ABORT;
    }
    updateClusterManager(m, params);
    exc.setResponse(Response.noContent().build());
    return Outcome.RETURN;
}
Also used : Matcher(java.util.regex.Matcher) URLParamUtil.parseQueryString(com.predic8.membrane.core.util.URLParamUtil.parseQueryString)

Example 62 with Exchange

use of com.predic8.membrane.core.exchange.Exchange 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 63 with Exchange

use of com.predic8.membrane.core.exchange.Exchange in project service-proxy by membrane.

the class HttpClient method setupConnectionForwarding.

public static void setupConnectionForwarding(Exchange exc, final Connection con, final String protocol, StreamPump.StreamPumpStats streamPumpStats) throws SocketException {
    final HttpServerHandler hsr = (HttpServerHandler) exc.getHandler();
    String source = hsr.getSourceSocket().getRemoteSocketAddress().toString();
    String dest = con.toString();
    final StreamPump a;
    final StreamPump b;
    if ("WebSocket".equals(protocol)) {
        WebSocketStreamPump aTemp = new WebSocketStreamPump(hsr.getSrcIn(), con.out, streamPumpStats, protocol + " " + source + " -> " + dest, exc.getRule(), true, exc);
        WebSocketStreamPump bTemp = new WebSocketStreamPump(con.in, hsr.getSrcOut(), streamPumpStats, protocol + " " + source + " <- " + dest, exc.getRule(), false, null);
        aTemp.init(bTemp);
        bTemp.init(aTemp);
        a = aTemp;
        b = bTemp;
    } else {
        a = new StreamPump(hsr.getSrcIn(), con.out, streamPumpStats, protocol + " " + source + " -> " + dest, exc.getRule());
        b = new StreamPump(con.in, hsr.getSrcOut(), streamPumpStats, protocol + " " + source + " <- " + dest, exc.getRule());
    }
    hsr.getSourceSocket().setSoTimeout(0);
    exc.addExchangeViewerListener(new AbstractExchangeViewerListener() {

        @Override
        public void setExchangeFinished() {
            String threadName = Thread.currentThread().getName();
            new Thread(b, threadName + " " + protocol + " Backward Thread").start();
            try {
                Thread.currentThread().setName(threadName + " " + protocol + " Onward Thread");
                a.run();
            } finally {
                try {
                    con.close();
                } catch (IOException e) {
                    log.debug("", e);
                }
            }
        }
    });
}
Also used : IOException(java.io.IOException) AbstractExchangeViewerListener(com.predic8.membrane.core.model.AbstractExchangeViewerListener)

Example 64 with Exchange

use of com.predic8.membrane.core.exchange.Exchange in project service-proxy by membrane.

the class StatisticCollector method collectFrom.

public void collectFrom(AbstractExchange exc) {
    totalCount++;
    if (exc.getStatus() == ExchangeState.FAILED) {
        errorCount++;
        if (!countErrorExchanges)
            return;
    }
    long timeReqSent = exc.getTimeReqSent();
    if (timeReqSent == 0)
        // this Exchange did not reach the HTTPClientInterceptor
        return;
    long timeResSent = exc.getTimeResSent();
    if (timeResSent == 0)
        // this Exchange is not yet completed
        return;
    goodCount++;
    int time = (int) (timeResSent - timeReqSent);
    if (time < minTime)
        minTime = time;
    if (time > maxTime)
        maxTime = time;
    totalTime += time;
    try {
        AbstractBody requestBody = exc.getRequest().getBody();
        totalBytesSent += requestBody.isRead() ? requestBody.getLength() : 0;
        AbstractBody responseBody = exc.getResponse().getBody();
        totalBytesReceived += responseBody.isRead() ? responseBody.getLength() : 0;
    } catch (IOException e) {
        log.warn("", e);
    }
}
Also used : AbstractBody(com.predic8.membrane.core.http.AbstractBody) IOException(java.io.IOException)

Example 65 with Exchange

use of com.predic8.membrane.core.exchange.Exchange in project service-proxy by membrane.

the class HTTPSchemaResolver method resolve.

public InputStream resolve(String url) throws ResourceRetrievalException {
    try {
        Exchange exc = new Request.Builder().method(Request.METHOD_GET).url(uriFactory, url).header(Header.USER_AGENT, Constants.PRODUCT_NAME + " " + Constants.VERSION).buildExchange();
        Response response = getHttpClient().call(exc).getResponse();
        response.readBody();
        if (response.getStatusCode() != 200) {
            ResourceRetrievalException rde = new ResourceRetrievalException(url, response.getStatusCode());
            throw rde;
        }
        return new ByteArrayInputStream(ByteUtil.getByteArrayData(response.getBodyAsStreamDecoded()));
    } catch (ResourceRetrievalException e) {
        throw e;
    } catch (Exception e) {
        ResourceRetrievalException rre = new ResourceRetrievalException(url, e);
        throw rre;
    }
}
Also used : Exchange(com.predic8.membrane.core.exchange.Exchange) Response(com.predic8.membrane.core.http.Response) ByteArrayInputStream(java.io.ByteArrayInputStream) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException)

Aggregations

Exchange (com.predic8.membrane.core.exchange.Exchange)107 Test (org.junit.Test)39 IOException (java.io.IOException)32 Request (com.predic8.membrane.core.http.Request)25 Outcome (com.predic8.membrane.core.interceptor.Outcome)24 Response (com.predic8.membrane.core.http.Response)16 AbstractInterceptor (com.predic8.membrane.core.interceptor.AbstractInterceptor)16 ServiceProxy (com.predic8.membrane.core.rules.ServiceProxy)16 HttpRouter (com.predic8.membrane.core.HttpRouter)14 Before (org.junit.Before)13 ServiceProxyKey (com.predic8.membrane.core.rules.ServiceProxyKey)12 AbstractExchange (com.predic8.membrane.core.exchange.AbstractExchange)11 Header (com.predic8.membrane.core.http.Header)10 HttpClient (com.predic8.membrane.core.transport.http.HttpClient)10 CacheBuilder (com.google.common.cache.CacheBuilder)9 Rule (com.predic8.membrane.core.rules.Rule)6 URISyntaxException (java.net.URISyntaxException)6 UnknownHostException (java.net.UnknownHostException)6 ArrayList (java.util.ArrayList)6 Session (com.predic8.membrane.core.interceptor.authentication.session.SessionManager.Session)5