Java源码示例:org.apache.synapse.transport.nhttp.NhttpConstants

示例1
public static void sendFault(MessageContext messageContext, int status) {
    org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext) messageContext).
            getAxis2MessageContext();

    axis2MC.setProperty(NhttpConstants.HTTP_SC, status);
    messageContext.setResponse(true);
    messageContext.setProperty("RESPONSE", "true");
    messageContext.setTo(null);        
    axis2MC.removeProperty("NO_ENTITY_BODY");

    // Always remove the ContentType - Let the formatter do its thing
    axis2MC.removeProperty(Constants.Configuration.CONTENT_TYPE);
    Map headers = (Map) axis2MC.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
    if (headers != null) {
        headers.remove(HttpHeaders.AUTHORIZATION);

        headers.remove(HttpHeaders.HOST);
    }
    Axis2Sender.sendBack(messageContext);
}
 
示例2
/**
 * This method sets the Age header.
 *
 * @param cachedResponse The cached response to be returned.
 * @param msgCtx         The messageContext.
 */
@SuppressWarnings("unchecked")
public static void setAgeHeader(CachableResponse cachedResponse,
                                org.apache.axis2.context.MessageContext msgCtx) {
    Map excessHeaders = new MultiValueMap();
    long responseCachedTime = cachedResponse.getResponseFetchedTime();
    long age = Math.abs((responseCachedTime - System.currentTimeMillis()) / 1000);
    excessHeaders.put(HttpHeaders.AGE, String.valueOf(age));

    msgCtx.setProperty(NhttpConstants.EXCESS_TRANSPORT_HEADERS, excessHeaders);
}
 
示例3
/**
 * Test case for setAgeHeader() method
 */
public void testSetAgeHeader() {
    CachableResponse cachedResponse = new CachableResponse();
    cachedResponse.setResponseFetchedTime(System.currentTimeMillis() - 3000);
    org.apache.axis2.context.MessageContext msgCtx = new org.apache.axis2.context.MessageContext();
    HttpCachingFilter.setAgeHeader(cachedResponse, msgCtx);
    Map excessHeaders = (MultiValueMap) msgCtx.getProperty(NhttpConstants.EXCESS_TRANSPORT_HEADERS);
    assertTrue(excessHeaders.get("Age") != null);
}
 
示例4
/**
 * Return the port the service was invoked.
 *
 * @param synCtx Synapse message context
 * @return port the port used to invoke the service
 */
private int getServiceInvokePort(MessageContext synCtx) {
    int invokePort = 0;
    if (null != ((Axis2MessageContext) synCtx).getAxis2MessageContext().
            getProperty(NhttpConstants.SERVICE_PREFIX)) {
        String servicePort = ((Axis2MessageContext) synCtx).getAxis2MessageContext().
                getProperty(NhttpConstants.SERVICE_PREFIX).toString();
        servicePort = servicePort.substring((servicePort.lastIndexOf(':') + 1),
                servicePort.lastIndexOf(DELIMITER));
        invokePort = Integer.parseInt(servicePort);
    }
    return invokePort;
}
 
示例5
/**
 * This method checks whether the request path contains matching vulnerable keywords.
 *
 * @param messageContext contains the message properties of the relevant API request which was
 *                       enabled the regexValidator message mediation in flow.
 * @return true if request path contains matching vulnerable keywords.
 */
private boolean isRequestPathVulnerable(MessageContext messageContext) {
    org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext)
            messageContext).getAxis2MessageContext();
    String parameter = null;
    if (enabledCheckPathParam) {
        String queryParams = (String) axis2MC.getProperty(NhttpConstants.REST_URL_POSTFIX);
        try {
            parameter = URLDecoder.decode(queryParams, APIMgtGatewayConstants.UTF8);
        } catch (UnsupportedEncodingException e) {
            String message = "Error occurred while decoding the query/path parameters: " + parameter;
            logger.error(message, e);
            GatewayUtils.handleThreat(messageContext, ThreatProtectorConstants.HTTP_SC_CODE,
                    message + e.getMessage());
            return true;
        }
        if (pattern != null && parameter != null && pattern.matcher(parameter).find()) {
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("Threat detected in query parameters [ %s ] by regex [ %s ]",
                        queryParams, pattern));
            }
            GatewayUtils.handleThreat(messageContext, APIMgtGatewayConstants.HTTP_SC_CODE,
                    threatType + " " + APIMgtGatewayConstants.QPARAM_THREAT_MSG);
            return true;
        }
    }
    return false;
}
 
