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);
}
}
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);
}
}
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);
}
}
}
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);
}
}
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();
}
Aggregations