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);