示例6
/**
 * Can be used to extract Query Params from {@code org.apache.axis2.context.MessageContext}.
 *
 * @param messageContext The Axis2 MessageContext
 * @return A Map with Name Value pairs.
 */
public static Map<String, String> getQueryParams(MessageContext messageContext) {

    String queryString = (String) messageContext.getProperty(NhttpConstants.REST_URL_POSTFIX);
    if (!StringUtils.isEmpty(queryString)) {
        if (queryString.indexOf("?") > -1) {
            queryString = queryString.substring(queryString.indexOf("?") + 1);
        }
        String[] queryParams = queryString.split("&");
        Map<String, String> queryParamsMap = new HashMap<String, String>();
        String[] queryParamArray;
        String queryParamName, queryParamValue = "";
        for (String queryParam : queryParams) {
            queryParamArray = queryParam.split("=");
            if (queryParamArray.length == 2) {
                queryParamName = queryParamArray[0];
                queryParamValue = queryParamArray[1];
            } else {
                queryParamName = queryParamArray[0];
            }
            queryParamsMap.put(queryParamName, queryParamValue);
        }

        return queryParamsMap;
    }
    return null;
}
 
示例7
private String extractApiKey(MessageContext mCtx) throws APISecurityException {

        org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext) mCtx).getAxis2MessageContext();
        String apiKey;

        //check headers to get apikey
        Map headers = (Map) (axis2MC.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS));
        if (headers != null) {
            apiKey = (String) headers.get(securityParam);
            if (apiKey != null) {
                //Remove apikey header from the request
                headers.remove(securityParam);
                return apiKey.trim();
            }
        }
        //check query params to get apikey
        try {
            apiKey = new SynapseXPath("$url:apikey").stringValueOf(mCtx);
            if (StringUtils.isNotBlank(apiKey)) {
                String rest_url_postfix = (String) axis2MC.getProperty(NhttpConstants.REST_URL_POSTFIX);
                rest_url_postfix = removeApiKeyFromQueryParameters(rest_url_postfix, URLEncoder.encode(apiKey));
                axis2MC.setProperty(NhttpConstants.REST_URL_POSTFIX, rest_url_postfix);
                return apiKey.trim();
            } else {
                if (log.isDebugEnabled()){
                    log.debug("Api Key Authentication failed: Header or Query parameter with the name '"
                            .concat(securityParam).concat("' was not found."));
                }
                throw new APISecurityException(APISecurityConstants.API_AUTH_MISSING_CREDENTIALS,
                        APISecurityConstants.API_AUTH_MISSING_CREDENTIALS_MESSAGE);
            }
        } catch (JaxenException e) {
            if (log.isDebugEnabled()) {
                log.debug("Error while retrieving apikey from the request query params.", e);
            }
            throw new APISecurityException(APISecurityConstants.API_AUTH_MISSING_CREDENTIALS,
                    APISecurityConstants.API_AUTH_MISSING_CREDENTIALS_MESSAGE);
        }
    }
 
示例8
/**
 * This method used to send the response back from the request.
 *
 * @param messageContext messageContext of the request
 * @param status         HTTP Status to return from the response
 */
public static void send(MessageContext messageContext, int status) {
    org.apache.axis2.context.MessageContext axis2MC =
            ((Axis2MessageContext) messageContext).getAxis2MessageContext();
    axis2MC.setProperty(NhttpConstants.HTTP_SC, status);
    messageContext.setResponse(true);
    messageContext.setProperty(SynapseConstants.RESPONSE, "true");
    messageContext.setTo(null);
    axis2MC.removeProperty(Constants.Configuration.CONTENT_TYPE);
    Axis2Sender.sendBack(messageContext);
}
 
