Search in sources :

Example 1 with ProxyTunnelHandler

use of org.apache.synapse.transport.http.conn.ProxyTunnelHandler in project wso2-synapse by wso2.

the class ClientHandler method requestReady.

public void requestReady(final NHttpClientConnection conn) throws IOException, HttpException {
    // The connection is ready for submission of a new request
    HttpContext context = conn.getContext();
    ProxyTunnelHandler tunnelHandler = (ProxyTunnelHandler) context.getAttribute(TUNNEL_HANDLER);
    if (tunnelHandler != null && !tunnelHandler.isCompleted()) {
        Axis2HttpRequest axis2HttpRequest = (Axis2HttpRequest) (context.getAttribute(ATTACHMENT_KEY));
        Object targetHost = axis2HttpRequest.getMsgContext().getProperty(NhttpConstants.PROXY_PROFILE_TARGET_HOST);
        context.setAttribute(NhttpConstants.PROXY_PROFILE_TARGET_HOST, targetHost);
        if (!tunnelHandler.isRequested()) {
            HttpRequest request = tunnelHandler.generateRequest(context);
            if (proxyauthenticator != null) {
                proxyauthenticator.authenticatePreemptively(request, context);
            }
            if (log.isDebugEnabled()) {
                log.debug(conn + ": Sending CONNECT request to " + tunnelHandler.getProxy());
            }
            conn.submitRequest(request);
            tunnelHandler.setRequested();
        }
        return;
    }
    Axis2HttpRequest axis2Req = (Axis2HttpRequest) context.removeAttribute(ATTACHMENT_KEY);
    if (axis2Req == null || axis2Req.isCompleted()) {
        return;
    }
    try {
        processConnection(conn, axis2Req);
    } catch (ConnectionClosedException e) {
        metrics.incrementFaultsSending();
        handleException("I/O Error submitting request : " + e.getMessage(), e, conn);
    }
}
Also used : HttpRequest(org.apache.http.HttpRequest) HttpContext(org.apache.http.protocol.HttpContext) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler) ConnectionClosedException(org.apache.http.ConnectionClosedException)

Example 2 with ProxyTunnelHandler

use of org.apache.synapse.transport.http.conn.ProxyTunnelHandler in project wso2-synapse by wso2.

the class TargetHandler method connected.

public void connected(NHttpClientConnection conn, Object o) {
    assert o instanceof HostConnections : "Attachment should be a HostConnections";
    HostConnections pool = (HostConnections) o;
    conn.getContext().setAttribute(PassThroughConstants.CONNECTION_POOL, pool);
    HttpRoute route = pool.getRoute();
    // create the connection information and set it to request ready
    TargetContext.create(conn, ProtocolState.REQUEST_READY, targetConfiguration);
    // notify the pool about the new connection
    targetConfiguration.getConnections().addConnection(conn);
    // notify about the new connection
    deliveryAgent.connected(pool.getRoute(), conn);
    HttpContext context = conn.getContext();
    context.setAttribute(PassThroughConstants.REQ_DEPARTURE_TIME, System.currentTimeMillis());
    metrics.connected();
    if (route.isTunnelled()) {
        // Requires a proxy tunnel
        ProxyTunnelHandler tunnelHandler = new ProxyTunnelHandler(route, connFactory);
        context.setAttribute(PassThroughConstants.TUNNEL_HANDLER, tunnelHandler);
    }
}
Also used : HttpRoute(org.apache.http.conn.routing.HttpRoute) HttpContext(org.apache.http.protocol.HttpContext) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler) HostConnections(org.apache.synapse.transport.passthru.connections.HostConnections)

Example 3 with ProxyTunnelHandler

use of org.apache.synapse.transport.http.conn.ProxyTunnelHandler in project wso2-synapse by wso2.

the class TargetHandler method requestReady.

