wms-winstone-1.0.5

on e)
        {
          logger.error("Error initializing web application: prefix [" + prefix + "]", e);
        }
        if (webAppConfig != null) {
          logger.info("Deployed web application found at {}", aChildren.getAbsolutePath());
        }
      }
    }
  }
  
  public WebAppConfiguration getWebAppBySessionKey(String sessionKey)
  {
    for (WebAppConfiguration webAppConfiguration : webapps.values())
    {
      WinstoneSession session = webAppConfiguration.getSessionById(sessionKey, Boolean.FALSE.booleanValue());
      if (session != null) {
        return webAppConfiguration;
      }
    }
    return null;
  }
  
  public String getDefaultWebApp()
  {
    return defaultWebApp;
  }
}

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

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.winstone.WinstoneException;
import net.winstone.cluster.Cluster;
import net.winstone.jndi.JndiManager;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HostGroup
{
  protected static Logger logger = LoggerFactory.getLogger(HostGroup.class);
  private static final transient String DEFAULT_HOSTNAME = "default";
  private final Map<String, HostConfiguration> hostConfigs;
  private String defaultHostName;
  private final JndiManager jndiManager;
  private final Cluster cluster;
  private final ObjectPool objectPool;
  private final Map<String, String> args;
  
  public HostGroup(Cluster cluster, ObjectPool objectPool, JndiManager jndiManager, Map<String, String> args)
    throws IOException
  {
    hostConfigs = new HashMap();
    this.cluster = cluster;
    this.objectPool = objectPool;
    this.jndiManager = jndiManager;
    this.args = args;
    
    String hostDirName = StringUtils.stringArg(args, "hostsDir", null);
    String webappsDirName = StringUtils.stringArg(args, "webappsDir", null);
    if (hostDirName == null)
    {
      addHostConfiguration(webappsDirName, "default");
      defaultHostName = "default";
      logger.debug("Initialized in non-virtual-host mode");
    }
    else
    {
      initMultiHostDir(hostDirName);
      logger.debug("Initialized in virtual host mode with {} hosts: hostnames - {}", hostConfigs.size() + "", hostConfigs.keySet() + "");
    }
  }
  
  public HostConfiguration getHostByName(String hostname)
  {
    HostConfiguration host = (HostConfiguration)hostConfigs.get(hostname);
    return host != null ? host : (HostConfiguration)hostConfigs.get(defaultHostName);
  }
  
  public void addHostConfiguration(String webappsDirName, String hostname)
  {
    logger.debug("Deploying host found at {}", hostname);
    HostConfiguration config = new HostConfiguration(hostname, cluster, objectPool, jndiManager, args, webappsDirName);
    hostConfigs.put(hostname, config);
  }
  
  public void removeHostConfiguration(String hostname)
  {
    if (hostConfigs.containsKey(hostname))
    {
      ((HostConfiguration)hostConfigs.get(hostname)).destroy();
      hostConfigs.remove(hostname);
    }
  }
  
  public void destroy()
  {
    if (hostConfigs != null)
    {
      Set<String> hostnames = new HashSet(hostConfigs.keySet());
      for (Iterator<String> i = hostnames.iterator(); i.hasNext();)
      {
        String hostname = (String)i.next();
        ((HostConfiguration)hostConfigs.get(hostname)).destroy();
        hostConfigs.remove(hostname);
      }
      hostConfigs.clear();
    }
  }
  
  protected final void initMultiHostDir(String hostsDirName)
    throws IOException, WinstoneException
  {
    if (hostsDirName == null) {
      hostsDirName = "hosts";
    }
    File hostsDir = new File(hostsDirName);
    if (!hostsDir.exists()) {
      throw new WinstoneException("Hosts dir " + hostsDirName + " not foundd");
    }
    if (!hostsDir.isDirectory()) {
      throw new WinstoneException("Hosts dir " + hostsDirName + " is not a directory");
    }
    File[] children = hostsDir.listFiles();
    if ((children == null) || (children.length == 0)) {
      throw new WinstoneException("Hosts dir " + hostsDirName + " is empty (no child webapps found)");
    }
    for (int n = 0; n < children.length; n++)
    {
      String childName = children[n].getName();
      if ((children[n].isDirectory()) && 
        (!hostConfigs.containsKey(childName))) {
        addHostConfiguration(children[n].getCanonicalPath(), childName);
      }
      if ((defaultHostName == null) || (childName.equals("default"))) {
        defaultHostName = childName;
      }
    }
  }
  
  protected void finalize()
    throws Throwable
  {
    try
    {
      destroy();
    }
    catch (Throwable e) {}
    super.finalize();
  }
}

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

