mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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. svn:r13005
This commit is contained in:
+110
-2
@@ -943,6 +943,93 @@ move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen)
|
||||
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 @@ fetch_from_buf_http(buf_t *buf,
|
||||
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 @@ fetch_from_buf_http(buf_t *buf,
|
||||
}
|
||||
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 @@ fetch_from_buf_http(buf_t *buf,
|
||||
}
|
||||
|
||||
#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));
|
||||
|
||||
Reference in New Issue
Block a user