httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject svn commit: r1770812 [7/7] - in /httpd/httpd/branches/2.4.x-openssl-1.1.0-compat: ./ docs/manual/ docs/manual/mod/ modules/http/ modules/http2/ modules/metadata/ modules/session/ modules/ssl/ server/
Date Tue, 22 Nov 2016 09:04:50 GMT
Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_filters.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_filters.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_filters.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_filters.c Tue Nov 22 09:04:49 2016
@@ -776,8 +776,7 @@ static void fixup_vary(request_rec *r)
      * its comma-separated fieldname values, and then add them to varies
      * if not already present in the array.
      */
-    apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
-                 (void *) varies, r->headers_out, "Vary", NULL);
+    apr_table_do(uniq_field_values, varies, r->headers_out, "Vary", NULL);
 
     /* If we found any, replace old Vary fields with unique-ified value */
 

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_request.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_request.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http/http_request.c Tue Nov 22 09:04:49 2016
@@ -711,8 +711,17 @@ AP_DECLARE(void) ap_internal_fast_redire
     update_r_in_filters(r->output_filters, rr, r);
 
     if (r->main) {
-        ap_add_output_filter_handle(ap_subreq_core_filter_handle,
-                                    NULL, r, r->connection);
+        ap_filter_t *next = r->output_filters;
+        while (next && (next != r->proto_output_filters)) {
+            if (next->frec == ap_subreq_core_filter_handle) {
+                break;
+            }
+            next = next->next;
+        }
+        if (!next || next == r->proto_output_filters) {
+            ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+                                        NULL, r, r->connection);
+        }
     }
     else {
         /*

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2.h Tue Nov 22 09:04:49 2016
@@ -55,8 +55,6 @@ extern const char *H2_MAGIC_TOKEN;
 /* Initial default window size, RFC 7540 ch. 6.5.2 */
 #define H2_INITIAL_WINDOW_SIZE      ((64*1024)-1)
 
-#define H2_HTTP_2XX(a)      ((a) >= 200 && (a) < 300)
-
 #define H2_STREAM_CLIENT_INITIATED(id)      (id&0x01)
 
 #define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.c Tue Nov 22 09:04:49 2016
@@ -62,6 +62,7 @@ static h2_config defconf = {
     NULL,                   /* map of content-type to priorities */
     256,                    /* push diary size */
     0,                      /* copy files across threads */
+    NULL                    /* push list */
 };
 
 void h2_config_init(apr_pool_t *pool)
@@ -73,7 +74,6 @@ static void *h2_config_create(apr_pool_t
                               const char *prefix, const char *x)
 {
     h2_config *conf = (h2_config *)apr_pcalloc(pool, sizeof(h2_config));
-    
     const char *s = x? x : "unknown";
     char *name = apr_pstrcat(pool, prefix, "[", s, "]", NULL);
     
@@ -96,7 +96,7 @@ static void *h2_config_create(apr_pool_t
     conf->priorities           = NULL;
     conf->push_diary_size      = DEF_VAL;
     conf->copy_files           = DEF_VAL;
-    
+    conf->push_list            = NULL;
     return conf;
 }
 
@@ -110,12 +110,11 @@ void *h2_config_create_dir(apr_pool_t *p
     return h2_config_create(pool, "dir", x);
 }
 
-void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv)
+static void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv)
 {
     h2_config *base = (h2_config *)basev;
     h2_config *add = (h2_config *)addv;
     h2_config *n = (h2_config *)apr_pcalloc(pool, sizeof(h2_config));
-
     char *name = apr_pstrcat(pool, "merged[", add->name, ", ", base->name, "]", NULL);
     n->name = name;
 
@@ -143,10 +142,25 @@ void *h2_config_merge(apr_pool_t *pool,
     }
     n->push_diary_size      = H2_CONFIG_GET(add, base, push_diary_size);
     n->copy_files           = H2_CONFIG_GET(add, base, copy_files);
-    
+    if (add->push_list && base->push_list) {
+        n->push_list        = apr_array_append(pool, base->push_list, add->push_list);
+    }
+    else {
+        n->push_list        = add->push_list? add->push_list : base->push_list;
+    }
     return n;
 }
 
+void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv)
+{
+    return h2_config_merge(pool, basev, addv);
+}
+
+void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv)
+{
+    return h2_config_merge(pool, basev, addv);
+}
+
 int h2_config_geti(const h2_config *conf, h2_config_var_t var)
 {
     return (int)h2_config_geti64(conf, var);
@@ -521,6 +535,59 @@ static const char *h2_conf_set_copy_file
     return "value must be On or Off";
 }
 
