On 16/12/2018 03:01, Kohei Nozaki wrote:
> Hello,
>
> It turned out that the "sjsxp" library which JAX-WS RI v2.1.3 uses makes
> Tomcat behave this way. I tried a different version of JAX-WS RI (v2.1.7)
> which doesn't use the "sjsxp" library anymore and it solved the issue.
Thanks for reporting back when you found a solution.
> A very similar issue posted on the Metro mailing list:
> http://metro.1045641.n5.nabble.com/JAX-WS-RI-2-1-5-returning-malformed-response-tp1063518.html
>
> It's surprising that a bug of a framework which is built on the Servlet API
> can make such an issue happen, but anyway thank you very much everyone who
> helped me out.
I'm guessing it held onto a reference and re-used it when it shouldn't.
That can cause all sorts of chaos.
Mark
>
> Regards,
> Kohei
>
>> On Dec 4, 2018, at 3:39, Christopher Schultz
>> wrote:
>>
> Kohei,
>
> On 12/1/18 10:06, Kohei Nozaki wrote:
Hello Konstantin, thanks for sharing the valuable information.
> On Dec 1, 2018, at 19:00, Konstantin Kolinko
> wrote:
>
>> * Our downstream Nginx instance (The client of our Tomcat
>> instance) recorded the error "upstream sent no valid HTTP/1.0
>> header while reading response header from upstream" at that
>> time and the error makes perfect sense concerning the response
>> which has neither HTTP status line nor HTTP headers.
>
> 1. See the official FAQ / Troubleshoting page:
> https://wiki.apache.org/tomcat/FAQ/Troubleshooting_and_Diagnostics
>
>
>
> Especially pay attention to
> 1) configuring an access log 2) setting system property
> org.apache.catalina.connector.RECYCLE_FACADES=true
I've investigated "RECYCLE_FACADES" and understand that an
improperly implemented application which keeps a reference to
Request or Response objects outside of their lifecycle can make
such an issue like mine happen (please correct me if I'm wrong..).
But I still don't quite understand what does "RECYCLE_FACADES=true"
do. The Wiki page says "This makes it easier to spot illegal access
when it happens, instead of waiting until side effects of such
access become visible" but how does it make easier? Does this
property make Tomcat produce an Exception or make Tomcat produce
some warning message to a log file or something when such accesses
happen, for example?
>
> Tomcat usually handles requests something like this. Imagine a
> single-threaded server where Tomcat only accepts a single connection
> at a time (just to simplify the code to the point where it fits into a
> ML post).
>
> Many of these methods are made-up. There is no
> TomcatHttpServletRequest class or a .setRequestLine method in it
> (though there are ... siilar concepts in there, way down deep). The
> point is how the objects are used, or rather *re* used.
>
> HttpServletRequest request = new TomcatHttpServletRequest();
> HttpServletResponse response = new TomcatHttpServletResponse();
>
> Connection conn = null;
>
> while(null != (conn = socket.acceptConnection()) {
>request.setRequestLine(conn.getRequestLine());
>request.setInputStream(conn.getInputStream());
>response.setOutputStream(conn.getOutputStream());
>
>Servlet servlet = getServletForRequest(request);
>if(null == servlet)
>servlet = defaultServlet;
>
>servlet.service(request, response);
>
>request.reset();
>response.reset();
> }
>
> In "real" Tomcat, each Connection object holds its own Request and
> Response objects ad manages them in a similar way, and of course,
> Tomcat can accept multiple simultaneous connections -- including
> multiple requests over a single connection -- simultaneously -- in the
> case of HTTP/2.
>
> If you enable the RECYCLE_FACADES in Tomcat, the code changes to
> behave like this:
>
> Connection conn = null;
>
> while(null != (conn = socket.acceptConnection()) {
>HttpServletRequest request = new TomcatHttpServletRequest();
>HttpServletResponse response = new TomcatHttpServletResponse();
>request.setRequestLine(conn.getRequestLine());
>request.setInputStream(conn.getInputStream());
>response.setOutputStream(conn.getOutputStream());
>
>Servlet servlet = getServletForRequest(request);
>if(null == servlet)
>servlet = defaultServlet;
>
>servlet.service(request, response);
>
>request.dispose();
>response.dispose();
> }
>
> Note how the request and response objects are no longer re-used across
> requests. This represents a trade-off between security/stability
> (always getting a fresh object) versus performance (less
> garbage-collection for a given request). An application can do things
> to the request or response that can break the way the server works, so
> an untrusted application should always be run with RECYCLE_FACADES set
> to ON.
>
> If the application keeps a reference to a request or response object
> after the request