示例9
@Test
public void testEnableQueryParamCondition() throws Exception {
    ThrottleProperties throttleProperties = new ThrottleProperties();
    throttleProperties.setEnabled(true);
    throttleProperties.setEnableQueryParamConditions(true);
    DataProcessAndPublishingAgent dataProcessAndPublishingAgent = new DataProcessAndPublishingAgentWrapper
            (throttleProperties);
    AuthenticationContext authenticationContext = new AuthenticationContext();
    MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
    org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext
            .class);
    Mockito.when(((Axis2MessageContext) messageContext).getAxis2MessageContext()).thenReturn(axis2MsgCntxt);
    Mockito.when(axis2MsgCntxt.getProperty(NhttpConstants.REST_URL_POSTFIX)).thenReturn("?a=1&b=2");
    Mockito.when(messageContext.getProperty(RESTConstants.SYNAPSE_REST_API)).thenReturn("admin--PizzaShackAPI");
    TreeMap headers = new TreeMap();
    headers.put(APIMgtGatewayConstants.X_FORWARDED_FOR, "192.168.1.1");
    Mockito.when(axis2MsgCntxt.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS))
            .thenReturn(headers);
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setContentAware(false);
    ArrayList<VerbInfoDTO> list = new ArrayList<VerbInfoDTO>();
    list.add(verbInfoDTO);
    Mockito.when(messageContext.getProperty(APIConstants.VERB_INFO_DTO)).thenReturn(list);
    dataProcessAndPublishingAgent.setDataReference(applicationLevelThrottleKey, applicationLevelTier,
            apiLevelThrottleKey, null, subscriptionLevelThrottleKey, subscriptionLevelTier,
            resourceLevelThrottleKey, resourceLevelTier, authorizedUser, apiContext, apiVersion, appTenant,
            apiTenant, appId, messageContext, authenticationContext);
    dataProcessAndPublishingAgent.run();
}
 
示例10
@Test
public void testEnableQueryParamConditionWithoutQueryParams() throws Exception {
    ThrottleProperties throttleProperties = new ThrottleProperties();
    throttleProperties.setEnabled(true);
    throttleProperties.setEnableQueryParamConditions(true);
    throttleProperties.setEnableJwtConditions(true);
    DataProcessAndPublishingAgent dataProcessAndPublishingAgent = new DataProcessAndPublishingAgentWrapper
            (throttleProperties);
    AuthenticationContext authenticationContext = new AuthenticationContext();
    MessageContext messageContext = Mockito.mock(Axis2MessageContext.class);
    org.apache.axis2.context.MessageContext axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext
            .class);
    Mockito.when(((Axis2MessageContext) messageContext).getAxis2MessageContext()).thenReturn(axis2MsgCntxt);
    Mockito.when(axis2MsgCntxt.getProperty(NhttpConstants.REST_URL_POSTFIX)).thenReturn("");
    Mockito.when(messageContext.getProperty(RESTConstants.SYNAPSE_REST_API)).thenReturn("admin--PizzaShackAPI");
    TreeMap headers = new TreeMap();
    headers.put(APIMgtGatewayConstants.X_FORWARDED_FOR, "192.168.1.1");
    Mockito.when(axis2MsgCntxt.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS))
            .thenReturn(headers);
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setContentAware(false);
    ArrayList<VerbInfoDTO> list = new ArrayList<VerbInfoDTO>();
    list.add(verbInfoDTO);
    Mockito.when(messageContext.getProperty(APIConstants.VERB_INFO_DTO)).thenReturn(list);
    dataProcessAndPublishingAgent.setDataReference(applicationLevelThrottleKey, applicationLevelTier,
            apiLevelThrottleKey, null, subscriptionLevelThrottleKey, subscriptionLevelTier,
            resourceLevelThrottleKey, resourceLevelTier, authorizedUser, apiContext, apiVersion, appTenant,
            apiTenant, appId, messageContext, authenticationContext);
    dataProcessAndPublishingAgent.run();
}
 
示例11
/**
 * Adding the X-Forwarded-For/X-Originating-IP headers to the outgoing message.
 *
 * @param synCtx Current message context
 */
