From 45e1dee27b0ba3322bf258e3f8a448dd5f7a199c Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 29 Jan 2016 11:40:19 +0000 Subject: [PATCH] correctly processing multiple rel values in Link headers, suppressing PUSH if nopush param is present in link header git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1727545 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 +++++ modules/http2/h2_conn.c | 5 +---- modules/http2/h2_push.c | 26 ++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 409be611aa..e8279021f3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_http2: allowing link header to specify multiple "rel" values, + space-separated inside a quoted string. Prohibiting push when Link parameter + "nopush" is present. + [Stefan Eissing] + *) core: Prevent a server crash in case of an invalid CONNECT request with a custom error page for status code 400 that uses server side includes. PR 58929 [Ruediger Pluem] diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c index 747edbc7a6..29e68c11c0 100644 --- a/modules/http2/h2_conn.c +++ b/modules/http2/h2_conn.c @@ -311,10 +311,7 @@ struct event_conn_state_t { conn_rec *c; /** request record (if any) this struct refers to */ request_rec *r; - /** is the current conn_rec suspended? (disassociated with - * a particular MPM thread; for suspend_/resume_connection - * hooks) - */ + /** server config this struct refers to */ void *sc; /** is the current conn_rec suspended? (disassociated with * a particular MPM thread; for suspend_/resume_connection diff --git a/modules/http2/h2_push.c b/modules/http2/h2_push.c index 717865c5ac..842382441e 100644 --- a/modules/http2/h2_push.c +++ b/modules/http2/h2_push.c @@ -282,14 +282,36 @@ static int set_header(void *ctx, const char *key, const char *value) return 1; } +static int has_param(link_ctx *ctx, const char *param) +{ + const char *p = apr_table_get(ctx->params, param); + return !!p; +} + +static int has_relation(link_ctx *ctx, const char *rel) +{ + const char *s, *val = apr_table_get(ctx->params, "rel"); + if (val) { + if (!strcmp(rel, val)) { + return 1; + } + s = ap_strstr_c(val, rel); + if (s && (s == val || s[-1] == ' ')) { + s += strlen(rel); + if (!*s || *s == ' ') { + return 1; + } + } + } + return 0; +} static int add_push(link_ctx *ctx) { /* so, we have read a Link header and need to decide * if we transform it into a push. */ - const char *rel = apr_table_get(ctx->params, "rel"); - if (rel && !strcmp("preload", rel)) { + if (has_relation(ctx, "preload") && !has_param(ctx, "nopush")) { apr_uri_t uri; if (apr_uri_parse(ctx->pool, ctx->link, &uri) == APR_SUCCESS) { if (uri.path && same_authority(ctx->req, &uri)) { -- 2.40.0