You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2016/07/20 13:04:58 UTC

svn commit: r1753498 - in /httpd/httpd/trunk: ./ docs/manual/mod/ modules/http2/

Author: icing
Date: Wed Jul 20 13:04:57 2016
New Revision: 1753498

URL: http://svn.apache.org/viewvc?rev=1753498&view=rev
Log:
mod_http2: new H2CopyFiles directive

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
    httpd/httpd/trunk/modules/http2/h2_bucket_beam.c
    httpd/httpd/trunk/modules/http2/h2_bucket_beam.h
    httpd/httpd/trunk/modules/http2/h2_config.c
    httpd/httpd/trunk/modules/http2/h2_config.h
    httpd/httpd/trunk/modules/http2/h2_h2.c
    httpd/httpd/trunk/modules/http2/h2_mplx.c
    httpd/httpd/trunk/modules/http2/h2_task.c
    httpd/httpd/trunk/modules/http2/h2_task.h
    httpd/httpd/trunk/modules/http2/mod_http2.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Wed Jul 20 13:04:57 2016
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_http2: new H2CopyFiles directive that changes treatment of file
+     handles in responses. Necessary in order to fix broken lifetime handling
+     in modules such as mod_wsgi.
+  
   *) mod_proxy_fcgi: avoid loops when ProxyErrorOverride is enabled
      and the error documents are proxied. PR 55415. [Luca Toscano]
 

Modified: httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_http2.xml?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_http2.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_http2.xml Wed Jul 20 13:04:57 2016
@@ -897,4 +897,41 @@ H2TLSCoolDownSecs 0
         </usage>
     </directivesynopsis>
     
+    <directivesynopsis>
+        <name>H2CopyFiles</name>
+        <description>Determine file handling in responses</description>
+        <syntax>H2CopyFiles on|off</syntax>
+        <default>H2CopyFiles off</default>
+        <contextlist>
+            <context>server config</context>
+            <context>virtual host</context>
+            <context>directory</context>
+            <context>.htaccess</context>
+        </contextlist>
+        <compatibility>Available in version 2.4.24 and later.</compatibility>
+        
+        <usage>
+            <p>
+                This directive influences how file content is handled in
+                responses. When off, which is the default, file handles are 
+                passed from the requestion processing down to the main
+                connection, using the usual Apache setaside handling for
+                manaaging the lifetime of the file.
+            </p>
+            <p>
+                When set to <code>on</code>, file content is copied while the
+                request is still being processed and the buffered data is passed
+                on to the main connection. This is better if a third party
+                module is injecting files with different lifetimes into the response. 
+            </p>
+            <p>
+                An example for such a module is <code>mod_wsgi</code> that may place
+                Python file handles into the response. Those files get close down when
+                Python thinks processing has finished. That may be well before
+                <code>mod_http2</code> is done with them.
+            </p>
+        </usage>
+    </directivesynopsis>
+    
+    
 </modulesynopsis>

Modified: httpd/httpd/trunk/modules/http2/h2_bucket_beam.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_bucket_beam.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_bucket_beam.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_bucket_beam.c Wed Jul 20 13:04:57 2016
@@ -1013,3 +1013,8 @@ apr_size_t h2_beam_get_files_beamed(h2_b
     return n;
 }
 
+int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file)
+{
+    return 0;
+}
+

Modified: httpd/httpd/trunk/modules/http2/h2_bucket_beam.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_bucket_beam.h?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_bucket_beam.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_bucket_beam.h Wed Jul 20 13:04:57 2016
@@ -163,6 +163,12 @@ typedef struct {
 typedef int h2_beam_can_beam_callback(void *ctx, h2_bucket_beam *beam,
                                       apr_file_t *file);
 
+/**
+ * Will deny all transfer of apr_file_t across the beam and force
+ * a data copy instead.
+ */
+int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file);
+
 struct h2_bucket_beam {
     int id;
     const char *tag;

Modified: httpd/httpd/trunk/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.c Wed Jul 20 13:04:57 2016
@@ -61,7 +61,7 @@ static h2_config defconf = {
     1,                      /* HTTP/2 server push enabled */
     NULL,                   /* map of content-type to priorities */
     256,                    /* push diary size */
-    
+    0,                      /* copy files across threads */
 };
 
 void h2_config_init(apr_pool_t *pool)
@@ -95,6 +95,7 @@ static void *h2_config_create(apr_pool_t
     conf->h2_push              = DEF_VAL;
     conf->priorities           = NULL;
     conf->push_diary_size      = DEF_VAL;
+    conf->copy_files           = DEF_VAL;
     
     return conf;
 }
@@ -141,6 +142,7 @@ void *h2_config_merge(apr_pool_t *pool,
         n->priorities       = add->priorities? add->priorities : base->priorities;
     }
     n->push_diary_size      = H2_CONFIG_GET(add, base, push_diary_size);
+    n->copy_files           = H2_CONFIG_GET(add, base, copy_files);
     
     return n;
 }
@@ -185,6 +187,8 @@ apr_int64_t h2_config_geti64(const h2_co
             return H2_CONFIG_GET(conf, &defconf, h2_push);
         case H2_CONF_PUSH_DIARY_SIZE:
             return H2_CONFIG_GET(conf, &defconf, push_diary_size);
+        case H2_CONF_COPY_FILES:
+            return H2_CONFIG_GET(conf, &defconf, copy_files);
         default:
             return DEF_VAL;
     }
@@ -500,6 +504,23 @@ static const char *h2_conf_set_push_diar
     return NULL;
 }
 