+static void add_push(apr_pool_t *pool, h2_config *conf, h2_push_res *push)
+{
+    h2_push_res *new;
+    if (!conf->push_list) {
+        conf->push_list = apr_array_make(pool, 10, sizeof(*push));
+    }
+    new = apr_array_push(conf->push_list);
+    new->uri_ref = push->uri_ref;
+    new->critical = push->critical;
+}
+
+static const char *h2_conf_add_push_res(cmd_parms *cmd, void *dirconf,
+                                        const char *arg1, const char *arg2,
+                                        const char *arg3)
+{
+    h2_config *dconf = (h2_config*)dirconf ;
+    h2_config *sconf = (h2_config*)h2_config_sget(cmd->server);
+    h2_push_res push;
+    const char *last = arg3;
+    
+    memset(&push, 0, sizeof(push));
+    if (!strcasecmp("add", arg1)) {
+        push.uri_ref = arg2;
+    }
+    else {
+        push.uri_ref = arg1;
+        last = arg2;
+        if (arg3) {
+            return "too many parameter";
+        }
+    }
+    
+    if (last) {
+        if (!strcasecmp("critical", last)) {
+            push.critical = 1;
+        }
+        else {
+            return "unknown last parameter";
+        }
+    }
+
+    /* server command? set both */
+    if (cmd->path == NULL) {
+        add_push(cmd->pool, sconf, &push);
+        add_push(cmd->pool, dconf, &push);
+    }
+    else {
+        add_push(cmd->pool, dconf, &push);
+    }
+
+    return NULL;
+}
+
 #define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
 
 const command_rec h2_cmds[] = {
@@ -561,7 +628,9 @@ const command_rec h2_cmds[] = {
     AP_INIT_TAKE1("H2PushDiarySize", h2_conf_set_push_diary_size, NULL,
                   RSRC_CONF, "size of push diary"),
     AP_INIT_TAKE1("H2CopyFiles", h2_conf_set_copy_files, NULL,
-                  OR_ALL, "on to perform copy of file data"),
+                  OR_FILEINFO, "on to perform copy of file data"),
+    AP_INIT_TAKE123("H2PushResource", h2_conf_add_push_res, NULL,
+                   OR_FILEINFO, "add a resource to be pushed in this location/on this server."),
     AP_END_CMD
 };
 

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_config.h Tue Nov 22 09:04:49 2016
@@ -45,6 +45,12 @@ typedef enum {
 
 struct apr_hash_t;
 struct h2_priority;
+struct h2_push_res;
+
+typedef struct h2_push_res {
+    const char *uri_ref;
+    int critical;
+} h2_push_res;
 
 /* Apache httpd module configuration for h2. */
 typedef struct h2_config {
@@ -70,14 +76,14 @@ typedef struct h2_config {
     
     int push_diary_size;          /* # of entries in push diary */
     int copy_files;               /* if files shall be copied vs setaside on output */
+    apr_array_header_t *push_list;/* list of h2_push_res configurations */
 } h2_config;
 
 
 void *h2_config_create_dir(apr_pool_t *pool, char *x);
+void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv);
 void *h2_config_create_svr(apr_pool_t *pool, server_rec *s);
-void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv);
-
-apr_status_t h2_config_apply_header(const h2_config *config, request_rec *r);
+void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv);
 
 extern const command_rec h2_cmds[];
 

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_from_h1.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_from_h1.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_from_h1.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_from_h1.c Tue Nov 22 09:04:49 2016
@@ -103,8 +103,7 @@ static void fix_vary(request_rec *r)
      * its comma-separated fieldname values, and then add them to varies
      * if not already present in the array.
      */
-    apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
-                 (void *) varies, r->headers_out, "Vary", NULL);
+    apr_table_do(uniq_field_values, varies, r->headers_out, "Vary", NULL);
     
     /* If we found any, replace old Vary fields with unique-ified value */
     
@@ -275,8 +274,7 @@ static h2_headers *create_response(h2_ta
     
     set_basic_http_header(headers, r, r->pool);
     if (r->status == HTTP_NOT_MODIFIED) {
-        apr_table_do((int (*)(void *, const char *, const char *)) copy_header,
-                     (void *) headers, r->headers_out,
+        apr_table_do(copy_header, headers, r->headers_out,
                      "ETag",
                      "Content-Location",
                      "Expires",
@@ -290,8 +288,7 @@ static h2_headers *create_response(h2_ta
                      NULL);
     }
     else {
-        apr_table_do((int (*)(void *, const char *, const char *)) copy_header,
-                     (void *) headers, r->headers_out, NULL);
+        apr_table_do(copy_header, headers, r->headers_out, NULL);
     }
     
     return h2_headers_rcreate(r, r->status, headers, r->pool);
@@ -491,10 +488,13 @@ apr_status_t h2_from_h1_parse_response(h
                 }
                 else if (line[0] == '\0') {
                     /* end of headers, pass response onward */
-                    
+                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
+                                  "h2_task(%s): end of response", task->id);
                     return pass_response(task, f, parser);
                 }
                 else {
+                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
+                                  "h2_task(%s): response header %s", task->id, line);
                     status = parse_header(parser, line);
                 }
                 break;
@@ -615,8 +615,8 @@ static void make_chunk(h2_task *task, ap
     }
     task->input.chunked_total += chunk_len;
     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c,
-                  "h2_task(%s): added chunk %"APR_OFF_T_FMT", total %"
-                  APR_OFF_T_FMT, task->id, chunk_len, task->input.chunked_total);
+                  "h2_task(%s): added chunk %ld, total %ld", 
+                  task->id, (long)chunk_len, (long)task->input.chunked_total);
 }
 
 static int ser_header(void *ctx, const char *name, const char *value) 

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_h2.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_h2.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_h2.c Tue Nov 22 09:04:49 2016
@@ -681,6 +681,31 @@ static int h2_h2_pre_close_conn(conn_rec
     return DECLINED;
 }
 
