[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r13005: Incomplete code to avoid doing needless pull-ups on HTTP. Al (in tor/trunk: . src/or)



Author: nickm
Date: 2007-12-29 12:36:03 -0500 (Sat, 29 Dec 2007)
New Revision: 13005

Modified:
   tor/trunk/
   tor/trunk/src/or/buffers.c
Log:
 r17433@catbus:  nickm | 2007-12-29 12:35:57 -0500
 Incomplete code to avoid doing needless pull-ups on HTTP.  Also, use memstr instead of strstr to find the content-length header.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r17433] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/buffers.c
===================================================================
--- tor/trunk/src/or/buffers.c	2007-12-29 16:18:10 UTC (rev 13004)
+++ tor/trunk/src/or/buffers.c	2007-12-29 17:36:03 UTC (rev 13005)
@@ -943,6 +943,93 @@
   return cp;
 }
 
+// #define BUFPOS
+#ifdef BUFPOS
+typedef struct buf_pos_t {
+  chunk_t *chunk;
+  int pos;
+  int pos_absolute;
+};
+
+static void
+buf_pos_init(buf_t *buf, buf_pos_t *out)
+{
+  out->chunk = buf->head;
+  out->pos = 0;
+  out->pos_absolute = 0;
+}
+
+static int
+buf_find_pos_of_char(const buf_t *buf, char ch, buf_pos_t *out)
+{
+  chunk_t *chunk;
+  int offset = 0;
+  int pos = chunk->pos;
+  for (chunk = out->chunk; chunk; chunk = chunk->next) {
+    char *cp = memchr(chunk->data+pos, ch, chunk->datalen-pos);
+    if (cp) {
+      out->chunk = chunk;
+      out->pos = cp - chunk->data;
+      out->pos_absolute = offset + (cp - chunk->data);
+      return out->pos_absolute;
+    } else {
+      offset += chunk->datalen;
+      pos = 0;
+    }
+  }
+  return -1;
+}
+
+static INLINE int
+buf_pos_inc(buf_pos_t *pos)
+{
+  if (pos->pos == pos->chunk->datalen) {
+    if (!pos->chunk->next)
+      return -1;
+    pos->chunk = pos->chunk->next;
+    pos->pos = 0;
+  } else {
+    ++pos->pos;
+  }
+  ++pos->pos_absolute;
+}
+
+static int
+buf_matches_at_pos(const buf_t *buf, const buf_pos_t *pos, const char *s,
+                   int n)
+{
+  buf_pos_t p;
+  memcpy(p, pos, sizeof(p));
+
+  while (n) {
+    char ch = p->chunk->data[p->pos];
+    if (ch != *s)
+      return 0;
+    ++s;
+    --n;
+    if (buf_pos_inc(p)<0)
+      return 0;
+  }
+  return 1;
+}
+
+static int
+buf_find_string_offset(const char *buf, const char *s, int n)
+{
+  buf_pos_t pos;
+  buf_pos_init(buf, &pos);
+  while (buf_find_pos_of_char(buf, *s, &pos) >= 0) {
+    if (buf_matches_at_pos(buf, pos, s, n)) {
+      return pos->pos_absolute;
+    } else {
+      if (buf_pos_inc(pos)<0)
+        return -1;
+    }
+  }
+  return -1;
+}
+#endif
+
 /** There is a (possibly incomplete) http statement on <b>buf</b>, of the
  * form "\%s\\r\\n\\r\\n\%s", headers, body. (body may contain nuls.)
  * If a) the headers include a Content-Length field and all bytes in
@@ -968,14 +1055,33 @@
                     char **body_out, size_t *body_used, size_t max_bodylen,
                     int force_complete)
 {
-  char *headers, *body, *p;
+  char *headers, *p, *body;
   size_t headerlen, bodylen, contentlen;
+#ifdef BUFPOS
+  int crlf_offset;
+#endif
 
   check();
   if (!buf->head)
     return 0;
 
   headers = buf->head->data;
+
+#ifdef BUFPOS
+  crlf_offset = buf_find_string_offset(buf, "\r\n\r\n", 4);
+  if (crlf_offset > max_headerlen ||
+      (crlf_offset < 0 && buf->datalen > max_headerlen)) {
+    log_debug(LD_HTTP,"headers too long.");
+    return -1;
+  } else if (crlf_offset < 0) {
+    log_debug(LD_HTTP,"headers not all here yet.");
+    return 0;
+  }
+  if (buf->head->datalen < crlf_offset + 4)
+    buf_pullup(buf, crlf_offset+4, 0);
+  headerlen = crlf_offset + 4;
+  body = buf->data + headerlen; /*XXX020 unused. */
+#else
   /* See if CRLFCRLF is already in the head chunk.  If it is, we don't need
    * to move or resize anything. */
   body = (char*) tor_memmem(buf->head->data, buf->head->datalen,
@@ -1001,6 +1107,8 @@
   }
   body += 4; /* Skip the the CRLFCRLF */
   headerlen = body-headers; /* includes the CRLFCRLF */
+#endif
+
   bodylen = buf->datalen - headerlen;
   log_debug(LD_HTTP,"headerlen %d, bodylen %d.", (int)headerlen, (int)bodylen);
 
@@ -1016,7 +1124,7 @@
   }
 
 #define CONTENT_LENGTH "\r\nContent-Length: "
-  p = strstr(headers, CONTENT_LENGTH);
+  p = (char*) tor_memstr(headers, headerlen, CONTENT_LENGTH);
   if (p) {
     int i;
     i = atoi(p+strlen(CONTENT_LENGTH));