public void requestReady(NHttpClientConnection conn) {
    HttpContext context = conn.getContext();
    ProtocolState connState = null;
    try {
        connState = TargetContext.getState(conn);
        if (connState == ProtocolState.REQUEST_DONE || connState == ProtocolState.RESPONSE_BODY) {
            return;
        }
        if (connState != ProtocolState.REQUEST_READY) {
            handleInvalidState(conn, "Request not started");
            return;
        }
        ProxyTunnelHandler tunnelHandler = (ProxyTunnelHandler) context.getAttribute(PassThroughConstants.TUNNEL_HANDLER);
        if (tunnelHandler != null && !tunnelHandler.isCompleted()) {
            Object targetHost = TargetContext.get(conn).getRequestMsgCtx().getProperty(PassThroughConstants.PROXY_PROFILE_TARGET_HOST);
            context.setAttribute(PassThroughConstants.PROXY_PROFILE_TARGET_HOST, targetHost);
            if (!tunnelHandler.isRequested()) {
                HttpRequest request = tunnelHandler.generateRequest(context);
                if (targetConfiguration.getProxyAuthenticator() != null) {
                    targetConfiguration.getProxyAuthenticator().authenticatePreemptively(request, context);
                }
                if (log.isDebugEnabled()) {
                    log.debug(conn + ": Sending CONNECT request to " + tunnelHandler.getProxy());
                }
                conn.submitRequest(request);
                tunnelHandler.setRequested();
            }
            return;
        }
        TargetRequest request = TargetContext.getRequest(conn);
        if (request != null) {
            request.start(conn);
            targetConfiguration.getMetrics().incrementMessagesSent();
        }
        context.setAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME, System.currentTimeMillis());
        context.setAttribute(PassThroughConstants.REQ_DEPARTURE_TIME, System.currentTimeMillis());
    } catch (IOException e) {
        logIOException(conn, e);
        TargetContext.updateState(conn, ProtocolState.CLOSED);
        targetConfiguration.getConnections().shutdownConnection(conn, true);
        MessageContext requestMsgCtx = TargetContext.get(conn).getRequestMsgCtx();
        if (requestMsgCtx != null) {
            targetErrorHandler.handleError(requestMsgCtx, ErrorCodes.SND_IO_ERROR, "Error in Sender", null, connState);
        }
    } catch (HttpException e) {
        log.error(e.getMessage(), e);
        TargetContext.updateState(conn, ProtocolState.CLOSED);
        targetConfiguration.getConnections().shutdownConnection(conn, true);
        MessageContext requestMsgCtx = TargetContext.get(conn).getRequestMsgCtx();
        if (requestMsgCtx != null) {
            targetErrorHandler.handleError(requestMsgCtx, ErrorCodes.SND_HTTP_ERROR, "Error in Sender", null, connState);
        }
    }
}
Also used : HttpRequest(org.apache.http.HttpRequest) HttpContext(org.apache.http.protocol.HttpContext) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler) HttpException(org.apache.http.HttpException) IOException(java.io.IOException) MessageContext(org.apache.axis2.context.MessageContext)

Example 4 with ProxyTunnelHandler

use of org.apache.synapse.transport.http.conn.ProxyTunnelHandler in project wso2-synapse by wso2.

the class TargetHandler method responseReceived.

