ComLine cookie support

Hello!

	I'm writing to share a modification I just made.

	I've been using the w3c tool from the libwww package for sending
arbitrary POSTs to a website.  Recently, I needed the ability to send a
cookie along with that POST as well.  I found out that the command line
tool has no support for cookies.  Actually, I retrieved the cookie from
the remote system by using grep and sed on w3c with the -vs option, and
THEN I realized there was no mechanism to send a cookie back!

	So, I made an addition to ComLine/src/HTLine.c and now my version
of w3c has a -cookie option that can be used to send a cookie.  You are
expected to enter:

	-cookie CookieVariable=CookieValue

	If you look at my code you will see that it is not a very pretty
hack - its the minimal effort required to make this support work.  I don't
do any validity checking, I just expect the command line usage to be whats
described above (and thats important to know, because when you use -cookie
the next arg is embedded directly into the protocol stream, so you will
send out invalid http if you use this option incorrectly).

	I was able to make my code change because of the *teriffic*
information I found from Jim_Ravan@avid.com at
http://lists.w3.org/Archives/Public/www-lib/1999JanMar/0372.html

	I hope my code change is useful to someone out there or perhaps
inspires someone to re-do this work correctly.  (I'd like my work to
resemble the cookie support in wget.  That is, you give a cookie-output
file and then ComLine uses HTCookie to grab cookies from a server and
formats and writes them to the file, and you can give a cookie-input file
and ComLine reads that and uses a generator much like I have done to send
cookies.  But -- the hackish code change that I did was enough effort for
me, I'll leave an improvment to the next custodian of this work.)

	Enjoy!

--- ComLine/src/HTLine.c.orig	Thu Jun  3 13:42:12 1999
+++ ComLine/src/HTLine.c	Thu Oct 28 23:11:40 2004
@@ -142,9 +142,10 @@

 PRIVATE void VersionInfo (const char * name)
 {
     HTPrint("\nW3C OpenSource Software");
-    HTPrint("\n-----------------------\n\n");
+    HTPrint("\n-----------------------\n");
+    HTPrint("This version was modified for -cookie support\n\n");
     HTPrint("\tWebCon version %s\n", APP_VERSION);
     HTPrint("\tusing the W3C libwww library version %s.\n\n",HTLib_version());
     HTPrint("\tTry \"%s -help\" for help\n\n", name ? name : APP_NAME);
     HTPrint("\tSee \"http://www.w3.org/ComLine/User/\" for user information\n");
@@ -232,8 +233,92 @@
     }
     return YES;
 }

+/* Storage for our cookie.. */
+HTList *cookie_list;
+char **cookie_strings;
+
+/* I don't know why I need to define this, but I do.  Thanks to:
+ * Jim_Ravan@avid.com for writing some help at:
+ * http://lists.w3.org/Archives/Public/www-lib/1999JanMar/0372.html
+ */
+struct _HTStream
+{
+	const HTStreamClass * isa;
+	HTStream * target;
+};
+
+static int SendCookie( HTRequest *request, HTStream *stream )
+{
+	const char CookiePrefix[] = "Cookie: ";
+	const char CookieSeperator[] = "; ";
+	const char CookieSuffix[] = "\n";
+	int i=0;
+
+	if( cookie_strings != NULL && cookie_strings[0] != NULL )
+		(*stream->target->isa->put_block) \
+			(stream->target, CookiePrefix, 8 );
+	else
+		return HT_OK;
+
+	while( cookie_strings[i] != NULL ) {
+		if( i != 0 )
+			(*stream->target->isa->put_block) \
+				(stream->target, CookieSeperator, 2 );
+
+		(*stream->target->isa->put_block) \
+			(stream->target, cookie_strings[i], \
+			strlen(cookie_strings[i]) );
+		i++;
+	}
+	(*stream->target->isa->put_block) (stream->target, CookieSuffix, 1 );
+
+	return HT_OK;
+}
+
+static void AddCookie( char *newStr )
+{
+	int len;
+
+	if( cookie_strings == NULL ) {
+		len = 0;
+		cookie_strings = malloc( 2*sizeof(char *) );
+		if( cookie_strings == NULL ) {
+			HTPrint("Fatal: Couldn't malloc!\n");
+			exit( 1 );
+		}
+		cookie_strings[0] = newStr;
+		cookie_strings[1] = NULL;
+	} else {
+		len = 0;
+		while( cookie_strings[len] != NULL )
+			len++;
+		cookie_strings = realloc(cookie_strings, (len+2)*sizeof(char *));
+		if( cookie_strings == NULL ) {
+			HTPrint("Fatal: Couldn't realloc!\n");
+			exit( 1 );
+		}
+		cookie_strings[len] = newStr;
+		cookie_strings[++len] = NULL;
+	}
+}
+
+PRIVATE BOOL InitCookies()
+{
+	cookie_list = HTList_new();
+	if( cookie_list == NULL ) {
+		HTPrint("Bad cookie list. Bad!\n");
+		return NO;
+	}
+	if( ! HTList_appendObject( cookie_list, SendCookie ) ) {
+		HTPrint("Didn't add object.\n");
+		return NO;
+	}
+	HTHeader_setGenerator( cookie_list );
+	return YES;
+}
+
 /* ------------------------------------------------------------------------- */
 /*				  MAIN PROGRAM				     */
 /* ------------------------------------------------------------------------- */

@@ -267,8 +352,10 @@
     SIOUXSettings.asktosaveonclose = false;
     argc=ccommand(&argv);
 #endif

+    cookie_strings = NULL;
+
     /* Initiate W3C Reference Library with a client profile */
     HTProfile_newNoCacheClient(APP_NAME, APP_VERSION);

     /* Need our own trace and print functions */
@@ -288,8 +375,13 @@
     ** matter that we get an encoding that we don't know.
     */
     HTFormat_addCoding("*", HTIdentityCoding, HTIdentityCoding, 0.3);

+    if( ! InitCookies() ) {
+        HTPrint("Problem initializing cookies!\n");
+        return 1;
+    }
+
     /* Scan command Line for parameters */
     for (arg=1; arg<argc; arg++) {
 	if (*argv[arg] == '-') {

@@ -441,8 +533,11 @@

 	    /* TRACE Method */
 	    } else if (!strcasecomp(argv[arg], "-trace")) {
 		method = METHOD_TRACE;
+
+	    } else if (!strcmp(argv[arg], "-cookie")) {
+		    AddCookie( argv[++arg] );

 	    } else {
 		if (SHOW_MSG) HTPrint("Bad Argument (%s)\n", argv[arg]);
 	    }

Received on Friday, 29 October 2004 15:25:28 UTC