public enum HttpProtocole
{
  HTTP_100("Continue"),  HTTP_101("Switching Protocols"),  HTTP_102("Processing"),  HTTP_200("OK"),  HTTP_201("Created"),  HTTP_202("Accepted"),  HTTP_203("Non-Authoritative Information"),  HTTP_204("No Content"),  HTTP_205("Reset Content"),  HTTP_206("Partial Content"),  HTTP_207("Multi-Status"),  HTTP_300("Multiple Choices"),  HTTP_301("Moved Permanently"),  HTTP_302("Found"),  HTTP_303("See Other"),  HTTP_304("Not Modified"),  HTTP_305("Use Proxy"),  HTTP_306("unused"),  HTTP_307("Temporary Redirect"),  HTTP_400("Bad Request"),  HTTP_401("Authorization Required"),  HTTP_402("Payment Required"),  HTTP_403("Forbidden"),  HTTP_404("Not Found"),  HTTP_405("Method Not Allowed"),  HTTP_406("Not Acceptable"),  HTTP_407("Proxy Authentication Required"),  HTTP_408("Request Time-out"),  HTTP_409("Conflict"),  HTTP_410("Gone"),  HTTP_411("Length Required"),  HTTP_412("Precondition Failed"),  HTTP_413("Request Entity Too Large"),  HTTP_414("Request-URI Too Large"),  HTTP_415("Unsupported Media Type"),  HTTP_416("Requested Range Not Satisfiable"),  HTTP_417("Expectation Failed"),  HTTP_418("unused"),  HTTP_419("unused"),  HTTP_420("unused"),  HTTP_421("unused"),  HTTP_422("Unprocessable Entity"),  HTTP_423("Locked"),  HTTP_424("Failed Dependency"),  HTTP_425("No code"),  HTTP_426("Upgrade Required"),  HTTP_500("Internal Server Error"),  HTTP_501("Method Not Implemented"),  HTTP_502("Bad Gateway"),  HTTP_503("Service Temporarily Unavailable"),  HTTP_504("Gateway Time-out"),  HTTP_505("HTTP Version Not Supported"),  HTTP_506("Variant Also Negotiates"),  HTTP_507("Insufficient Storage"),  HTTP_508("unused"),  HTTP_509("unused"),  HTTP_510("Not Extended");
  
  private final String message;
  
  private HttpProtocole(String message)
  {
    this.message = message;
  }
  
  public final String getMessage()
  {
    return message;
  }
}

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

