Search in sources :

Example 6 with ProxyTunnelHandler

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

the class ClientHandler method responseReceived.

/**
 * Process a response received for the request sent out
 *
 * @param conn the connection being processed
 */
public void responseReceived(final NHttpClientConnection conn) {
    setServerContextAttribute(NhttpConstants.RES_FROM_BACKEND_READ_START_TIME, System.currentTimeMillis(), conn);
    HttpContext context = conn.getContext();
    // set the current message size to zero
    if (isMessageSizeValidationEnabled) {
        context.setAttribute(NhttpConstants.MESSAGE_SIZE_VALIDATION_SUM, 0);
    }
    HttpResponse response = conn.getHttpResponse();
    ProxyTunnelHandler tunnelHandler = (ProxyTunnelHandler) context.getAttribute(TUNNEL_HANDLER);
    if (tunnelHandler != null && !tunnelHandler.isCompleted()) {
        context.removeAttribute(TUNNEL_HANDLER);
        tunnelHandler.handleResponse(response, conn);
        if (tunnelHandler.isSuccessful()) {
            log.debug(conn + ": Tunnel established");
            conn.resetInput();
            conn.requestOutput();
            return;
        } else {
            Axis2HttpRequest axis2Req = (Axis2HttpRequest) context.getAttribute(ATTACHMENT_KEY);
            context.setAttribute(AXIS2_HTTP_REQUEST, axis2Req);
            context.setAttribute(OUTGOING_MESSAGE_CONTEXT, axis2Req.getMsgContext());
            ContentOutputBuffer outputBuffer = new NhttpSharedOutputBuffer(bufferSize, conn, allocator, socketTimeout);
            axis2Req.setOutputBuffer(outputBuffer);
            context.setAttribute(REQUEST_SOURCE_BUFFER, outputBuffer);
            context.setAttribute(NhttpConstants.DISCARD_ON_COMPLETE, Boolean.TRUE);
        }
    }
    setServerContextAttribute(NhttpConstants.RES_HEADER_ARRIVAL_TIME, System.currentTimeMillis(), conn);
    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CONTINUE) {
        if (log.isDebugEnabled()) {
            log.debug(conn + ": Received a 100 Continue response");
        }
        // and wait for the response
        return;
    }
    ClientConnectionDebug ccd = (ClientConnectionDebug) conn.getContext().getAttribute(CLIENT_CONNECTION_DEBUG);
    if (ccd != null) {
        ccd.recordResponseStartTime(response.getStatusLine().toString());
    }
    // Have we sent out our request fully in the first place? if not, forget about it now..
    Axis2HttpRequest req = (Axis2HttpRequest) conn.getContext().getAttribute(AXIS2_HTTP_REQUEST);
    if (req != null) {
        req.setCompleted(true);
        if (log.isDebugEnabled()) {
            log.debug(conn + ": Response Received for Request : " + req);
        }
        if (!req.isSendingCompleted()) {
            req.getMsgContext().setProperty(NhttpConstants.ERROR_CODE, NhttpConstants.SEND_ABORT);
            NhttpSharedOutputBuffer outputBuffer = (NhttpSharedOutputBuffer) conn.getContext().getAttribute(REQUEST_SOURCE_BUFFER);
            if (outputBuffer != null) {
                outputBuffer.shutdown();
            }
            if (log.isDebugEnabled()) {
                log.debug(conn + ": Remote server aborted request being sent and replied : " + conn + " for request : " + conn.getContext().getAttribute(NhttpConstants.HTTP_REQ_METHOD));
            }
            context.setAttribute(NhttpConstants.DISCARD_ON_COMPLETE, Boolean.TRUE);
            if (metrics != null) {
                metrics.incrementFaultsSending(NhttpConstants.SEND_ABORT, req.getMsgContext());
            }
        }
    }
    switch(response.getStatusLine().getStatusCode()) {
        case HttpStatus.SC_ACCEPTED:
            {
                if (log.isDebugEnabled()) {
                    log.debug(conn + ": Received a 202 Accepted response");
                }
                // Process response body if Content-Type header is present in the response
                // If Content-Type header is null, We will ignore entity body
                Header contentType = response.getFirstHeader(HTTP.CONTENT_TYPE);
                if (contentType != null) {
                    processResponse(conn, context, response);
                    return;
                }
                // sometimes, some http clients sends an "\r\n" as the content body with a
                // HTTP 202 OK.. we will just get it into this temp buffer and ignore it..
                ContentInputBuffer inputBuffer = new SharedInputBuffer(8, conn, allocator);
                context.setAttribute(RESPONSE_SINK_BUFFER, inputBuffer);
                // create a dummy message with an empty SOAP envelope and a property
                // NhttpConstants.SC_ACCEPTED set to Boolean.TRUE to indicate this is a
                // placeholder message for the transport to send a HTTP 202 to the
                // client. Should / would be ignored by any transport other than
                // nhttp. For example, JMS would not send a reply message for one-way
                // operations.
                MessageContext outMsgCtx = (MessageContext) context.getAttribute(OUTGOING_MESSAGE_CONTEXT);
                MessageReceiver mr = outMsgCtx.getAxisOperation().getMessageReceiver();
                // 202 Accepted message
                if (!outMsgCtx.isPropertyTrue(NhttpConstants.IGNORE_SC_ACCEPTED)) {
                    try {
                        MessageContext responseMsgCtx = outMsgCtx.getOperationContext().getMessageContext(WSDL2Constants.MESSAGE_LABEL_IN);
                        if (responseMsgCtx == null || outMsgCtx.getOptions().isUseSeparateListener() || outMsgCtx.getOperationContext().isComplete()) {
                            if (responseMsgCtx != null && responseMsgCtx.getProperty("synapse.send") == null) {
                                return;
                            }
                        } else if (responseMsgCtx == null || outMsgCtx.getOptions().isUseSeparateListener()) {
                            // Since we need to notify the SynapseCallback receiver to remove the
                            // call backs registered  we set a custom property
                            setHeaders(context, response, outMsgCtx, responseMsgCtx);
                            outMsgCtx.setProperty(NhttpConstants.HTTP_202_RECEIVED, "true");
                            mr.receive(outMsgCtx);
                            return;
                        }
                        if (responseMsgCtx == null) {
                            return;
                        }
                        setHeaders(context, response, outMsgCtx, responseMsgCtx);
                        responseMsgCtx.setServerSide(true);
                        responseMsgCtx.setDoingREST(outMsgCtx.isDoingREST());
                        responseMsgCtx.setProperty(MessageContext.TRANSPORT_IN, outMsgCtx.getProperty(MessageContext.TRANSPORT_IN));
                        responseMsgCtx.setTransportIn(outMsgCtx.getTransportIn());
                        responseMsgCtx.setTransportOut(outMsgCtx.getTransportOut());
                        responseMsgCtx.setAxisMessage(outMsgCtx.getAxisOperation().getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE));
                        responseMsgCtx.setOperationContext(outMsgCtx.getOperationContext());
                        responseMsgCtx.setConfigurationContext(outMsgCtx.getConfigurationContext());
                        responseMsgCtx.setTo(null);
                        if (!outMsgCtx.isDoingREST() && !outMsgCtx.isSOAP11()) {
                            responseMsgCtx.setEnvelope(new SOAP12Factory().getDefaultEnvelope());
                        } else {
                            responseMsgCtx.setEnvelope(new SOAP11Factory().getDefaultEnvelope());
                        }
                        responseMsgCtx.setProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.TRUE);
                        responseMsgCtx.setProperty(NhttpConstants.SC_ACCEPTED, Boolean.TRUE);
                        int statusCode = response.getStatusLine().getStatusCode();
                        responseMsgCtx.setProperty(NhttpConstants.HTTP_SC, statusCode);
                        mr.receive(responseMsgCtx);
                    } catch (org.apache.axis2.AxisFault af) {
                        log.debug(conn + ": Unable to report back " + "202 Accepted state to the message receiver");
                    }
                }
                return;
            }
        case HttpStatus.SC_OK:
            {
                processResponse(conn, context, response);
                return;
            }
        case HttpStatus.SC_INTERNAL_SERVER_ERROR:
            {
                if (warnOnHttp500(response)) {
                    log.warn(getErrorMessage("Received an internal server error : " + response.getStatusLine().getReasonPhrase(), conn));
                }
                processResponse(conn, context, response);
                return;
            }
        default:
            {
                if (log.isDebugEnabled()) {
                    log.debug(conn + ": " + getErrorMessage("HTTP status code received : " + response.getStatusLine().getStatusCode() + " :: " + response.getStatusLine().getReasonPhrase(), conn));
                }
                Header contentType = response.getFirstHeader(HTTP.CONTENT_TYPE);
                if (contentType != null) {
                    if ((contentType.getValue().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) >= 0) || contentType.getValue().indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) >= 0) {
                        if (log.isDebugEnabled()) {
                            log.debug(conn + ": Received an unexpected response with a SOAP payload");
                        }
                    } else if (contentType.getValue().indexOf("html") == -1) {
                        if (log.isDebugEnabled()) {
                            log.debug(conn + ": Received an unexpected response with a POX/REST payload");
                        }
                    } else {
                        log.warn(getErrorMessage("Received an unexpected response - " + "of content type : " + contentType.getValue() + " and status code : " + response.getStatusLine().getStatusCode() + " with reason : " + response.getStatusLine().getReasonPhrase(), conn));
                    }
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug(conn + ": " + getErrorMessage("Received a response - " + "without a content type with status code : " + response.getStatusLine().getStatusCode() + " and reason : " + response.getStatusLine().getReasonPhrase(), conn));
                    }
                }
                processResponse(conn, context, response);
            }
    }
}
Also used : SharedInputBuffer(org.apache.http.nio.util.SharedInputBuffer) AxisFault(org.apache.axis2.AxisFault) HttpContext(org.apache.http.protocol.HttpContext) HttpResponse(org.apache.http.HttpResponse) ClientConnectionDebug(org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug) ContentOutputBuffer(org.apache.http.nio.util.ContentOutputBuffer) Header(org.apache.http.Header) MessageReceiver(org.apache.axis2.engine.MessageReceiver) SOAP12Factory(org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory) SOAP11Factory(org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory) ProxyTunnelHandler(org.apache.synapse.transport.http.conn.ProxyTunnelHandler) MessageContext(org.apache.axis2.context.MessageContext) ContentInputBuffer(org.apache.http.nio.util.ContentInputBuffer)

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