Loading src/or/buffers.c +110 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, Loading @@ -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); Loading @@ -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)); Loading Loading
src/or/buffers.c +110 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, Loading @@ -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); Loading @@ -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)); Loading