Package org.apache.tools.moo.cookie

Source Code of org.apache.tools.moo.cookie.CookieJar

/*
* $Header: /home/cvspublic/jakarta-tools/moo/src/share/org/apache/tools/moo/cookie/CookieJar.java,v 1.1 1999/10/20 23:33:15 arun Exp $
* $Date: 1999/10/20 23:33:15 $
* $Revision: 1.1 $
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* @author  Ramesh Mandava [rameshm@eng.sun.com]
*/
package org.apache.tools.moo.cookie;

import java.util.*;
import java.io.*;
import java.net.URLConnection;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.net.URL;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;

/**
* Represents a collection of Cookie instances.
* <p>
* Fires events when the cookies have been changed internally. Deals
* with management of cookies in terms of saving and loading them,
* and disabling them.
*
*/

public class CookieJar implements CookieJarInterface {

    private VetoableChangeSupport vceListeners;

    private int listenerNum = 0;

    private static Hashtable cookieJar;

    private static boolean initialized = false;

    /* public no arg constructor for bean */
    public CookieJar() {
  if (!initialized) {
      vceListeners = new VetoableChangeSupport(this);
      cookieJar = new Hashtable();
      initialized = true;
  }
    }

/////////////////////////////////////////////////////////////
/**
     * Records any cookies which have been sent as part of an HTTP response.
     * The connection parameter must be already have been opened, so that
     * the response headers are available.  It's ok to pass a non-HTTP
     * URL connection, or one which does not have any set-cookie headers.
     */
    public void recordAnyCookies(Vector rcvVectorOfCookies , URL url ) {

  if ((rcvVectorOfCookies == null) || ( rcvVectorOfCookies.size()== 0) ) {
      // no headers here
      return;
 
  try {
        Properties properties = new Properties();
  //FileInputStream fin = new FileInputStream("ServerAutoRun.properties");
  //properties.load(fin);
    InputStream fin =
        this.getClass().getResourceAsStream("cookie.properties");
  properties.load(fin);

  String cookiepolicy = properties.getProperty("cookie.acceptpolicy");
  if (cookiepolicy == null || cookiepolicy.equals("none")) {
      return;
  }


  for (int hi = 0; hi<rcvVectorOfCookies.size(); hi++) {

    String cookieValue = (String)rcvVectorOfCookies.elementAt(hi) ;
    recordCookie(url, cookieValue); // What to do here
      }

  }
  catch( Exception e )
  {
    System.out.println("exception : " + e );
  }
    }


    /**
     * Create a cookie from the cookie, and use the HttpURLConnection to
     * fill in unspecified values in the cookie with defaults.
     */
    public void recordCookie(URL url,
             String cookieValue) {
  HttpCookie cookie = new HttpCookie(url, cookieValue);
 
  // First, check to make sure the cookie's domain matches the
  // server's, and has the required number of '.'s
  String twodot[]=
      {"com", "edu", "net", "org", "gov", "mil", "int"};
  String domain = cookie.getDomain();
  if( domain == null )
      return;
  int index = domain.indexOf(':');
  if (index != -1) {
      int portCookie;
      try {
    portCookie = (Integer.valueOf(domain.substring(index+1,domain.length()))).intValue();
      } catch (Exception e) {
    return;
      }
      portCookie = ( portCookie == -1 ) ? 80 : portCookie;
      domain=domain.substring(0,index);
  }
  domain.toLowerCase();
 
  String host = url.getHost();
  host.toLowerCase();

  boolean domainOK = host.equals(domain);
  if( !domainOK && host.endsWith( domain ) ) {
      int dotsNeeded = 2;
      for( int i = 0; i < twodot.length; i++ ) {
    if( domain.endsWith( twodot[i] ) ) {
        dotsNeeded = 1;
    }
      }

      int lastChar = domain.length();
      for( ; lastChar > 0 && dotsNeeded > 0; dotsNeeded-- ) {
    lastChar = domain.lastIndexOf( '.', lastChar-1 );
      }

      if( lastChar > 0 )
    domainOK = true;
  }

  if( domainOK ) {
      recordCookie(cookie);

  }
    }


    /**
     * Record the cookie in the in-memory container of cookies.  If there
     * is already a cookie which is in the exact same domain with the
     * exact same
     */
    public void recordCookie(HttpCookie cookie) {
  if (!checkIfCookieOK(cookie)) {
      return;
  }
  synchronized (cookieJar) {
     
      String domain = cookie.getDomain().toLowerCase();

      Vector cookieList = (Vector)cookieJar.get(domain);
      if (cookieList == null) {
    cookieList = new Vector();
      }

      addOrReplaceCookie(cookieList, cookie);
      cookieJar.put(domain, cookieList);
     
  }

    }

    public boolean checkIfCookieOK(HttpCookie cookie) {
  try {
      if (vceListeners != null) {
    vceListeners.fireVetoableChange("cookie", null, cookie );
      }
  } catch (PropertyVetoException ex) {
      return false;
  }
 
  return true;
    }

    /**
     * Scans the vector of cookies looking for an exact match with the
     * given cookie.  Replaces it if there is one, otherwise adds
     * one at the end.  The vector is presumed to have cookies which all
     * have the same domain, so the domain of the cookie is not checked.
     * <p>
     * <p>
     * If this is called, it is assumed that the cookie jar is exclusively
     * held by the current thread.
     *
     */
    private void addOrReplaceCookie(Vector cookies,
               HttpCookie cookie) {
  int numCookies = cookies.size();

  String path = cookie.getPath();
  String name = cookie.getName();
  HttpCookie replaced = null;
  int replacedIndex = -1;

  for (int i = 0; i < numCookies; i++) {
      HttpCookie existingCookie = (HttpCookie)cookies.elementAt(i);
 
      String existingPath = existingCookie.getPath();
      if (path.equals(existingPath)) {
    String existingName = existingCookie.getName();
    if (name.equals(existingName)) {
        // need to replace this one!
        replaced = existingCookie;
        replacedIndex = i;
        break;
    }
      }
  }
 
 
  // Do the replace - if cookie has already expired, remove
  // the replaced cookie.
  if (replaced != null) {
      if (cookie.isSaveableInMemory()) {
    cookies.setElementAt(cookie, replacedIndex);
    //System.out.println("REPLACED existing cookie with " + cookie);
      } else {
    cookies.removeElementAt(replacedIndex);
    //System.out.println("Removed cookie b/c or expr " + cookie);
      }

  } else { // only save the cookie in memory if it is non persistent
             // or not expired.
      if (cookie.isSaveableInMemory()) {
    cookies.addElement(cookie);
    //System.out.println("RECORDED new cookie " + cookie);
      }

  }

    }

    public String applyRelevantCookies(URL url ) {

       try
    Properties properties = new Properties();
    //FileInputStream fin = new FileInputStream("ServerAutoRun.properties");
    //properties.load(fin);
        InputStream fin =
        this.getClass().getResourceAsStream("cookie.properties");
    properties.load(fin);
    // check current accept policy instead enableCookies
    String cookiepolicy = properties.getProperty("cookie.acceptpolicy");
    if (cookiepolicy == null || cookiepolicy.equals("none")) {
        return null;
    }

    return applyCookiesForHost(url);

  }
  catch ( Exception e )
  {
    System.out.println("Exception : " +e );
    return null;
  }
     



    }

   
   /**
     * Host may be a FQDN, or a partial domain name starting with a dot.
     * Adds any cookies which match the host and path to the
     * cookie set on the URL connection.
     */
    private String applyCookiesForHost(URL url ){
  String cookieString = null;
  Vector cookieVector = getAllRelevantCookies(url);
 
  if (cookieVector != null) {

      for (Enumeration e = cookieVector.elements(); e.hasMoreElements();) {
    HttpCookie cookie = (HttpCookie)e.nextElement();
    if( cookieString == null ) {
        cookieString = cookie.getNameValue();
    } else {
        cookieString = cookieString + "; " + cookie.getNameValue();
    }
      }
     
   /*

      if( cookieString != null ) {
    httpConn.setRequestProperty("Cookie", cookieString);
  
//    System.out.println("Returned cookie string: " + cookieString + " for HOST = " + host);
       }

    */


  }
//    System.out.println("Returned cookie string: " + cookieString + " for HOST = " + host);
  return cookieString;
 
    }

