/* The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.sun.com/cddl/cddl.html or * install_dir/legal/LICENSE * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at install_dir/legal/LICENSE. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved */ package com.sun.faban.harness.webclient; import com.sun.faban.harness.common.Config; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import java.io.IOException; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; /** * The content reader reads requests for output files from the actual file * location which is not a subpath of the context and sends it back to the * requestor. * * @author Akara Sucharitakul */ public class ContentReader extends HttpServlet { ObjectPool bufferPool = new ObjectPool(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getContextPath(); String uri = request.getRequestURI(); ServletOutputStream out = response.getOutputStream(); // Safety check making sure the resource is part of URI. if (!uri.startsWith(path)) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); out.println("Could not identify requested resource."); out.flush(); out.close(); return; } // Now create a resource path with the context and servlet path // taken out. path = uri.substring(path.length()); // Now we have a resource i.e. /output/xmark.1A/summary.xml // We need to know the resource type by extracting the next level. int idx = path.indexOf('/', 1); // Then we break down the resource further to the actual file we wanted String resource = ""; if (idx != -1) { resource = path.substring(idx + 1); path = path.substring(0, idx); } // Now the resource is actually the resource resource we want. // We have to append the real output dir to it. if ("/output".equals(path)) { resource = Config.OUT_DIR + resource; } else if ("/analysis".equals(path)) { resource = Config.ANALYSIS_DIR + resource; } else if ("/bench_downloads".equals(path)) { resource = Config.BENCHMARK_DIR + resource; } else if ("/service_downloads".equals(path)) { resource = Config.SERVICE_DIR + resource; }else if ("/benchmarks".equals(path)) { // This is the form /benchmarks/<bench_name>/resource // It maps to public_html under the benchmark. int idx1 = resource.indexOf('/'); String benchName = resource.substring(0, idx1); resource = Config.BENCHMARK_DIR + benchName + "/public_html/" + resource.substring(idx1 + 1); } else { String msg = "Routing of path " + path + " not implemented."; out.println(msg); response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, msg); out.flush(); out.close(); return; } // Need to check that this file exists and is not a directory. File f = new File(resource); if (!f.exists()) { String msg = "Resource " + resource + " not found."; out.println("Resource " + resource + " not found."); response.sendError(HttpServletResponse.SC_NOT_FOUND, msg); out.flush(); out.close(); return; } // For directory, we send a text list of entries in the directory. // This is even easier to parse than XML. if (f.isDirectory()) { response.setContentType("text/plain"); // Note: wWe use '\n' instead of println so we can be sure it is // always '\n' and not '\r\n', etc. out.print(" Directory: " + f.getName() + '\n'); File[] entries = f.listFiles(); for (int i = 0; i < entries.length; i++) { char postfix; if (!entries[i].exists()) continue; if (entries[i].isDirectory()) postfix = '/'; else postfix = ' '; out.print(entries[i].getName() + postfix + '\n'); } out.flush(); out.close(); return; } if (resource.endsWith(".html") || resource.endsWith(".htm")) response.setContentType("text/html"); else if (resource.contains(".log.") || resource.contains(".xan.") || resource.endsWith(".log") || resource.endsWith(".xan")) response.setContentType("text/plain"); // We don't want to keep allocating 8K all the time, so we keep // our buffers in a pool. byte[] buffer = (byte[]) bufferPool.get(); if (buffer == null) buffer = new byte[8192]; // Then we just transfer the file to the servlet output. FileInputStream fIn = new FileInputStream(f); for (;;) { int length = fIn.read(buffer); if (length > 0) out.write(buffer, 0, length); else if (length == -1) break; } // Now return the buffer to the pool. bufferPool.put(buffer); // All done. Now we just close everything. out.flush(); out.close(); } static class ObjectPool { ArrayList backingList = new ArrayList(); public synchronized Object get() { if (backingList.size() == 0) return null; return backingList.remove(backingList.size() - 1); } public synchronized void put(Object o) { backingList.add(o); } } }