import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import net.winstone.WinstoneException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Ajp13IncomingPacket
{
  private static Logger logger = LoggerFactory.getLogger(Ajp13IncomingPacket.class);
  byte SERVER_FORWARD_REQUEST = 2;
  private final int packetLength;
  private final byte[] packetBytes;
  private byte packetType;
  private String method;
  private String protocol;
  private String uri;
  private String remoteAddr;
  private String remoteHost;
  private String serverName;
  private int serverPort;
  private boolean isSSL;
  private String[] headers;
  private Map<String, String> attributes;
  
  public Ajp13IncomingPacket(InputStream in, RequestHandlerThread handler)
    throws IOException
  {
    DataInputStream din = new DataInputStream(in);
    
    byte[] headerBuffer = new byte[4];
    din.readFully(headerBuffer);
    handler.setRequestStartTime();
    if ((headerBuffer[0] != 18) || (headerBuffer[1] != 52)) {
      throw new WinstoneException("Invalid AJP header");
    }
    packetLength = (((headerBuffer[2] & 0xFF) << 8) + (headerBuffer[3] & 0xFF));
    packetBytes = new byte[packetLength];
    din.readFully(packetBytes);
  }
  
  public byte parsePacket(String encoding)
    throws IOException
  {
    DataInputStream di = new DataInputStream(new ByteArrayInputStream(packetBytes));
    packetType = di.readByte();
    if (packetType != SERVER_FORWARD_REQUEST) {
      throw new WinstoneException("Unknown AJP packet type - " + packetType);
    }
    if (packetBytes[(packetLength - 1)] != -1) {
      throw new WinstoneException("Invalid AJP packet terminator");
    }
    method = decodeMethodType(di.readByte());
    logger.debug("Method: {}", method);
    
    protocol = readString(di, encoding);
    logger.debug("Protocol: {}", protocol);
    
    uri = readString(di, encoding);
    logger.debug("URI: {}", uri);
    
    remoteAddr = readString(di, encoding);
    logger.debug("Remote address: {}", remoteAddr);
    
    remoteHost = readString(di, encoding);
    logger.debug("RemoteHost: {}", remoteHost);
    
    serverName = readString(di, encoding);
    logger.debug("Server name: {}", serverName);
    
    serverPort = di.readShort();
    logger.debug("Server port: {}", "" + serverPort);
    
    isSSL = di.readBoolean();
    logger.debug("SSL: {}", "" + isSSL);
    
    int headerCount = di.readShort();
    logger.debug("Header Count: {}", "" + headerCount);
    
    headers = new String[headerCount];
    for (int n = 0; n < headerCount; n++)
    {
      int headerTypeOrLength = di.readShort();
      String headerName;
      String headerName;
      if ((headerTypeOrLength & 0xFF00) == 40960) {
        headerName = decodeHeaderType(headerTypeOrLength & 0xFFFF);
      } else {
        headerName = readString(di, encoding, headerTypeOrLength);
      }
      headers[n] = (headerName + ": " + readString(di, encoding));
      logger.debug("Header: {}", headers[n]);
    }
    attributes = new HashMap();
    while (Boolean.TRUE.booleanValue())
    {
      byte type = di.readByte();
      if (type == -1) {
        break;
      }
      String attName = decodeAttributeType(type);
      if (type == 10) {
        attName = readString(di, encoding);
      }
      String attValue = readString(di, encoding);
      attributes.put(attName, attValue);
      logger.debug("Attribute: {}={}", attName, attValue);
    }
    logger.debug("Successfully read AJP13 packet - length={}", "" + packetLength);
    return packetType;
  }
  
  public int getPacketLength()
  {
    return packetLength;
  }
  
  public String getMethod()
  {
    return method;
  }
  
  public String getProtocol()
  {
    return protocol;
  }
  
  public String getURI()
  {
    return uri;
  }
  
  public String getRemoteAddress()
  {
    return remoteAddr;
  }
  
  public String getRemoteHost()
  {
    return remoteHost;
  }
  
  public String getServerName()
  {
    return serverName;
  }
  
  public int getServerPort()
  {
    return serverPort;
  }
  
  public boolean isSSL()
  {
    return isSSL;
  }
  
  public String[] getHeaders()
  {
    return headers;
  }
  
  public Map<String, String> getAttributes()
  {
    return attributes;
  }
  
  private String readString(DataInput di, String encoding)
    throws IOException
  {
    return readString(di, encoding, di.readShort());
  }
  
  private String readString(DataInput di, String encoding, int length)
    throws IOException
  {
    if (length == -1) {
      return null;
    }
    if (length == 0)
    {
      di.readByte();
      return "";
    }
    byte[] buf = new byte[length];
    di.readFully(buf);
    di.readByte();
    return new String(buf, encoding);
  }
  
  private String decodeMethodType(byte methodType)
  {
    switch (methodType)
    {
    case 1: 
      return "OPTIONS";
    case 2: 
      return "GET";
    case 3: 
      return "HEAD";
    case 4: 
      return "POST";
    case 5: 
      return "PUT";
    case 6: 
      return "DELETE";
    case 7: 
      return "TRACE";
    case 8: 
      return "PROPFIND";
    case 9: 
      return "PROPPATCH";
    case 10: 
      return "MKCOL";
    case 11: 
      return "COPY";
    case 12: 
      return "MOVE";
    case 13: 
      return "LOCK";
    case 14: 
      return "UNLOCK";
    case 15: 
      return "ACL";
    case 16: 
      return "REPORT";
    case 17: 
      return "VERSION-CONTROL";
    case 18: 
      return "CHECKIN";
    case 19: 
      return "CHECKOUT";
    case 20: 
      return "UNCHECKOUT";
    case 21: 
      return "SEARCH";
    case 22: 
      return "MKWORKSPACE";
    case 23: 
      return "UPDATE";
    case 24: 
      return "LABEL";
    case 25: 
      return "MERGE";
    case 26: 
      return "BASELINE_CONTROL";
    case 27: 
      return "MKACTIVITY";
    }
    return "UNKNOWN";
  }
  
  private String decodeHeaderType(int headerType)
  {
    switch (headerType)
    {
    case 40961: 
      return "Accept";
    case 40962: 
      return "Accept-Charset";
    case 40963: 
      return "Accept-Encoding";
    case 40964: 
      return "Accept-Language";
    case 40965: 
      return "Authorization";
    case 40966: 
      return "Connection";
    case 40967: 
      return "Content-Type";
    case 40968: 
      return "Content-Length";
    case 40969: 
      return "Cookie";
    case 40970: 
      return "Cookie2";
    case 40971: 
      return "Host";
    case 40972: 
      return "Pragma";
    case 40973: 
      return "Referer";
    case 40974: 
      return "User-Agent";
    }
    return null;
  }
  
  private String decodeAttributeType(byte attributeType)
  {
    switch (attributeType)
    {
    case 1: 
      return "context";
    case 2: 
      return "servlet_path";
    case 3: 
      return "remote_user";
    case 4: 
      return "auth_type";
    case 5: 
      return "query_string";
    case 6: 
      return "jvm_route";
    case 7: 
      return "ssl_cert";
    case 8: 
      return "ssl_cipher";
    case 9: 
      return "ssl_session";
    case 10: 
      return "req_attribute";
    case 11: 
      return "ssl_key_size";
    case 12: 
      return "secret";
    case 13: 
      return "stored_method";
    }
    return null;
  }
}

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

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Map;
import net.winstone.WinstoneException;
import net.winstone.core.HostGroup;
import net.winstone.core.ObjectPool;
import net.winstone.core.WinstoneInputStream;
import net.winstone.core.WinstoneOutputStream;
import net.winstone.core.WinstoneRequest;
import net.winstone.core.WinstoneResponse;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Ajp13Listener
  implements Listener, Runnable
{
  protected static Logger logger = LoggerFactory.getLogger(Ajp13Listener.class);
  private static final int LISTENER_TIMEOUT = 5000;
  private static final int DEFAULT_PORT = 8009;
  private static final int CONNECTION_TIMEOUT = 60000;
  private static final int BACKLOG_COUNT = 1000;
  private static final int KEEP_ALIVE_TIMEOUT = -1;
  private static final String TEMPORARY_URL_STASH = "winstone.ajp13.TemporaryURLAttribute";
  private final HostGroup hostGroup;
  private final ObjectPool objectPool;
  private final int listenPort;
  private boolean interrupted;
  private final String listenAddress;
  private ServerSocket serverSocket;
  
  public Ajp13Listener(Map<String, String> args, ObjectPool objectPool, HostGroup hostGroup)
  {
    this.hostGroup = hostGroup;
    this.objectPool = objectPool;
    listenPort = StringUtils.intArg(args, "ajp13Port", 8009);
    listenAddress = StringUtils.stringArg(args, "ajp13ListenAddress", null);
  }
  
  public boolean start()
    throws IOException
  {
    if (listenPort < 0) {
      return Boolean.FALSE.booleanValue();
    }
    ServerSocket ss = null;
    try
    {
      ss = listenAddress == null ? new ServerSocket(listenPort, 1000) : new ServerSocket(listenPort, 1000, InetAddress.getByName(listenAddress));
    }
    catch (IOException e)
    {
      throw ((IOException)new IOException("Failed to listen on port " + listenPort).initCause(e));
    }
    ss.setSoTimeout(5000);
    logger.info("AJP13 Listener started: port={}", listenPort + "");
    serverSocket = ss;
    
    interrupted = Boolean.FALSE.booleanValue();
    Thread thread = new Thread(this, StringUtils.replaceToken("ConnectorThread:ajp13-[#0]", new String[] { Integer.toString(listenPort) }));
    thread.setDaemon(Boolean.TRUE.booleanValue());
    thread.start();
    return Boolean.TRUE.booleanValue();
  }
  
  public void run()
  {
    try
    {
      while (!interrupted)
      {
        Socket s = null;
        try
        {
          s = serverSocket.accept();
        }
        catch (InterruptedIOException err)
        {
          s = null;
        }
        if (s != null) {
          objectPool.handleRequest(s, this);
        }
      }
      serverSocket.close();
      serverSocket = null;
      logger.info("AJP13 Listener shutdown successfully");
    }
    catch (Throwable err)
    {
      logger.error("Error during AJP13 listener init or shutdown", err);
    }
  }
  
  public void destroy()
  {
    interrupted = Boolean.TRUE.booleanValue();
  }
  
  public void allocateRequestResponse(Socket socket, InputStream inSocket, OutputStream outSocket, RequestHandlerThread handler, boolean iAmFirst)
    throws SocketException, IOException
  {
    WinstoneRequest request = objectPool.getRequestFromPool();
    WinstoneResponse response = objectPool.getResponseFromPool();
    response.setRequest(request);
    request.setHostGroup(hostGroup);
    if (iAmFirst) {
      socket.setSoTimeout(60000);
    } else {
      socket.setSoTimeout(-1);
    }
    Ajp13IncomingPacket headers = null;
    try
    {
      headers = new Ajp13IncomingPacket(inSocket, handler);
      try
      {
        socket.setSoTimeout(60000);
      }
      catch (Throwable err) {}
      if (headers.getPacketLength() <= 0) {
        return;
      }
    }
    catch (InterruptedIOException err)
    {
      if (iAmFirst) {
        throw err;
      }
      deallocateRequestResponse(handler, request, response, null, null); return;
    }
    finally
    {
      try
      {
        socket.setSoTimeout(60000);
      }
      catch (Throwable err) {}
    }
    headers.parsePacket("8859_1");
    parseSocketInfo(headers, request);
    request.parseHeaders(Arrays.asList(headers.getHeaders()));
    String servletURI = parseURILine(headers, request, response);
    request.setAttribute("winstone.ajp13.TemporaryURLAttribute", servletURI);
    
    int contentLength = request.getContentLength();
    WinstoneInputStream inData;
    if (contentLength > 0)
    {
      byte[] bodyContent = new byte[contentLength];
      int position = 0;
      while (position < contentLength)
      {
        outSocket.write(getBodyRequestPacket(Math.min(contentLength - position, 8184)));
        position = getBodyResponsePacket(inSocket, bodyContent, position);
        logger.debug("Read {}/{} bytes from request body", "" + position, "" + contentLength);
      }
      WinstoneInputStream inData = new WinstoneInputStream(bodyContent);
      inData.setContentLength(contentLength);
    }
    else
    {
      inData = new WinstoneInputStream(new byte[0]);
    }
    request.setInputStream(inData);
    
    WinstoneOutputStream outData = new Ajp13OutputStream(socket.getOutputStream(), "8859_1");
    outData.setResponse(response);
    response.setOutputStream(outData);
    
    handler.setRequest(request);
    handler.setResponse(response);
    handler.setInStream(inData);
    handler.setOutStream(outData);
  }
  
  public void deallocateRequestResponse(RequestHandlerThread handler, WinstoneRequest request, WinstoneResponse response, WinstoneInputStream inData, WinstoneOutputStream outData)
    throws IOException
  {
    handler.setInStream(null);
    handler.setOutStream(null);
    handler.setRequest(null);
    handler.setResponse(null);
    if (request != null) {
      objectPool.releaseRequestToPool(request);
    }
    if (response != null) {
      objectPool.releaseResponseToPool(response);
    }
  }
  
  public String parseURI(RequestHandlerThread handler, WinstoneRequest req, WinstoneResponse rsp, WinstoneInputStream inData, Socket socket, boolean iAmFirst)
    throws IOException
  {
    String uri = (String)req.getAttribute("winstone.ajp13.TemporaryURLAttribute");
    req.removeAttribute("winstone.ajp13.TemporaryURLAttribute");
    return uri;
  }
  
  public void releaseSocket(Socket socket, InputStream inSocket, OutputStream outSocket)
    throws IOException
  {
    inSocket.close();
    outSocket.close();
    socket.close();
  }
  
  private void parseSocketInfo(Ajp13IncomingPacket headers, WinstoneRequest req)
  {
    req.setServerPort(headers.getServerPort());
    req.setRemoteIP(headers.getRemoteAddress());
    req.setServerName(headers.getServerName());
    req.setLocalPort(headers.getServerPort());
    req.setLocalAddr(headers.getServerName());
    req.setRemoteIP(headers.getRemoteAddress());
    if ((headers.getRemoteHost() != null) && (!headers.getRemoteHost().equals(""))) {
      req.setRemoteName(headers.getRemoteHost());
    } else {
      req.setRemoteName(headers.getRemoteAddress());
    }
    req.setScheme(headers.isSSL() ? "https" : "http");
    req.setIsSecure(headers.isSSL());
  }
  
  private String parseURILine(Ajp13IncomingPacket headers, WinstoneRequest request, WinstoneResponse response)
    throws UnsupportedEncodingException
  {
    request.setMethod(headers.getMethod());
    request.setProtocol(headers.getProtocol());
    response.setProtocol(headers.getProtocol());
    response.extractRequestKeepAliveHeader(request);
    for (Object o : headers.getAttributes().keySet())
    {
      String attName = (String)o;
      if (attName.equals("query_string"))
      {
        String qs = (String)headers.getAttributes().get("query_string");
        request.setQueryString(qs);
      }
      else if (attName.equals("ssl_cert"))
      {
        String certValue = (String)headers.getAttributes().get("ssl_cert");
        InputStream certStream = new ByteArrayInputStream(certValue.getBytes("8859_1"));
        X509Certificate[] certificateArray = new X509Certificate[1];
        try
        {
          certificateArray[0] = ((X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(certStream));
        }
        catch (CertificateException err)
        {
          logger.debug("Skipping invalid SSL certificate: {}", certValue);
        }
        request.setAttribute("javax.servlet.request.X509Certificate", certificateArray);
        request.setIsSecure(Boolean.TRUE.booleanValue());
      }
      else if (attName.equals("ssl_cipher"))
      {
        String cipher = (String)headers.getAttributes().get("ssl_cipher");
        request.setAttribute("javax.servlet.request.cipher_suite", cipher);
        request.setAttribute("javax.servlet.request.key_size", getKeySize(cipher));
        request.setIsSecure(Boolean.TRUE.booleanValue());
      }
      else if (attName.equals("ssl_session"))
      {
        request.setAttribute("javax.servlet.request.ssl_session", headers.getAttributes().get("ssl_session"));
        request.setIsSecure(Boolean.TRUE.booleanValue());
      }
      else
      {
        logger.debug("Unknown request attribute ignored: {}={}", attName, "" + (String)headers.getAttributes().get(attName));
      }
    }
    return headers.getURI();
  }
  
  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 boolean processKeepAlive(WinstoneRequest request, WinstoneResponse response, InputStream inSocket)
    throws IOException, InterruptedException
  {
    return Boolean.TRUE.booleanValue();
  }
  
  private byte[] getBodyRequestPacket(int desiredPacketLength)
  {
    byte[] getBodyRequestPacket = { 65, 66, 0, 3, 6, 0, 0 };
    Ajp13OutputStream.setIntBlock(desiredPacketLength, getBodyRequestPacket, 5);
    return getBodyRequestPacket;
  }
  
  private int getBodyResponsePacket(InputStream in, byte[] buffer, int offset)
    throws IOException
  {
    DataInputStream din = new DataInputStream(in);
    
    byte[] headerBuffer = new byte[4];
    din.readFully(headerBuffer);
    if ((headerBuffer[0] != 18) || (headerBuffer[1] != 52)) {
      throw new WinstoneException("Invalid AJP header");
    }
    int packetLength = ((headerBuffer[2] & 0xFF) << 8) + (headerBuffer[3] & 0xFF);
    if (packetLength == 0) {
      return offset;
    }
    byte[] bodyLengthBuffer = new byte[2];
    din.readFully(bodyLengthBuffer);
    int bodyLength = ((bodyLengthBuffer[0] & 0xFF) << 8) + (bodyLengthBuffer[1] & 0xFF);
    din.readFully(buffer, offset, bodyLength);
    
    return bodyLength + offset;
  }
  
  public static void packetDump(byte[] packetBytes, int packetLength)
  {
    String dump = "";
    for (int n = 0; n < packetLength; n += 16)
    {
      String line = Integer.toHexString(n >> 4 & 0xF) + "0:";
      for (int j = 0; j < Math.min(packetLength - n, 16); j++) {
        line = line + " " + ((packetBytes[(n + j)] & 0xFF) < 16 ? "0" : "") + Integer.toHexString(packetBytes[(n + j)] & 0xFF);
      }
      line = line + "    ";
      for (int j = 0; j < Math.min(packetLength - n, 16); j++)
      {
        byte me = (byte)(packetBytes[(n + j)] & 0xFF);
        line = line + ((me > 32) && (me < 123) ? (char)me : '.');
      }
      dump = dump + line + "\r\n";
    }
    System.out.println(dump);
  }
}

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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
import net.winstone.WinstoneException;
import net.winstone.core.WinstoneOutputStream;
import net.winstone.core.WinstoneResponse;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Ajp13OutputStream
  extends WinstoneOutputStream
{
  protected static Logger logger = LoggerFactory.getLogger(Ajp13OutputStream.class);
  byte CONTAINER_SEND_BODY_CHUNK = 3;
  byte CONTAINER_SEND_HEADERS = 4;
  byte CONTAINER_END_RESPONSE = 5;
  static final Map<String, byte[]> headerCodes = new HashMap();
  private final String headerEncoding;
  
  static
  {
    headerCodes.put("content-type", new byte[] { -96, 1 });
    headerCodes.put("content-language", new byte[] { -96, 2 });
    headerCodes.put("content-length", new byte[] { -96, 3 });
    headerCodes.put("date", new byte[] { -96, 4 });
    headerCodes.put("last-modified", new byte[] { -96, 5 });
    headerCodes.put("location", new byte[] { -96, 6 });
    headerCodes.put("set-cookie", new byte[] { -96, 7 });
    headerCodes.put("set-cookie2", new byte[] { -96, 8 });
    headerCodes.put("servlet-engine", new byte[] { -96, 9 });
    headerCodes.put("server", new byte[] { -96, 9 });
    headerCodes.put("status", new byte[] { -96, 10 });
    headerCodes.put("www-authenticate", new byte[] { -96, 11 });
  }
  
  public Ajp13OutputStream(OutputStream outStream, String headerEncoding)
  {
    super(outStream, Boolean.FALSE.booleanValue());
    this.headerEncoding = headerEncoding;
  }
  
  public void commit()
    throws IOException
  {
    logger.trace("Written {} bytes to response body", "" + bytesCommitted);
    buffer.flush();
    if (!committed)
    {
      owner.validateHeaders();
      committed = Boolean.TRUE.booleanValue();
      ByteArrayOutputStream headerArrayStream = new ByteArrayOutputStream();
      for (String header : owner.getHeaders())
      {
        int colonPos = header.indexOf(':');
        if (colonPos == -1) {
          throw new WinstoneException("No colon header: " + header);
        }
        String headerName = StringUtils.noCRLF(header.substring(0, colonPos).trim());
        String headerValue = StringUtils.noCRLF(header.substring(colonPos + 1).trim());
        byte[] headerCode = (byte[])headerCodes.get(headerName.toLowerCase());
        if (headerCode == null) {
          headerArrayStream.write(getStringBlock(headerName));
        } else {
          headerArrayStream.write(headerCode);
        }
        headerArrayStream.write(getStringBlock(headerValue));
      }
      for (Cookie cookie : owner.getCookies())
      {
        String cookieText = owner.writeCookie(cookie);
        int colonPos = cookieText.indexOf(':');
        if (colonPos == -1) {
          throw new WinstoneException("No colon header: " + cookieText);
        }
        String headerName = cookieText.substring(0, colonPos).trim();
        String headerValue = cookieText.substring(colonPos + 1).trim();
        byte[] headerCode = (byte[])headerCodes.get(headerName.toLowerCase());
        if (headerCode == null) {
          headerArrayStream.write(getStringBlock(headerName));
        } else {
          headerArrayStream.write(headerCode);
        }
        headerArrayStream.write(getStringBlock(headerValue));
      }
      byte[] headerArray = headerArrayStream.toByteArray();
      byte[] headerPacket = new byte[12];
      headerPacket[0] = 65;
      headerPacket[1] = 66;
      setIntBlock(headerArray.length + 8, headerPacket, 2);
      headerPacket[4] = CONTAINER_SEND_HEADERS;
      setIntBlock(owner.getStatus(), headerPacket, 5);
      setIntBlock(0, headerPacket, 7);
      headerPacket[9] = 0;
      setIntBlock(owner.getHeaders().size() + owner.getCookies().size(), headerPacket, 10);
      
      outStream.write(headerPacket);
      outStream.write(headerArray);
    }
    byte[] bufferContents = buffer.toByteArray();
    int position = 0;
    while (position < bufferContents.length)
    {
      int packetLength = Math.min(bufferContents.length - position, 8184);
      byte[] responsePacket = new byte[packetLength + 8];
      responsePacket[0] = 65;
      responsePacket[1] = 66;
      setIntBlock(packetLength + 4, responsePacket, 2);
      responsePacket[4] = CONTAINER_SEND_BODY_CHUNK;
      setIntBlock(packetLength, responsePacket, 5);
      System.arraycopy(bufferContents, position, responsePacket, 7, packetLength);
      responsePacket[(packetLength + 7)] = 0;
      position += packetLength;
      
      outStream.write(responsePacket);
    }
    buffer.reset();
    bufferPosition = 0L;
  }
  
  public void finishResponse()
    throws IOException
  {
    byte[] endResponse = { 65, 66, 0, 2, CONTAINER_END_RESPONSE, 1 };
    
    outStream.write(endResponse);
  }
  
  public byte[] getIntBlock(int integer)
  {
    byte hi = (byte)(0xFF & integer >> 8);
    byte lo = (byte)(0xFF & integer - (hi << 8));
    return new byte[] { hi, lo };
  }
  
  public static void setIntBlock(int integer, byte[] packet, int offset)
  {
    byte hi = (byte)(0xFF & integer >> 8);
    byte lo = (byte)(0xFF & integer - (hi << 8));
    packet[offset] = hi;
    packet[(offset + 1)] = lo;
  }
  
  public byte[] getStringBlock(String text)
    throws UnsupportedEncodingException
  {
    byte[] textBytes = text.getBytes(headerEncoding);
    byte[] outArray = new byte[textBytes.length + 3];
    System.arraycopy(getIntBlock(textBytes.length), 0, outArray, 0, 2);
    System.arraycopy(textBytes, 0, outArray, 2, textBytes.length);
    outArray[(textBytes.length + 2)] = 0;
    return outArray;
  }
}

/* Location:
 * Qualified Name:     net.winstone.core.listener.Ajp13OutputStream
 * 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.Inet6Address;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.winstone.WinstoneException;
import net.winstone.WinstoneResourceBundle;
import net.winstone.core.HostGroup;
import net.winstone.core.ObjectPool;
import net.winstone.core.WinstoneInputStream;
import net.winstone.core.WinstoneOutputStream;
import net.winstone.core.WinstoneRequest;
import net.winstone.core.WinstoneResponse;
import net.winstone.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpListener
  implements Listener, Runnable
{
  private static Logger logger = LoggerFactory.getLogger(HttpListener.class);
  protected static int LISTENER_TIMEOUT = 5000;
  protected static int CONNECTION_TIMEOUT = 60000;
  protected static int BACKLOG_COUNT = 5000;
  protected static boolean DEFAULT_HNL = Boolean.FALSE.booleanValue();
  protected static int KEEP_ALIVE_TIMEOUT = 10000;
  protected static int KEEP_ALIVE_SLEEP = 20;
  protected static int KEEP_ALIVE_SLEEP_MAX = 500;
  protected final HostGroup hostGroup;
  protected final ObjectPool objectPool;
  protected boolean doHostnameLookups;
  protected int listenPort;
  protected String listenAddress;
  protected boolean interrupted = Boolean.FALSE.booleanValue();
  private final String serverVersion;
  private ServerSocket serverSocket;
  
  public HttpListener(Map<String, String> args, ObjectPool objectPool, HostGroup hostGroup)
    throws IOException
  {
    serverVersion = WinstoneResourceBundle.getInstance().getString("ServerVersion");
    
    this.hostGroup = hostGroup;
    this.objectPool = objectPool;
    listenPort = Integer.parseInt(StringUtils.stringArg(args, getConnectorName() + "Port", "" + getDefaultPort()));
    listenAddress = StringUtils.stringArg(args, getConnectorName() + "ListenAddress", null);
    doHostnameLookups = StringUtils.booleanArg(args, getConnectorName() + "DoHostnameLookups", DEFAULT_HNL);
  }
  
  public boolean start()
    throws IOException
  {
    if (listenPort < 0) {
      return Boolean.FALSE.booleanValue();
    }
    interrupted = Boolean.FALSE.booleanValue();
    
    ServerSocket ss = getServerSocket();
    ss.setSoTimeout(LISTENER_TIMEOUT);
    logger.info("{} Listener started: port={}", getConnectorName().toUpperCase(), listenPort + "");
    serverSocket = ss;
    
    Thread thread = new Thread(this, "ConnectorThread:" + getConnectorName() + "-" + Integer.toString(listenPort));
    thread.setDaemon(Boolean.TRUE.booleanValue());
    thread.start();
    return Boolean.TRUE.booleanValue();
  }
  
  protected int getDefaultPort()
  {
    return 8080;
  }
  
  protected final String getConnectorName()
  {
    return getConnectorScheme();
  }
  
  protected String getConnectorScheme()
  {
    return "http";
  }
  
  protected ServerSocket getServerSocket()
    throws IOException
  {
    try
    {
      return listenAddress == null ? new ServerSocket(listenPort, BACKLOG_COUNT) : new ServerSocket(listenPort, BACKLOG_COUNT, InetAddress.getByName(listenAddress));
    }
    catch (IOException e)
    {
      throw ((IOException)new IOException("Failed to listen on port " + listenPort).initCause(e));
    }
  }
  
  public void run()
  {
    try
    {
      while (!interrupted)
      {
        Socket s = null;
        try
        {
          s = serverSocket.accept();
        }
        catch (InterruptedIOException err)
        {
          s = null;
        }
        if (s != null) {
          objectPool.handleRequest(s, this);
        }
      }
      serverSocket.close();
      serverSocket = null;
      
      logger.info("{} Listener shutdown successfully", getConnectorName().toUpperCase());
    }
    catch (Throwable err)
    {
      logger.error("Error during " + getConnectorName().toUpperCase() + " listener init or shutdown", err);
    }
  }
  
  public void destroy()
  {
    interrupted = Boolean.TRUE.booleanValue();
  }
  
  public void allocateRequestResponse(Socket socket, InputStream inSocket, OutputStream outSocket, RequestHandlerThread handler, boolean iAmFirst)
    throws SocketException, IOException
  {
    logger.trace("Allocating request/response", Thread.currentThread().getName());
    
    socket.setSoTimeout(CONNECTION_TIMEOUT);
    
    WinstoneInputStream inData = new WinstoneInputStream(inSocket);
    WinstoneOutputStream outData = new WinstoneOutputStream(outSocket, Boolean.FALSE.booleanValue());
    WinstoneRequest request = objectPool.getRequestFromPool();
    WinstoneResponse rsp = objectPool.getResponseFromPool();
    outData.setResponse(rsp);
    request.setInputStream(inData);
    rsp.setOutputStream(outData);
    rsp.setRequest(request);
    
    request.setHostGroup(hostGroup);
    
    handler.setRequest(request);
    handler.setResponse(rsp);
    handler.setInStream(inData);
    handler.setOutStream(outData);
    
    rsp.setHeader("Server", serverVersion);
  }
  
  public void deallocateRequestResponse(RequestHandlerThread handler, WinstoneRequest req, WinstoneResponse rsp, WinstoneInputStream inData, WinstoneOutputStream outData)
    throws IOException
  {
    handler.setInStream(null);
    handler.setOutStream(null);
    handler.setRequest(null);
    handler.setResponse(null);
    if (req != null) {
      objectPool.releaseRequestToPool(req);
    }
    if (rsp != null) {
      objectPool.releaseResponseToPool(rsp);
    }
  }
  
  public String parseURI(RequestHandlerThread handler, WinstoneRequest req, WinstoneResponse rsp, WinstoneInputStream inData, Socket socket, boolean iAmFirst)
    throws IOException
  {
    parseSocketInfo(socket, req);
    
    socket.setSoTimeout(KEEP_ALIVE_TIMEOUT);
    
    byte[] uriBuffer = null;
    try
    {
      logger.debug("Waiting for a URI line");
      uriBuffer = inData.readLine();
      try
      {
        socket.setSoTimeout(CONNECTION_TIMEOUT);
      }
      catch (Throwable err) {}
      handler.setRequestStartTime();
    }
    catch (InterruptedIOException err)
    {
      if (iAmFirst) {
        throw err;
      }
      return null;
    }
    finally
    {
      try
      {
        socket.setSoTimeout(CONNECTION_TIMEOUT);
      }
      catch (Throwable err) {}
    }
    String uriLine = new String(uriBuffer);
    if (uriLine.trim().equals("")) {
      throw new SocketException("Empty URI Line");
    }
    String s
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