Jetty Filter to change response - java.lang.IllegalStateException: WRITER

I try to change the http response in the filter and get the following exception

java.lang.IllegalStateException: WRITER at org.eclipse.jetty.server.Response.getOutputStream (Response.java:657) in javax.servlet.ServletResponseWrapper.getOutputStream (ServletResponseWrapper.java:l2.source ProxyServlet.service (ProxyServlet.javarige14) in org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.java:643) in org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter (ServletHandler.java in com.cisco.vsx.node.proxy.http.RegexFilter.doFilter (RegexFilter.java:36)

I am using SelectChannelSelector and ProxyServlet.Transparent proxy.

Below is a snippet from the test class

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); ProxyServlet.Transparent p1 = new ProxyServlet.Transparent("/proxy", "www.cisco.com", 80); ServletHolder servletHolder = new ServletHolder(p1); context.addServlet(servletHolder, "/proxy/*"); context.addFilter(new FilterHolder(RegexFilter.class), "/*", null); server.setHandler(context); server.start(); server.join(); 

This is the code from the filter class.

 PrintWriter out = response.getWriter(); CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response); chain.doFilter(request, wrapper); String html = wrapper.toString(); if (regex != null && response.getContentType() != null && response.getContentType().startsWith("text/html")) { Matcher matcher = regex.matcher(html); Map<Integer, Integer> matches = new LinkedHashMap<Integer, Integer>(); while (matcher.find()) { int start = matcher.start(1); System.out.println("START" + start); int end = matcher.end(1); System.out.println("END" + end); matches.put(start, end - start); } StringBuffer sb = new StringBuffer(); int start = 0; for (int startIndex : matches.keySet()) { String str = html.substring(start, startIndex) + "/proxy/"; sb.append(str); start = startIndex + matches.get(startIndex); } html = sb.toString(); } response.setContentLength(html.getBytes().length); out.write(html); 

Not sure where something is wrong.

+6
source share
1 answer

Your Jetty answer can be in two (technically three) different modes. One is the recording mode, the other is the streaming mode (and the third is basically an indecisive mode).

If you call getWriter() in the "undefined" response, you put it in write mode, which cannot be undone. If something later tries to use this response in streaming mode (by calling getOutputStream() ), you will see an exception.

To fix this, do not use this answer in recording mode and "do your thing" in OutputStream. If you accessed the writer at a later point (after doChain), you will get the opposite exception

java.lang.IllegalStateException: STREAM

instead.

+11
source

All Articles