Re: Handling Client-Side Cookies

Dear Gentlemen,

	This is intended to follow my previous message titled "Handling Client-Side 
Cookies."

	I believe that I have found and fixed some five (5) minor bugs in 
Client-Side Jigsaw.  Specifically, I solved my aforementioned problem in 
handling Client-Side cookies with the following source code modifications to 
the HttpSetCookieList.parse(), CookieFilter.outgoingFilter(), 
DomainNode.addCookie() and DomainNode.insertCookie() methods.  Please note 
that I have made and tested this modification to the source code that I 
downloaded in the Jigsaw 2.1.2 release and that I have compiled the "fixed" 
code with Java 1.2.2.  Furthermore, be advised that the source code for the 
classes DomainNode and DomainTree are contained with in the 
"CookieFilter.java" file.

	Here are the putative bugs with my suggested fixes:

(Bug#1) Near the end of the HttpSetCookieList.parse() method "if 
(!inExpireItem){" should be replaced with "if (inExpireItem){"  .  That is, 
simply take out the "!" in front of "inExpireItem" or in other words, 
replace this:

    protected void parse()
	throws HttpParserException
    {
	ParseState cl  = new ParseState(roff, rlen);
	ParseState av  = new ParseState(0, 0);

~~~~~~~all the source code is not shown here to save space~~~~~

			    HttpParser.nextItem(raw, val);
			    sc.setValue(val.toString(raw));
			}
		    }
		}
		av.prepare();
	    }
	    if (!inExpireItem) // Add the newly created cookie:
		setcookies.addElement(sc);
	    cl.prepare();
	}
    }

with this:

			    HttpParser.nextItem(raw, val);
			    sc.setValue(val.toString(raw));
			}
		    }
		}
		av.prepare();
	    }

	    if (inExpireItem)

		setcookies.addElement(sc);
	    cl.prepare();
	}
    }




(Bug#2) Near the end of the CookieFilter.outgoingFilter() method replace 
this:

		while (i < cooks.length) {
		    if (cooks[i].getDomain() == null)
			cooks[i].setDomain(request.getURL().getHost());
		    root.insertCookie(cooks[i++]);
		}

with this:

		while (i < cooks.length) {
		    if (cooks[i].getDomain() == null)
			cooks[i].setDomain(request.getURL().getHost());

		    root.insertCookie(cooks[i]);
		    i++;

		}

(Bug#3) In the middle of DomainNode.addCookie() method replace this:

	if (nbcookies < cookies.length) {
	    cookies[nbcookies++] = cookie;
	} else {

with this:

	if (nbcookies < cookies.length) {

	    cookies[nbcookies] = cookie;
	    nbcookies++;

	} else {

(Bug#4) Likewise, at the end of DomainNode.addCookie() method replace this:

	} else {

	    HttpSetCookie ncookies [] = new HttpSetCookie[cookies.length +1];
	    System.arraycopy(cookies,0,ncookies,0,cookies.length);
	    ncookies[nbcookies++] = cookie;
	    cookies = ncookies;
	}
    }

with this:

	} else {

	    HttpSetCookie ncookies [] = new HttpSetCookie[cookies.length +1];
	    System.arraycopy(cookies,0,ncookies,0,cookies.length);

	    ncookies[nbcookies] = cookie;
	    nbcookies++;

	    cookies = ncookies;
	}
    }

(Bug#5) This may be a legitimate bug (as opposed to the type of simple logic 
errors detailed above).  In Jigsaw, Client-Side cookies are stored in tree 
structure (DomainTree) built from nodes (DomainNodes).  Apparently, a cookie 
from some URL, like "www.netscape.com," is stored in DomainNodes that are 
supposed to be accessable through names derived from parsing the "domain" 
field in the "Set-Cookie" header of the Reply.  So, a cookie received in a 
Reply from "www.netscape.com" should be accessable by the 
CookieFilter.ingoingFilter() method via looking up in series three (3) nodes 
with the "names" (or as in terms of Jigsaw source code "parts"): "www" , 
"netscape"  and "com".

	Here is the apparent problem: sometimes the "domain" field in the 
"Set-Cookie" header looks like this: "domain=.netscape.com;" as opposed to 
this "domain=www.netscape.com;" .  When this happens Jigsaw (specifically, 
the DomainTree.getCookies() method) does not find any cookies to add to the 
Request headers, because, for some reason that I have not explored, it looks 
for a "www" DomainNode (even though none was created by the 
DomainTree.insertCookies() method).

	In any case, if this:

    public void insertCookie(HttpSetCookie cookie) {
	String domain  = cookie.getDomain();
	String parts[] = domainParts(domain);
	if (parts == null) //FIXME Exception
	    return;
	int i = 0;
	DomainNode node = null;
	Hashtable childs = nodes;

is replaced with this:

    public void insertCookie(HttpSetCookie cookie) {
	String domain  = cookie.getDomain();
	String parts[] = domainParts(domain);
	if (parts == null) //FIXME Exception
	    return;

	if(parts[0].length() == 0)parts[0] = "www";

	int i = 0;
	DomainNode node = null;
	Hashtable childs = nodes;


Jigsaw then appears to handle Client-Side cookies perfectly (and my problem 
is solved!).

Again, I would like to thank the Jigsaw Team for sharing their excellent 
software and close by saying that I am proud to have had this oppurtunity to 
contribute to their work.


	Truly yours,
	John Philip Anderson
	Michigan, USA

	jpanderson_215@hotmail.com


>From: "John Philip Anderson" <jpanderson_215@hotmail.com>
>To: www-jigsaw@w3.org
>Subject: Handling Client-Side Cookies
>Date: Fri, 08 Dec 2000 20:46:57 -0000
>
>Dear Gentlemen,
>
>	I find Jigsaw and Winie to be invaluable, thank you very much for sharing
>this work. I have studied all the posted resources, yet I still do not
>understand how to handle Client-Side cookies.
>
>	Posted below is sourcecode ("CookieTest.java") and its output, that uses
>Client-Side Jigsaw components to send an HTTP.GET Request to
>www.netscape.com.  As indicated by output enumeration of the Reply Header
>Descriptions, the Reply contains a "set-cookie" header and applying the
>methods: getHeaderValue("set-cookie") and value.getValue() to the Reply 
>does
>indeed returns an unparsed "set-cookie" value for the netscape.com Domain
>(as expected).
>
>	However, the CookieFilter and HttpManager do not appear to process this
>information because a "cookie" header does is enumerated in the Request2
>headers (to the same URL: www.netscape.com).  Furthermore, applying the
>method: getSetCookie() to the Reply returns an empty SetCookieList.
>
>	So, I would be extremely grateful if you could tell me what I am doing
>wrong.
>
>Specifically:
>
>	1.)	Why do CookieFilter and HttpManager appear not to process the
>"set-cookie" header in the Reply by not yielding a "cookie" header in
>Request2?
>
>	2.)	Why does Reply.getSetCookie() generate an empty SetCookieList while
>getHeaderValue("set-cookie") and value.getValue() appear to find a cookie.
>
>	3.)	And finally, is there any technical reason why CookieFilter has not
>been incorporated into Winie? (I can usually answer my own Client-Side
>questions by studying Winie sourcecode.)
>
>
>	Truly yours,
>	John Philip Anderson
>
>	jpanderson_215@hotmail.com
>
>~~~~~~~~~~~~~~~~~~~~~~~~
>
>CookieTest.java OUTPUT::
>
>
>Reply Header Descriptions:
>date
>transfer-encoding
>set-cookie
>content-type
>server
>
>Cooks Array Length:
>0
>
>SET-COOKIE header value:
>uidc=24.19.89.21:0976303991:634295;domain=.netscape.com;path=/;expires=31-Dec-2010
>23:59:59 GMT
>
>Request2 Header Descriptions:
>date
>accept
>host
>user-agent
>
>~~~~~~~~~~~~~~~~~~~~~~~~
>
>CookieTest.java SOURCECODE::
>
>
>// CookieTest.java
>
>import java.io.*;
>import java.util.*;
>import java.net.*;
>import org.w3c.util.*;
>import org.w3c.www.http.*;
>import org.w3c.www.protocol.http.*;
>import org.w3c.www.protocol.http.cookies.*;
>
>public class CookieTest{
>
>public static void main(String[] args) {
>try {
>	PrintStream out1 = new PrintStream(
>	new BufferedOutputStream(
>	new FileOutputStream("log.txt")), true);
>	System.setOut(out1);
>
>	HttpManager manager = HttpManager.getManager();							CookieFilter cfilter
>=  new CookieFilter();
>	cfilter.initialize(manager);
>	Request request1 = manager.createRequest();
>	request1.setMethod("GET");
>
>
>	String host = "http://www.netscape.com";
>	request.setURL(new URL(host));
>	Reply reply = manager.runRequest(request1);
>
>
>System.out.println("Reply Header Descriptions:");
>	Enumeration e = reply.enumerateHeaderDescriptions();
>	while(e.hasMoreElements()){
>System.out.println(((HeaderDescription) e.nextElement()).getName());
>	}
>System.out.println();
>
>
>System.out.println("Cooks Array Length:");
>	HttpSetCookieList list = reply.getSetCookie();
>	if (list != null){
>	HttpSetCookie[] cooks = list.getSetCookies();
>System.out.println(cooks.length);
>System.out.println();
>	}
>
>
>	HeaderValue value  = reply.getHeaderValue("set-cookie");
>	HttpSetCookieList list1 = (HttpSetCookieList) value.getValue();
>System.out.println("SET-COOKIE header value:");
>System.out.println(list1.toString());
>System.out.println();
>
>
>	Request request2 = manager.createRequest();
>	request2.setURL(new URL(host));
>	manager.runRequest(request2);
>
>
>System.out.println("Request2 Header Descriptions:");
>	e = request2.enumerateHeaderDescriptions();
>	while(e.hasMoreElements()){
>System.out.println(((HeaderDescription) e.nextElement()).getName());
>	}
>
>
>	out1.close();
>
>} catch(PropRequestFilterException prfexcpt) {
>System.out.println("PropRequestFilterException : " + prfexcpt);
>
>} catch(HttpException excpt) {
>System.out.println("HttpException : " + excpt);
>
>} catch(IOException e) {
>System.out.println("IO Exception:" + e);
>
>}
>
>System.exit(0);
>
>}
>
>}
>
>
>
>_____________________________________________________________________________________
>Get more from the Web.  FREE MSN Explorer download : 
>http://explorer.msn.com
>

_____________________________________________________________________________________
Get more from the Web.  FREE MSN Explorer download : http://explorer.msn.com

Received on Tuesday, 12 December 2000 01:26:50 UTC