merge cookie headers in O(n) order
@@ -147,7 +147,7 @@ static void build_request(h2o_req_t *req, h2o_iovec_t *method, h2o_url_t *url, h
char remote_addr[NI_MAXHOST];
struct sockaddr_storage ss;
socklen_t sslen;
- h2o_iovec_t cookie_buf = {NULL}, xff_buf = {NULL}, via_buf = {NULL};
+ h2o_iovec_t xff_buf = {NULL}, via_buf = {NULL};
int preserve_x_forwarded_proto = req->conn->ctx->globalconf->proxy.preserve_x_forwarded_proto;
int emit_x_forwarded_headers = req->conn->ctx->globalconf->proxy.emit_x_forwarded_headers;
int emit_via_header = req->conn->ctx->globalconf->proxy.emit_via_header;
@@ -197,6 +197,7 @@ static void build_request(h2o_req_t *req, h2o_iovec_t *method, h2o_url_t *url, h
}
/* headers */
+ h2o_iovec_vector_t cookie_values = {NULL};
{
const h2o_header_t *h, *h_end;
int found_early_data = 0;
@@ -206,9 +207,8 @@ static void build_request(h2o_req_t *req, h2o_iovec_t *method, h2o_url_t *url, h
if (token->flags.proxy_should_drop_for_req)
continue;
if (token == H2O_TOKEN_COOKIE) {
- /* merge the cookie headers; see HTTP/2 8.1.2.5 and HTTP/1 (RFC6265 5.4) */
- /* FIXME current algorithm is O(n^2) against the number of cookie headers */
- cookie_buf = build_request_merge_headers(&req->pool, cookie_buf, h->value, ';');
+ h2o_vector_reserve(&req->pool, &cookie_values, cookie_values.size + 1);
+ cookie_values.entries[cookie_values.size++] = h->value;
continue;
} else if (token == H2O_TOKEN_VIA) {
if (!emit_via_header) {
@@ -245,7 +245,9 @@ static void build_request(h2o_req_t *req, h2o_iovec_t *method, h2o_url_t *url, h
}
}
- if (cookie_buf.len != 0) {
+ if (cookie_values.size != 0) {
+ /* merge the cookie headers; see HTTP/2 8.1.2.5 and HTTP/1 (RFC6265 5.4) */
+ h2o_iovec_t cookie_buf = h2o_join_list(&req->pool, cookie_values.entries, cookie_values.size, h2o_iovec_init(H2O_STRLIT("; ")));
h2o_add_header(&req->pool, headers, H2O_TOKEN_COOKIE, NULL, cookie_buf.base, cookie_buf.len);
}
if (emit_x_forwarded_headers) {