protected void setupTransportHeaders(MessageContext synCtx) {
    Axis2MessageContext axis2smc = (Axis2MessageContext) synCtx;
    org.apache.axis2.context.MessageContext axis2MessageCtx = axis2smc.getAxis2MessageContext();
    Object headers = axis2MessageCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
    if (headers != null && headers instanceof Map) {
        Map headersMap = (Map) headers;
        String xForwardFor = (String) headersMap.get(NhttpConstants.HEADER_X_FORWARDED_FOR);
        String remoteHost = (String) axis2MessageCtx.getProperty(org.apache.axis2.context.MessageContext.REMOTE_ADDR);

        if (xForwardFor != null && !"".equals(xForwardFor)) {
            StringBuilder xForwardedForString = new StringBuilder();
            xForwardedForString.append(xForwardFor);
            if (remoteHost != null && !"".equals(remoteHost)) {
                xForwardedForString.append(",").append(remoteHost);
            }
            headersMap.put(NhttpConstants.HEADER_X_FORWARDED_FOR, xForwardedForString.toString());
        } else {
            headersMap.put(NhttpConstants.HEADER_X_FORWARDED_FOR, remoteHost);
        }

        //Extracting information of X-Originating-IP
        if (headersMap.get(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_1) != null) {
            headersMap.put(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_1, headersMap.get(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_1));
        } else if (headersMap.get(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_2) != null) {
            headersMap.put(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_2, headersMap.get(NhttpConstants.HEADER_X_ORIGINATING_IP_FORM_2));
        }

    }
}
 
示例12
/**
 * This method returns the existing cached response.
 * @param synCtx Message context.
 * @param synLog Synapse log.
 * @param msgCtx Axis2 contex.
 * @param cachedResponse Cached response.
 */
private void replaceEnvelopeWithCachedResponse(MessageContext synCtx, SynapseLog synLog,
                                               org.apache.axis2.context.MessageContext msgCtx, CachableResponse cachedResponse) {
    Map<String, Object> headerProperties;
    try {
        if (cachedResponse.isJson()) {
            byte[] payload = cachedResponse.getResponsePayload();
            OMElement response = JsonUtil.getNewJsonPayload(msgCtx, payload, 0,
                    payload.length, false, false);
            if (msgCtx.getEnvelope().getBody().getFirstElement() != null) {
                msgCtx.getEnvelope().getBody().getFirstElement().detach();
            }
            msgCtx.getEnvelope().getBody().addChild(response);

        } else {
            msgCtx.setEnvelope(MessageHelper.cloneSOAPEnvelope(cachedResponse.getResponseEnvelope()));
        }
    } catch (AxisFault e) {
        handleException("Error creating response OM from cache : " + id, synCtx);
    }
    if (CachingConstants.HTTP_PROTOCOL_TYPE.equals(getProtocolType())) {
        if (cachedResponse.getStatusCode() != null) {
            msgCtx.setProperty(NhttpConstants.HTTP_SC,
                    Integer.parseInt(cachedResponse.getStatusCode()));
        }
        if (cachedResponse.getStatusReason() != null) {
            msgCtx.setProperty(PassThroughConstants.HTTP_SC_DESC, cachedResponse.getStatusReason());
        }
        //Set Age header to the cached response.
        if (cachedResponse.isAddAgeHeaderEnabled()) {
            HttpCachingFilter.setAgeHeader(cachedResponse, msgCtx);
        }
    }
    if (msgCtx.isDoingREST()) {

        msgCtx.removeProperty(PassThroughConstants.NO_ENTITY_BODY);
        msgCtx.removeProperty(Constants.Configuration.CONTENT_TYPE);
    }
    if ((headerProperties = cachedResponse.getHeaderProperties()) != null) {

        msgCtx.setProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS,
                headerProperties);
        msgCtx.setProperty(Constants.Configuration.MESSAGE_TYPE,
                headerProperties.get(Constants.Configuration.MESSAGE_TYPE));
    }

    // take specified action on cache hit
    if (onCacheHitSequence != null) {
        // if there is an onCacheHit use that for the mediation
        synLog.traceOrDebug("Delegating message to the onCacheHit "
                + "Anonymous sequence");
        ContinuationStackManager.addReliantContinuationState(synCtx, 0, getMediatorPosition());
        if (onCacheHitSequence.mediate(synCtx)) {
            ContinuationStackManager.removeReliantContinuationState(synCtx);
        }

    } else if (onCacheHitRef != null) {
        if (synLog.isTraceOrDebugEnabled()) {
            synLog.traceOrDebug("Delegating message to the onCacheHit "
                    + "sequence : " + onCacheHitRef);
        }
        ContinuationStackManager.updateSeqContinuationState(synCtx, getMediatorPosition());
        synCtx.getSequence(onCacheHitRef).mediate(synCtx);

    } else {

        if (synLog.isTraceOrDebugEnabled()) {
            synLog.traceOrDebug("Request message " + synCtx.getMessageID() +
                    " was served from the cache");
        }
        // send the response back if there is not onCacheHit is specified
        synCtx.setTo(null);
        //Todo continueExecution if needed
        Axis2Sender.sendBack(synCtx);

    }
}
 
