Download | Plain Text | No Line Numbers


  1. diff --git a/docs/manual/mod/mod_proxy_fcgi.xml b/docs/manual/mod/mod_proxy_fcgi.xml
  2. index fb3c7f8..c9f5941 100644
  3. --- a/docs/manual/mod/mod_proxy_fcgi.xml
  4. +++ b/docs/manual/mod/mod_proxy_fcgi.xml
  5. @@ -119,4 +119,33 @@ ProxyPass /myapp/ balancer://myappcluster/
  6. </dl>
  7. </section>
  8.  
  9. +<directivesynopsis>
  10. + <name>ProxyFCGIPassHeader</name>
  11. + <description>Header name which will be passed to FastCGI as environment variable.</description>
  12. + <syntax>ProxyFCGIPassHeader <em>name</em></syntax>
  13. + <default>none</default>
  14. + <contextlist><context>server config</context> <context>virtual host</context></contextlist>
  15. + <usage>
  16. + <p>This directive specifies the name of a request header which
  17. + will be passed to the FastCGI application as an environment
  18. + variable. The name of the environment variable is derived from
  19. + the value specified on this directive, as discussed below:</p>
  20. +
  21. + <p>The value specified on this directive is converted to
  22. + upper case, prefixed with <code>HTTP_</code>, and hyphens are
  23. + converted to underscores.</p>
  24. +
  25. + <note type="hint"><title>Note</title>
  26. + <p>Most request headers are already available to the application
  27. + as environment variables, and generally are prefixed with
  28. + <code>HTTP_</code>. (Notable exceptions are <code>Content-type</code>
  29. + and <code>Content-length</code>, which do not have the
  30. + <code>HTTP_</code> prefix.) Thus, this directive is only required
  31. + for request headers that are purposefully omitted, such as
  32. + <code>Authorization</code> and <code>Proxy-Authorization</code>.
  33. + Only pass these request headers if absolutely required.</p>
  34. + </note>
  35. + </usage>
  36. +</directivesynopsis>
  37. +
  38. </modulesynopsis>
  39. diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
  40. index d7ab5cb..61447a6 100644
  41. --- a/modules/proxy/mod_proxy_fcgi.c
  42. +++ b/modules/proxy/mod_proxy_fcgi.c
  43. @@ -20,6 +20,10 @@
  44.  
  45. module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
  46.  
  47. +typedef struct {
  48. + apr_array_header_t *pass_headers;
  49. +} fcgi_server_conf;
  50. +
  51. /*
  52. * Canonicalise http-like URLs.
  53. * scheme is the scheme for the URL
  54. @@ -193,6 +197,62 @@ static apr_status_t send_begin_request(proxy_conn_rec *conn,
  55. return send_data(conn, vec, 2, &len);
  56. }
  57.  
  58. +/* http2env stolen from util_script.c */
  59. +static char *http2env(request_rec *r, const char *w)
  60. +{
  61. + char *res = (char *)apr_palloc(r->pool, sizeof("HTTP_") + strlen(w));
  62. + char *cp = res;
  63. + char c;
  64. +
  65. + *cp++ = 'H';
  66. + *cp++ = 'T';
  67. + *cp++ = 'T';
  68. + *cp++ = 'P';
  69. + *cp++ = '_';
  70. +
  71. + while ((c = *w++) != 0) {
  72. + if (apr_isalnum(c)) {
  73. + *cp++ = apr_toupper(c);
  74. + }
  75. + else if (c == '-') {
  76. + *cp++ = '_';
  77. + }
  78. + else {
  79. + if (APLOGrtrace1(r))
  80. + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
  81. + "Not exporting header with invalid name as envvar: %s",
  82. + ap_escape_logitem(r->pool, w));
  83. + return NULL;
  84. + }
  85. + }
  86. + *cp = 0;
  87. +
  88. + return res;
  89. +}
  90. +
  91. +static void fcgi_add_cgi_vars(request_rec * r)
  92. +{
  93. + fcgi_server_conf *conf =
  94. + ap_get_module_config(r->server->module_config, &proxy_fcgi_module);
  95. + apr_array_header_t *passheaders = conf->pass_headers;
  96. +
  97. + if (passheaders != NULL) {
  98. + const char **hdr = (const char **) passheaders->elts;
  99. + int hdrcnt = passheaders->nelts;
  100. + int i;
  101. +
  102. + for (i = 0; i < hdrcnt; i++, ++hdr) {
  103. + /* standard munging of header name (upcase, HTTP_, etc.) */
  104. + const char *name = http2env(r, *hdr);
  105. + const char *val = apr_table_get(r->headers_in, *hdr);
  106. +
  107. + if (name && val) {
  108. + apr_table_setn(r->subprocess_env, name, val);
  109. + }
  110. + }
  111. + }
  112. +}
  113. +
  114. static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
  115. apr_pool_t *temp_pool,
  116. apr_uint16_t request_id)
  117. @@ -209,6 +269,7 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
  118.  
  119. ap_add_common_vars(r);
  120. ap_add_cgi_vars(r);
  121. + fcgi_add_cgi_vars(r);
  122.  
  123. /* XXX are there any FastCGI specific env vars we need to send? */
  124.  
  125. @@ -840,6 +901,46 @@ cleanup:
  126. return status;
  127. }
  128.  
  129. +static void *create_config(apr_pool_t *p, server_rec *s)
  130. +{
  131. + fcgi_server_conf *conf = apr_palloc(p, sizeof(*conf));
  132. + conf->pass_headers = apr_array_make(p, 10, sizeof(const char *));
  133. + return conf;
  134. +}
  135. +
  136. +static void *merge_config(apr_pool_t *p, void *base_, void *add_)
  137. +{
  138. + fcgi_server_conf *base = (fcgi_server_conf *)base_;
  139. + fcgi_server_conf *add = (fcgi_server_conf *)add_;
  140. + fcgi_server_conf *conf = apr_pcalloc(p, sizeof(*conf));
  141. +
  142. + conf->pass_headers = apr_array_append(p, base->pass_headers,
  143. + add->pass_headers);
  144. +
  145. + return conf;
  146. +}
  147. +
  148. +static const char *add_pass_headers(cmd_parms * cmd, void *dummy,
  149. + const char *arg)
  150. +{
  151. + const char **header;
  152. + fcgi_server_conf *conf =
  153. + ap_get_module_config(cmd->server->module_config, &proxy_fcgi_module);
  154. +
  155. + header = (const char **) apr_array_push(conf->pass_headers);
  156. + *header = ap_getword_conf(cmd->pool, &arg);
  157. +
  158. + return header ? NULL : "Invalid ProxyFCGIPassHeader";
  159. +}
  160. +
  161. +static const command_rec fcgi_cmds[] =
  162. +{
  163. + AP_INIT_TAKE1("ProxyFCGIPassHeader", add_pass_headers,
  164. + NULL, RSRC_CONF,
  165. + "Header name which will be passed to FastCGI as environment variable."),
  166. + {NULL}
  167. +};
  168. +
  169. static void register_hooks(apr_pool_t *p)
  170. {
  171. proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST);
  172. @@ -850,8 +951,8 @@ AP_DECLARE_MODULE(proxy_fcgi) = {
  173. STANDARD20_MODULE_STUFF,
  174. NULL, /* create per-directory config structure */
  175. NULL, /* merge per-directory config structures */
  176. - NULL, /* create per-server config structure */
  177. - NULL, /* merge per-server config structures */
  178. - NULL, /* command apr_table_t */
  179. + create_config, /* create per-server config structure */
  180. + merge_config, /* merge per-server config structures */
  181. + fcgi_cmds, /* command apr_table_t */
  182. register_hooks /* register hooks */
  183. };
  184.