+static void check_push(request_rec *r, const char *tag)
+{
+    const h2_config *conf = h2_config_rget(r);
+    if (conf && conf->push_list && conf->push_list->nelts > 0) {
+        int i, old_status;
+        const char *old_line;
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, 
+                      "%s, early announcing %d resources for push",
+                      tag, conf->push_list->nelts);
+        for (i = 0; i < conf->push_list->nelts; ++i) {
+            h2_push_res *push = &APR_ARRAY_IDX(conf->push_list, i, h2_push_res);
+            apr_table_addn(r->headers_out, "Link", 
+                           apr_psprintf(r->pool, "<%s>; rel=preload%s", 
+                                        push->uri_ref, push->critical? "; critical" : ""));
+        }
+        old_status = r->status;
+        old_line = r->status_line;
+        r->status = 103;
+        r->status_line = "103 Early Hints";
+        ap_send_interim_response(r, 1);
+        r->status = old_status;
+        r->status_line = old_line;
+    }
+}
+
 static int h2_h2_post_read_req(request_rec *r)
 {
     /* slave connection? */
@@ -691,7 +716,8 @@ static int h2_h2_post_read_req(request_r
          * that we manipulate filters only once. */
         if (task && !task->filters_set) {
             ap_filter_t *f;
-            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding request filters");
+            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, 
+                          "h2_task(%s): adding request filters", task->id);
 
             /* setup the correct filters to process the request for h2 */
             ap_add_input_filter("H2_REQUEST", task, r, r->connection);
@@ -729,6 +755,7 @@ static int h2_h2_late_fixups(request_rec
                               "h2_slave_out(%s): copy_files on", task->id);
                 h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL);
             }
+            check_push(r, "late_fixup");
         }
     }
     return DECLINED;

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_mplx.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_mplx.c Tue Nov 22 09:04:49 2016
@@ -512,10 +512,6 @@ static int task_print(void *ctx, void *v
                       (stream? 0 : 1), task->worker_started, 
                       task->worker_done, task->frozen);
     }
-    else if (task) {
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */
-                      "->03198: h2_stream(%ld-%d): NULL", m->id, task->stream_id);
-    }
     else {
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */
                       "->03198: h2_stream(%ld-NULL): NULL", m->id);

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_session.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_session.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_session.c Tue Nov 22 09:04:49 2016
@@ -36,6 +36,8 @@ typedef struct h2_proxy_stream {
     const char *url;
     request_rec *r;
     h2_proxy_request *req;
+    const char *real_server_uri;
+    const char *p_server_uri;
     int standalone;
 
     h2_stream_state_t state;
@@ -161,7 +163,17 @@ static int on_frame_recv(nghttp2_session
                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 
                               "h2_proxy_session(%s): got interim HEADERS, status=%d",
                               session->id, r->status);
-                r->status_line = ap_get_status_line(r->status);
+                switch(r->status) {
+                    case 103:
+                        /* workaround until we get this into http protocol base
+                         * parts. without this, unknown codes are converted to
+                         * 500... */
+                        r->status_line = "103 Early Hints";
+                        break;
+                    default:
+                        r->status_line = ap_get_status_line(r->status);
+                        break;
+                }
                 ap_send_interim_response(r, 1);
             }
             stream->waiting_on_100 = 0;
@@ -216,8 +228,9 @@ static int add_header(void *table, const
     return 1;
 }
 
-static void process_proxy_header(request_rec *r, const char *n, const char *v)
+static void process_proxy_header(h2_proxy_stream *stream, const char *n, const char *v)
 {
+    request_rec *r = stream->r;
     static const struct {
         const char *name;
         ap_proxy_header_reverse_map_fn func;
@@ -240,6 +253,13 @@ static void process_proxy_header(request
             return;
        }
     }
+    if (!ap_cstr_casecmp("Link", n)) {
+        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
+        apr_table_add(r->headers_out, n,
+                      h2_proxy_link_reverse_map(r, dconf, 
+                      stream->real_server_uri, stream->p_server_uri, v));
+        return;
+    }
     apr_table_add(r->headers_out, n, v);
 }
 
@@ -274,7 +294,7 @@ static apr_status_t h2_proxy_stream_add_
         ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c, 
                       "h2_proxy_stream(%s-%d): got header %s: %s", 
                       stream->session->id, stream->id, hname, hvalue);
-        process_proxy_header(stream->r, hname, hvalue);
+        process_proxy_header(stream, hname, hvalue);
     }
     return APR_SUCCESS;
 }
@@ -383,9 +403,9 @@ static int stream_response_data(nghttp2_
     
     status = ap_pass_brigade(stream->r->output_filters, stream->output);
     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03359)
