001 // This file is part of the Attempto Java Packages. 002 // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 003 // 004 // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the 005 // terms of the GNU Lesser General Public License as published by the Free Software Foundation, 006 // either version 3 of the License, or (at your option) any later version. 007 // 008 // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY 009 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 // PURPOSE. See the GNU Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with the Attempto 013 // Java Packages. If not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.echocomp; 016 017 import java.io.ByteArrayInputStream; 018 import java.io.ByteArrayOutputStream; 019 import java.io.IOException; 020 import java.io.UnsupportedEncodingException; 021 022 import javax.servlet.Filter; 023 import javax.servlet.FilterChain; 024 import javax.servlet.FilterConfig; 025 import javax.servlet.ServletException; 026 import javax.servlet.ServletInputStream; 027 import javax.servlet.ServletRequest; 028 import javax.servlet.ServletResponse; 029 import javax.servlet.http.HttpServletRequest; 030 import javax.servlet.http.HttpServletRequestWrapper; 031 032 /** 033 * This filter is a workaround for the problem that Firefox 3.0.0 to 3.0.4 somehow sends wrong 034 * XML headers to the server. 035 * See the discussion in <a href="http://echo.nextapp.com/site/node/5230" target="_blank">this thread</a> 036 * of the Echo forum. 037 * This code is inspired by the workaround proposed by the user "Nadir". 038 *<p> 039 * In order to apply this filter, the following lines have to be added to web.xml: 040 * 041 * <pre> 042 * <filter> 043 * <filter-name>headercontrol</filter-name> 044 * <filter-class>ch.uzh.ifi.attempto.echocomp.HeaderControlFilter</filter-class> 045 * <init-param> 046 * <param-name>request.reencoding</param-name> 047 * <param-value>UTF-8</param-value> 048 * </init-param> 049 * </filter> 050 * 051 * <filter-mapping> 052 * <filter-name>headercontrol</filter-name> 053 * <url-pattern>*</url-pattern> 054 * </filter-mapping> 055 * </pre> 056 */ 057 public class HeaderControlFilter implements Filter { 058 059 protected String reencParam = null; 060 061 public void init(FilterConfig filterConfig) throws ServletException { 062 this.reencParam = filterConfig.getInitParameter("request.reencoding"); 063 } 064 065 public void destroy() { 066 } 067 068 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { 069 HttpServletRequest httpRequest = (HttpServletRequest) req; 070 // Firefox 3.0.4 requires a less strict check. Before it was: 071 // if (reencParam != null && req.getCharacterEncoding() != null && !reencParam.equals(req.getCharacterEncoding())) { 072 if (reencParam != null && req.getCharacterEncoding() != null) { 073 req = new HeaderControlRequest(httpRequest, reencParam); 074 } 075 chain.doFilter(req, resp); 076 } 077 078 } 079 080 081 class HeaderControlRequest extends HttpServletRequestWrapper { 082 083 String encoding; 084 ServletInputStream inputStream; 085 086 public HeaderControlRequest(HttpServletRequest req, String encoding) { 087 super(req); 088 this.encoding = encoding; 089 } 090 091 public ServletInputStream getInputStream() throws IOException { 092 if (inputStream == null) { 093 inputStream = new InputStreamReencoder(super.getInputStream(), super.getCharacterEncoding(), encoding); 094 } 095 return inputStream; 096 } 097 098 } 099 100 101 class InputStreamReencoder extends ServletInputStream { 102 103 ByteArrayInputStream byteInputStream; 104 105 public InputStreamReencoder(ServletInputStream inputStream, String encIn, String encOut) { 106 ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); 107 byte[] buffer = new byte[4096]; 108 109 int bytesRead = 0; 110 try { 111 do { 112 bytesRead = inputStream.read(buffer); 113 if (bytesRead > 0) { 114 byteOutputStream.write(buffer, 0, bytesRead); 115 } 116 } while (bytesRead > 0); 117 } catch (IOException e) { 118 e.printStackTrace(); 119 } finally { 120 if (inputStream != null) { 121 try { 122 inputStream.close(); 123 } catch (IOException ex) {} 124 } 125 } 126 127 byte[] data = byteOutputStream.toByteArray(); 128 try { 129 data = new String(data, encIn).trim().getBytes(encOut); 130 byteInputStream = new ByteArrayInputStream(data); 131 } catch (UnsupportedEncodingException ex) {} 132 } 133 134 public int read() throws IOException { 135 return byteInputStream.read(); 136 } 137 138 }