wms-winstone-1.0.5

ervletURI = parseURILine(uriLine, req, rsp);
    parseHeaders(req, inData);
    rsp.extractRequestKeepAliveHeader(req);
    int contentLength = req.getContentLength();
    if (contentLength != -1) {
      inData.setContentLength(contentLength);
    }
    return servletURI;
  }
  
  public void releaseSocket(Socket socket, InputStream inSocket, OutputStream outSocket)
    throws IOException
  {
    IOException ioException = null;
    try
    {
      inSocket.close();
    }
    catch (IOException e)
    {
      ioException = e;
    }
    try
    {
      outSocket.close();
    }
    catch (IOException e)
    {
      ioException = e;
    }
    try
    {
      socket.close();
    }
    catch (IOException e)
    {
      ioException = e;
    }
    if (ioException != null) {
      throw ioException;
    }
  }
  
  protected void parseSocketInfo(Socket socket, WinstoneRequest request)
    throws IOException
  {
    logger.debug("Parsing socket info");
    request.setScheme(getConnectorScheme());
    request.setServerPort(socket.getLocalPort());
    request.setLocalPort(socket.getLocalPort());
    request.setLocalAddr(socket.getLocalAddress().getHostAddress());
    request.setRemoteIP(socket.getInetAddress().getHostAddress());
    request.setRemotePort(socket.getPort());
    if (doHostnameLookups)
    {
      request.setServerName(getHostName(socket.getLocalAddress()));
      request.setRemoteName(socket.getInetAddress().getHostName());
      request.setLocalName(getHostName(socket.getLocalAddress()));
    }
    else
    {
      request.setServerName(getHostAddress(socket.getLocalAddress()));
      request.setRemoteName(socket.getInetAddress().getHostAddress());
      request.setLocalName(getHostAddress(socket.getLocalAddress()));
    }
  }
  
  public boolean processKeepAlive(WinstoneRequest request, WinstoneResponse response, InputStream inSocket)
    throws IOException, InterruptedException
  {
    boolean continueFlag = !response.closeAfterRequest();
    return continueFlag;
  }
  
  private static String parseURILine(String uriLine, WinstoneRequest req, WinstoneResponse rsp)
  {
    logger.trace("URI Line:", uriLine.trim());
    
    int spacePos = uriLine.indexOf(' ');
    if (spacePos == -1) {
      throw new WinstoneException("Error URI Line: " + uriLine);
    }
    String method = uriLine.substring(0, spacePos).toUpperCase();
    
    String remainder = uriLine.substring(spacePos + 1);
    spacePos = remainder.indexOf(' ');
    String fullURI;
    if (spacePos == -1)
    {
      String fullURI = trimHostName(remainder.trim());
      req.setProtocol("HTTP/0.9");
      rsp.setProtocol("HTTP/0.9");
    }
    else
    {
      fullURI = trimHostName(remainder.substring(0, spacePos).trim());
      String protocol = remainder.substring(spacePos + 1).trim().toUpperCase();
      if (!protocol.startsWith("HTTP/")) {
        protocol = "HTTP/1.0";
      }
      req.setProtocol(protocol);
      rsp.setProtocol(protocol);
    }
    req.setMethod(method);
    
    return fullURI;
  }
  
  private static String trimHostName(String input)
  {
    if (input == null) {
      return null;
    }
    if (input.startsWith("/")) {
      return input;
    }
    int hostStart = input.indexOf("://");
    if (hostStart == -1) {
      return input;
    }
    String hostName = input.substring(hostStart + 3);
    int pathStart = hostName.indexOf('/');
    if (pathStart == -1) {
      return "/";
    }
    return hostName.substring(pathStart);
  }
  
  public void parseHeaders(WinstoneRequest req, WinstoneInputStream inData)
    throws IOException
  {
    List<String> headerList = new ArrayList();
    if (!req.getProtocol().startsWith("HTTP/0"))
    {
      byte[] headerBuffer = inData.readLine();
      String headerLine = new String(headerBuffer);
      while (headerLine.trim().length() > 0)
      {
        if (headerLine.indexOf(':') != -1)
        {
          headerList.add(headerLine.trim());
          logger.debug("Header: " + headerLine.trim());
        }
        headerBuffer = inData.readLine();
        headerLine = new String(headerBuffer);
      }
    }
    req.parseHeaders(headerList);
  }
  
  private String getHostAddress(InetAddress adrs)
  {
    if ((adrs instanceof Inet6Address)) {
      return '[' + adrs.getHostAddress() + ']';
    }
    return adrs.getHostAddress();
  }
  
  private String getHostName(InetAddress adrs)
  {
    if ((adrs instanceof Inet6Address))
    {
      String n = adrs.getHostName();
      if (n.indexOf(':') >= 0) {
        return '[' + n + ']';
      }
      return n;
    }
    return adrs.getHostName();
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.HttpListener
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core.listener;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Reader;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.RSAPrivateKeySpec;
import java.util.Enumeration;
import java.util.Map;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import net.winstone.WinstoneException;
import net.winstone.core.HostGroup;
import net.winstone.core.ObjectPool;
import net.winstone.core.WinstoneRequest;
import net.winstone.util.Base64;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.X500Name;

public class HttpsListener
  extends HttpListener
{
  private static Logger logger = LoggerFactory.getLogger(HttpListener.class);
  private final KeyStore keystore;
  private final char[] password;
  private final String keyManagerType;
  private boolean performClientAuth;
  
  public HttpsListener(Map<String, String> args, ObjectPool objectPool, HostGroup hostGroup)
    throws IOException
  {
    super(args, objectPool, hostGroup);
    if (listenPort < 0)
    {
      keystore = null;
      password = null;
      keyManagerType = null;
    }
    else
    {
      try
      {
        String pwd = StringUtils.stringArg(args, getConnectorName() + "KeyStorePassword", null);
        keyManagerType = StringUtils.stringArg(args, getConnectorName() + "KeyManagerType", "SunX509");
        performClientAuth = StringUtils.booleanArg(args, "httpsVerifyClient", Boolean.FALSE.booleanValue());
        
        File opensslCert = StringUtils.fileArg(args, "httpsCertificate");
        File opensslKey = StringUtils.fileArg(args, "httpsPrivateKey");
        File keyStore = StringUtils.fileArg(args, "httpsKeyStore");
        if (((opensslCert != null ? 1 : 0) ^ (opensslKey != null ? 1 : 0)) != 0) {
          throw new WinstoneException("--httpsCertificate and --httpsPrivateKey need to be used together");
        }
        if ((keyStore != null) && (opensslKey != null)) {
          throw new WinstoneException("--httpsKeyStore and --httpsPrivateKey are mutually exclusive");
        }
        if (keyStore != null)
        {
          if ((!keyStore.exists()) || (!keyStore.isFile())) {
            throw new WinstoneException("No SSL key store found at " + keyStore.getPath());
          }
          password = (pwd != null ? pwd.toCharArray() : null);
          keystore = KeyStore.getInstance("JKS");
          keystore.load(new FileInputStream(keyStore), password);
        }
        else if (opensslCert != null)
        {
          CertificateFactory cf = CertificateFactory.getInstance("X509");
          Certificate cert = cf.generateCertificate(new FileInputStream(opensslCert));
          PrivateKey key = readPEMRSAPrivateKey(new FileReader(opensslKey));
          password = "changeit".toCharArray();
          keystore = KeyStore.getInstance("JKS");
          keystore.load(null);
          keystore.setKeyEntry("hudson", key, password, new Certificate[] { cert });
        }
        else
        {
          password = "changeit".toCharArray();
          System.out.println("Using one-time self-signed certificate");
          CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
          ckg.generate(1024);
          PrivateKey privKey = ckg.getPrivateKey();
          X500Name xn = new X500Name("Test site", "Unknown", "Unknown", "Unknown");
          X509Certificate cert = ckg.getSelfCertificate(xn, 315360000L);
          keystore = KeyStore.getInstance("JKS");
          keystore.load(null);
          keystore.setKeyEntry("hudson", privKey, password, new Certificate[] { cert });
        }
      }
      catch (GeneralSecurityException e)
      {
        throw ((IOException)new IOException("Failed to handle keys").initCause(e));
      }
    }
  }
  
  private static PrivateKey readPEMRSAPrivateKey(Reader reader)
    throws IOException, GeneralSecurityException
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try
    {
      BufferedReader r = new BufferedReader(reader);
      
      boolean in = Boolean.FALSE.booleanValue();
      String line;
      while ((line = r.readLine()) != null) {
        if (line.startsWith("-----"))
        {
          in = !in;
        }
        else if (in)
        {
          char[] inBytes = line.toCharArray();
          byte[] outBytes = new byte[inBytes.length * 3 / 4];
          int length = Base64.decode(inBytes, outBytes, 0, inBytes.length, 0);
          baos.write(outBytes, 0, length);
        }
      }
    }
    finally
    {
      reader.close();
    }
    DerInputStream dis = new DerInputStream(baos.toByteArray());
    DerValue[] seq = dis.getSequence(0);
    
    BigInteger mod = seq[1].getBigInteger();
    
    BigInteger privExpo = seq[3].getBigInteger();
    
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(new RSAPrivateKeySpec(mod, privExpo));
  }
  
  protected int getDefaultPort()
  {
    return -1;
  }
  
  protected String getConnectorScheme()
  {
    return "https";
  }
  
  protected ServerSocket getServerSocket()
    throws IOException
  {
    SSLContext context = getSSLContext();
    SSLServerSocketFactory factory = context.getServerSocketFactory();
    SSLServerSocket ss = (SSLServerSocket)(listenAddress == null ? factory.createServerSocket(listenPort, HttpListener.BACKLOG_COUNT) : factory.createServerSocket(listenPort, HttpListener.BACKLOG_COUNT, InetAddress.getByName(listenAddress)));
    
    ss.setEnableSessionCreation(Boolean.TRUE.booleanValue());
    if (performClientAuth) {
      ss.setNeedClientAuth(Boolean.TRUE.booleanValue());
    }
    return ss;
  }
  
  protected void parseSocketInfo(Socket socket, WinstoneRequest req)
    throws IOException
  {
    super.parseSocketInfo(socket, req);
    if ((socket instanceof SSLSocket))
    {
      SSLSocket s = (SSLSocket)socket;
      SSLSession ss = s.getSession();
      if (ss != null)
      {
        Certificate[] certChain = null;
        try
        {
          certChain = ss.getPeerCertificates();
        }
        catch (Throwable err) {}
        if (certChain != null)
        {
          req.setAttribute("javax.servlet.request.X509Certificate", certChain);
          req.setAttribute("javax.servlet.request.cipher_suite", ss.getCipherSuite());
          req.setAttribute("javax.servlet.request.ssl_session", new String(ss.getId()));
          req.setAttribute("javax.servlet.request.key_size", getKeySize(ss.getCipherSuite()));
        }
      }
      req.setIsSecure(Boolean.TRUE.booleanValue());
    }
  }
  
  private Integer getKeySize(String cipherSuite)
  {
    if (cipherSuite.indexOf("_WITH_NULL_") != -1) {
      return Integer.valueOf(0);
    }
    if (cipherSuite.indexOf("_WITH_IDEA_CBC_") != -1) {
      return Integer.valueOf(128);
    }
    if (cipherSuite.indexOf("_WITH_RC2_CBC_40_") != -1) {
      return Integer.valueOf(40);
    }
    if (cipherSuite.indexOf("_WITH_RC4_40_") != -1) {
      return Integer.valueOf(40);
    }
    if (cipherSuite.indexOf("_WITH_RC4_128_") != -1) {
      return Integer.valueOf(128);
    }
    if (cipherSuite.indexOf("_WITH_DES40_CBC_") != -1) {
      return Integer.valueOf(40);
    }
    if (cipherSuite.indexOf("_WITH_DES_CBC_") != -1) {
      return Integer.valueOf(56);
    }
    if (cipherSuite.indexOf("_WITH_3DES_EDE_CBC_") != -1) {
      return Integer.valueOf(168);
    }
    return null;
  }
  
  public SSLContext getSSLContext()
  {
    try
    {
      KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerType);
      kmf.init(keystore, password);
      logger.debug("Keys/certificates found: ", keystore.size() + "");
      for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements();)
      {
        String alias = (String)e.nextElement();
        logger.debug("Keys : {} - {}", alias, keystore.getCertificate(alias) + "");
      }
      SSLContext context = SSLContext.getInstance("SSL");
      context.init(kmf.getKeyManagers(), null, null);
      return context;
    }
    catch (Throwable err)
    {
      throw new WinstoneException("Error getting the SSL context object", err);
    }
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.HttpsListener
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core.listener;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import net.winstone.core.WinstoneInputStream;
import net.winstone.core.WinstoneOutputStream;
import net.winstone.core.WinstoneRequest;
import net.winstone.core.WinstoneResponse;

