Example usage for org.apache.http.nio.util SharedInputBuffer SharedInputBuffer

List of usage examples for org.apache.http.nio.util SharedInputBuffer SharedInputBuffer

Introduction

In this page you can find the example usage for org.apache.http.nio.util SharedInputBuffer SharedInputBuffer.

Prototype

public SharedInputBuffer(int buffersize, final IOControl ioctrl, final ByteBufferAllocator allocator) 

Source Link

Usage

From source file:org.apache.synapse.transport.nhttp.ClientHandler.java

/**
 * Perform processing of the received response though Axis2
 *
 * @param conn HTTP connection to be processed
 * @param context HTTP context associated with the connection
 * @param response HTTP response associated with the connection
 *///from   w w w .  j  a  v  a 2  s . c o  m
private void processResponse(final NHttpClientConnection conn, HttpContext context, HttpResponse response) {

    ContentInputBuffer inputBuffer = null;
    MessageContext outMsgContext = (MessageContext) context.getAttribute(OUTGOING_MESSAGE_CONTEXT);
    String endptPrefix = (String) context.getAttribute(NhttpConstants.ENDPOINT_PREFIX);
    String requestMethod = (String) context.getAttribute(NhttpConstants.HTTP_REQ_METHOD);
    int statusCode = response.getStatusLine().getStatusCode();

    boolean expectEntityBody = false;
    if (!"HEAD".equals(requestMethod) && !"OPTIONS".equals(requestMethod) && statusCode >= HttpStatus.SC_OK
            && statusCode != HttpStatus.SC_NO_CONTENT && statusCode != HttpStatus.SC_NOT_MODIFIED
            && statusCode != HttpStatus.SC_RESET_CONTENT) {
        expectEntityBody = true;
    } else if (NhttpConstants.HTTP_HEAD.equals(requestMethod)) {
        // When invoking http HEAD request esb set content length as 0 to response header. Since there is no message
        // body content length cannot be calculated inside synapse. Hence additional two headers are added to
        // which contains content length of the backend response and the request method. These headers are removed
        // before submitting the actual response.
        response.addHeader(NhttpConstants.HTTP_REQUEST_METHOD, requestMethod);

        if (response.getFirstHeader(HTTP.CONTENT_LEN) != null) {
            response.addHeader(NhttpConstants.ORIGINAL_CONTENT_LEN,
                    response.getFirstHeader(HTTP.CONTENT_LEN).getValue());
        }
    }

    if (expectEntityBody) {
        inputBuffer = new SharedInputBuffer(cfg.getBufferSize(), conn, allocator);
        context.setAttribute(RESPONSE_SINK_BUFFER, inputBuffer);

        BasicHttpEntity entity = new BasicHttpEntity();
        if (response.getStatusLine().getProtocolVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
            entity.setChunked(true);
        }
        response.setEntity(entity);
        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);

    } else {
        conn.resetInput();
        conn.resetOutput();

        if (context.getAttribute(NhttpConstants.DISCARD_ON_COMPLETE) != null
                || !connStrategy.keepAlive(response, context)) {
            try {
                // this is a connection we should not re-use
                connpool.forget(conn);
                shutdownConnection(conn, false, null);
                context.removeAttribute(RESPONSE_SINK_BUFFER);
                context.removeAttribute(REQUEST_SOURCE_BUFFER);
            } catch (Exception ignore) {
            }
        } else {
            connpool.release(conn);
        }
    }

    workerPool
            .execute(new ClientWorker(cfgCtx, inputBuffer == null ? null : new ContentInputStream(inputBuffer),
                    response, outMsgContext, endptPrefix));
}

From source file:org.apache.synapse.transport.nhttp.ClientHandler.java

/**
 * Process a response received for the request sent out
 * //  w  ww  . jav  a2  s.  c  o m
 * @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();
    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 SharedOutputBuffer(cfg.getBufferSize(), conn, allocator);
            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");
        }
        // according to the HTTP 1.1 specification HTTP status 100 continue implies that
        // the response will be followed, and the client should just ignore the 100 Continue
        // 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);
            SharedOutputBuffer outputBuffer = (SharedOutputBuffer) 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();

        // the following check is to support the dual channel invocation. Hence the
        // response will be sent as a new request to the client over a different channel
        // client sends back a 202 Accepted response to synapse and we need to neglect that 
        // 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);
    }
    }
}

From source file:org.apache.synapse.transport.nhttp.ServerHandler.java

/**
 * Process a new incoming request//from ww w .  ja va  2s . com
 * @param conn the connection
 */
public void requestReceived(final NHttpServerConnection conn) {

    HttpContext context = conn.getContext();
    context.setAttribute(NhttpConstants.REQ_ARRIVAL_TIME, System.currentTimeMillis());
    context.setAttribute(NhttpConstants.REQ_FROM_CLIENT_READ_START_TIME, System.currentTimeMillis());
    HttpRequest request = conn.getHttpRequest();
    context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
    context.setAttribute(NhttpConstants.MESSAGE_IN_FLIGHT, "true");

    // prepare to collect debug information
    conn.getContext().setAttribute(ServerHandler.SERVER_CONNECTION_DEBUG, new ServerConnectionDebug(conn));

    NHttpConfiguration cfg = NHttpConfiguration.getInstance();
    try {
        InputStream is;
        // Only create an input buffer and ContentInputStream if the request has content
        if (request instanceof HttpEntityEnclosingRequest) {
            // Mark request as not yet fully read, to detect timeouts from harmless keepalive deaths
            conn.getContext().setAttribute(NhttpConstants.REQUEST_READ, Boolean.FALSE);

            ContentInputBuffer inputBuffer = new SharedInputBuffer(cfg.getBufferSize(), conn, allocator);
            context.setAttribute(REQUEST_SINK_BUFFER, inputBuffer);
            is = new ContentInputStream(inputBuffer);
        } else {
            is = null;
            conn.getContext().removeAttribute(NhttpConstants.REQUEST_READ);
        }

        ContentOutputBuffer outputBuffer = new SharedOutputBuffer(cfg.getBufferSize(), conn, allocator);
        context.setAttribute(RESPONSE_SOURCE_BUFFER, outputBuffer);
        OutputStream os = new ContentOutputStream(outputBuffer);

        // create the default response to this request
        ProtocolVersion httpVersion = request.getRequestLine().getProtocolVersion();
        HttpResponse response = responseFactory.newHttpResponse(httpVersion, HttpStatus.SC_OK, context);

        // create a basic HttpEntity using the source channel of the response pipe
        BasicHttpEntity entity = new BasicHttpEntity();
        if (httpVersion.greaterEquals(HttpVersion.HTTP_1_1)) {
            entity.setChunked(true);
        }
        response.setEntity(entity);

        if (metrics != null) {
            metrics.incrementMessagesReceived();
        }
        // hand off processing of the request to a thread off the pool
        ServerWorker worker = new ServerWorker(cfgCtx, scheme.getName(), metrics, conn, this, request, is,
                response, os, listenerContext.isRestDispatching(),
                listenerContext.getHttpGetRequestProcessor());

        if (workerPool != null) {
            workerPool.execute(worker);
        } else if (executor != null) {
            Map<String, String> headers = new HashMap<String, String>();
            for (Header header : request.getAllHeaders()) {
                headers.put(header.getName(), header.getValue());
            }

            EvaluatorContext evaluatorContext = new EvaluatorContext(request.getRequestLine().getUri(),
                    headers);
            int priority = parser.parse(evaluatorContext);
            executor.execute(worker, priority);
        }

        // See if the client expects a 100-Continue
        Header expect = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE);
        if (expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue())) {
            HttpResponse ack = new BasicHttpResponse(request.getProtocolVersion(), HttpStatus.SC_CONTINUE,
                    "Continue");
            conn.submitResponse(ack);
            if (log.isDebugEnabled()) {
                log.debug(conn + ": Expect :100 Continue hit, sending ack back to the server");
            }
            return;
        }

    } catch (Exception e) {
        if (metrics != null) {
            metrics.incrementFaultsReceiving();
        }
        handleException("Error processing request received for : " + request.getRequestLine().getUri(), e,
                conn);
    }
}