-                  "h2_proxy_session(%s): stream=%d, response DATA %ld, %"
-                  APR_OFF_T_FMT " total", session->id, stream_id, (long)len,
-                  stream->data_received);
+                  "h2_proxy_session(%s): stream=%d, response DATA %ld, %ld"
+                  " total", session->id, stream_id, (long)len,
+                  (long)stream->data_received);
     if (status != APR_SUCCESS) {
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c, APLOGNO(03344)
                       "h2_proxy_session(%s): passing output on stream %d", 
@@ -517,9 +537,9 @@ static ssize_t stream_request_data(nghtt
 
         stream->data_sent += readlen;
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03468) 
-                      "h2_proxy_stream(%d): request DATA %ld, %"
-                      APR_OFF_T_FMT" total, flags=%d", 
-                      stream->id, (long)readlen, stream->data_sent,
+                      "h2_proxy_stream(%d): request DATA %ld, %ld"
+                      " total, flags=%d", 
+                      stream->id, (long)readlen, (long)stream->data_sent,
                       (int)*data_flags);
         return readlen;
     }
@@ -689,6 +709,10 @@ static apr_status_t open_stream(h2_proxy
         /* port info missing and port is not default for scheme: append */
         authority = apr_psprintf(stream->pool, "%s:%d", authority, puri.port);
     }
+    /* we need this for mapping relative uris in headers ("Link") back
+     * to local uris */
+    stream->real_server_uri = apr_psprintf(stream->pool, "%s://%s", scheme, authority); 
+    stream->p_server_uri = apr_psprintf(stream->pool, "%s://%s", puri.scheme, authority); 
     path = apr_uri_unparse(stream->pool, &puri, APR_URI_UNP_OMITSITEPART);
     h2_proxy_req_make(stream->req, stream->pool, r->method, scheme,
                 authority, path, r->headers_in);

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.c Tue Nov 22 09:04:49 2016
@@ -14,18 +14,22 @@
  */
 
 #include <assert.h>
+#include <apr_lib.h>
 #include <apr_strings.h>
 
 #include <httpd.h>
 #include <http_core.h>
 #include <http_log.h>
 #include <http_request.h>
+#include <mod_proxy.h>
 
 #include <nghttp2/nghttp2.h>
 
 #include "h2.h"
 #include "h2_proxy_util.h"
 
+APLOG_USE_MODULE(proxy_http2);
+
 /* h2_log2(n) iff n is a power of 2 */
 unsigned char h2_proxy_log2(int n)
 {
@@ -701,3 +705,351 @@ int h2_proxy_util_frame_print(const nght
                                 frame->hd.flags, frame->hd.stream_id);
     }
 }
