You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by as...@apache.org on 2009/05/24 07:33:22 UTC
svn commit: r778087 - in /synapse/trunk/java/modules:
core/src/main/java/org/apache/synapse/
core/src/main/java/org/apache/synapse/config/xml/endpoints/
core/src/main/java/org/apache/synapse/core/axis2/
core/src/main/java/org/apache/synapse/endpoints/ ...
Author: asankha
Date: Sun May 24 05:33:21 2009
New Revision: 778087
URL: http://svn.apache.org/viewvc?rev=778087&view=rev
Log:
fix SYNAPSE-551 [includes SYNAPSE-477, SYNAPSE-186, SYNAPSE-386] and also the fix for SYNAPSE-550
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/DefaultEndpointFactory.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/Axis2HttpRequest.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientHandler.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientWorker.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HttpCoreNIOSender.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerHandler.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java
synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java Sun May 24 05:33:21 2009
@@ -281,7 +281,8 @@
public static final String FORMAT_GET = "get";
public static final String FORMAT_SOAP11 = "soap11";
public static final String FORMAT_SOAP12 = "soap12";
-
+ public static final String FORMAT_REST = "rest";
+
/** Synapse server instance name */
public static final String SERVER_NAME = "serverName";
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/DefaultEndpointFactory.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/DefaultEndpointFactory.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/DefaultEndpointFactory.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/DefaultEndpointFactory.java Sun May 24 05:33:21 2009
@@ -112,6 +112,10 @@
definition.setForceSOAP12(true);
definition.setFormat(SynapseConstants.FORMAT_SOAP12);
+ } else if (SynapseConstants.FORMAT_REST.equals(forceValue)) {
+ definition.setForceREST(true);
+ definition.setFormat(SynapseConstants.FORMAT_REST);
+
} else {
handleException("force value -\"" + forceValue + "\" not yet implemented");
}
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java Sun May 24 05:33:21 2009
@@ -40,6 +40,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.SynapseConstants;
+import org.apache.synapse.transport.nhttp.NhttpConstants;
import org.apache.synapse.endpoints.EndpointDefinition;
import org.apache.synapse.util.MessageHelper;
@@ -162,7 +163,9 @@
if(axisOutMsgCtx.isSOAP11()) {
SOAPUtils.convertSOAP11toSOAP12(axisOutMsgCtx);
}
-
+
+ } else if (SynapseConstants.FORMAT_REST.equals(endpoint.getFormat())) {
+ axisOutMsgCtx.setDoingREST(true);
}
if (endpoint.isUseMTOM()) {
@@ -188,7 +191,16 @@
}
if (endpoint.getAddress() != null) {
- axisOutMsgCtx.setTo(new EndpointReference(endpoint.getAddress()));
+ if (SynapseConstants.FORMAT_REST.equals(endpoint.getFormat()) &&
+ axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX) != null) {
+ axisOutMsgCtx.setTo(
+ new EndpointReference(endpoint.getAddress() +
+ axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX)
+ ));
+ } else {
+ axisOutMsgCtx.setTo(new EndpointReference(endpoint.getAddress()));
+ }
+ axisOutMsgCtx.setProperty(NhttpConstants.ENDPOINT_PREFIX, endpoint.getAddress());
}
if (endpoint.isUseSeparateListener()) {
@@ -197,7 +209,7 @@
}
if (wsAddressingEnabled) {
-
+
if (wsAddressingVersion != null &&
SynapseConstants.ADDRESSING_VERSION_SUBMISSION.equals(wsAddressingVersion)) {
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java Sun May 24 05:33:21 2009
@@ -92,6 +92,10 @@
*/
private boolean forceSOAP12 = false;
/**
+ * force REST on ?
+ */
+ private boolean forceREST = false;
+ /**
* use MTOM *
*/
private boolean useMTOM = false;
@@ -350,6 +354,14 @@
return forceSOAP12;
}
+ public boolean isForceREST() {
+ return forceREST;
+ }
+
+ public void setForceREST(boolean forceREST) {
+ this.forceREST = forceREST;
+ }
+
public boolean isUseMTOM() {
return useMTOM;
}
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/Axis2HttpRequest.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/Axis2HttpRequest.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/Axis2HttpRequest.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/Axis2HttpRequest.java Sun May 24 05:33:21 2009
@@ -38,7 +38,6 @@
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.protocol.HTTP;
import org.apache.synapse.transport.nhttp.util.MessageFormatterDecoratorFactory;
-import org.apache.synapse.transport.nhttp.util.RESTUtil;
import org.apache.synapse.transport.nhttp.util.NhttpUtil;
import org.apache.synapse.commons.util.TemporaryData;
@@ -72,14 +71,16 @@
OMOutputFormat format = null;
private ContentOutputBuffer outputBuffer = null;
/** ready to begin streaming? */
- private boolean readyToStream = false;
+ private volatile boolean readyToStream = false;
/** The sending of this request has fully completed */
- private boolean sendingCompleted = false;
+ private volatile boolean sendingCompleted = false;
/**
* for request complete checking - request complete means the request has been fully sent
* and the response it fully received
*/
- private boolean completed = false;
+ private volatile boolean completed = false;
+ /** The URL prefix of the endpoint (to be used for Location header re-writing in the response)*/
+ private String endpointURLPrefix = null;
public Axis2HttpRequest(EndpointReference epr, HttpHost httpHost, MessageContext msgContext) {
this.epr = epr;
@@ -127,33 +128,39 @@
this.timeout = timeout;
}
+ public String getEndpointURLPrefix() {
+ return endpointURLPrefix;
+ }
+
+ public void setEndpointURLPrefix(String endpointURLPrefix) {
+ this.endpointURLPrefix = endpointURLPrefix;
+ }
+
/**
* Create and return a new HttpPost request to the destination EPR
* @return the HttpRequest to be sent out
*/
public HttpRequest getRequest() throws IOException {
- boolean doingGET = Constants.Configuration.HTTP_METHOD_GET.equals(
- msgContext.getProperty(Constants.Configuration.HTTP_METHOD));
+ String httpMethod = (String) msgContext.getProperty(Constants.Configuration.HTTP_METHOD);
+ if (httpMethod == null) {
+ httpMethod = "POST";
+ }
+ endpointURLPrefix = (String) msgContext.getProperty(NhttpConstants.ENDPOINT_PREFIX);
HttpRequest httpRequest = null;
- if (msgContext.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0)) {
-
- if (doingGET) {
-
- httpRequest = new BasicHttpRequest(
- "GET", RESTUtil.getURI(
- msgContext, epr.getAddress()), HttpVersion.HTTP_1_0);
-
- } else {
- if (msgContext.isPropertyTrue(NhttpConstants.POST_TO_PATH)) {
- httpRequest = new BasicHttpEntityEnclosingRequest(
- "POST", new URL(epr.getAddress()).getPath(), HttpVersion.HTTP_1_0);
- } else {
- httpRequest = new BasicHttpEntityEnclosingRequest(
- "POST", epr.getAddress(), HttpVersion.HTTP_1_0);
- }
-
+ if ("POST".equals(httpMethod) || "PUT".equals(httpMethod)) {
+
+ httpRequest = new BasicHttpEntityEnclosingRequest(
+ httpMethod,
+ msgContext.isPropertyTrue(NhttpConstants.POST_TO_PATH) ?
+ new URL(epr.getAddress()).getPath() : epr.getAddress(),
+ msgContext.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0) ?
+ HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1);
+
+ BasicHttpEntity entity = new BasicHttpEntity();
+
+ if (msgContext.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0)) {
TemporaryData serialized = new TemporaryData(256, 4096, "http-nio_", ".dat");
OutputStream out = serialized.getOutputStream();
try {
@@ -161,34 +168,26 @@
} finally {
out.close();
}
- BasicHttpEntity entity = new BasicHttpEntity();
msgContext.setProperty(NhttpConstants.SERIALIZED_BYTES, serialized);
entity.setContentLength(serialized.getLength());
- ((BasicHttpEntityEnclosingRequest) httpRequest).setEntity(entity);
+ } else {
+ entity.setChunked(!msgContext.isPropertyTrue(NhttpConstants.DISABLE_CHUNKING));
}
+ ((BasicHttpEntityEnclosingRequest) httpRequest).setEntity(entity);
+ httpRequest.setHeader(
+ HTTP.CONTENT_TYPE,
+ messageFormatter.getContentType(msgContext, format, msgContext.getSoapAction()));
} else {
-
- if (doingGET) {
-
- httpRequest = new BasicHttpRequest(
- "GET", RESTUtil.getURI(msgContext, epr.getAddress()));
- } else {
- if (msgContext.isPropertyTrue(NhttpConstants.POST_TO_PATH)) {
- httpRequest = new BasicHttpEntityEnclosingRequest(
- "POST", new URL(epr.getAddress()).getPath());
- } else {
- httpRequest = new BasicHttpEntityEnclosingRequest("POST", epr.getAddress());
- }
- BasicHttpEntity entity = new BasicHttpEntity();
- if (msgContext.isPropertyTrue(NhttpConstants.DISABLE_CHUNKING)) {
- entity.setChunked(false);
- }
- ((BasicHttpEntityEnclosingRequest) httpRequest).setEntity(entity);
- }
+ httpRequest = new BasicHttpRequest(
+ httpMethod,
+ msgContext.isPropertyTrue(NhttpConstants.POST_TO_PATH) ?
+ new URL(epr.getAddress()).getPath() : epr.getAddress(),
+ msgContext.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0) ?
+ HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1);
}
// set any transport headers
@@ -229,10 +228,6 @@
soapAction);
}
- httpRequest.setHeader(
- HTTP.CONTENT_TYPE,
- messageFormatter.getContentType(msgContext, format, msgContext.getSoapAction()));
-
if (NHttpConfiguration.getInstance().isKeepAliveDisabled() ||
msgContext.isPropertyTrue(NhttpConstants.NO_KEEPALIVE)) {
httpRequest.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientHandler.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientHandler.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientHandler.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientHandler.java Sun May 24 05:33:21 2009
@@ -189,9 +189,11 @@
if (axis2Req.getTimeout() > 0) {
conn.setSocketTimeout(axis2Req.getTimeout());
}
-
- conn.submitRequest(request);
+
+ context.setAttribute(NhttpConstants.ENDPOINT_PREFIX, axis2Req.getEndpointURLPrefix());
+ context.setAttribute(NhttpConstants.HTTP_REQ_METHOD, request.getRequestLine().getMethod());
context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
+ conn.submitRequest(request);
} catch (ConnectionClosedException e) {
throw e;
} catch (IOException e) {
@@ -469,10 +471,15 @@
if (context.getAttribute(NhttpConstants.DISCARD_ON_COMPLETE) != null) {
try {
// this is a connection we should not re-use
- conn.shutdown();
+ ConnectionPool.forget(conn);
+ shutdownConnection(conn);
+ context.removeAttribute(RESPONSE_SINK_BUFFER);
+ context.removeAttribute(REQUEST_SOURCE_BUFFER);
} catch (Exception ignore) {}
} else if (!connStrategy.keepAlive(response, context)) {
- conn.close();
+ shutdownConnection(conn);
+ context.removeAttribute(RESPONSE_SINK_BUFFER);
+ context.removeAttribute(REQUEST_SOURCE_BUFFER);
} else {
ConnectionPool.release(conn);
}
@@ -537,17 +544,28 @@
HttpContext context = conn.getContext();
HttpResponse response = conn.getHttpResponse();
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CONTINUE) {
+ if (log.isDebugEnabled()) {
+ log.debug("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;
+ }
+
+
// 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("Response Received for Request : " + req);
}
- if (HttpStatus.SC_CONTINUE != response.getStatusLine().getStatusCode() &&
- !req.isSendingCompleted()) {
- req.setCompleted(true);
+ if (!req.isSendingCompleted()) {
req.getMsgContext().setProperty(
NhttpConstants.ERROR_CODE, NhttpConstants.SEND_ABORT);
SharedOutputBuffer outputBuffer = (SharedOutputBuffer)
@@ -555,7 +573,11 @@
if (outputBuffer != null) {
outputBuffer.shutdown();
}
- log.warn("Remote server aborted request being sent and replied : " + conn);
+ if (log.isDebugEnabled()) {
+ log.debug("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());
@@ -631,38 +653,19 @@
return;
}
- case HttpStatus.SC_BAD_REQUEST : {
- log.error(getErrorMessage("Received bad request: "
- + response.getStatusLine().getReasonPhrase(), conn));
- return;
- }
- case HttpStatus.SC_INTERNAL_SERVER_ERROR : {
- log.error(getErrorMessage("Received an internal server error : " +
- response.getStatusLine().getReasonPhrase(), conn));
- processResponse(conn, context, response);
- return;
- }
- case HttpStatus.SC_CONTINUE : {
-
- if (log.isDebugEnabled()) {
- log.debug("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;
- }
case HttpStatus.SC_OK : {
processResponse(conn, context, response);
return;
}
default : {
- log.warn(getErrorMessage("Unexpected HTTP status code received : " +
+ if (log.isDebugEnabled()) {
+ log.debug(getErrorMessage("HTTP status code received : " +
response.getStatusLine().getStatusCode() + " :: " +
response.getStatusLine().getReasonPhrase(), conn));
+ }
- Header contentType = response.getFirstHeader(CONTENT_TYPE);
+ Header contentType = response.getFirstHeader(HTTP.CONTENT_TYPE);
if (contentType != null) {
if ((contentType.getValue().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) >= 0)
|| contentType.getValue().indexOf(
@@ -684,10 +687,12 @@
response.getStatusLine().getReasonPhrase(), conn));
}
} else {
- log.warn(getErrorMessage("Received an unexpected response - " +
- "of unknown content type with status code : " +
+ if (log.isDebugEnabled()) {
+ log.debug(getErrorMessage("Received a response - " +
+ "without a content type with status code : " +
response.getStatusLine().getStatusCode() + " and reason : " +
response.getStatusLine().getReasonPhrase(), conn));
+ }
}
processResponse(conn, context, response);
@@ -705,21 +710,55 @@
private void processResponse(final NHttpClientConnection conn, HttpContext context,
HttpResponse response) {
- ContentInputBuffer inputBuffer
+ 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;
+ }
+
+ if (expectEntityBody) {
+ inputBuffer
= new SharedInputBuffer(cfg.getBufferSize(), conn, allocator);
- context.setAttribute(RESPONSE_SINK_BUFFER, inputBuffer);
+ context.setAttribute(RESPONSE_SINK_BUFFER, inputBuffer);
- BasicHttpEntity entity = new BasicHttpEntity();
- if (response.getStatusLine().getProtocolVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
- entity.setChunked(true);
+ 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
+ ConnectionPool.forget(conn);
+ shutdownConnection(conn);
+ context.removeAttribute(RESPONSE_SINK_BUFFER);
+ context.removeAttribute(REQUEST_SOURCE_BUFFER);
+ } catch (Exception ignore) {}
+ } else {
+ ConnectionPool.release(conn);
+ }
}
- response.setEntity(entity);
- context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
workerPool.execute(
- new ClientWorker(cfgCtx, new ContentInputStream(inputBuffer), response,
- (MessageContext) context.getAttribute(OUTGOING_MESSAGE_CONTEXT)));
-
+ new ClientWorker(cfgCtx,
+ inputBuffer == null ? null : new ContentInputStream(inputBuffer),
+ response, outMsgContext, endptPrefix));
}
public void execute(Runnable task) {
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientWorker.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientWorker.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientWorker.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ClientWorker.java Sun May 24 05:33:21 2009
@@ -59,6 +59,8 @@
private InputStream in = null;
/** the HttpResponse received */
private HttpResponse response = null;
+ /** the endpoint URL prefix */
+ private String endpointURLPrefix = null;
/**
* Create the thread that would process the response message received for the outgoing message
@@ -68,11 +70,12 @@
* @param outMsgCtx the original outgoing message context (i.e. corresponding request)
*/
public ClientWorker(ConfigurationContext cfgCtx, InputStream in,
- HttpResponse response, MessageContext outMsgCtx) {
+ HttpResponse response, MessageContext outMsgCtx, String endpointURLPrefix) {
this.cfgCtx = cfgCtx;
this.in = in;
this.response = response;
+ this.endpointURLPrefix = endpointURLPrefix;
try {
responseMsgCtx = outMsgCtx.getOperationContext().
@@ -116,7 +119,16 @@
Map headerMap = new HashMap();
for (int i=0; i<headers.length; i++) {
Header header = headers[i];
- headerMap.put(header.getName(), header.getValue());
+ if ("Location".equals(header.getName())
+ && endpointURLPrefix != null
+ && outMsgCtx.getProperty(NhttpConstants.SERVICE_PREFIX) != null) {
+
+ headerMap.put(header.getName(),
+ header.getValue().replaceAll(endpointURLPrefix,
+ (String) outMsgCtx.getProperty(NhttpConstants.SERVICE_PREFIX)));
+ } else {
+ headerMap.put(header.getName(), header.getValue());
+ }
}
responseMsgCtx.setProperty(MessageContext.TRANSPORT_HEADERS, headerMap);
}
@@ -144,58 +156,63 @@
Header cType = response.getFirstHeader(HTTP.CONTENT_TYPE);
- String contentType = "";
if (cType != null) {
- contentType = cType.getValue();
- }
+ String contentType = cType.getValue();
- String charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
- if (charSetEnc == null) {
- charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
- }
+ String charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
+ if (charSetEnc == null) {
+ charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
+ }
- if (contentType.indexOf(HTTP.CHARSET_PARAM) > 0) {
- responseMsgCtx.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEnc);
- } else {
- responseMsgCtx.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
- MessageContext.DEFAULT_CHAR_SET_ENCODING);
- }
- // workaround for Axis2 TransportUtils.createSOAPMessage() issue, where a response
- // of content type "text/xml" is thought to be REST if !MC.isServerSide(). This
- // question is still under debate and due to the timelines, I am commiting this
- // workaround as Axis2 1.2 is about to be released and Synapse 1.0
- responseMsgCtx.setServerSide(false);
- try {
- envelope = TransportUtils.createSOAPMessage(
- responseMsgCtx,
- HTTPTransportUtils.handleGZip(responseMsgCtx, in),
- contentType);
- } catch (OMException e) {
- // handle non SOAP and POX/REST payloads (probably text/html)
- String errorMessage = "Unexpected response received. HTTP response code : "
- + this.response.getStatusLine().getStatusCode() + " HTTP status : "
- + this.response.getStatusLine().getReasonPhrase() + " exception : "
- + e.getMessage();
-
- log.warn(errorMessage);
- if (log.isDebugEnabled()) {
- log.debug(errorMessage, e);
- log.debug("Creating the SOAPFault to be injected...");
+ responseMsgCtx.setProperty(
+ Constants.Configuration.CHARACTER_SET_ENCODING,
+ contentType.indexOf(HTTP.CHARSET_PARAM) > 0 ?
+ charSetEnc : MessageContext.DEFAULT_CHAR_SET_ENCODING);
+
+ // workaround for Axis2 TransportUtils.createSOAPMessage() issue, where a response
+ // of content type "text/xml" is thought to be REST if !MC.isServerSide(). This
+ // question is still under debate and due to the timelines, I am commiting this
+ // workaround as Axis2 1.2 is about to be released and Synapse 1.0
+ responseMsgCtx.setServerSide(false);
+ try {
+ envelope = TransportUtils.createSOAPMessage(
+ responseMsgCtx,
+ HTTPTransportUtils.handleGZip(responseMsgCtx, in),
+ contentType);
+
+ } catch (OMException e) {
+ // handle non SOAP and POX/REST payloads (probably text/html)
+ String errorMessage = "Unexpected response received. HTTP response code : "
+ + this.response.getStatusLine().getStatusCode() + " HTTP status : "
+ + this.response.getStatusLine().getReasonPhrase() + " exception : "
+ + e.getMessage();
+
+ log.warn(errorMessage);
+ if (log.isDebugEnabled()) {
+ log.debug(errorMessage, e);
+ log.debug("Creating the SOAPFault to be injected...");
+ }
+ SOAPFactory factory = new SOAP11Factory();
+ envelope = factory.getDefaultFaultEnvelope();
+ SOAPFaultDetail detail = factory.createSOAPFaultDetail();
+ detail.setText(errorMessage);
+ envelope.getBody().getFault().setDetail(detail);
+ SOAPFaultReason reason = factory.createSOAPFaultReason();
+ reason.setText(errorMessage);
+ envelope.getBody().getFault().setReason(reason);
+ SOAPFaultCode code = factory.createSOAPFaultCode();
+ code.setText(Integer.toString(this.response.getStatusLine().getStatusCode()));
+ envelope.getBody().getFault().setCode(code);
}
- SOAPFactory factory = new SOAP11Factory();
- envelope = factory.getDefaultFaultEnvelope();
- SOAPFaultDetail detail = factory.createSOAPFaultDetail();
- detail.setText(errorMessage);
- envelope.getBody().getFault().setDetail(detail);
- SOAPFaultReason reason = factory.createSOAPFaultReason();
- reason.setText(errorMessage);
- envelope.getBody().getFault().setReason(reason);
- SOAPFaultCode code = factory.createSOAPFaultCode();
- code.setText(Integer.toString(this.response.getStatusLine().getStatusCode()));
- envelope.getBody().getFault().setCode(code);
+ responseMsgCtx.setServerSide(true);
+ responseMsgCtx.setEnvelope(envelope);
+
+ } else {
+ // there is no response entity-body
+ responseMsgCtx.setProperty(NhttpConstants.NO_ENTITY_BODY, Boolean.TRUE);
+ responseMsgCtx.setEnvelope(new SOAP11Factory().getDefaultEnvelope());
}
- responseMsgCtx.setServerSide(true);
- responseMsgCtx.setEnvelope(envelope);
+
// copy the HTTP status code as a message context property with the key HTTP_SC to be
// used at the sender to set the propper status code when passing the message
int statusCode = this.response.getStatusLine().getStatusCode();
@@ -204,6 +221,9 @@
responseMsgCtx.setProperty(NhttpConstants.FAULT_MESSAGE, NhttpConstants.TRUE);
}
responseMsgCtx.setProperty(NhttpConstants.NON_BLOCKING_TRANSPORT, true);
+ if (endpointURLPrefix != null) {
+ responseMsgCtx.setProperty(NhttpConstants.ENDPOINT_PREFIX, endpointURLPrefix);
+ }
// process response received
try {
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HttpCoreNIOSender.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HttpCoreNIOSender.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HttpCoreNIOSender.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HttpCoreNIOSender.java Sun May 24 05:33:21 2009
@@ -427,10 +427,12 @@
OMOutputFormat format = NhttpUtil.getOMOutputFormat(msgContext);
MessageFormatter messageFormatter =
MessageFormatterDecoratorFactory.createMessageFormatterDecorator(msgContext);
- response.setHeader(
- HTTP.CONTENT_TYPE,
- messageFormatter.getContentType(msgContext, format, msgContext.getSoapAction()));
-
+ Boolean noEntityBody = (Boolean) msgContext.getProperty(NhttpConstants.NO_ENTITY_BODY);
+ if (noEntityBody == null || Boolean.FALSE == noEntityBody) {
+ response.setHeader(
+ HTTP.CONTENT_TYPE,
+ messageFormatter.getContentType(msgContext, format, msgContext.getSoapAction()));
+ }
response.setStatusCode(determineHttpStatusCode(msgContext, response));
// set any transport headers
@@ -456,7 +458,8 @@
* if this is a dummy message to handle http 202 case with non-blocking IO
* write an empty byte array as body
*/
- if (msgContext.isPropertyTrue(NhttpConstants.SC_ACCEPTED)) {
+ if (msgContext.isPropertyTrue(NhttpConstants.SC_ACCEPTED)
+ || Boolean.TRUE == noEntityBody) {
out.write(new byte[0]);
} else {
messageFormatter.writeTo(msgContext, format, out, false);
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java Sun May 24 05:33:21 2009
@@ -77,4 +77,10 @@
public static final int CONNECT_TIMEOUT = 101508;
public static final int SEND_ABORT = 101509;
// ********** DO NOT CHANGE THESE UNLESS CORRESPONDING SYNAPSE CONSTANT ARE CHANGED ************
+
+ public static final String REST_URL_POSTFIX = "REST_URL_POSTFIX";
+ public static final String SERVICE_PREFIX = "SERVICE_PREFIX";
+ public static final String HTTP_REQ_METHOD = "HTTP_REQ_METHOD";
+ public static final String NO_ENTITY_BODY = "NO_ENTITY_BODY";
+ public static final String ENDPOINT_PREFIX = "ENDPOINT_PREFIX";
}
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerHandler.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerHandler.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerHandler.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerHandler.java Sun May 24 05:33:21 2009
@@ -115,18 +115,19 @@
HttpRequest request = conn.getHttpRequest();
context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
- // Mark request as not yet fully read, to detect timeouts from harmless keepalive deaths
- conn.getContext().setAttribute(NhttpConstants.REQUEST_READ, Boolean.FALSE);
-
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);
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java Sun May 24 05:33:21 2009
@@ -21,6 +21,7 @@
import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
+import org.apache.axis2.builder.BuilderUtil;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
@@ -31,6 +32,7 @@
import org.apache.axis2.transport.base.MetricsCollector;
import org.apache.axis2.transport.http.HTTPTransportReceiver;
import org.apache.axis2.transport.http.HTTPTransportUtils;
+import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.MessageContextBuilder;
import org.apache.axis2.wsdl.WSDLConstants;
@@ -189,10 +191,64 @@
public void run() {
String method = request.getRequestLine().getMethod().toUpperCase();
+ msgContext.setProperty(Constants.Configuration.HTTP_METHOD,
+ request.getRequestLine().getMethod());
+
+ String uri = request.getRequestLine().getUri();
+ String oriUri = uri;
+
+ if (uri.indexOf(cfgCtx.getServicePath()) != -1) {
+ // discard upto servicePath
+ uri = uri.substring(uri.indexOf(cfgCtx.getServicePath()) +
+ cfgCtx.getServicePath().length());
+ // discard [proxy] service name if any
+ int pos = uri.indexOf("/", 1);
+ if (pos > 0) {
+ uri = uri.substring(pos);
+ } else {
+ pos = uri.indexOf("?");
+ if (pos != -1) {
+ uri = uri.substring(pos);
+ } else {
+ uri = "";
+ }
+ }
+ } else {
+ // remove any absolute prefix if any
+ int pos = uri.indexOf("://");
+ if (pos != -1) {
+ uri = uri.substring(pos + 3);
+ pos = uri.indexOf("/");
+ if (pos != -1) {
+ uri = uri.substring(pos + 1);
+ }
+ }
+ }
+ msgContext.setProperty(NhttpConstants.REST_URL_POSTFIX, uri);
+ String servicePrefix = oriUri.substring(0, oriUri.indexOf(uri));
+ if (servicePrefix.indexOf("://") == -1) {
+ HttpInetConnection inetConn = (HttpInetConnection) conn;
+ InetAddress localAddr = inetConn.getLocalAddress();
+ servicePrefix = (isHttps ? "https://" : "http://") +
+ localAddr.getHostName() + ":" + inetConn.getLocalPort() + servicePrefix;
+ }
+ msgContext.setProperty(NhttpConstants.SERVICE_PREFIX, servicePrefix);
+
+
if ("GET".equals(method)) {
processGet();
} else if ("POST".equals(method)) {
- processPost();
+ processEntityEnclosingMethod();
+ } else if ("PUT".equals(method)) {
+ processEntityEnclosingMethod();
+ } else if ("HEAD".equals(method)) {
+ processNonEntityEnclosingMethod();
+ } else if ("OPTIONS".equals(method)) {
+ processNonEntityEnclosingMethod();
+ } else if ("DELETE".equals(method)) {
+ processNonEntityEnclosingMethod();
+ } else if ("TRACE".equals(method)) {
+ processNonEntityEnclosingMethod();
} else {
handleException("Unsupported method : " + method, null);
}
@@ -279,16 +335,21 @@
/**
*
*/
- private void processPost() {
+ private void processEntityEnclosingMethod() {
try {
Header contentType = request.getFirstHeader(HTTP.CONTENT_TYPE);
+ String contentTypeStr = contentType != null ? contentType.getValue() : null;
+
+ String charSetEncoding = BuilderUtil.getCharSetEncoding(contentTypeStr);
+ msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEncoding);
+
Header soapAction = request.getFirstHeader(SOAPACTION);
HTTPTransportUtils.processHTTPPostRequest(
msgContext, is,
os,
- (contentType != null ? contentType.getValue() : null),
+ contentTypeStr,
(soapAction != null ? soapAction.getValue() : null),
request.getRequestLine().getUri());
} catch (AxisFault e) {
@@ -297,6 +358,22 @@
}
/**
+ * Process HEAD, DELETE, TRACE, OPTIONS
+ */
+ private void processNonEntityEnclosingMethod() {
+
+ try {
+ RESTUtil.processURLRequest(
+ msgContext, os, null,
+ request.getRequestLine().getUri());
+
+ } catch (AxisFault e) {
+ handleException("Error processing " + request.getRequestLine().getMethod() +
+ " request for : " + request.getRequestLine().getUri(), e);
+ }
+ }
+
+ /**
*
*/
private void processGet() {
@@ -344,11 +421,6 @@
msgContext.setTo(new EndpointReference(uri));
}
- if ("GET".equalsIgnoreCase(request.getRequestLine().getMethod())) {
- msgContext.setProperty(Constants.Configuration.HTTP_METHOD,
- Constants.Configuration.HTTP_METHOD_GET);
- }
-
if (uri.equals("/favicon.ico")) {
response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY);
response.addHeader(LOCATION, "http://ws.apache.org/favicon.ico");
@@ -501,20 +573,14 @@
} else {
try {
- if (RESTUtil.processURLRequest(
+ RESTUtil.processGETRequest(
msgContext, os, (request.getFirstHeader(SOAPACTION) != null ?
request.getFirstHeader(SOAPACTION).getValue() : null),
- request.getRequestLine().getUri(), cfgCtx, parameters)) {
- // If RestUtil succesfully decoded the request, do not let the output
- // stream close (as by default below) since we are serving this GET request
- // through the Synapse engine
- return;
- } else {
- response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY);
- response.addHeader(LOCATION, servicePath + "/");
- serverHandler.commitResponseHideExceptions(conn, response);
- }
-
+ request.getRequestLine().getUri(), cfgCtx, parameters);
+ // do not let the output stream close (as by default below) since
+ // we are serving this GET request through the Synapse engine
+ return;
+
} catch (AxisFault axisFault) {
handleException("Error processing GET request for: " +
request.getRequestLine().getUri(), axisFault);
Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java?rev=778087&r1=778086&r2=778087&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java Sun May 24 05:33:21 2009
@@ -34,6 +34,7 @@
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.transport.http.util.URIEncoderDecoder;
import org.apache.axis2.util.Utils;
+import org.apache.synapse.transport.nhttp.NhttpConstants;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
@@ -126,8 +127,9 @@
* @return boolean indication whether the operation was succesfull
* @throws AxisFault - Thrown in case a fault occurs
*/
- public static boolean processURLRequest(MessageContext msgContext, OutputStream out,
- String soapAction, String requestURI, ConfigurationContext configurationContext,
+ public static void processGETRequest(MessageContext msgContext, OutputStream out,
+ String soapAction, String requestURI,
+ ConfigurationContext configurationContext,
Map requestParameters) throws AxisFault {
if ((soapAction != null) && soapAction.startsWith("\"") && soapAction.endsWith("\"")) {
@@ -138,17 +140,40 @@
msgContext.setTo(new EndpointReference(requestURI));
msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
msgContext.setServerSide(true);
- SOAPEnvelope envelope = createEnvelopeFromGetRequest(
- requestURI, requestParameters, configurationContext);
+ msgContext.setDoingREST(true);
+ msgContext.setEnvelope(createEnvelopeFromGetRequest(
+ requestURI, requestParameters, configurationContext));
+ msgContext.setProperty(NhttpConstants.NO_ENTITY_BODY, Boolean.TRUE);
+ AxisEngine.receive(msgContext);
+ }
- if (envelope == null) {
- return false;
- } else {
- msgContext.setDoingREST(true);
- msgContext.setEnvelope(envelope);
- AxisEngine.receive(msgContext);
- return true;
+ /**
+ * Processes the HTTP GET request and builds the SOAP info-set of the REST message
+ *
+ * @param msgContext The MessageContext of the Request Message
+ * @param out The output stream of the response
+ * @param soapAction SoapAction of the request
+ * @param requestURI The URL that the request came to
+ * @param configurationContext The Axis Configuration Context
+ * @param requestParameters The parameters of the request message
+ * @return boolean indication whether the operation was succesfull
+ * @throws AxisFault - Thrown in case a fault occurs
+ */
+ public static void processURLRequest(MessageContext msgContext, OutputStream out,
+ String soapAction, String requestURI) throws AxisFault {
+
+ if ((soapAction != null) && soapAction.startsWith("\"") && soapAction.endsWith("\"")) {
+ soapAction = soapAction.substring(1, soapAction.length() - 1);
}
+
+ msgContext.setSoapAction(soapAction);
+ msgContext.setTo(new EndpointReference(requestURI));
+ msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
+ msgContext.setServerSide(true);
+ msgContext.setDoingREST(true);
+ msgContext.setEnvelope(new SOAP11Factory().getDefaultEnvelope());
+ msgContext.setProperty(NhttpConstants.NO_ENTITY_BODY, Boolean.TRUE);
+ AxisEngine.receive(msgContext);
}
/**
@@ -161,7 +186,7 @@
* @return created SOAPEnvelope or null if cannot be processed
* @throws AxisFault if the service represented by the GET request URL cannot be found
*/
- public static SOAPEnvelope createEnvelopeFromGetRequest(String requestUrl, Map map,
+ private static SOAPEnvelope createEnvelopeFromGetRequest(String requestUrl, Map map,
ConfigurationContext configCtx) throws AxisFault {
String[] values = Utils.parseRequestURLForServiceAndOperation(