Hi, Mark and Tomcat team, Thank you for your support so far and I will take it up with Firefox. I will look into CSP as well. Thanks for checking this.
Thanks, Bhavesh On Sat, Mar 18, 2023 at 4:56 AM Mark Thomas <ma...@apache.org> wrote: > That looks like a browser bug then. You'll need to raise that with Firefox. > > Also, the CSP doesn't look quite right. > > "...form-action 'self'; https:;..." > > should probably be: > > "...form-action 'self' https:;..." > > Mark > > > On 17/03/2023 23:34, Bhavesh Mistry wrote: > > Hi Tomcat Team and Mark, > > > > I am able to reproduce the problem with your sample app. *CSP large > > header is causing this problem we attached it to ALL responses. This > > custom header. I am not sure if this is a tomcat issue or Firefox. *We > > get *NS_ERROR_ABORT*. Sorry, it took a while but the issue is > > reproducible with CSP or Large header. > > > > Sample: > > > https://github.com/bmistry13/tomat-204-issue/blob/main/no-content-test.war > < > https://github.com/bmistry13/tomat-204-issue/blob/main/no-content-test.war > > > > > > web.xml > > <web-app > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance > > <http://www.w3.org/2001/XMLSchema-instance>" > > xmlns="http://java.sun.com/xml/ns/javaee > > <http://java.sun.com/xml/ns/javaee>" > > xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd > > <http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd>" > > xsi:schemaLocation="http://java.sun.com/xml/ns/javaee > > <http://java.sun.com/xml/ns/javaee> > > https://java.sun.com/xml/ns/javaee/web-app_4_0.xsd > > <https://java.sun.com/xml/ns/javaee/web-app_4_0.xsd>" > > id="Versa" > > version="4.0"> > > > > <display-name>testa</display-name> > > > > * <servlet> > > <description>TESTServlet</description> > > <servlet-name>AjaxTestServlet</servlet-name> > > <servlet-class>AjaxServletTest</servlet-class> > > </servlet> > > > > <servlet-mapping> > > <servlet-name>AjaxTestServlet</servlet-name> > > <url-pattern>/test</url-pattern> > > </servlet-mapping>* > > <session-config> > > <session-timeout>60</session-timeout> > > <tracking-mode>COOKIE</tracking-mode> > > <cookie-config> > > <http-only>true</http-only> > > <secure>true</secure> > > </cookie-config> > > </session-config> > > <security-constraint> > > <web-resource-collection> > > <web-resource-name>HTTPSOnly</web-resource-name> > > <url-pattern>/*</url-pattern> > > </web-resource-collection> > > </security-constraint> > > <security-constraint> > > <auth-constraint> > > <!-- empty constraint: forbid all access --> > > </auth-constraint> > > </security-constraint> > > <mime-mapping> > > <extension>js</extension> > > <mime-type>application/javascript</mime-type> > > </mime-mapping> > > </web-app> > > ~ > > > > --- JSP change > > > > <html> > > > > <body> > > <script type="text/javascript" > > src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js > > <http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js > >"></script> > > <script type="text/javascript"> > > function test() { > > > > for (let i = 5; i < 10; i++) { > > $.ajax({ > > async: true, > > type: "GET", > > url: "/no-content-test/test?q=test1", > > contentType: "application/json; charset=utf-8", > > dataType: "json", > > success: function (response) { > > alert(response.status); > > } > > }); > > } > > for (let i = 5; i < 10; i++) { > > $.ajax({ > > async: true, > > type: "GET", > > url: "/no-content-test/test?q=test2", > > contentType: "application/json; charset=utf-8", > > dataType: "json", > > success: function (response) { > > alert(response.d); > > } > > }); > > } > > } > > </script> > > <p>Clinking on button to ajax test <input type='button' > > onclick='test();' value='Click Me and See Dev Tool Netowrk Tab'/></p> > > </body> > > </html> > > ------ > > > > import javax.servlet.ServletException; > > import javax.servlet.http.HttpServlet; > > import javax.servlet.http.HttpServletRequest; > > import javax.servlet.http.HttpServletResponse; > > import java.io.IOException; > > > > public class AjaxServletTest extends HttpServlet { > > > > private static final String CSP_HEADER ="Content-Security-Policy"; > > > > private static final String CSP_HEADER_POLICY ="default-src 'self' > https:;font-src 'self' data: > > https://fonts.googleapis.com/ <https://fonts.googleapis.com/> > > https://fonts.gstatic.com <https://fonts.gstatic.com>; script-src > 'self' " + > > "'sha256-BdZ62JYXk9kaPAizrIertjvay2mtb//aXKRFuOz6RLI=' > > 'sha256-Rv1DFftLIYbmrwNcvKH3vd+fs4aXTb6/RNjTs7CLJOg=' " + > > "'sha256-BDvo3wEMDWiXAoVw9mYgGW9GCvsvo3ECBHjc4FzPky8=' > 'unsafe-eval' > > https://maps.googleapis.com/maps/api/geocode/json > > <https://maps.googleapis.com/maps/api/geocode/json> > > https://maps.googleapis.com/ <https://maps.googleapis.com/> " + > > "https://*.tile.openstreetmap.org < > http://tile.openstreetmap.org> > > https://export.highcharts.com/ <https://export.highcharts.com/> > > https://code.highcharts.com/ <https://code.highcharts.com/>; img-src > > 'self' blob: " + > > "data: https://maps.googleapis.com/maps/api/geocode/json > > <https://maps.googleapis.com/maps/api/geocode/json> > > https://maps.gstatic.com/ <https://maps.gstatic.com/> > > https://maps.googleapis.com/ <https://maps.googleapis.com/> > > https://*.tile.openstreetmap.org <http://tile.openstreetmap.org> " + > > "https://chart.apis.google.com/ < > https://chart.apis.google.com/> > > https://export.highcharts.com/ <https://export.highcharts.com/>; > > style-src 'self' 'unsafe-inline' data: " + > > "https://maps.googleapis.com/maps/api/geocode/json > > <https://maps.googleapis.com/maps/api/geocode/json> > > https://*.tile.openstreetmap.org <http://tile.openstreetmap.org> " + > > "https://fonts.googleapis.com/ < > https://fonts.googleapis.com/> > > https://export.highcharts.com/ <https://export.highcharts.com/> " + > > "https://code.highcharts.com/;form-action > > <https://code.highcharts.com/;form-action> 'self'; https:; > > block-all-mixed-content; connect-src 'self' wss://self:6080 data: > > https://maps.googleapis.com <https://maps.googleapis.com> > > https://*.tile.openstreetmap.org/ <http://tile.openstreetmap.org/> > > https://ipapi.co <https://ipapi.co> https://oauth2.googleapis.com/token > > <https://oauth2.googleapis.com/token> https://dialogflow.googleapis.com > > <https://dialogflow.googleapis.com>"; > > > > public void doGet(HttpServletRequest req,HttpServletResponse > resp)throws ServletException,IOException { > > resp.setStatus(204); > > resp.setHeader(CSP_HEADER,CSP_HEADER_POLICY); > > } > > } > > > > > > On Wed, Mar 15, 2023 at 11:30 AM Bhavesh Mistry > > <mistry.p.bhav...@gmail.com <mailto:mistry.p.bhav...@gmail.com>> wrote: > > > > Hi Mark and Tomcat Team, > > > > We have been using tomcat 9 from version 0 to 70 and no issues so > > far with our application and firefox. We also tried to upgrade to > > 9.0.73, and show the same issue: > > > > As you can see from Devtools it is missing Protocol HTTP2 and > > is hung there. > > image.png > > > > [04/Mar/2023:00:40:47 +0000] 10.40.207.127 - > > https-jsse-nio-127.0.0.1-8443-exec-54 Administrator "GET > > /versa/ncs-services/vnms/analyticgroup/all *HTTP/2.0*" 204 - 148ms > 148ms > > > > > > Any clue you have in the filter or why it might be 204 response > > caused firefox to be hung? we have added a custom header to the > > response that is all. I remove them still same issue. Any theory > > or clue you have further to debug this notorious issue? > > > > Thanks, > > > > > > Bhavesh > > > > > > On Thu, Mar 9, 2023 at 11:54 AM Mark Thomas <ma...@apache.org > > <mailto:ma...@apache.org>> wrote: > > > > On 09/03/2023 18:19, Bhavesh Mistry wrote: > > > Hi Mark, > > > > > > Your sample application worked 204 Firefox and our > > application does not > > > work. That leads me to believe *Application Filter *is an > > issue. But > > > should tomcat throw an exception if the response is already > > committed? > > > > A call to setStatus() after the response has been committed will > > be a NO-OP. > > > > > I > > > will try to see if I can reproduce it using a filter with the > > sample app > > > you gave me. Only one line change > > (streamOutputBuffer.closed = true) > > > would make our application work. So it seems to me that the > > application > > > filter is writing something after the stream is closed and > > this may lead to > > > this behavior. I will try to reproduce using this app. Do > > still consider > > > this application bug or a tomcat platform bug? > > > > Definitely an application bug. > > > > Mark > > > > > > > > Thank you so far for your excellent support and quick > responses. > > > > > > Thanks, > > > > > > Bhavesh > > > > > > > > > > > > On Thu, Mar 9, 2023 at 1:14 AM Mark Thomas <ma...@apache.org > > <mailto:ma...@apache.org>> wrote: > > > > > >> On 08/03/2023 21:32, Bhavesh Mistry wrote: > > >>> Hi Mark, > > >>> > > >>> We have a NAT rule that forwards 443 to 8443. > > >> > > >> OK. That explains the change in port. > > >> > > >>> Trust me on that, we have a > > >>> direct connection. To rule out any networking layer issues, > > I did > > >>> direct ssh -L 8443:localhost:8443 admin@10.40.207.140 > > <mailto:admin@10.40.207.140> and created a > > >> tunnel > > >>> (https://localhost:8443/ <https://localhost:8443/>) to > > bypass port 443. Yet, the issue is still > > >>> reproducible. So there is *NOTHING* in the middle that > > could cause this > > >>> issue. > > >> > > >> There must be. Could be a FireFox plugin, a Filter used by > > the web > > >> application, a Valve for a third-party authentication > > module, etc. > > >> > > >> Try deploying this war: > > >> https://people.apache.org/~markt/dev/no-content-test.war > > <https://people.apache.org/~markt/dev/no-content-test.war> > > >> > > >> It contains 2 JSPs. > > >> index.jsp has a link to no-content.jsp > > >> no-content.jsp just returns a 204 > > >> > > >> This works as expected, with no errors with the latest 9.0.x > > code, > > >> 9.0.72, Chrome and FireFox. > > >> > > >> If it works when deployed to your server, that points to > > something in > > >> the web application. If it doesn't work, that points to > > something in the > > >> network and/or browser. > > >> > > >> Mark > > >> > > >> * Is publicly exposing tomcat enough for debugging *or > > do you still > > >>> need an independent application? I can have SSH open but > > you will have > > >> to > > >>> give me your private email to email credentials and public > IP. > > >>> > > >>> sudo iptables -t nat -L > > >>> Chain PREROUTING (policy ACCEPT) > > >>> target prot opt source destination > > >>> VNMS all -- anywhere anywhere > > >>> > > >>> Chain INPUT (policy ACCEPT) > > >>> target prot opt source destination > > >>> > > >>> Chain OUTPUT (policy ACCEPT) > > >>> target prot opt source destination > > >>> > > >>> Chain POSTROUTING (policy ACCEPT) > > >>> target prot opt source destination > > >>> MASQUERADE tcp -- 172.17.0.2 172.17.0.2 > > tcp > > >> dpt:8000 > > >>> > > >>> Chain DOCKER (0 references) > > >>> target prot opt source destination > > >>> DNAT tcp -- anywhere anywhere > > tcp > > >> dpt:8000 > > >>> to:172.17.0.2:8000 <http://172.17.0.2:8000> > > >>> > > >>> Chain VNMS (1 references) > > >>> target prot opt source destination > > >>> DNAT tcp -- anywhere anywhere > > tcp > > >> dpt:http > > >>> to:127.0.0.1:8080 <http://127.0.0.1:8080> > > >>> *DNAT tcp -- anywhere anywhere > > tcp > > >>> dpt:https to:127.0.0.1:8443 <http://127.0.0.1:8443> > > <http://127.0.0.1:8443 <http://127.0.0.1:8443>> // this rule > > >> Fowards > > >>> it to the 8443.* > > >>> admin@SDWAN-VOAE1:~$ > > >>> > > >>> On Wed, Mar 8, 2023 at 12:29 PM Mark Thomas > > <ma...@apache.org <mailto:ma...@apache.org>> wrote: > > >>> > > >>>> On 08/03/2023 19:52, Bhavesh Mistry wrote: > > >>>>> Hi Mark, > > >>>>> > > >>>>> It is a *direct connection* with no proxy or no reverse > > proxy or no > > >> load > > >>>>> balancer in the middle. We have a web app (UI) that make > > backend call > > >>>> and > > >>>>> return 204 with no content and send it to the browser. > > An interesting > > >>>> fact > > >>>>> is very thing works on Chrome but not with firefox. We > > have tried > > >>>>> everything and we looked tomcat code and we see a change > > log around > > >> this > > >>>>> area. > > >>>> > > >>>> That data you provided previously is not consistent with > > that statement. > > >>>> > > >>>> Tomcat is listening on port 8443. > > >>>> > > >>>> Firefox is connecting to port 443. > > >>>> > > >>>> I have no doubt the Tomcat change to 204 handling > > triggered the change > > >>>> in behavior you are seeing. It appears to have exposed a > > HTTP/2 bug > > >>>> somewhere in your system. > > >>>> > > >>>>> It is hard to come up with a sample, but I will try it. > > I am just > > >> trying > > >>>>> to give clue which code or line causing the problem to > > narrow down the > > >>>>> issue, but it is not helping. > > >>>> > > >>>> Tomcat isn't the root cause. A simple test here with an > > index JSP and a > > >>>> JSP that just returns a 204 works as expected with Chrome > > and FireFox. > > >>>> > > >>>> All the indications are that there is an additional > > component in the > > >>>> system you are testing that can't handle an HTTP/2 204 > > response without > > >>>> a body. > > >>>> > > >>>> Mark > > >>>> > > >>>> > > >>>>> > > >>>>> Thanks, > > >>>>> > > >>>>> Bhavesh > > >>>>> > > >>>>> > > >>>>> > > >>>>> On Wed, Mar 8, 2023 at 11:43 AM Mark Thomas > > <ma...@apache.org <mailto:ma...@apache.org>> wrote: > > >>>>> > > >>>>>> On 08/03/2023 19:38, Bhavesh Mistry wrote: > > >>>>>>> I will see if I can give a sample. But after removing > > JUST ONE > > >> LINE ( > > >>>>>>> streamOutputBuffer.closed = true;) Everything seems to > > work. Somehow, > > >>>>>>> firefox does not like an active stream being closed (I > > am not 100% > > >> what > > >>>>>>> close does). > > >>>>>>> > > >>>>>>> I will try to work on a sample to reproduce this. I > > hope the above > > >> can > > >>>>>>> give you some clue as to where the issue is. > > >>>>>> > > >>>>>> Wherever the issue is, it isn't with Tomcat and it isn't > > with Firefox. > > >>>>>> I've tested them locally and they work correctly. > > >>>>>> > > >>>>>> Might you have a reverse proxy between Firefox and > Tomcat? > > >>>>>> > > >>>>>> Mark > > >>>>>> > > >>>>>> > > > --------------------------------------------------------------------- > > >>>>>> To unsubscribe, e-mail: > > users-unsubscr...@tomcat.apache.org > > <mailto:users-unsubscr...@tomcat.apache.org> > > >>>>>> For additional commands, e-mail: > > users-h...@tomcat.apache.org <mailto: > users-h...@tomcat.apache.org> > > >>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>>> > > > --------------------------------------------------------------------- > > >>>> To unsubscribe, e-mail: > > users-unsubscr...@tomcat.apache.org > > <mailto:users-unsubscr...@tomcat.apache.org> > > >>>> For additional commands, e-mail: > > users-h...@tomcat.apache.org <mailto: > users-h...@tomcat.apache.org> > > >>>> > > >>>> > > >>> > > >> > > >> > > > --------------------------------------------------------------------- > > >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > > <mailto:users-unsubscr...@tomcat.apache.org> > > >> For additional commands, e-mail: > > users-h...@tomcat.apache.org <mailto: > users-h...@tomcat.apache.org> > > >> > > >> > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > > <mailto:users-unsubscr...@tomcat.apache.org> > > For additional commands, e-mail: users-h...@tomcat.apache.org > > <mailto:users-h...@tomcat.apache.org> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >