Return-Path: X-Original-To: apmail-lucene-dev-archive@www.apache.org Delivered-To: apmail-lucene-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CC96A7FA4 for ; Sat, 5 Nov 2011 10:41:16 +0000 (UTC) Received: (qmail 71046 invoked by uid 500); 5 Nov 2011 10:41:15 -0000 Delivered-To: apmail-lucene-dev-archive@lucene.apache.org Received: (qmail 71005 invoked by uid 500); 5 Nov 2011 10:41:15 -0000 Mailing-List: contact dev-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@lucene.apache.org Delivered-To: mailing list dev@lucene.apache.org Received: (qmail 70997 invoked by uid 99); 5 Nov 2011 10:41:15 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 05 Nov 2011 10:41:15 +0000 X-ASF-Spam-Status: No, hits=-2001.2 required=5.0 tests=ALL_TRUSTED,RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 05 Nov 2011 10:41:12 +0000 Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116]) by hel.zones.apache.org (Postfix) with ESMTP id 7E06B3333DE for ; Sat, 5 Nov 2011 10:40:51 +0000 (UTC) Date: Sat, 5 Nov 2011 10:40:51 +0000 (UTC) From: "Uwe Schindler (Commented) (JIRA)" To: dev@lucene.apache.org Message-ID: <1328037554.2744.1320489651517.JavaMail.tomcat@hel.zones.apache.org> In-Reply-To: <543736239.1733.1320449632166.JavaMail.tomcat@hel.zones.apache.org> Subject: [jira] [Commented] (SOLR-2878) Regression in SolrDispatchFilter.java concerning the getOutputStream vs getWriter MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/SOLR-2878?page=3Dcom.atlassian.= jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D13144= 648#comment-13144648 ]=20 Uwe Schindler commented on SOLR-2878: ------------------------------------- Just to add another note: The API of ServletResponse supplying getWriter() APIs is a mis-conception i= n relation to the HTTP protocol. The HTTP protocol is defined to transfer b= inary output. The use of a char stream as Java supplies by getWriter() is o= nly for convenience, but a filter should never rely on the fact that a Serv= let uses a Writer. Unfortunately Sun never changed this for backwards compa= tibility reasons, but the correct API design of the Servlet API would be to= make the getWriter() method final in the ServletResponse. About your last example code that works around your issue: The code of your= filter is simply wrong - it assumes that all chars are represented by exac= tly one byte with the same binary code-point in the output, which is only t= rue for US-ASCII. It completely ignores the charset. Solr by default always= uses UTF-8 so you would make the output unreadable once a code poiunt > 12= 7 would appear in the output. To correctly buffer your output use a ByteArr= ayOutputStream. To check the contents of the buffered code as a string, you= have to use: new String(ByteArrayOutputStream.getBytes(), ServletResponse.= getCharacterEncoding()); =20 > Regression in SolrDispatchFilter.java concerning the getOutputStream vs g= etWriter > -------------------------------------------------------------------------= -------- > > Key: SOLR-2878 > URL: https://issues.apache.org/jira/browse/SOLR-2878 > Project: Solr > Issue Type: Bug > Components: Build, Response Writers > Affects Versions: 3.4 > Environment: Any unix system, it's a global problem > Reporter: Nick Veenhof > Labels: filter, getOutputStream, getWriter, regression > Fix For: 3.5, 4.0 > > > In solr 1.4 we used getWriter in the writeResponse for solrDispatchFilter= ::doFilter which invoked writeResponse. > This code looked in summary like this : > {code:title=3DsolrDispatchFilter.java|borderStyle=3Dsolid} > private void writeResponse(SolrQueryResponse solrRsp, ServletResponse res= ponse,=20 > QueryResponseWriter responseWriter, SolrQueryRequest solrReq, Method r= eqMethod)=20 > throws IOException { > ... > PrintWriter out =3D response.getWriter(); > responseWriter.write(out, solrReq, solrRsp); > ... > {code} > In solr 3.x this has changed to something like this=20 > {code:title=3DsolrDispatchFilter.java|borderStyle=3Dsolid} > private void writeResponse(SolrQueryResponse solrRsp, ServletResponse res= ponse, > QueryResponseWriter responseWriter, SolrQueryRequest solrReq, Method re= qMethod)=20 > throws IOException { > ... > String charset =3D ContentStreamBase.getCharsetFromContentType(ct); > Writer out =3D (charset =3D=3D null || charset.equalsIgnoreCase("UTF-8")) > ? new OutputStreamWriter(response.getOutputStream(), UTF8) > : new OutputStreamWriter(response.getOutputStream(), charset); > out =3D new FastWriter(out); > responseWriter.write(out, solrReq, solrRsp); > out.flush(); > ... > {code} > Now, when we add another filter that tries to modify the output it is bei= ng blocked by the out.flush().=20 > flush() is telling our outputstream that it can write directly to the des= tination (similar to the out.close()), since this normally happens automati= cally there shouldn't be a need to execute this flush. > In our case this secondary filter is trying to add headers to the respons= e object. When we were using getwriter() it was not closing the writer so w= e could still modify this output. Since the flush happens now we are no lon= ger able to modify the headers accordingly.=20 > It would be an easy fix if the flush could be commented out and everythin= g would work but that is not the case. The headers are working when this ha= ppens but there is no more output. > When I modify both classes to use getWriter() everything is working as ex= pected. > This is a severe regression for our use of solr. > Our code that is used in the filter > {code:title=3DsolrCustomFilter.java|borderStyle=3Dsolid} > public void doFilter(ServletRequest req, ServletResponse res,FilterChain = chain)=20 > throws IOException, ServletException { > ... > Writer out =3D new OutputStreamWriter(response.getOutputStream(), "UTF8")= ; //auto flush > out =3D new FastWriter(out); > // convert to a chartext > CharResponseWrapper wrapper =3D new CharResponseWrapper((HttpServletRespo= nse) response); > chain.doFilter(request, wrapper); > String responseBody =3D wrapper.toString(); > //write the outgoing header. Only succeeds when flush of solrDispatchFilt= er is commented out > response.addHeader("pragma", "somevalue;"); > out.write(responseBody); > ... > {code} > Sources : > {quote} > SRV.5.5 Closure of Response Object > When a response is closed, the container must immediately flush all remai= ning content in the response buffer to the client. The following events ind= icate that the servlet has satisfied the request and that the response obje= ct is to be closed: > =E2=80=A2 The termination of the service method of the servlet.=20 > =E2=80=A2 The amount of content specified in the setContentLength method = of the response has been written to the response.=20 > =E2=80=A2 The sendError method is called.=20 > =E2=80=A2 The sendRedirect method is called. > {quote} > Solr 1.4 https://svn.apache.org/repos/asf/lucene/solr/branches/branch-1.4= /src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java > Solr 3.4 https://svn.apache.org/repos/asf/lucene/dev/branches/lucene_solr= _3_4/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrato= rs: https://issues.apache.org/jira/secure/ContactAdministrators!default.jsp= a For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@lucene.apache.org For additional commands, e-mail: dev-help@lucene.apache.org