Hi,

this is a small patch updated for the current CVS. It doesn't add any
functionality. 

* Only adds X-Queued if X-Queue major version = 1 (PARQ) and the ID is
known.
* Internal header parsing should not find incorrect value.

I'm almost positive this version completly supports PARQ client side as
well as active queueing.

- Jeroen

ps. I will fix the dl_queued in downloads.h later this week. Allthough I
am not convinced it is the best thing to do.


Index: src/downloads.h
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/downloads.h,v
retrieving revision 1.60
diff -u -r1.60 downloads.h
--- src/downloads.h	2 Feb 2003 23:03:06 -0000	1.60
+++ src/downloads.h	3 Feb 2003 21:13:36 -0000
@@ -54,6 +54,11 @@
 	DL_LIST_SZ		= 3,
 };
 
+struct major_minor_version {
+	guint major;
+	guint minor;
+};
+
 struct dl_key {
 	guchar *guid;			/* GUID of server (atom) */
 	guint32 ip;				/* IP address of server */
@@ -67,6 +72,8 @@
 	gchar *vendor;			/* Remote server vendor string (atom) */
 	time_t retry_after;		/* Time at which we may retry from this host */
 	guint32 attrs;
+	
+	struct major_minor_version parq_version;
 };
 
 /* 
Index: src/parq.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/parq.c,v
retrieving revision 1.3
diff -u -r1.3 parq.c
--- src/parq.c	3 Feb 2003 07:16:22 -0000	1.3
+++ src/parq.c	3 Feb 2003 21:13:37 -0000
@@ -44,6 +44,7 @@
 {
 	return sscanf(header, ": %d.%d", major, minor) != 0;
 }
+
 /* 
  * get_header_value
  *
@@ -51,22 +52,64 @@
  * is returned for that value.
  */
 gchar *get_header_value(
-	gchar const *const s, gchar const *const attribute, gint *length)
+	gchar *const s, gchar const *const attribute, gint *length)
 {
-	gchar *lowercase_header;
+	gchar *lowercase_header = s;
 	gchar *end;
+	gboolean found_right_attribute = FALSE;
 	
 	g_assert(s != NULL);
 	g_assert(attribute != NULL);
 
-	// XXX This routine is fragile.  If looking for say "bar=x", we can
-	// XXX mistakenly parse "foobar=x" instead. --RAM, 03/02/2003
-	
-	lowercase_header = strcasestr(s, attribute);
+	/*
+	 * When we are looking for "foo", make sure we aren't actually
+	 * parsing "barfoobar". There should be at least a space, or a
+	 * delimiter at the end and at the beginning.
+	 */
 
+	do {
+		lowercase_header = strcasestr(lowercase_header, attribute);
+		
+		if (lowercase_header == NULL)
+			return NULL;
+		
+		if (lowercase_header == s) {
+			/*
+			 * This is actually the first value of the header. And it
+			 * started at position '0'. Which is the same as were
+			 * s pointed too. Only check to see if the end is correct
+			 */
+			found_right_attribute = (
+				(*(lowercase_header + strlen(attribute)) == ' ') ||
+				(*(lowercase_header + strlen(attribute)) == '=')
+			);
+			
+		} else {
+			found_right_attribute = (
+					(*(lowercase_header - 1) == ';') ||
+					(*(lowercase_header - 1) == ',') ||
+					(*(lowercase_header - 1) == ':') ||
+					(*(lowercase_header - 1) == ' ')
+				) && (
+					(*(lowercase_header + strlen(attribute)) == ' ') ||
+					(*(lowercase_header + strlen(attribute)) == '=')
+				);
+		}
+		
+		/* 
+		 * If we weren't looking at the right value. Move on to the next.
+		 * If there are no valid values, the while loop will abort with 
+		 * lowercase_header == NULL
+		 */
+		if (!found_right_attribute)
+			lowercase_header++;
+
+	} while (!found_right_attribute && lowercase_header != NULL);	
+	
+	
 	if (lowercase_header == NULL)
 		return NULL;
-
+		
 	lowercase_header = strchr(lowercase_header, '=');
 	if (lowercase_header == NULL)
 		return NULL;
@@ -97,7 +140,6 @@
 	return lowercase_header;
 }
 
-
 /*
  * parq_download_retry_active_queued
  *
@@ -196,6 +238,9 @@
 		minor = 1;
 	}
 	
+	d->server->parq_version.major = major;
+	d->server->parq_version.minor = minor;
+	
 	switch (major) {
 	case 0:				/* Active queueing */		
 		d->queue_status.ID[0] = '\0';
@@ -241,8 +286,6 @@
 			d->queue_status.retry_delay);
 	}
 	
-	
-	/* FIXME: This isn't 100% correct yet for PARQ, it is for active queueing */
 	if (parq_download_is_active_queued(d)) {
 		/*
 		 * Don't keep a chunk busy if we are queued, perhaps another servent
@@ -285,10 +328,12 @@
 		"X-Queue: %d.%d\r\n", PARQ_VERSION_MAJOR, PARQ_VERSION_MINOR);
 
 	/*
-	 * XXX -- assume it's not PARQ if there is no ID --RAM, 02/02/2003.
+	 * Only add X-Queued header if server really supports X-Queue: 1.x. Don't
+	 * add X-Queued if there is no ID available. This could be because it is
+	 * a first request.
 	 */
 
-	if (d->queue_status.ID[0] != '\0')
+	if (d->server->parq_version.major == 1 && d->queue_status.ID[0] != '\0')
 		*rw += gm_snprintf(&buf[*rw], len - *rw,
 			"X-Queued: position=%d; ID=%s\r\n",
 			d->queue_status.position, d->queue_status.ID);

Reply via email to