public void responseReceived(NHttpClientConnection conn) {
    HttpContext context = conn.getContext();
    if (isMessageSizeValidationEnabled) {
        context.setAttribute(PassThroughConstants.MESSAGE_SIZE_VALIDATION_SUM, 0);
    }
    HttpResponse response = conn.getHttpResponse();
    ProtocolState connState;
    try {
        String method = null;
        ProxyTunnelHandler tunnelHandler = (ProxyTunnelHandler) context.getAttribute(PassThroughConstants.TUNNEL_HANDLER);
        if (tunnelHandler != null && !tunnelHandler.isCompleted()) {
            method = "CONNECT";
            context.removeAttribute(PassThroughConstants.TUNNEL_HANDLER);
            tunnelHandler.handleResponse(response, conn);
            if (tunnelHandler.isSuccessful()) {
                log.debug(conn + ": Tunnel established");
                conn.resetInput();
                conn.requestOutput();
                return;
            } else {
                log.warn("Tunnel response failed");
                // the reason for getting the targetRequest and calling the consumeError() on pipe. Instead of
                // calling the informWriterError(NHTTPClientConnection) is, at this point the
                // "writeCondition.await()" is already called but the corresponding pipe is not yet set as
                // a writer in TargetContext
                TargetRequest targetRequest = TargetContext.getRequest(conn);
                if (targetRequest != null) {
                    targetRequest.getPipe().consumerError();
                } else {
                    log.warn("Failed target response, but the target request is null");
                }
                TargetContext.updateState(conn, ProtocolState.REQUEST_DONE);
            }
        }
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode < HttpStatus.SC_OK) {
            if (log.isDebugEnabled()) {
                log.debug(conn + ": Received a 100 Continue response");
            }
            // Ignore 1xx response
            return;
        }
        boolean isError = false;
        context.setAttribute(PassThroughConstants.RES_HEADER_ARRIVAL_TIME, System.currentTimeMillis());
        connState = TargetContext.getState(conn);
        MessageContext requestMsgContext = TargetContext.get(conn).getRequestMsgCtx();
        NHttpServerConnection sourceConn = (NHttpServerConnection) requestMsgContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONNECTION);
        if (connState != ProtocolState.REQUEST_DONE) {
            isError = true;
            // State is not REQUEST_DONE. i.e the request is not completely written. But the response is started
            // receiving, therefore informing a write error has occurred. So the thread which is
            // waiting on writing the request out, will get notified.
            informWriterError(conn);
            StatusLine errorStatus = response.getStatusLine();
            /* We might receive a 404 or a similar type, even before we write the request body. */
            if (errorStatus != null) {
                if (errorStatus.getStatusCode() >= HttpStatus.SC_BAD_REQUEST) {
                    TargetContext.updateState(conn, ProtocolState.REQUEST_DONE);
                    conn.resetOutput();
                    if (sourceConn != null) {
                        SourceContext.updateState(sourceConn, ProtocolState.REQUEST_DONE);
                        SourceContext.get(sourceConn).setShutDown(true);
                    }
                    if (log.isDebugEnabled()) {
                        log.debug(conn + ": Received response with status code : " + response.getStatusLine().getStatusCode() + " in invalid state : " + connState.name());
                    }
                }
            } else {
                handleInvalidState(conn, "Receiving response");
                return;
            }
        }
        context.setAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_START_TIME, System.currentTimeMillis());
        TargetRequest targetRequest = TargetContext.getRequest(conn);
        if (targetRequest != null) {
            method = targetRequest.getMethod();
        }
        if (method == null) {
            method = "POST";
        }
        boolean canResponseHaveBody = isResponseHaveBodyExpected(method, response);
        if (!canResponseHaveBody) {
            if (log.isDebugEnabled()) {
                log.debug(conn + ": Received no-content response " + response.getStatusLine().getStatusCode());
            }
            conn.resetInput();
        }
        TargetResponse targetResponse = new TargetResponse(targetConfiguration, response, conn, canResponseHaveBody, isError);
        TargetContext.setResponse(conn, targetResponse);
        targetResponse.start(conn);
        if (statusCode == HttpStatus.SC_ACCEPTED && handle202(requestMsgContext)) {
            return;
        }
        targetConfiguration.getWorkerPool().execute(new ClientWorker(targetConfiguration, requestMsgContext, targetResponse));
        targetConfiguration.getMetrics().incrementMessagesReceived();
        sourceConn = (NHttpServerConnection) requestMsgContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONNECTION);
        if (sourceConn != null) {
            sourceConn.getContext().setAttribute(PassThroughConstants.RES_HEADER_ARRIVAL_TIME, conn.getContext().getAttribute(PassThroughConstants.RES_HEADER_ARRIVAL_TIME));
            conn.getContext().removeAttribute(PassThroughConstants.RES_HEADER_ARRIVAL_TIME);
            sourceConn.getContext().setAttribute(PassThroughConstants.REQ_DEPARTURE_TIME, conn.getContext().getAttribute(PassThroughConstants.REQ_DEPARTURE_TIME));
            conn.getContext().removeAttribute(PassThroughConstants.REQ_DEPARTURE_TIME);
            sourceConn.getContext().setAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME, conn.getContext().getAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME));
            conn.getContext().removeAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME);
            sourceConn.getContext().setAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_END_TIME, conn.getContext().getAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_END_TIME));
            conn.getContext().removeAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_END_TIME);
            sourceConn.getContext().setAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_START_TIME, conn.getContext().getAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_START_TIME));
            conn.getContext().removeAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_START_TIME);
        }
    } catch (Exception ex) {
        log.error("Exception occurred while processing response", ex);
        informReaderError(conn);
        TargetContext.updateState(conn, ProtocolState.CLOSED);
        targetConfiguration.getConnections().shutdownConnection(conn, true);
    }
}
Also used : HttpContext(org.apache.http.protocol.HttpContext) HttpResponse(org.apache.http.HttpResponse) IOException(java.io.IOException) HttpException(org.apache.http.HttpException) ConnectionClosedException(org.apache.http.ConnectionClosedException) NHttpServerConnection(org.apache.http.nio.NHttpServerConnection) StatusLine(org.apache.http.StatusLine) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler) MessageContext(org.apache.axis2.context.MessageContext)