+static const char *h2_conf_set_copy_files(cmd_parms *parms,
+                                          void *arg, const char *value)
+{
+    h2_config *cfg = (h2_config *)arg;
+    if (!strcasecmp(value, "On")) {
+        cfg->copy_files = 1;
+        return NULL;
+    }
+    else if (!strcasecmp(value, "Off")) {
+        cfg->copy_files = 0;
+        return NULL;
+    }
+    
+    (void)arg;
+    return "value must be On or Off";
+}
+
 #define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
 
 const command_rec h2_cmds[] = {
@@ -539,6 +560,8 @@ const command_rec h2_cmds[] = {
                   RSRC_CONF, "define priority of PUSHed resources per content type"),
     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"),
     AP_END_CMD
 };
 

Modified: httpd/httpd/trunk/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.h?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.h Wed Jul 20 13:04:57 2016
@@ -40,6 +40,7 @@ typedef enum {
     H2_CONF_TLS_COOLDOWN_SECS,
     H2_CONF_PUSH,
     H2_CONF_PUSH_DIARY_SIZE,
+    H2_CONF_COPY_FILES,
 } h2_config_var_t;
 
 struct apr_hash_t;
@@ -68,6 +69,7 @@ typedef struct h2_config {
     struct apr_hash_t *priorities;/* map of content-type to h2_priority records */
     
     int push_diary_size;          /* # of entries in push diary */
+    int copy_files;               /* if files shall be copied vs setaside on output */
 } h2_config;
 
 

Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_h2.c Wed Jul 20 13:04:57 2016
@@ -433,6 +433,7 @@ static int cipher_is_blacklisted(const c
 static int h2_h2_process_conn(conn_rec* c);
 static int h2_h2_pre_close_conn(conn_rec* c);
 static int h2_h2_post_read_req(request_rec *r);
+static int h2_h2_late_fixups(request_rec *r);
 
 /*******************************************************************************
  * Once per lifetime init, retrieve optional functions
@@ -567,6 +568,7 @@ void h2_h2_register_hooks(void)
      * never see the response.
      */
     ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
+    ap_hook_fixups(h2_h2_late_fixups, NULL, NULL, APR_HOOK_LAST);
 }
 
 int h2_h2_process_conn(conn_rec* c)
@@ -682,7 +684,7 @@ static int h2_h2_post_read_req(request_r
          * that we manipulate filters only once. */
         if (task && !task->filters_set) {
             ap_filter_t *f;
-            
+
             /* setup the correct output filters to process the response
              * on the proper mod_http2 way. */
             ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding task output filter");
@@ -710,5 +712,20 @@ static int h2_h2_post_read_req(request_r
         }
     }
     return DECLINED;
+}
+
+static int h2_h2_late_fixups(request_rec *r)
+{
+    /* slave connection? */
+    if (r->connection->master) {
+        h2_ctx *ctx = h2_ctx_rget(r);
+        struct h2_task *task = h2_ctx_get_task(ctx);
+        if (task) {
+            /* check if we copy vs. setaside files in this location */
+            task->output.copy_files = h2_config_geti(h2_config_rget(r), 
+                                                     H2_CONF_COPY_FILES);
+        }
+    }
+    return DECLINED;
 }
 

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Wed Jul 20 13:04:57 2016
@@ -686,7 +686,9 @@ static apr_status_t out_open(h2_mplx *m,
         h2_beam_timeout_set(task->output.beam, m->stream_timeout);
         h2_beam_on_consumed(task->output.beam, stream_output_consumed, task);
         m->tx_handles_reserved -= h2_beam_get_files_beamed(task->output.beam);
-        h2_beam_on_file_beam(task->output.beam, can_beam_file, m);
+        if (!task->output.copy_files) {
+            h2_beam_on_file_beam(task->output.beam, can_beam_file, m);
+        }
         h2_beam_mutex_set(task->output.beam, beam_enter, task->cond, m);
     }
     

Modified: httpd/httpd/trunk/modules/http2/h2_task.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_task.c Wed Jul 20 13:04:57 2016
@@ -406,7 +406,12 @@ static apr_status_t output_write(h2_task
     
     if (!task->output.beam) {
         h2_beam_create(&task->output.beam, task->pool, 
-                       task->stream_id, "output", 0); 
+                       task->stream_id, "output", 0);
+        if (task->output.copy_files) {
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
+                          "h2_task(%s): copy_files on", task->id);
+            h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL);
+        }
     }
     
     /* Attempt to write saved brigade first */

Modified: httpd/httpd/trunk/modules/http2/h2_task.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task.h?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_task.h Wed Jul 20 13:04:57 2016
@@ -71,6 +71,7 @@ struct h2_task {
         struct h2_bucket_beam *beam;
         struct h2_from_h1 *from_h1;
         unsigned int response_open : 1;
+        unsigned int copy_files : 1;
         apr_off_t written;
         apr_bucket_brigade *bb;
     } output;

Modified: httpd/httpd/trunk/modules/http2/mod_http2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.c?rev=1753498&r1=1753497&r2=1753498&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/mod_http2.c (original)
+++ httpd/httpd/trunk/modules/http2/mod_http2.c Wed Jul 20 13:04:57 2016
@@ -47,8 +47,8 @@ static void h2_hooks(apr_pool_t *pool);
 
 AP_DECLARE_MODULE(http2) = {
     STANDARD20_MODULE_STUFF,
-    NULL,
-    NULL,
+    h2_config_create_dir, /* func to create per dir config */
+    h2_config_merge,
     h2_config_create_svr, /* func to create per server config */
     h2_config_merge,      /* func to merge per server config */
     h2_cmds,              /* command handlers */