示例13
/**
 * Returns the HTML text for the list of services deployed.
 * This can be delegated to another Class as well
 * where it will handle more options of GET messages.
 *
 * @param prefix to be used for the Service names
 * @return the HTML to be displayed as a String
 */
protected String getServicesHTML(String prefix) {

    Map services = cfgCtx.getAxisConfiguration().getServices();
    Hashtable erroneousServices = cfgCtx.getAxisConfiguration().getFaultyServices();
    boolean servicesFound = false;

    StringBuffer resultBuf = new StringBuffer();
    resultBuf.append("<html><head><title>Axis2: Services</title></head>" + "<body>");

    if ((services != null) && !services.isEmpty()) {

        servicesFound = true;
        resultBuf.append("<h2>" + "Deployed services" + "</h2>");

        for (Object service : services.values()) {

            AxisService axisService = (AxisService) service;
            Parameter isHiddenService = axisService.getParameter(
                    NhttpConstants.HIDDEN_SERVICE_PARAM_NAME);
            Parameter isAdminService = axisService.getParameter("adminService");
            boolean isClientSide = axisService.isClientSide();

            boolean isSkippedService = (isHiddenService != null &&
                    JavaUtils.isTrueExplicitly(isHiddenService.getValue())) || (isAdminService != null &&
                    JavaUtils.isTrueExplicitly(isAdminService.getValue())) || isClientSide;
            if (axisService.getName().startsWith("__") || isSkippedService) {
                continue;    // skip private services
            }

            Iterator iterator = axisService.getOperations();
            resultBuf.append("<h3><a href=\"").append(prefix).append(axisService.getName()).append(
                    "?wsdl\">").append(axisService.getName()).append("</a></h3>");

            if (iterator.hasNext()) {
                resultBuf.append("Available operations <ul>");

                for (; iterator.hasNext();) {
                    AxisOperation axisOperation = (AxisOperation) iterator.next();
                    resultBuf.append("<li>").append(
                            axisOperation.getName().getLocalPart()).append("</li>");
                }
                resultBuf.append("</ul>");
            } else {
                resultBuf.append("No operations specified for this service");
            }
        }
    }

    if ((erroneousServices != null) && !erroneousServices.isEmpty()) {
        servicesFound = true;
        resultBuf.append("<hr><h2><font color=\"blue\">Faulty Services</font></h2>");
        Enumeration faultyservices = erroneousServices.keys();

        while (faultyservices.hasMoreElements()) {
            String faultyserviceName = (String) faultyservices.nextElement();
            resultBuf.append("<h3><font color=\"blue\">").append(
                    faultyserviceName).append("</font></h3>");
        }
    }

    if (!servicesFound) {
        resultBuf.append("<h2>There are no services deployed</h2>");
    }

    resultBuf.append("</body></html>");
    return resultBuf.toString();
}
 
示例14
/**
 * Returns the service name.
 *
 * @param request HttpRequest
 * @return service name as a String
 */