    private Vector getAllRelevantCookies(URL url) {
  String host = url.getHost();
  Vector cookieVector = getSubsetRelevantCookies(host, url);

  Vector tempVector;
  int index;

  while ((index = host.indexOf('.', 1)) >= 0) {
      // trim off everything up to, and including the dot.
      host = host.substring(index+1);
     
            // add onto cookieVector
      tempVector = getSubsetRelevantCookies(host,url);
      if (tempVector != null ) {
    for (Enumeration e = tempVector.elements(); e.hasMoreElements(); ) {
        if (cookieVector == null) {
      cookieVector = new Vector(2);
        }

        cookieVector.addElement(e.nextElement());

    }
      }
  }
  return cookieVector;
    }

    private Vector getSubsetRelevantCookies(String host, URL url) {

  Vector cookieList = (Vector)cookieJar.get(host);
 
//  System.out.println("getRelevantCookies() .. for host, url " + host +", "+url);
  Vector cookiePortList = (Vector)cookieJar.get(host+":"+((url.getPort() == -1) ? 80 : url.getPort()));
  if (cookiePortList != null) {
      if (cookieList == null) {
    cookieList = new Vector(10);
      }
      Enumeration cookies = cookiePortList.elements();
      while (cookies.hasMoreElements()) {
    cookieList.addElement(cookies.nextElement());
     
  }
 
     
  if (cookieList == null) {
      return null;
  }

  String path = url.getFile();
//  System.out.println("        path is " + path + "; protocol = " + url.getProtocol());


  int queryInd = path.indexOf('?');
  if (queryInd > 0) {
      // strip off the part following the ?
      path = path.substring(0, queryInd);
  }

  Enumeration cookies = cookieList.elements();
  Vector cookiesToSend = new Vector(10);

  while (cookies.hasMoreElements()) {
      HttpCookie cookie = (HttpCookie)cookies.nextElement();
 
      String cookiePath = cookie.getPath();

      if (path.startsWith(cookiePath)) {
    // larrylf: Actually, my documentation (from Netscape)
    // says that /foo should
    // match /foobar and /foo/bar.  Yuck!!!

    if (!cookie.hasExpired()) {
        cookiesToSend.addElement(cookie);
    }

/*
   We're keeping this piece of commented out code around just in
   case we decide to put it back.  the spec does specify the above,
   but it is so disgusting!

    int cookiePathLen = cookiePath.length();

    // verify that /foo does not match /foobar by mistake
    if ((path.length() == cookiePathLen)
        || (path.length() > cookiePathLen &&
      path.charAt(cookiePathLen) == '/')) {
   
        // We have a matching cookie!

        if (!cookie.hasExpired()) {
      cookiesToSend.addElement(cookie);
        }
    }
*/
      }
  }

  // Now, sort the cookies in most to least specific order
  // Yes, its the deaded bubblesort!! Wah Ha-ha-ha-ha....
  // (it should be a small vector, so perf is not an issue...)
  if( cookiesToSend.size() > 1 ) {
      for( int i = 0; i < cookiesToSend.size()-1; i++ ) {
    HttpCookie headC = (HttpCookie)cookiesToSend.elementAt(i);
    String head = headC.getPath();
    // This little excercise is a cheap way to get
    // '/foo' to read more specfic then '/'
    if( !head.endsWith("/") ) {
        head = head + "/";
    }
    for( int j = i+1; j < cookiesToSend.size(); j++ ) {
        HttpCookie scanC = (HttpCookie)cookiesToSend.elementAt(j);
        String scan = scanC.getPath();
        if( !scan.endsWith("/") ) {
      scan = scan + "/";
        }

        int headCount = 0;
        int index = -1;
        while( (index=head.indexOf('/', index+1)) != -1 ) {
      headCount++;
        }
        index = -1;

        int scanCount = 0;
        while( (index=scan.indexOf('/', index+1)) != -1 ) {
      scanCount++;
        }

        if( scanCount > headCount ) {
      cookiesToSend.setElementAt(headC, j);
      cookiesToSend.setElementAt(scanC, i);
      headC = scanC;
      head = scan;
        }
    }
      }
  }


    return cookiesToSend;

    }

    /*
     * Writes cookies out to PrintWriter if they are persistent
     * (i.e. have a expr date)
     * and haven't expired. Will remove cookies that have expired as well
     */
    private void saveCookiesToStream(PrintWriter pw) {

  Enumeration cookieLists = cookieJar.elements();
   
  while (cookieLists.hasMoreElements()) {
      Vector cookieList = (Vector)cookieLists.nextElement();

      Enumeration cookies = cookieList.elements();

      while (cookies.hasMoreElements()) {
    HttpCookie cookie = (HttpCookie)cookies.nextElement();
   
    if (cookie.getExpirationDate() != null) {
        if (cookie.isSaveable()) {
      pw.println(cookie);
        } else { // the cookie must have expired,
      //remove from Vector cookieList
      cookieList.removeElement(cookie);
        }
    
    }  
      }
  }
        // Must print something to the printwriter in the case that
  // the cookieJar has been cleared - otherwise the old cookie
  // file will continue to exist.
  pw.print("");
    }
/////////////////////////////////////////////////////////////
    /* adds cookieList to the existing cookie jar*/
    public void addToCookieJar(HttpCookie[] cookieList) {

  if (cookieList != null) {
      for (int i = 0; i < cookieList.length; i++) {
   
    recordCookie(cookieList[i]);
      }
  }

    }

    /*adds one cookie to the Cookie Jar */
    public void addToCookieJar(String cookieString, URL docURL) {
  recordCookie(new HttpCookie(docURL, cookieString));
    }

    /* loads the cookies from the given filename */
    public void loadCookieJarFromFile(String cookieFileName) {
  try {
      FileReader fr = new FileReader(cookieFileName);
     
      BufferedReader in = new BufferedReader(fr);

      try {
    String cookieString;
    while ((cookieString = in.readLine()) != null) {
        HttpCookie cookie = new HttpCookie(cookieString);
        // Record the cookie, without notification.  We don't
        // do a notification for cookies that are read at
        // program start-up.
        recordCookie(cookie);
    }
      } finally {
    in.close();
      }

     
  } catch (IOException e) {
      // do nothing; it's not an error not to have persistent cookies
  }

    }
   
    /* saves the cookies to the given file specified by fname */
    public void saveCookieJarToFile(String cookieFileName) {
  try {
      FileWriter fw = new FileWriter(cookieFileName);
      PrintWriter pw = new PrintWriter(fw, false);

      try {
    saveCookiesToStream(pw);
      } finally {
    pw.close();
      }

  } catch (IOException e) {
      // REMIND: I18N
      System.err.println("Saving cookies failed " + e.getMessage());
  }
    }

    /**
     * Return an array with all of the cookies represented by this
     * jar.  This is useful when the bean is shutting down, and the client
     * wants to make the cookie jar persist.
     */
    public HttpCookie[] getAllCookies() {

  Vector result = new Vector();
  Hashtable jar;
  jar = (Hashtable) cookieJar.clone();
 
  synchronized (jar) {
 
      for (Enumeration e = jar.elements(); e.hasMoreElements() ;) {
    Vector v = (Vector) e.nextElement();
    for (int i = 0; i < v.size(); i++) {
        HttpCookie hc = (HttpCookie) v.elementAt(i);
        result.addElement(hc);
       
    }
   
      }
  }

  HttpCookie[] resultA = new HttpCookie[result.size()];
  for (int i = 0; i < result.size(); i++) {
      resultA[i] = (HttpCookie) result.elementAt(i);
  }
  return resultA;
    }

    /* Gets all cookies that applies for the URL */
    public HttpCookie[] getCookiesForURL(URL url) {

  Vector cookieVector = getAllRelevantCookies(url);

  if (cookieVector == null) {
      return null;
  }

  int i = 0;
  HttpCookie[] cookieArr = new HttpCookie[cookieVector.size()];

  for (Enumeration e = cookieVector.elements(); e.hasMoreElements(); ) {

      cookieArr[i++] = (HttpCookie)e.nextElement();
//      System.out.println("cookieArr["+(i-1)+"] = " +cookieArr[i-1].toString());
  }
     
  return cookieArr;
    }

    /* this will set the property of enableCookies to isDisabled */
    public void setCookieDisable(boolean isDisabled) {

  // Pending visit back this again
  try {
  Properties properties = new Properties();
  //properties.load(new FileInputStream("ServerAutoRun.properties") );
 
    InputStream fin =
        this.getClass().getResourceAsStream("cookie.properties");
  properties.load(fin);
 
  properties.put("enableCookies", isDisabled ? "false" : "true");
    properties.save(new FileOutputStream("ServerAutoRun.properties"),"comments");
  }
  catch ( Exception e )
  {
    System.out.println("Exception : " + e );
  }
    }

    public void discardAllCookies() {
  try {
      if (vceListeners != null) {
    vceListeners.fireVetoableChange("cookie", null, null);
      }
  } catch (PropertyVetoException ex) {
     
  }
 
  cookieJar.clear();
 
    }

    /*
     * purges any expired cookies in the Cookie hashtable.
     */
    public void purgeExpiredCookies() {
  Enumeration cookieLists = cookieJar.elements();
   
  while (cookieLists.hasMoreElements()) {
      Vector cookieList = (Vector)cookieLists.nextElement();

      Enumeration cookies = cookieList.elements();

      while (cookies.hasMoreElements()) {
    HttpCookie cookie = (HttpCookie)cookies.nextElement();
   
    if (cookie.hasExpired()) {
        cookieList.removeElement(cookie);
    }  
      }
  }

    }

    /*********************
     * Listener methods
     *********************/

    /* Add listener to CookieJar. If the first listener registers,
     * add CookieJar's listener to sunw.hotjava.misc.Cookies. This
     * management done to avoid having unnecessary object retention*/
    public void addVetoableChangeListener(VetoableChangeListener l) {
  vceListeners.addVetoableChangeListener(l);
 
    }

    /* Removes listener to CookieJar. If there are no more listeners
     * to CookieJar, remove CookieJar's listener to sunw.hotjava.misc.Cookies.
     */
    public void removeVetoableChangeListener(VetoableChangeListener l) {
  vceListeners.removeVetoableChangeListener(l);
    }
   

    /*********
     * Older code that could serve as a reminder for future
     *********/
    /**
     * Predicate function which returns true if the cookie appears to be
     * invalid somehow and should not be added to the cookie set.
     */
    /* This code used to be called in recordCookie(HttpCookie cookie),
       however, I couldn't figure out what it would be good for, so
       I took it out for now. See the misc.Cookies in deleted file
       for more context*/
    private boolean shouldRejectCookie(HttpCookie cookie) {
  // REMIND: implement per http-state-mgmt Internet Draft
  return false;
    }

}
TOP

Related Classes of org.apache.tools.moo.cookie.CookieJar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.