WAR deployment under linux tomcat 7

66 views
Skip to first unread message

gcr...@gmail.com

unread,
Sep 22, 2015, 8:30:59 PM9/22/15
to membrane-monitor

Hi,

I am attempting to deploy the membrane war - version 4.0.26 under Apache Tomcat Version 7.0.52 on Linux. I get the following error -

2015-09-23 10:22:15,709 [localhost-startStop-3] (ApplicationContext.java:730) INFO  - No Spring WebApplicationInitializer types detected on classpath

Any ideas?

Regards,
Gary

run...@gmail.com

unread,
Oct 27, 2015, 5:54:02 AM10/27/15
to membrane-monitor, gcr...@gmail.com
4.1.0 deployed fine in Tomcat 7, but it has issues with chunked encoding...

Tobias Polley

unread,
Oct 27, 2015, 5:59:50 AM10/27/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Hi runger1,

the <headerFilter>...<exclude>Transfer-Encoding</exclude>...</headerFilter> in
https://github.com/membrane/service-proxy/blob/master/war/src/main/webapp/WEB-INF/proxies.xml should take care of the chunking.

Can you share your proxies.xml?

Best, Tobias

run...@gmail.com

unread,
Oct 27, 2015, 6:39:22 AM10/27/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Hi,

Thanks for the response. We have the <headerFilter> in there, but I think this works too late. createBody() is called  first thing in com.predic8.membrane.servlet.embedded.HttpServletHandler.run() quite a bit before invokeHandlers...

Our proxies.xml looks like this:

<spring:beans xmlns="http://membrane-soa.org/proxies/1/"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="http://membrane-soa.org/war/1/"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://membrane-soa.org/proxies/1/ http://membrane-soa.org/schemas/proxies-1.xsd
   http://membrane-soa.org/war/1/ http://membrane-soa.org/schemas/war-1.xsd">
     

<limitedMemoryExchangeStore id="memoryExchangeStore" />

<router hotDeploy="false" exchangeStore="memoryExchangeStore">

<web:servletTransport id="transport">
<headerFilter>
<exclude>Connection</exclude>
<exclude>Content-Encoding</exclude>
<exclude>Content-Length</exclude>
<exclude>Content-MD5</exclude>
<exclude>Server</exclude>
<exclude>Transfer-Encoding</exclude>
<exclude>X-Powered-By</exclude>
</headerFilter>
<ruleMatching />
<exchangeStore name="memoryExchangeStore" />
<dispatching />
<reverseProxying />
<userFeature />
<httpClient />
</web:servletTransport>


<!-- Sets up the Administration Web Interface below "/admin". -->
   <serviceProxy>
    <path isRegExp="true">^/admin.*</path>
    <basicAuthentication>
<user name="admin" password="membrane" />
</basicAuthentication>
<adminConsole />
   </serviceProxy>
        

               <soapProxy wsdl="http://xxxxxxxx:8084/xyz1.wsdl">
               </soapProxy>
               <soapProxy wsdl="http://xxxxxxx:8084/xyz2.wsdl">
               </soapProxy>

</router>

</spring:beans>

Any ideas?

Thank you very much from Vienna,

Richard

Tobias Polley

unread,
Oct 27, 2015, 11:29:24 AM10/27/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Hi Richard,

you are correct. HttpServerHandler.createHeader() should probably drop the "Transfer-Encoding" header the same way .writeResponse() already does.

Best, Tobias

run...@gmail.com

unread,
Oct 28, 2015, 5:33:41 AM10/28/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Hi Tobias,

Thank you very much for the quick responses and confirming this for us.

I will create a patched 4.1 branch for us.

Are you associated with the project? Is there anything I should do to bring this issue to a solution in the next release version?

Regards from Vienna,

Richard

run...@gmail.com

unread,
Nov 11, 2015, 9:07:49 AM11/11/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Dear Tobias,

It turned out to be considerably more difficult than simply stripping the header....
I have now solved the problem with a patched version, but I can't imagine Membrane 4.1 actually works inside tomcat for other users either.

The underlying issue is that Membrane and the Request/Response/Message objects assume a symmetry regarding chunked encoding, ie if the incoming request is chunked then the outgoing request must be too, if the incoming response is chunked then the outgoing response must be too...

