Add HEADER_CHECK_DUPE to bypass duplicate check

Almost all header entries are guaranteed to be added only once, so we
don't need to check for duplicates all the time. In the current code
base only Content-Length has the potential for being added twice, and
even then it seems highly unlikely. For all others, we can now bypass
this check.
This commit also changes the header_copy flags to be 1-bit flags, so
that they can be combined.
master
Jessie Murray 3 years ago
parent dc9d1b646e
commit 7ce6d497c1
No known key found for this signature in database
GPG Key ID: E7E4D57EDDA744C5

@ -97,13 +97,15 @@ http_response_set_header(struct http_response *r, const char *k, const char *v,
size_t key_sz = strlen(k);
size_t val_sz = strlen(v);
for(i = 0; i < r->header_count; ++i) {
if(strncmp(r->headers[i].key, k, key_sz) == 0) {
pos = i;
/* free old value before replacing it. */
if(r->headers[i].copy == HEADER_COPY_KEY) free(r->headers[i].key);
if(r->headers[i].copy == HEADER_COPY_VALUE) free(r->headers[i].val);
break;
if(copy & HEADER_CHECK_DUPE) {
for(i = 0; i < r->header_count; ++i) {
if(strncmp(r->headers[i].key, k, key_sz) == 0) {
pos = i;
/* free old value before replacing it. */
if(r->headers[i].copy & HEADER_COPY_KEY) free(r->headers[i].key);
if(r->headers[i].copy & HEADER_COPY_VALUE) free(r->headers[i].val);
break;
}
}
}
@ -117,7 +119,7 @@ http_response_set_header(struct http_response *r, const char *k, const char *v,
r->header_count++;
/* copy key if needed */
if(copy == HEADER_COPY_KEY) {
if(copy & HEADER_COPY_KEY) {
r->headers[pos].key = calloc(key_sz + 1, 1);
memcpy(r->headers[pos].key, k, key_sz);
} else {
@ -126,7 +128,7 @@ http_response_set_header(struct http_response *r, const char *k, const char *v,
r->headers[pos].key_sz = key_sz;
/* copy val */
if(copy == HEADER_COPY_VALUE) {
if(copy & HEADER_COPY_VALUE) {
r->headers[pos].val = calloc(val_sz + 1, 1);
memcpy(r->headers[pos].val, v, val_sz);
} else {
@ -243,9 +245,9 @@ http_response_write(struct http_response *r, int fd) {
if(r->code == 200 && r->body) {
char content_length[22];
sprintf(content_length, "%zd", r->body_len);
http_response_set_header(r, "Content-Length", content_length, HEADER_COPY_VALUE);
http_response_set_header(r, "Content-Length", content_length, HEADER_COPY_VALUE | HEADER_CHECK_DUPE);
} else {
http_response_set_header(r, "Content-Length", "0", HEADER_COPY_NONE);
http_response_set_header(r, "Content-Length", "0", HEADER_COPY_NONE | HEADER_CHECK_DUPE);
}
}

@ -7,10 +7,12 @@
struct http_client;
struct worker;
/* bit flags */
typedef enum {
HEADER_COPY_NONE = 0,
HEADER_COPY_KEY = 1,
HEADER_COPY_VALUE = 2
HEADER_COPY_NONE = 0, /* don't strdup key or value */
HEADER_COPY_KEY = 1, /* strdup key only */
HEADER_COPY_VALUE = 2, /* strdup value only */
HEADER_CHECK_DUPE = 4 /* replace duplicate when adding header */
} header_copy;
struct http_header {

Loading…
Cancel
Save