protected String getServiceName(HttpRequest request) {
    String uri = request.getRequestLine().getUri();

    String servicePath = cfgCtx.getServiceContextPath();
    if (!servicePath.startsWith("/")) {
        servicePath = "/" + servicePath;
    }

    String serviceName = null;
    if (uri.startsWith(servicePath)) {
        serviceName = uri.substring(servicePath.length());
        if (serviceName.startsWith("/")) {
            serviceName = serviceName.substring(1);
        }
        if (serviceName.indexOf("?") != -1) {
            serviceName = serviceName.substring(0, serviceName.indexOf("?"));
        }
    } else {
        // this may be a custom URI
        String incomingURI = request.getRequestLine().getUri();

        Map serviceURIMap = (Map) cfgCtx.getProperty(NhttpConstants.EPR_TO_SERVICE_NAME_MAP);
        if (serviceURIMap != null) {
            Set keySet = serviceURIMap.keySet();
            for (Object key : keySet) {
                if (incomingURI.toLowerCase().contains(((String) key).toLowerCase())) {
                    return (String) serviceURIMap.get(key);
                }
            }
        }
    }

    if (serviceName != null) {
        int opnStart = serviceName.indexOf("/");
        if (opnStart != -1) {
            serviceName = serviceName.substring(0, opnStart);
        }
    }
    return serviceName;
}
 
示例15
protected void sendToApplicationMember(MessageContext synCtx,
                                       org.apache.axis2.clustering.Member currentMember,
                                       DynamicLoadbalanceFaultHandler faultHandler,
                                       boolean newSession) {
    //Rewriting the URL
    org.apache.axis2.context.MessageContext axis2MsgCtx =
            ((Axis2MessageContext) synCtx).getAxis2MessageContext();

    //Removing the REST_URL_POSTFIX - this is a hack.
    //In this load balance endpoint we create an endpoint per request by setting the complete url as the address.
    //If a REST message comes Axis2FlexibleMEPClient append the REST_URL_POSTFIX to the address. Hence endpoint fails
    //do send the request. e.g.  http://localhost:8080/example/index.html/example/index.html
    axis2MsgCtx.removeProperty(NhttpConstants.REST_URL_POSTFIX);

    String transport = axis2MsgCtx.getTransportIn().getName();
    EndpointReference to = getEndpointReferenceAfterURLRewrite(synCtx, currentMember, transport);
    synCtx.setTo(to);

    Endpoint endpoint = getEndpoint(to, currentMember, synCtx);

    // Push fault handler to manage statistics and fail-over logic
    faultHandler.setTo(to);
    faultHandler.setCurrentMember(currentMember);
    faultHandler.setCurrentEp(endpoint);
    synCtx.pushFaultHandler(faultHandler);
    synCtx.getEnvelope().build();

    if (isSessionAffinityBasedLB()) {
        synCtx.setProperty(SynapseConstants.PROP_SAL_ENDPOINT_DEFAULT_SESSION_TIMEOUT, getSessionTimeout());
        synCtx.setProperty(SynapseConstants.PROP_SAL_ENDPOINT_CURRENT_DISPATCHER, dispatcher);

        if (newSession) {
            prepareEndPointSequence(synCtx, endpoint);
            synCtx.setProperty(SynapseConstants.PROP_SAL_ENDPOINT_CURRENT_MEMBER, currentMember);
            // we should also indicate that this is the first message in the session. so that
            // onFault(...) method can resend only the failed attempts for the first message.
            synCtx.setProperty(SynapseConstants.PROP_SAL_ENDPOINT_FIRST_MESSAGE_IN_SESSION,
                    Boolean.TRUE);
        }
    }

    Map<String, String> memberHosts;
    if ((memberHosts = (Map<String, String>) currentMember.getProperties().get(HttpSessionDispatcher.HOSTS)) == null) {
        currentMember.getProperties().put(HttpSessionDispatcher.HOSTS,
                memberHosts = new HashMap<String, String>());
    }
    memberHosts.put(extractTargetHost(synCtx), "true");
    setupTransportHeaders(synCtx);
    setupLoadBalancerContextProperties(synCtx, currentMember);

    try {
        if (log.isDebugEnabled()) {
            log.debug(String.format("Sending request %s to endpoint: %s", synCtx.getMessageID(), to.getAddress()));
        }
        endpoint.send(synCtx);

        // Increment in-flight request count
        incrementInFlightRequestCount(synCtx);
    } catch (Exception e) {
        if (e.getMessage().toLowerCase().contains("io reactor shutdown")) {
            log.fatal("System cannot continue normal operation. Restarting", e);
            System.exit(121); // restart
        } else {
            throw new SynapseException(e);
        }
    }
}