When running Membrane in tomcat, this logic is not correct.
Instead, messages passing through tomcat's connector (ie the incoming request and the outgoing response) must never be processed for chunks, tomcat will always take care of that.
On the other hand the messages passing through membrane's HttpClient (ie the outgoing request and the incoming response) always need processing for chunks.

As is membrane gets it all wrong, and there is no way to fix that just by stripping out (or leaving in) the header...  instead you need to "know" what stage you're at when writing the message to the outputstream, and either process chunks or not, accordingly.

I do hope someone takes a look at this for the real release, as I do think running membrane in a servlet container or embedded in another application is an important use case.



On Tuesday, October 27, 2015 at 4:29:24 PM UTC+1, Tobias Polley wrote:

run...@gmail.com

unread,
Nov 11, 2015, 9:12:03 AM11/11/15
to membrane-monitor, gcr...@gmail.com, run...@gmail.com
Some more details - here are the relevant places in the code that needed looking at, and my analysis:



Create incoming request:
{looks good, now strips out Transfer-Encoding header}

com.predic8.membrane.servlet.embedded.HttpServletHandler.createRequest()
--> com.predic8.membrane.core.http.Request.create(String, String, String, Header, InputStream)
------> com.predic8.membrane.core.http.Request.createBody(InputStream)
----------> com.predic8.membrane.core.http.Message.createBody(InputStream)



Create incoming response:
{looks good, uses chunked / unchunked as indicated by header}

com.predic8.membrane.core.transport.http.HttpClient.doCall(Exchange, Connection)
--> com.predic8.membrane.core.http.Response.read(InputStream, boolean)
------> com.predic8.membrane.core.http.Response.createBody(InputStream)
----------> com.predic8.membrane.core.http.Message.createBody(InputStream)



Create outgoing request:
{bad - writes unchunked in all cases, and without content-length. Need to add handling}

com.predic8.membrane.core.transport.http.HttpClient.doCall(Exchange, Connection)
--> com.predic8.membrane.core.http.Message.write(OutputStream)
------> com.predic8.membrane.core.http.AbstractBody.write(AbstractBodyTransferrer)
----------> com.predic8.membrane.core.http.AbstractBody.writeAlreadyRead(AbstractBodyTransferrer)
----------> com.predic8.membrane.core.http.AbstractBody.writeNotRead(AbstractBodyTransferrer)
(see ChunkedBody, PlainTextBody, etc...)



Create outgoing response:
{looks good, using PlainBodyTransferrer - missing ContentLength in some cases??}

com.predic8.membrane.servlet.embedded.HttpServletHandler.writeResponse(Response)
--> com.predic8.membrane.core.http.AbstractBody.write(AbstractBodyTransferrer)
------> com.predic8.membrane.core.http.AbstractBody.writeAlreadyRead(AbstractBodyTransferrer)
------> com.predic8.membrane.core.http.AbstractBody.writeNotRead(AbstractBodyTransferrer)
----------> using com.predic8.membrane.core.http.PlainBodyTransferrer


And here's how I finally changed the com.predic8.membrane.core.http.Message.write(OutputStream) method to fix the problem:

public final void write(OutputStream out) throws IOException {
// add chunked encoding here if it is missing. This is to make ALL outgoing messages chunked
// because messages written via this method go out the HttpClient, and are not subject to tomcat "auto-chunking"
// we make all messages chunked because the chunked/content-length headers get stripped out during processing.
boolean added = false;
if (header.getNumberOf(Header.TRANSFER_ENCODING)<1){
header.add(Header.TRANSFER_ENCODING, Header.CHUNKED);
added = true;
}
writeStartLine(out);
header.write(out);
out.write(Constants.CRLF_BYTES);
if (header.is100ContinueExpected()) {
out.flush();
return;
}
// when running in WAR / embedded mode in tomcat, the body never arrives chunked
// we prevent this block from running by stripping out the "transfer-encoding: chunked" header...
body.write(getHeader().isChunked() ? new ChunkedBodyTransferrer(out) : new PlainBodyTransferrer(out));
if (added)
header.removeFields(Header.TRANSFER_ENCODING);
out.flush();
}


On Tuesday, October 27, 2015 at 4:29:24 PM UTC+1, Tobias Polley wrote:
Reply all
Reply to author
Forward
0 new messages