public abstract interface Listener
{
  public abstract void destroy();
  
  public abstract boolean start()
    throws IOException;
  
  public abstract void allocateRequestResponse(Socket paramSocket, InputStream paramInputStream, OutputStream paramOutputStream, RequestHandlerThread paramRequestHandlerThread, boolean paramBoolean)
    throws SocketException, IOException;
  
  public abstract void deallocateRequestResponse(RequestHandlerThread paramRequestHandlerThread, WinstoneRequest paramWinstoneRequest, WinstoneResponse paramWinstoneResponse, WinstoneInputStream paramWinstoneInputStream, WinstoneOutputStream paramWinstoneOutputStream)
    throws IOException;
  
  public abstract String parseURI(RequestHandlerThread paramRequestHandlerThread, WinstoneRequest paramWinstoneRequest, WinstoneResponse paramWinstoneResponse, WinstoneInputStream paramWinstoneInputStream, Socket paramSocket, boolean paramBoolean)
    throws IOException;
  
  public abstract void releaseSocket(Socket paramSocket, InputStream paramInputStream, OutputStream paramOutputStream)
    throws IOException;
  
  public abstract boolean processKeepAlive(WinstoneRequest paramWinstoneRequest, WinstoneResponse paramWinstoneResponse, InputStream paramInputStream)
    throws IOException, InterruptedException;
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.Listener
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core.listener;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioSocketServer
  implements Runnable
{
  private static final int LISTEN_PORT = 6475;
  private Thread thread;
  private Selector selector;
  private ServerSocket serverSocket;
  
  public NioSocketServer(boolean useNIO)
    throws IOException
  {
    if (useNIO)
    {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking(false);
      ServerSocket ss = ssc.socket();
      ss.bind(new InetSocketAddress(6475));
      
      selector = Selector.open();
      ssc.register(selector, 16);
    }
    else
    {
      serverSocket = new ServerSocket(6475);
      serverSocket.setSoTimeout(500);
    }
    thread = new Thread(this);
    thread.setDaemon(true);
    thread.start();
  }
  
  public void run()
  {
    boolean interrupted = false;
    while (!interrupted) {
      try
      {
        if (selector != null) {
          nioLoop();
        } else {
          jioLoop();
        }
        interrupted = Thread.interrupted();
      }
      catch (IOException err)
      {
        err.printStackTrace();
        interrupted = true;
      }
    }
    thread = null;
  }
  
  private void nioLoop()
    throws IOException
  {
    selector.select(500L);
    Set<SelectionKey> selectedKeys = selector.selectedKeys();
    Iterator<SelectionKey> i = selectedKeys.iterator();
    while (i.hasNext())
    {
      SelectionKey key = (SelectionKey)i.next();
      if (key.isAcceptable())
      {
        ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
        SocketChannel sc = ssc.accept();
        sc.configureBlocking(false);
        sc.register(selector, 1);
      }
      else if (key.isReadable())
      {
        SocketChannel sc = (SocketChannel)key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(10);
        buffer.clear();
        sc.read(buffer);
        buffer.flip();
        sc.write(buffer);
        sc.close();
      }
      i.remove();
    }
  }
  
  private void jioLoop()
    throws IOException
  {
    Socket socket = null;
    try
    {
      socket = serverSocket.accept();
    }
    catch (SocketTimeoutException err) {}
    if (socket != null)
    {
      InputStream in = socket.getInputStream();
      int pos = 0;
      int read = 0;
      byte[] buffer = new byte[10];
      while ((pos < buffer.length) && ((read = in.read(buffer, pos, buffer.length - pos)) != -1)) {
        pos += read;
      }
      OutputStream out = socket.getOutputStream();
      out.write(buffer, 0, pos);
      in.close();
      out.close();
      socket.close();
    }
  }
  
  public void stop()
  {
    thread.interrupt();
  }
  
  public static void main(String[] argv)
    throws Exception
  {
    String iterArg = argv.length > 1 ? argv[1] : "1000";
    int ITERATION_COUNT = Integer.parseInt(iterArg);
    boolean useNIO = (argv.length > 0) && (argv[0].equals("nio"));
    
    InetAddress LOCATION = InetAddress.getLocalHost();
    System.out.println("Address: " + LOCATION);
    
    NioSocketServer server = new NioSocketServer(useNIO);
    Thread.sleep(1000L);
    
    long startTime = System.currentTimeMillis();
    
    byte[] TEST_ARRAY = "1234567890".getBytes();
    for (int n = 0; n < ITERATION_COUNT; n++)
    {
      byte[] buffer = new byte[TEST_ARRAY.length];
      Socket socket = new Socket(LOCATION, 6475);
      socket.setSoTimeout(50);
      OutputStream out = socket.getOutputStream();
      out.write(TEST_ARRAY);
      
      InputStream in = socket.getInputStream();
      int read = 0;
      int pos = 0;
      while ((pos < buffer.length) && ((read = in.read(buffer, pos, buffer.length - pos)) != -1)) {
        pos += read;
      }
      in.close();
      out.close();
      socket.close();
      if (n % 500 == 0) {
        System.out.println("Completed " + n + " iterations in " + (System.currentTimeMillis() - startTime) + "ms");
      }
    }
    System.out.println("Completed " + ITERATION_COUNT + " iterations in " + (System.currentTimeMillis() - startTime) + "ms");
    server.stop();
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.NioSocketServer
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core.listener;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import net.winstone.accesslog.AccessLogger;
import net.winstone.core.ClientSocketException;
import net.winstone.core.HostConfiguration;
import net.winstone.core.HostGroup;
import net.winstone.core.SimpleRequestDispatcher;
import net.winstone.core.WebAppConfiguration;
import net.winstone.core.WinstoneInputStream;
import net.winstone.core.WinstoneOutputStream;
import net.winstone.core.WinstoneRequest;
import net.winstone.core.WinstoneResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RequestHandlerThread
  implements Runnable
{
  protected static Logger logger = LoggerFactory.getLogger(RequestHandlerThread.class);
  private WinstoneInputStream inData;
  private WinstoneOutputStream outData;
  private WinstoneRequest req;
  private WinstoneResponse rsp;
  private Listener listener;
  private Socket socket;
  private long requestStartTime;
  private final boolean simulateModUniqueId;
  private final boolean saveSessions;
  
  public RequestHandlerThread(boolean simulateModUniqueId, boolean saveSessions, Socket socket, Listener listener)
  {
    this.simulateModUniqueId = simulateModUniqueId;
    this.saveSessions = saveSessions;
    this.socket = socket;
    this.listener = listener;
  }
  
  public void run()
  {
    InputStream inSocket = null;
    OutputStream outSocket = null;
    boolean iAmFirst = true;
    try
    {
      inSocket = socket.getInputStream();
      outSocket = socket.getOutputStream();
      
      boolean continueFlag = true;
      while (continueFlag) {
        try
        {
          long requestId = System.currentTimeMillis();
          listener.allocateRequestResponse(socket, inSocket, outSocket, this, iAmFirst);
          if (req == null)
          {
            listener.deallocateRequestResponse(this, req, rsp, inData, outData);
          }
          else
          {
            String servletURI = listener.parseURI(this, req, rsp, inData, socket, iAmFirst);
            if (servletURI == null)
            {
              logger.debug("Keep alive timed out in thread: {}", Thread.currentThread().getName());
              
              listener.deallocateRequestResponse(this, req, rsp, inData, outData);
              continueFlag = false;
            }
            else
            {
              if (simulateModUniqueId) {
                req.setAttribute("UNIQUE_ID", "" + requestId);
              }
              long headerParseTime = getRequestProcessTime();
              iAmFirst = false;
              
              HostConfiguration hostConfig = req.getHostGroup().getHostByName(req.getServerName());
              logger.debug("Starting request on host:[{}] with id: {}", "" + requestId, hostConfig.getHostname());
              
              WebAppConfiguration webAppConfig = hostConfig.getWebAppByURI(servletURI);
              if (webAppConfig == null) {
                webAppConfig = hostConfig.getWebAppByURI("/");
              }
              if (webAppConfig == null)
              {
                logger.warn("Request URL {} not found - doesn't match any webapp prefix", servletURI);
                rsp.sendRedirect(hostConfig.getDefaultWebApp());
                rsp.sendError(404, "Request URL " + servletURI + " not found.<br><br>");
                rsp.flushBuffer();
                req.discardRequestBody();
                writeToAccessLog(servletURI, req, rsp, null);
                
                continueFlag = listener.processKeepAlive(req, rsp, inSocket);
                listener.deallocateRequestResponse(this, req, rsp, inData, outData);
                logger.debug("Finishing request id:  {}", "" + requestId);
                logger.debug("Processed complete request: headerParseTime={}ms totalTime={}ms path={}", new Object[] { "" + headerParseTime, "" + getRequestProcessTime(), servletURI });
              }
              else
              {
                req.setWebAppConfig(webAppConfig);
                
                ServletRequestListener[] reqLsnrs = webAppConfig.getRequestListeners();
                for (ServletRequestListener reqLsnr1 : reqLsnrs)
                {
                  ClassLoader cl = Thread.currentThread().getContextClassLoader();
                  Thread.currentThread().setContextClassLoader(webAppConfig.getLoader());
                  reqLsnr1.requestInitialized(new ServletRequestEvent(webAppConfig, req));
                  Thread.currentThread().setContextClassLoader(cl);
                }
                processRequest(webAppConfig, req, rsp, webAppConfig.getServletURIFromRequestURI(servletURI));
                writeToAccessLog(servletURI, req, rsp, webAppConfig);
                
                outData.finishResponse();
                inData.finishRequest();
                logger.debug("Finishing request id:  {}", "" + requestId);
                
                continueFlag = listener.processKeepAlive(req, rsp, inSocket);
                
                req.markSessionsAsRequestFinished(requestStartTime, saveSessions);
                for (ServletRequestListener reqLsnr : reqLsnrs)
                {
                  ClassLoader cl = Thread.currentThread().getContextClassLoader();
                  Thread.currentThread().setContextClassLoader(webAppConfig.getLoader());
                  reqLsnr.requestDestroyed(new ServletRequestEvent(webAppConfig, req));
                  Thread.currentThread().setContextClassLoader(cl);
                }
                req.setWebAppConfig(null);
                rsp.setWebAppConfig(null);
                req.setRequestAttributeListeners(null);
                
                listener.deallocateRequestResponse(this, req, rsp, inData, outData);
                logger.debug("Processed complete request: headerParseTime={}ms totalTime={}ms path={}", new Object[] { "" + headerParseTime, "" + getRequestProcessTime(), servletURI });
              }
            }
          }
        }
        catch (InterruptedIOException errIO)
        {
          continueFlag = false;
          logger.error("Socket read timed out - exiting request handler thread", errIO);
        }
        catch (SocketException errIO)
        {
          continueFlag = false;
        }
      }
      listener.deallocateRequestResponse(this, req, rsp, inData, outData);
      listener.releaseSocket(socket, inSocket, outSocket);
    }
    catch (Throwable err)
    {
      try
      {
        listener.deallocateRequestResponse(this, req, rsp, inData, outData);
      }
      catch (Throwable errClose) {}
      try
      {
        listener.releaseSocket(socket, inSocket, outSocket);
      }
      catch (Throwable errClose) {}
      if (!(err instanceof ClientSocketException)) {
        logger.error("Error within request handler thread", err);
      }
    }
  }
  
  private void processRequest(WebAppConfiguration webAppConfig, WinstoneRequest req, WinstoneResponse rsp, String path)
    throws IOException, ServletException
  {
    SimpleRequestDispatcher rd = null;
    RequestDispatcher rdError = null;
    try
    {
      rd = webAppConfig.getInitialDispatcher(path, req, rsp);
      if (rd != null)
      {
        logger.debug("Processing with RD: {}", rd.getName());
        rd.forward(req, rsp);
      }
    }
    catch (ClientSocketException err) {}catch (Throwable err)
    {
      boolean ignore = Boolean.FALSE.booleanValue();
      for (Throwable t = err; t != null; t = t.getCause()) {
        if ((t instanceof ClientSocketException))
        {
          ignore = Boolean.TRUE.booleanValue();
          break;
        }
      }
      if (!ignore)
      {
        logger.warn("Untrapped Error in Servlet", err);
        rdError = webAppConfig.getErrorDispatcherByClass(err);
      }
    }
    if (rdError != null) {
      try
      {
        if (rsp.isCommitted())
        {
          rdError.include(req, rsp);
        }
        else
        {
          rsp.resetBuffer();
          rdError.forward(req, rsp);
        }
      }
      catch (Throwable err)
      {
        logger.error("Error in the error servlet ", err);
      }
    }
    rsp.flushBuffer();
    rsp.getWinstoneOutputStream().setClosed(Boolean.TRUE.booleanValue());
    req.discardRequestBody();
  }
  
  public void setRequest(WinstoneRequest request)
  {
    req = request;
  }
  
  public void setResponse(WinstoneResponse response)
  {
    rsp = response;
  }
  
  public void setInStream(WinstoneInputStream inStream)
  {
    inData = inStream;
  }
  
  public void setOutStream(WinstoneOutputStream outStream)
  {
    outData = outStream;
  }
  
  public void setRequestStartTime()
  {
    requestStartTime = System.currentTimeMillis();
  }
  
  public long getRequestProcessTime()
  {
    return System.currentTimeMillis() - requestStartTime;
  }
  
  protected void writeToAccessLog(String originalURL, WinstoneRequest request, WinstoneResponse response, WebAppConfiguration webAppConfig)
  {
    if (webAppConfig != null)
    {
      AccessLogger accessLogger = webAppConfig.getAccessLogger();
      if (accessLogger != null) {
        accessLogger.log(originalURL, request, response);
      }
    }
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.RequestHandlerThread
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core;

import java.util.Comparator;
import net.winstone.WinstoneException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Mapping
  implements Comparator<Mapping>
{
  protected static Logger logger = LoggerFactory.getLogger(Mapping.class);
  public static final int EXACT_PATTERN = 1;
  public static final int FOLDER_PATTERN = 2;
  public static final int EXTENSION_PATTERN = 3;
  public static final int DEFAULT_SERVLET = 4;
  public static final String STAR = "*";
  public static final String SLASH = "/";
  private String urlPattern;
  private String linkName;
  private final String mappedTo;
  private int patternType;
  private boolean isPatternFirst;
  
  protected Mapping(String mappedTo)
  {
    this.mappedTo = mappedTo;
  }
  
  public static Mapping createFromURL(String mappedTo, String pattern)
  {
    if ((pattern == null) || (mappedTo == null)) {
      throw new WinstoneException("WebAppConfig: Invalid pattern mount for " + mappedTo + " pattern " + pattern + " - ignoring");
    }
    if ((!pattern.equals("")) && (!pattern.startsWith("*")) && (!pattern.startsWith("/")))
    {
      pattern = "/" + pattern;
    }
    else if (pattern.equals("*"))
    {
      logger.warn("WARNING: Invalid \"*\" only mount. Interpreting as a \"/*\" mount");
      pattern = "/*";
    }
    Mapping me = new Mapping(mappedTo);
    
    int firstStarPos = pattern.indexOf("*");
    int lastStarPos = pattern.lastIndexOf("*");
    int patternLength = pattern.length();
    if (pattern.equals("/"))
    {
      urlPattern = "";
      patternType = 4;
    }
    else if (firstStarPos == -1)
    {
      urlPattern = pattern;
      patternType = 1;
    }
    else
    {
      if (firstStarPos != lastStarPos) {
        throw new WinstoneException("WebAppConfig: Invalid pattern mount for " + mappedTo + " pattern " + pattern + " - ignoring");
      }
      if (pattern.indexOf("/*") == patternLength - "/*".length())
      {
        urlPattern = pattern.substring(0, pattern.length() - "/*".length());
        patternType = 2;
      }
      else
      {
        if (pattern.indexOf("/") != -1) {
          throw new WinstoneException("WebAppConfig: Invalid pattern mount for " + mappedTo + " pattern " + pattern + " - ignoring");
        }
        if (firstStarPos == 0)
        {
          urlPattern = pattern.substring("*".length());
          patternType = 3;
          isPatternFirst = Boolean.FALSE.booleanValue();
        }
        else if (firstStarPos == patternLength - "*".length())
        {
          urlPattern = pattern.substring(0, patternLength - "*".length());
          patternType = 3;
          isPatternFirst = Boolean.TRUE.booleanValue();
        }
        else
        {
          throw new WinstoneException("WebAppConfig: Invalid pattern mount for " + mappedTo + " pattern " + pattern + " - ignoring");
        }
      }
    }
    logger.debug("Mapped: {} to {}", mappedTo, pattern);
    return me;
  }
  
  public static Mapping createFromLink(String mappedTo, String linkName)
  {
    if ((linkName == null) || (mappedTo == null)) {
      throw new WinstoneException("WebAppConfig: Invalid link mount for " + mappedTo + " link " + linkName + " - ignoring");
    }
    Mapping me = new Mapping(mappedTo);
    linkName = linkName;
    return me;
  }
  
  public int getPatternType()
  {
    return patternType;
  }
  
  public String getUrlPattern()
  {
    return urlPattern;
  }
  
  public String getMappedTo()
  {
    return mappedTo;
  }
  
  public String getLinkName()
  {
    return linkName;
  }
  
  public boolean match(String inputPattern, StringBuilder servletPath, StringBuilder pathInfo)
  {
    switch (patternType)
    {
    case 2: 
      if ((inputPattern.startsWith(urlPattern + '/')) || (inputPattern.equals(urlPattern)))
      {
        if (servletPath != null) {
          servletPath.append(WinstoneRequest.decodePathURLToken(urlPattern));
        }
        if (pathInfo != null) {
          pathInfo.append(WinstoneRequest.decodeURLToken(inputPattern.substring(urlPattern.length())));
        }
        return Boolean.TRUE.booleanValue();
      }
      return Boolean.FALSE.booleanValue();
    case 3: 
      int slashPos = inputPattern.lastIndexOf("/");
      if ((slashPos == -1) || (slashPos == inputPattern.length() - 1)) {
        return Boolean.FALSE.booleanValue();
      }
      String fileName = inputPattern.substring(slashPos + 1);
      if (((isPatternFirst) && (fileName.startsWith(urlPattern))) || ((!isPatternFirst) && (fileName.endsWith(urlPattern))))
      {
        if (servletPath != null) {
          servletPath.append(WinstoneRequest.decodePathURLToken(inputPattern));
        }
        return Boolean.TRUE.booleanValue();
      }
      return Boolean.FALSE.booleanValue();
    case 1: 
      if (inputPattern.equals(urlPattern))
      {
        if (servletPath != null) {
          servletPath.append(WinstoneRequest.decodePathURLToken(inputPattern));
        }
        return Boolean.TRUE.booleanValue();
      }
      return Boolean.FALSE.booleanValue();
    case 4: 
      if (servletPath != null) {
        servletPath.append(WinstoneRequest.decodePathURLToken(inputPattern));
      }
      return Boolean.TRUE.booleanValue();
    }
    return Boolean.FALSE.booleanValue();
  }
  
  public String toString()
  {
    return "URLPattern:type=" + patternType + ",pattern=" + urlPattern;
  }
  
  public int compare(Mapping one, Mapping two)
  {
    Integer intOne = new Integer(one.getPatternType());
    Integer intTwo = new Integer(two.getPatternType());
    int order = -1 * intOne.compareTo(intTwo);
    if (order != 0) {
      return order;
    }
    if (one.getLinkName() != null) {
      return one.getLinkName().compareTo(two.getLinkName());
    }
    return -1 * one.getUrlPattern().compareTo(two.getUrlPattern());
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.Mapping
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core;

import java.util.concurrent.ThreadFactory;

class ObjectPool$1
  implements ThreadFactory
{
  private int threadIndex;
  
  ObjectPool$1(ObjectPool paramObjectPool) {}
  
  public synchronized Thread newThread(Runnable r)
  {
    String threadName = "RequestHandlerThread[" + ++threadIndex + "]";
    
    Thread thread = new Thread(r, threadName);
    thread.setDaemon(true);
    return thread;
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.ObjectPool.1
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package net.winstone.core;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.winstone.core.listener.Listener;
import net.winstone.core.listener.RequestHandlerThread;
import net.winstone.util.BoundedExecutorService;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ObjectPool
{
  protected static Logger logger = LoggerFactory.getLogger(ObjectPool.class);
  private static final transient int STARTUP_REQUEST_HANDLERS_IN_POOL = 5;
  private static final transient int MAX_IDLE_REQUEST_HANDLERS_IN_POOL = 20;
  private static final transient int MAX_REQUEST_HANDLERS_IN_POOL = 200;
  private static final transient int START_REQUESTS_IN_POOL = 10;
  private static final transient int MAX_REQUESTS_IN_POOL = 1000;
  private static final transient int START_RESPONSES_IN_POOL = 10;
  private static final transient int MAX_RESPONSES_IN_POOL = 1000;
  private final ExecutorService requestHandler;
  private List<WinstoneRequest> unusedRequestPool;
  private List<WinstoneResponse> unusedResponsePool;
  private final Object requestPoolSemaphore = new Object();
  private final Object responsePoolSemaphore = new Object();
  private final boolean simulateModUniqueId;
  private final boolean saveSessions;
  int startupRequest = 5;
  int maxRequestHandlesInPool = 200;
  int maxIdleRequestHandlesInPool = 20;
  private static int MAXPARAMALLOWED = WinstoneConstant.DEFAULT_MAXIMUM_PARAMETER_ALLOWED.intValue();
  
  public ObjectPool(Map<String, String> args)
    throws IOException
  {
    simulateModUniqueId = StringUtils.booleanArg(args, "simulateModUniqueId", Boolean.FALSE.booleanValue());
    
    int maxParamAllowed = StringUtils.intArg(args, "maxParamAllowed", WinstoneConstant.DEFAULT_MAXIMUM_PARAMETER_ALLOWED.intValue());
    if (maxParamAllowed < 1)
    {
      logger.error("MaxParamAllowed should be greather than 1. Set to default value {}", WinstoneConstant.DEFAULT_MAXIMUM_PARAMETER_ALLOWED);
      maxParamAllowed = WinstoneConstant.DEFAULT_MAXIMUM_PARAMETER_ALLOWED.intValue();
    }
    MAXPARAMALLOWED = maxParamAllowed;
    
    saveSessions = WebAppConfiguration.useSavedSessions(args);
    
    ExecutorService es = new ThreadPoolExecutor(20, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue(), new ThreadFactory()
    {
      private int threadIndex;
      
      public synchronized Thread newThread(Runnable r)
      {
        String threadName = "RequestHandlerThread[" + ++threadIndex + "]";
        
        Thread thread = new Thread(r, threadName);
        thread.setDaemon(true);
        return thread;
      }
    });
    requestHandler = new BoundedExecutorService(es, 200);
    
    unusedRequestPool = new ArrayList();
    unusedResponsePool = new ArrayList();
    
    startupRequest = StringUtils.intArg(args, "handlerCountStartup", 5);
    maxRequestHandlesInPool = StringUtils.intArg(args, "handlerCountMax", 200);
    maxIdleRequestHandlesInPool = StringUtils.intArg(args, "handlerCountMaxIdle", 20);
    for (int n = 0; n < 10; n++) {
      unusedRequestPool.add(new WinstoneRequest(MAXPARAMALLOWE
1 2 3 4 5 6 7 8 9 10 11 12 13 14

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd