use of org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug in project wso2-synapse by wso2.
the class ClientHandler method processConnection.
/**
* Process a new connection over an existing TCP connection or new
*
* @param conn HTTP connection to be processed
* @param axis2Req axis2 representation of the message in the connection
* @throws ConnectionClosedException if the connection is closed
*/
private void processConnection(final NHttpClientConnection conn, final Axis2HttpRequest axis2Req) throws ConnectionClosedException {
// record start time of request
ClientConnectionDebug cd = (ClientConnectionDebug) axis2Req.getMsgContext().getProperty(CLIENT_CONNECTION_DEBUG);
if (cd != null) {
cd.recordRequestStartTime(conn, axis2Req);
conn.getContext().setAttribute(CLIENT_CONNECTION_DEBUG, cd);
}
try {
// Reset connection metrics
conn.getMetrics().reset();
HttpContext context = conn.getContext();
ContentOutputBuffer outputBuffer = new NhttpSharedOutputBuffer(bufferSize, conn, allocator, socketTimeout);
axis2Req.setOutputBuffer(outputBuffer);
context.setAttribute(REQUEST_SOURCE_BUFFER, outputBuffer);
HttpRoute route = axis2Req.getRoute();
context.setAttribute(AXIS2_HTTP_REQUEST, axis2Req);
context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, route.getTargetHost());
context.setAttribute(OUTGOING_MESSAGE_CONTEXT, axis2Req.getMsgContext());
context.setAttribute(NhttpConstants.PROXY_PROFILE_TARGET_HOST, axis2Req.getMsgContext().getProperty(NhttpConstants.PROXY_PROFILE_TARGET_HOST));
HttpRequest request = axis2Req.getRequest();
request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
/*
* Remove Content-Length and Transfer-Encoding headers, if already present.
* */
request.removeHeaders(HTTP.TRANSFER_ENCODING);
request.removeHeaders(HTTP.CONTENT_LEN);
this.httpProcessor.process(request, context);
if (proxyauthenticator != null && route.getProxyHost() != null && !route.isTunnelled()) {
proxyauthenticator.authenticatePreemptively(request, context);
}
if (axis2Req.getTimeout() > 0) {
conn.setSocketTimeout(axis2Req.getTimeout());
}
context.setAttribute(NhttpConstants.ENDPOINT_PREFIX, axis2Req.getEndpointURLPrefix());
context.setAttribute(NhttpConstants.HTTP_REQ_METHOD, request.getRequestLine().getMethod());
context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
setServerContextAttribute(NhttpConstants.REQ_DEPARTURE_TIME, System.currentTimeMillis(), conn);
setServerContextAttribute(NhttpConstants.REQ_TO_BACKEND_WRITE_START_TIME, System.currentTimeMillis(), conn);
conn.submitRequest(request);
} catch (ConnectionClosedException e) {
throw e;
} catch (IOException e) {
if (metrics != null) {
metrics.incrementFaultsSending();
}
handleException("I/O Error submitting request : " + e.getMessage(), e, conn);
} catch (HttpException e) {
if (metrics != null) {
metrics.incrementFaultsSending();
}
handleException("HTTP protocol error submitting request : " + e.getMessage(), e, conn);
} finally {
synchronized (axis2Req) {
axis2Req.setReadyToStream(true);
axis2Req.notifyAll();
}
}
}
use of org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug in project wso2-synapse by wso2.
the class ClientHandler method outputReady.
/**
* Process ready output (i.e. write request to remote server)
*
* @param conn the connection being processed
* @param encoder the encoder in use
*/
public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder) {
HttpContext context = conn.getContext();
ContentOutputBuffer outBuf = (ContentOutputBuffer) context.getAttribute(REQUEST_SOURCE_BUFFER);
if (outBuf == null)
return;
try {
int bytesWritten = outBuf.produceContent(encoder);
if (metrics != null) {
if (bytesWritten > 0) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
metrics.incrementBytesSent(getMessageContext(conn), bytesWritten);
} else {
metrics.incrementBytesSent(bytesWritten);
}
}
if (encoder.isCompleted()) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
metrics.incrementMessagesSent(getMessageContext(conn));
} else {
metrics.incrementMessagesSent();
}
}
}
if (encoder.isCompleted()) {
ClientConnectionDebug ccd = (ClientConnectionDebug) context.getAttribute(CLIENT_CONNECTION_DEBUG);
if (ccd != null) {
ccd.recordRequestCompletionTime();
}
setServerContextAttribute(NhttpConstants.REQ_TO_BACKEND_WRITE_END_TIME, System.currentTimeMillis(), conn);
}
} catch (IOException e) {
if (metrics != null) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
metrics.incrementFaultsSending(NhttpConstants.SND_IO_ERROR_SENDING, getMessageContext(conn));
} else {
metrics.incrementFaultsSending();
}
}
handleException("I/O Error at outputReady : " + e.getMessage(), e, conn);
}
}
use of org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug in project wso2-synapse by wso2.
the class ClientHandler method inputReady.
/**
* Process ready input (i.e. response from remote server)
*
* @param conn connection being processed
* @param decoder the content decoder in use
*/
public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder) {
HttpContext context = conn.getContext();
HttpResponse response = conn.getHttpResponse();
ContentInputBuffer inBuf = (ContentInputBuffer) context.getAttribute(RESPONSE_SINK_BUFFER);
try {
int bytesRead = inBuf.consumeContent(decoder);
if (isMessageSizeValidationEnabled) {
HttpContext httpContext = conn.getContext();
if (httpContext.getAttribute(NhttpConstants.MESSAGE_SIZE_VALIDATION_SUM) == null) {
httpContext.setAttribute(NhttpConstants.MESSAGE_SIZE_VALIDATION_SUM, 0);
}
int messageSizeSum = (int) httpContext.getAttribute(NhttpConstants.MESSAGE_SIZE_VALIDATION_SUM);
messageSizeSum += bytesRead;
if (messageSizeSum > validMaxMessageSize) {
log.warn("Payload exceeds valid payload size range, hence discontinuing chunk stream at " + messageSizeSum + " bytes to prevent OOM.");
dropClientConnection(conn);
conn.getContext().setAttribute(NhttpConstants.CONNECTION_DROPPED, true);
// stopped http chunk stream from here and mark end of stream
((SharedInputBuffer) inBuf).close();
}
httpContext.setAttribute(NhttpConstants.MESSAGE_SIZE_VALIDATION_SUM, messageSizeSum);
}
if (metrics != null && bytesRead > 0) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
metrics.incrementBytesReceived(getMessageContext(conn), bytesRead);
} else {
metrics.incrementBytesReceived(bytesRead);
}
}
if (decoder.isCompleted()) {
setServerContextAttribute(NhttpConstants.RES_ARRIVAL_TIME, System.currentTimeMillis(), conn);
setServerContextAttribute(NhttpConstants.RES_FROM_BACKEND_READ_END_TIME, System.currentTimeMillis(), conn);
ClientConnectionDebug ccd = (ClientConnectionDebug) conn.getContext().getAttribute(CLIENT_CONNECTION_DEBUG);
if (ccd != null) {
ccd.recordResponseCompletionTime();
}
if (metrics != null) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
MessageContext mc = getMessageContext(conn);
metrics.incrementMessagesReceived(mc);
metrics.notifyReceivedMessageSize(mc, conn.getMetrics().getReceivedBytesCount());
metrics.notifySentMessageSize(mc, conn.getMetrics().getSentBytesCount());
metrics.reportResponseCode(mc, response.getStatusLine().getStatusCode());
} else {
metrics.incrementMessagesReceived();
metrics.notifyReceivedMessageSize(conn.getMetrics().getReceivedBytesCount());
metrics.notifySentMessageSize(conn.getMetrics().getSentBytesCount());
}
}
// reset metrics on connection
conn.getMetrics().reset();
if (context.getAttribute(NhttpConstants.DISCARD_ON_COMPLETE) != null) {
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 if (!connStrategy.keepAlive(response, context)) {
shutdownConnection(conn, false, null);
context.removeAttribute(RESPONSE_SINK_BUFFER);
context.removeAttribute(REQUEST_SOURCE_BUFFER);
} else {
connpool.release(conn);
}
}
} catch (IOException e) {
if (metrics != null) {
if (metrics.getLevel() == MetricsCollector.LEVEL_FULL) {
metrics.incrementFaultsReceiving(NhttpConstants.SND_IO_ERROR_RECEIVING, getMessageContext(conn));
} else {
metrics.incrementFaultsReceiving();
}
}
handleException("I/O Error at inputReady : " + e.getMessage(), e, conn);
}
}
use of org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug 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);
}
}
}
use of org.apache.synapse.transport.nhttp.debug.ClientConnectionDebug in project wso2-synapse by wso2.
the class HttpCoreNIOSender method sendAsyncRequest.
/**
* Send the request message asynchronously to the given EPR
* @param epr the destination EPR for the message
* @param msgContext the message being sent
* @throws AxisFault on error
*/
private void sendAsyncRequest(EndpointReference epr, MessageContext msgContext) throws AxisFault {
try {
URL url = new URL(epr.getAddress());
String scheme = url.getProtocol() != null ? url.getProtocol() : "http";
String hostname = url.getHost();
int port = url.getPort();
if (port == -1) {
// use default
if ("http".equals(scheme)) {
port = 80;
} else if ("https".equals(scheme)) {
port = 443;
}
}
HttpHost target = new HttpHost(hostname, port, scheme);
boolean secure = "https".equalsIgnoreCase(target.getSchemeName());
HttpHost proxy = proxyConfig.selectProxy(target);
msgContext.setProperty(NhttpConstants.PROXY_PROFILE_TARGET_HOST, target.getHostName());
HttpRoute route;
if (proxy != null) {
route = new HttpRoute(target, null, proxy, secure);
} else {
route = new HttpRoute(target, null, secure);
}
Axis2HttpRequest axis2Req = new Axis2HttpRequest(epr, route, msgContext);
Object timeout = msgContext.getProperty(NhttpConstants.SEND_TIMEOUT);
if (timeout != null && timeout instanceof Long) {
axis2Req.setTimeout((int) ((Long) timeout).longValue());
}
NHttpClientConnection conn = connpool.getConnection(route);
// Ensure MessageContext has a ClientConnectionDebug attached before we start streaming
ServerConnectionDebug scd = (ServerConnectionDebug) msgContext.getProperty(ServerHandler.SERVER_CONNECTION_DEBUG);
ClientConnectionDebug ccd;
if (scd != null) {
ccd = scd.getClientConnectionDebug();
if (ccd == null) {
ccd = new ClientConnectionDebug(scd);
scd.setClientConnectionDebug(ccd);
}
ccd.recordRequestStartTime(conn, axis2Req);
msgContext.setProperty(ClientHandler.CLIENT_CONNECTION_DEBUG, ccd);
}
if (conn == null) {
HttpHost host = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost();
ioReactor.connect(new InetSocketAddress(host.getHostName(), host.getPort()), null, axis2Req, sessionRequestCallback);
if (log.isDebugEnabled()) {
log.debug("A new connection established to : " + route);
}
} else {
// reinitialize timeouts for the pooled connection
conn.setSocketTimeout(socketTimeout);
try {
handler.submitRequest(conn, axis2Req);
if (log.isDebugEnabled()) {
log.debug("An existing connection reused to : " + hostname + ":" + port);
}
} catch (ConnectionClosedException e) {
ioReactor.connect(new InetSocketAddress(hostname, port), null, axis2Req, sessionRequestCallback);
if (log.isDebugEnabled()) {
log.debug("A new connection established to : " + hostname + ":" + port);
}
}
}
try {
axis2Req.streamMessageContents();
} catch (AxisFault af) {
throw af;
}
} catch (MalformedURLException e) {
handleException("Malformed destination EPR : " + epr.getAddress(), e);
}
}
Aggregations