+
+/*******************************************************************************
+ * link header handling 
+ ******************************************************************************/
+
+typedef struct {
+    apr_pool_t *pool;
+    request_rec *r;
+    proxy_dir_conf *conf;
+    const char *s;
+    int slen;
+    int i;
+    const char *server_uri;
+    int su_len;
+    const char *real_backend_uri;
+    int rbu_len;
+    const char *p_server_uri;
+    int psu_len;
+    int link_start;
+    int link_end;
+} link_ctx;
+
+static int attr_char(char c) 
+{
+    switch (c) {
+        case '!':
+        case '#':
+        case '$':
+        case '&':
+        case '+':
+        case '-':
+        case '.':
+        case '^':
+        case '_':
+        case '`':
+        case '|':
+        case '~':
+            return 1;
+        default:
+            return apr_isalnum(c);
+    }
+}
+
+static int ptoken_char(char c) 
+{
+    switch (c) {
+        case '!':
+        case '#':
+        case '$':
+        case '&':
+        case '\'':
+        case '(':
+        case ')':
+        case '*':
+        case '+':
+        case '-':
+        case '.':
+        case '/':
+        case ':':
+        case '<':
+        case '=':
+        case '>':
+        case '?':
+        case '@':
+        case '[':
+        case ']':
+        case '^':
+        case '_':
+        case '`':
+        case '{':
+        case '|':
+        case '}':
+        case '~':
+            return 1;
+        default:
+            return apr_isalnum(c);
+    }
+}
+
+static int skip_ws(link_ctx *ctx)
+{
+    char c;
+    while (ctx->i < ctx->slen 
+           && (((c = ctx->s[ctx->i]) == ' ') || (c == '\t'))) {
+        ++ctx->i;
+    }
+    return (ctx->i < ctx->slen);
+}
+
+static int find_chr(link_ctx *ctx, char c, int *pidx)
+{
+    int j;
+    for (j = ctx->i; j < ctx->slen; ++j) {
+        if (ctx->s[j] == c) {
+            *pidx = j;
+            return 1;
+        }
+    } 
+    return 0;
+}
+
+static int read_chr(link_ctx *ctx, char c)
+{
+    if (ctx->i < ctx->slen && ctx->s[ctx->i] == c) {
+        ++ctx->i;
+        return 1;
+    }
+    return 0;
+}
+
+static int skip_qstring(link_ctx *ctx)
+{
+    if (skip_ws(ctx) && read_chr(ctx, '\"')) {
+        int end;
+        if (find_chr(ctx, '\"', &end)) {
+            ctx->i = end + 1;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int skip_ptoken(link_ctx *ctx)
+{
+    if (skip_ws(ctx)) {
+        int i;
+        for (i = ctx->i; i < ctx->slen && ptoken_char(ctx->s[i]); ++i) {
+            /* nop */
+        }
+        if (i > ctx->i) {
+            ctx->i = i;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+static int read_link(link_ctx *ctx)
+{
+    ctx->link_start = ctx->link_end = 0;
+    if (skip_ws(ctx) && read_chr(ctx, '<')) {
+        int end;
+        if (find_chr(ctx, '>', &end)) {
+            ctx->link_start = ctx->i;
+            ctx->link_end = end;
+            ctx->i = end + 1;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int skip_pname(link_ctx *ctx)
+{
+    if (skip_ws(ctx)) {
+        int i;
+        for (i = ctx->i; i < ctx->slen && attr_char(ctx->s[i]); ++i) {
+            /* nop */
+        }
+        if (i > ctx->i) {
+            ctx->i = i;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int skip_pvalue(link_ctx *ctx)
+{
+    if (skip_ws(ctx) && read_chr(ctx, '=')) {
+        if (skip_qstring(ctx) || skip_ptoken(ctx)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int skip_param(link_ctx *ctx)
+{
+    if (skip_ws(ctx) && read_chr(ctx, ';')) {
+        if (skip_pname(ctx)) {
+            skip_pvalue(ctx); /* value is optional */
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int read_sep(link_ctx *ctx)
+{
+    if (skip_ws(ctx) && read_chr(ctx, ',')) {
+        return 1;
+    }
+    return 0;
+}
+
+static size_t subst_str(link_ctx *ctx, int start, int end, const char *ns)
+{
+    int olen, nlen, plen;
+    int delta;
+    char *p;
+    
+    olen = end - start;
+    nlen = (int)strlen(ns);
+    delta = nlen - olen;
+    plen = ctx->slen + delta + 1;
+    p = apr_pcalloc(ctx->pool, plen);
+    strncpy(p, ctx->s, start);
+    strncpy(p + start, ns, nlen);
+    strcpy(p + start + nlen, ctx->s + end);
+    ctx->s = p;
+    ctx->slen = (int)strlen(p);
+    if (ctx->i >= end) {
+        ctx->i += delta;
+    }
+    return nlen; 
+}
+
+static void map_link(link_ctx *ctx) 
+{
+    if (ctx->link_start < ctx->link_end) {
+        char buffer[HUGE_STRING_LEN];
+        int need_len, link_len, buffer_len, prepend_p_server; 
+        const char *mapped;
+        
+        buffer[0] = '\0';
+        buffer_len = 0;
+        link_len = ctx->link_end - ctx->link_start;
+        need_len = link_len + 1;
+        prepend_p_server = (ctx->s[ctx->link_start] == '/'); 
+        if (prepend_p_server) {
+            /* common to use relative uris in link header, for mappings
+             * to work need to prefix the backend server uri */
+            need_len += ctx->psu_len;
+            strncpy(buffer, ctx->p_server_uri, sizeof(buffer));
+            buffer_len = ctx->psu_len;
+        }
+        if (need_len > sizeof(buffer)) {
+            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, ctx->r, APLOGNO(03482) 
+                          "link_reverse_map uri too long, skipped: %s", ctx->s);
+            return;
+        }
+        strncpy(buffer + buffer_len, ctx->s + ctx->link_start, link_len);
+        buffer_len += link_len;
+        buffer[buffer_len] = '\0';
+        if (!prepend_p_server
+            && strcmp(ctx->real_backend_uri, ctx->p_server_uri)
+            && !strncmp(buffer, ctx->real_backend_uri, ctx->rbu_len)) {
+            /* the server uri and our local proxy uri we use differ, for mapping
+             * to work, we need to use the proxy uri */
+            int path_start = ctx->link_start + ctx->rbu_len;
+            link_len -= ctx->rbu_len;
+            strcpy(buffer, ctx->p_server_uri);
+            strncpy(buffer + ctx->psu_len, ctx->s + path_start, link_len);
+            buffer_len = ctx->psu_len + link_len;
+            buffer[buffer_len] = '\0';            
+        }
+        mapped = ap_proxy_location_reverse_map(ctx->r, ctx->conf, buffer);
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, ctx->r, 
+                      "reverse_map[%s] %s --> %s", ctx->p_server_uri, buffer, mapped);
+        if (mapped != buffer) {
+            if (prepend_p_server) {
+                if (ctx->server_uri == NULL) {
+                    ctx->server_uri = ap_construct_url(ctx->pool, "", ctx->r);
+                    ctx->su_len = (int)strlen(ctx->server_uri);
+                }
+                if (!strncmp(mapped, ctx->server_uri, ctx->su_len)) {
+                    mapped += ctx->su_len;
+                }
+            }
+            subst_str(ctx, ctx->link_start, ctx->link_end, mapped);
+        }
+    }
+}
+
+/* RFC 5988 <https://tools.ietf.org/html/rfc5988#section-6.2.1>
+  Link           = "Link" ":" #link-value
+  link-value     = "<" URI-Reference ">" *( ";" link-param )
+  link-param     = ( ( "rel" "=" relation-types )
+                 | ( "anchor" "=" <"> URI-Reference <"> )
+                 | ( "rev" "=" relation-types )
+                 | ( "hreflang" "=" Language-Tag )
+                 | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) )
+                 | ( "title" "=" quoted-string )
+                 | ( "title*" "=" ext-value )
+                 | ( "type" "=" ( media-type | quoted-mt ) )
+                 | ( link-extension ) )
+  link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] )
+                 | ( ext-name-star "=" ext-value )
+  ext-name-star  = parmname "*" ; reserved for RFC2231-profiled
+                                ; extensions.  Whitespace NOT
+                                ; allowed in between.
+  ptoken         = 1*ptokenchar
+  ptokenchar     = "!" | "#" | "$" | "%" | "&" | "'" | "("
+                 | ")" | "*" | "+" | "-" | "." | "/" | DIGIT
+                 | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA
+                 | "[" | "]" | "^" | "_" | "`" | "{" | "|"
+                 | "}" | "~"
+  media-type     = type-name "/" subtype-name
+  quoted-mt      = <"> media-type <">
+  relation-types = relation-type
+                 | <"> relation-type *( 1*SP relation-type ) <">
+  relation-type  = reg-rel-type | ext-rel-type
+  reg-rel-type   = LOALPHA *( LOALPHA | DIGIT | "." | "-" )
+  ext-rel-type   = URI
+  
+  and from <https://tools.ietf.org/html/rfc5987>
+  parmname      = 1*attr-char
+  attr-char     = ALPHA / DIGIT
+                   / "!" / "#" / "$" / "&" / "+" / "-" / "."
+                   / "^" / "_" / "`" / "|" / "~"
+ */
+
+const char *h2_proxy_link_reverse_map(request_rec *r,
+                                      proxy_dir_conf *conf, 
+                                      const char *real_backend_uri,
+                                      const char *proxy_server_uri,
+                                      const char *s)
+{
+    link_ctx ctx;
+    
+    if (r->proxyreq != PROXYREQ_REVERSE) {
+        return s;
+    }
+    memset(&ctx, 0, sizeof(ctx));
+    ctx.r = r;
+    ctx.pool = r->pool;
+    ctx.conf = conf;
+    ctx.real_backend_uri = real_backend_uri;
+    ctx.rbu_len = (int)strlen(ctx.real_backend_uri);
+    ctx.p_server_uri = proxy_server_uri;
+    ctx.psu_len = (int)strlen(ctx.p_server_uri);
+    ctx.s = s;
+    ctx.slen = (int)strlen(s);
+    while (read_link(&ctx)) {
+        while (skip_param(&ctx)) {
+            /* nop */
+        }
+        map_link(&ctx);
+        if (!read_sep(&ctx)) {
+            break;
+        }
+    }
+    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, 
+                  "link_reverse_map %s --> %s", s, ctx.s);
+    return ctx.s;
+}

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_proxy_util.h Tue Nov 22 09:04:49 2016
@@ -192,6 +192,13 @@ apr_status_t h2_proxy_req_make(h2_proxy_
                                const char *authority, const char *path, 
                                apr_table_t *headers);
 
-
+/*******************************************************************************
+ * reverse mapping for link headers
+ ******************************************************************************/
+const char *h2_proxy_link_reverse_map(request_rec *r,
+                                      proxy_dir_conf *conf, 
+                                      const char *real_server_uri,
+                                      const char *proxy_server_uri,
+                                      const char *s);
 
 #endif /* defined(__mod_h2__h2_proxy_util__) */

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.c Tue Nov 22 09:04:49 2016
@@ -353,7 +353,11 @@ static int add_push(link_ctx *ctx)
                 /* atm, we do not push on pushes */
                 h2_request_end_headers(req, ctx->pool, 1);
                 push->req = req;
-                
+                if (has_param(ctx, "critical")) {
+                    h2_priority *prio = apr_pcalloc(ctx->pool, sizeof(*prio));
+                    prio->dependency = H2_DEPENDANT_BEFORE;
+                    push->priority = prio;
+                }
                 if (!ctx->pushes) {
                     ctx->pushes = apr_array_make(ctx->pool, 5, sizeof(h2_push*));
                 }

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_push.h Tue Nov 22 09:04:49 2016
@@ -25,6 +25,7 @@ struct h2_stream;
 
 typedef struct h2_push {
     const struct h2_request *req;
+    h2_priority *priority;
 } h2_push;
 
 typedef enum {

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_session.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_session.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_session.c Tue Nov 22 09:04:49 2016
@@ -1233,6 +1233,7 @@ struct h2_stream *h2_session_push(h2_ses
                   
     stream = h2_session_open_stream(session, nid, is->id, push->req);
     if (stream) {
+        h2_session_set_prio(session, stream, push->priority);
         status = stream_schedule(session, stream, 1);
         if (status != APR_SUCCESS) {
             ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c,
@@ -1271,6 +1272,10 @@ apr_status_t h2_session_set_prio(h2_sess
 #ifdef H2_NG2_CHANGE_PRIO
     nghttp2_stream *s_grandpa, *s_parent, *s;
     
+    if (prio == NULL) {
+        /* we treat this as a NOP */
+        return APR_SUCCESS;
+    }
     s = nghttp2_session_find_stream(session->ngh2, stream->id);
     if (!s) {
         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
@@ -1437,7 +1442,6 @@ static apr_status_t on_stream_headers(h2
         nghttp2_data_provider provider, *pprovider = NULL;
         h2_ngheader *ngh;
         apr_table_t *hout;
-        const h2_priority *prio;
         const char *note;
         
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03073)
@@ -1454,7 +1458,7 @@ static apr_status_t on_stream_headers(h2
         
         /* If this stream is not a pushed one itself,
          * and HTTP/2 server push is enabled here,
-         * and the response is in the range 200-299 *),
+         * and the response HTTP status is not sth >= 400,
          * and the remote side has pushing enabled,
          * -> find and perform any pushes on this stream
          *    *before* we submit the stream response itself.
@@ -1462,23 +1466,24 @@ static apr_status_t on_stream_headers(h2
          *    headers that get pushed right afterwards.
          * 
          * *) the response code is relevant, as we do not want to 
-         *    make pushes on 401 or 403 codes, neiterh on 301/302
-         *    and friends. And if we see a 304, we do not push either
+         *    make pushes on 401 or 403 codes and friends. 
+         *    And if we see a 304, we do not push either
          *    as the client, having this resource in its cache, might
          *    also have the pushed ones as well.
          */
         if (!stream->initiated_on
-            && h2_headers_are_response(headers)
-            && H2_HTTP_2XX(headers->status)
+            && !stream->has_response
+            && (headers->status < 400)
+            && (headers->status != 304)
             && h2_session_push_enabled(session)) {
             
             h2_stream_submit_pushes(stream, headers);
         }
         
-        prio = h2_stream_get_priority(stream, headers);
-        if (prio) {
-            h2_session_set_prio(session, stream, prio);
+        if (!stream->pref_priority) {
+            stream->pref_priority = h2_stream_get_priority(stream, headers);
         }
+        h2_session_set_prio(session, stream, stream->pref_priority);
         
         hout = headers->headers;
         note = apr_table_get(headers->notes, H2_FILTER_DEBUG_NOTE);

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_stream.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_stream.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_stream.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_stream.h Tue Nov 22 09:04:49 2016
@@ -67,6 +67,7 @@ struct h2_stream {
     unsigned int push_policy;   /* which push policy to use for this request */
     unsigned int can_be_cleaned : 1; /* stream pool can be cleaned */
     
+    const h2_priority *pref_priority; /* preferred priority for this stream */
     apr_off_t out_data_frames;  /* # of DATA frames sent */
     apr_off_t out_data_octets;  /* # of DATA octets (payload) sent */
     apr_off_t in_data_frames;   /* # of DATA frames received */

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_version.h?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_version.h (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/h2_version.h Tue Nov 22 09:04:49 2016
@@ -26,7 +26,7 @@
  * @macro
  * Version number of the http2 module as c string
  */
-#define MOD_HTTP2_VERSION "1.7.9"
+#define MOD_HTTP2_VERSION "1.8.0"
 
 /**
  * @macro
@@ -34,7 +34,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_HTTP2_VERSION_NUM 0x010709
+#define MOD_HTTP2_VERSION_NUM 0x010800
 
 
 #endif /* mod_h2_h2_version_h */

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/mod_http2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/mod_http2.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/mod_http2.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/http2/mod_http2.c Tue Nov 22 09:04:49 2016
@@ -48,9 +48,9 @@ static void h2_hooks(apr_pool_t *pool);
 AP_DECLARE_MODULE(http2) = {
     STANDARD20_MODULE_STUFF,
     h2_config_create_dir, /* func to create per dir config */
-    h2_config_merge,
+    h2_config_merge_dir,  /* func to merge per dir config */
     h2_config_create_svr, /* func to create per server config */
-    h2_config_merge,      /* func to merge per server config */
+    h2_config_merge_svr,  /* func to merge per server config */
     h2_cmds,              /* command handlers */
     h2_hooks
 };

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/metadata/mod_headers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/metadata/mod_headers.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/metadata/mod_headers.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/metadata/mod_headers.c Tue Nov 22 09:04:49 2016
@@ -666,13 +666,15 @@ static const char *process_regexp(header
     return ret;
 }
 
-static int echo_header(echo_do *v, const char *key, const char *val)
+static int echo_header(void *v, const char *key, const char *val)
 {
+    edit_do *ed = v;
+
     /* If the input header (key) matches the regex, echo it intact to
      * r->headers_out.
      */
-    if (!ap_regexec(v->hdr->regex, key, 0, NULL, 0)) {
-        apr_table_add(v->r->headers_out, key, val);
+    if (!ap_regexec(ed->hdr->regex, key, 0, NULL, 0)) {
+        apr_table_add(ed->r->headers_out, key, val);
     }
 
     return 1;
@@ -808,8 +810,7 @@ static int do_headers_fixup(request_rec
         case hdr_echo:
             v.r = r;
             v.hdr = hdr;
-            apr_table_do((int (*) (void *, const char *, const char *))
-                         echo_header, (void *) &v, r->headers_in, NULL);
+            apr_table_do(echo_header, &v, r->headers_in, NULL);
             break;
         case hdr_edit:
         case hdr_edit_r:

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/session/mod_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/session/mod_session.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/session/mod_session.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/session/mod_session.c Tue Nov 22 09:04:49 2016
@@ -299,15 +299,16 @@ static apr_status_t ap_session_set(reque
     return APR_SUCCESS;
 }
 
-static int identity_count(int *count, const char *key, const char *val)
+static int identity_count(void *v, const char *key, const char *val)
 {
+    int *count = v;
     *count += strlen(key) * 3 + strlen(val) * 3 + 1;
     return 1;
 }
 
-static int identity_concat(char *buffer, const char *key, const char *val)
+static int identity_concat(void *v, const char *key, const char *val)
 {
-    char *slider = buffer;
+    char *slider = v;
     int length = strlen(slider);
     slider += length;
     if (length) {
@@ -344,11 +345,9 @@ static apr_status_t session_identity_enc
         char *expiry = apr_psprintf(z->pool, "%" APR_INT64_T_FMT, z->expiry);
         apr_table_setn(z->entries, SESSION_EXPIRY, expiry);
     }
-    apr_table_do((int (*) (void *, const char *, const char *))
-                 identity_count, &length, z->entries, NULL);
+    apr_table_do(identity_count, &length, z->entries, NULL);
     buffer = apr_pcalloc(r->pool, length + 1);
-    apr_table_do((int (*) (void *, const char *, const char *))
-                 identity_concat, buffer, z->entries, NULL);
+    apr_table_do(identity_concat, buffer, z->entries, NULL);
     z->encoded = buffer;
     return OK;
 

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/ssl/ssl_engine_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/ssl/ssl_engine_io.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/ssl/ssl_engine_io.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/modules/ssl/ssl_engine_io.c Tue Nov 22 09:04:49 2016
@@ -661,6 +661,11 @@ static apr_status_t ssl_io_input_read(bi
             break;
         }
 
+        /* We rely on SSL_get_error() after the read, which requires an empty
+         * error queue before the read in order to work properly.
+         */
+        ERR_clear_error();
+
         /* SSL_read may not read because we haven't taken enough data
          * from the stack.  This is where we want to consider all of
          * the blocking and SPECULATIVE semantics
@@ -838,6 +843,11 @@ static apr_status_t ssl_filter_write(ap_
         return APR_EGENERAL;
     }
 
+    /* We rely on SSL_get_error() after the write, which requires an empty error
+     * queue before the write in order to work properly.
+     */
+    ERR_clear_error();
+
     outctx = (bio_filter_out_ctx_t *)BIO_get_data(filter_ctx->pbioWrite);
     res = SSL_write(filter_ctx->pssl, (unsigned char *)data, len);
 
@@ -1309,6 +1319,11 @@ static apr_status_t ssl_io_filter_handsh
         return APR_SUCCESS;
     }
 
+    /* We rely on SSL_get_error() after the accept, which requires an empty
+     * error queue before the accept in order to work properly.
+     */
+    ERR_clear_error();
+
     if ((n = SSL_accept(filter_ctx->pssl)) <= 0) {
         bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)
                                      BIO_get_data(filter_ctx->pbioRead);

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/request.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/request.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/request.c Tue Nov 22 09:04:49 2016
@@ -1960,6 +1960,8 @@ static request_rec *make_sub_request(con
 
     /* start with the same set of output filters */
     if (next_filter) {
+        ap_filter_t *scan = next_filter;
+
         /* while there are no input filters for a subrequest, we will
          * try to insert some, so if we don't have valid data, the code
          * will seg fault.
@@ -1968,8 +1970,16 @@ static request_rec *make_sub_request(con
         rnew->proto_input_filters = r->proto_input_filters;
         rnew->output_filters = next_filter;
         rnew->proto_output_filters = r->proto_output_filters;
-        ap_add_output_filter_handle(ap_subreq_core_filter_handle,
-                                    NULL, rnew, rnew->connection);
+        while (scan && (scan != r->proto_output_filters)) {
+            if (scan->frec == ap_subreq_core_filter_handle) {
+                break;
+            }
+            scan = scan->next;
+        }
+        if (!scan || scan == r->proto_output_filters) {
+            ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+                    NULL, rnew, rnew->connection);
+        }
     }
     else {
         /* If NULL - we are expecting to be internal_fast_redirect'ed

Modified: httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/util_cookies.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/util_cookies.c?rev=1770812&r1=1770811&r2=1770812&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/util_cookies.c (original)
+++ httpd/httpd/branches/2.4.x-openssl-1.1.0-compat/server/util_cookies.c Tue Nov 22 09:04:49 2016
@@ -174,8 +174,9 @@ AP_DECLARE(apr_status_t) ap_cookie_remov
  * $path or other attributes following our cookie if present. If we end
  * up with an empty cookie, remove the whole header.
  */
-static int extract_cookie_line(ap_cookie_do * v, const char *key, const char *val)
+static int extract_cookie_line(void *varg, const char *key, const char *val)
 {
+    ap_cookie_do *v = varg;
     char *last1, *last2;
     char *cookie = apr_pstrdup(v->r->pool, val);
     const char *name = apr_pstrcat(v->r->pool, v->name ? v->name : "", "=", NULL);
@@ -252,8 +253,7 @@ AP_DECLARE(apr_status_t) ap_cookie_read(
     v.duplicated = 0;
     v.name = name;
 
-    apr_table_do((int (*) (void *, const char *, const char *))
-                 extract_cookie_line, (void *) &v, r->headers_in,
+    apr_table_do(extract_cookie_line, &v, r->headers_in,
                  "Cookie", "Cookie2", NULL);
     if (v.duplicated) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00011) LOG_PREFIX



Mime
View raw message