1 29 30 package com.caucho.servlets; 31 32 import com.caucho.util.L10N; 33 import com.caucho.vfs.Path; 34 import com.caucho.vfs.ReadStream; 35 import com.caucho.vfs.ReadWritePair; 36 import com.caucho.vfs.Vfs; 37 import com.caucho.vfs.WriteStream; 38 39 import javax.servlet.GenericServlet ; 40 import javax.servlet.ServletException ; 41 import javax.servlet.ServletRequest ; 42 import javax.servlet.ServletResponse ; 43 import javax.servlet.http.HttpServletRequest ; 44 import javax.servlet.http.HttpServletResponse ; 45 import java.io.IOException ; 46 import java.io.InputStream ; 47 import java.io.OutputStream ; 48 import java.io.PrintWriter ; 49 import java.util.ArrayList ; 50 import java.util.Enumeration ; 51 import java.util.Iterator ; 52 import java.util.logging.Level ; 53 import java.util.logging.Logger ; 54 55 66 public class HttpProxyServlet extends GenericServlet { 67 static protected final Logger log = 68 Logger.getLogger(HttpProxyServlet.class.getName()); 69 static final L10N L = new L10N(HttpProxyServlet.class); 70 71 private ArrayList <String > _hosts = new ArrayList <String >(); 72 private Path []_urlPaths; 73 private int _roundRobin; 74 75 78 public void addHost(String host) 79 { 80 _hosts.add(host); 81 } 82 83 86 public void init() 87 throws ServletException 88 { 89 if (_hosts.size() == 0) 90 throw new ServletException (L.l("HttpProxyServlet needs at least one host.")); 91 92 _urlPaths = new Path[_hosts.size()]; 93 94 for (int i = 0; i < _hosts.size(); i++) { 95 String host = _hosts.get(i); 96 97 if (host.startsWith("http")) 98 _urlPaths[i] = Vfs.lookup(host); 99 else 100 _urlPaths[i] = Vfs.lookup("http://" + host); 101 } 102 } 103 104 107 public void service(ServletRequest request, ServletResponse response) 108 throws ServletException , IOException 109 { 110 HttpServletRequest req = (HttpServletRequest ) request; 111 HttpServletResponse res = (HttpServletResponse ) response; 112 113 PrintWriter out = res.getWriter(); 114 115 int startIndex = _roundRobin; 116 _roundRobin = (_roundRobin + 1) % _urlPaths.length; 117 118 for (int i = 0; i < _urlPaths.length; i++) { 119 int index = (startIndex + i) % _urlPaths.length; 120 121 if (handleRequest(req, res, _urlPaths[index])) 122 return; 123 } 124 125 res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); 126 } 127 128 private boolean handleRequest(HttpServletRequest req, 129 HttpServletResponse res, 130 Path path) 131 throws ServletException , IOException 132 { 133 String hostURL = path.getURL(); 134 135 String uri; 136 if (req.isRequestedSessionIdFromUrl()) { 137 uri = (req.getRequestURI() + ";jsessionid=" + 138 req.getRequestedSessionId()); 139 } 140 else 141 uri = req.getRequestURI(); 142 143 if (req.getQueryString() != null) 144 uri += '?' + req.getQueryString(); 145 146 path = path.lookup(uri); 147 148 ReadWritePair pair = path.openReadWrite(); 149 150 ReadStream rs = pair.getReadStream(); 151 WriteStream ws = pair.getWriteStream(); 152 153 ws.setAttribute("method", req.getMethod()); 154 155 Enumeration e = req.getHeaderNames(); 156 while (e.hasMoreElements()) { 157 String name = (String ) e.nextElement(); 158 String value = req.getHeader(name); 159 160 ws.setAttribute(name, value); 161 } 162 163 try { 164 InputStream is = req.getInputStream(); 165 ws.writeStream(is); 166 167 String status = (String ) rs.getAttribute("status"); 168 int statusCode = 200; 169 170 if (status != null) { 171 try { 172 statusCode = Integer.parseInt(status); 173 } catch (Throwable e1) { 174 } 175 } 176 177 String location = null; 178 Iterator iter = rs.getAttributeNames(); 179 while (iter.hasNext()) { 180 String name = (String ) iter.next(); 181 182 if (name.equalsIgnoreCase("status")) { 183 } 184 else if (name.equalsIgnoreCase("transfer-encoding")) { 185 } 186 else if (name.equalsIgnoreCase("content-length")) { 187 } 188 else if (name.equalsIgnoreCase("location")) 189 location = (String ) rs.getAttribute("location"); 190 else 191 res.addHeader(name, (String ) rs.getAttribute(name)); 192 } 193 194 if (location == null) { 195 } 196 else if (location.startsWith(hostURL)) { 197 location = location.substring(hostURL.length()); 198 199 String prefix; 200 if (req.isSecure()) { 201 if (req.getServerPort() != 443) 202 prefix = ("https://" + req.getServerName() + 203 ":" + req.getServerPort()); 204 else 205 prefix = ("https://" + req.getServerName()); 206 } 207 else { 208 if (req.getServerPort() != 80) 209 prefix = ("http://" + req.getServerName() + 210 ":" + req.getServerPort()); 211 else 212 prefix = ("http://" + req.getServerName()); 213 } 214 215 if (! location.startsWith("/")) 216 location = prefix + "/" + location; 217 else 218 location = prefix + location; 219 } 220 221 if (location != null) 222 res.setHeader("Location", location); 223 224 if (statusCode == 302 && location != null) 225 res.sendRedirect(location); 226 else if (statusCode != 200) 227 res.setStatus(statusCode); 228 229 OutputStream os = res.getOutputStream(); 230 rs.writeToStream(os); 231 } catch (IOException e1) { 232 log.log(Level.FINE, e1.toString(), e1); 233 234 return false; 235 } finally { 236 ws.close(); 237 rs.close(); 238 } 239 240 return true; 241 } 242 } 243 | Popular Tags |