Example 5 with ProxyTunnelHandler

use of org.apache.synapse.transport.http.conn.ProxyTunnelHandler in project wso2-synapse by wso2.

the class ClientHandler method connected.

/**
 * Invoked when the destination is connected
 *
 * @param conn the connection being processed
 * @param attachment the attachment set previously
 */
public void connected(final NHttpClientConnection conn, final Object attachment) {
    if (log.isDebugEnabled()) {
        log.debug(conn + ": ClientHandler connected : " + conn);
    }
    HttpContext context = conn.getContext();
    metrics.connected();
    // record connection creation time for debug logging
    context.setAttribute(CONNECTION_CREATION_TIME, System.currentTimeMillis());
    if (countConnections) {
        recordConnection(conn);
    }
    Axis2HttpRequest axis2Req = (Axis2HttpRequest) attachment;
    HttpRoute route = axis2Req.getRoute();
    if (route.isTunnelled()) {
        // Requires a proxy tunnel
        ProxyTunnelHandler tunnelHandler = new ProxyTunnelHandler(route, connFactory);
        context.setAttribute(TUNNEL_HANDLER, tunnelHandler);
    }
    context.setAttribute(ATTACHMENT_KEY, axis2Req);
    conn.requestOutput();
}
Also used : HttpRoute(org.apache.http.conn.routing.HttpRoute) HttpContext(org.apache.http.protocol.HttpContext) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler)

Aggregations

HttpContext (org.apache.http.protocol.HttpContext)6 ProxyTunnelHandler (org.apache.synapse.transport.http.conn.ProxyTunnelHandler)6 MessageContext (org.apache.axis2.context.MessageContext)3 IOException (java.io.IOException)2 ConnectionClosedException (org.apache.http.ConnectionClosedException)2 HttpException (org.apache.http.HttpException)2 HttpRequest (org.apache.http.HttpRequest)2 HttpResponse (org.apache.http.HttpResponse)2 HttpRoute (org.apache.http.conn.routing.HttpRoute)2 SOAP11Factory (org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory)1 SOAP12Factory (org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory)1 AxisFault (org.apache.axis2.AxisFault)1 MessageReceiver (org.apache.axis2.engine.MessageReceiver)1 Header (org.apache.http.Header)1 StatusLine (org.apache.http.StatusLine)1 NHttpServerConnection (org.apache.http.nio.NHttpServerConnection)1 ContentInputBuffer (org.apache.http.nio.util.ContentInputBuffer)1 ContentOutputBuffer (org.apache.http.nio.util.ContentOutputBuffer)1 SharedInputBuffer (org.apache.http.nio.util.SharedInputBuffer)1 ClientConnectionDebug (org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug)1