Re: mod_proxy: unwieldy unix socket implementation.

2014-03-19 Thread Jan Kaluža

On 03/19/2014 06:15 AM, Andreas B. wrote:

Hello,

I saw the new unix sockets for mod_proxy in 2.4.9 and I am wondering why
there has to be a special url format. Wouldn't it be possible to supply
the socket path as a proxy parameter? I have something like this in mind:

 Proxy fcgi://php-fpm.local
 ProxySet unix=/run/php-fpm/php-fpm.sock
 /Proxy
 FilesMatch \.php$
 SetHandler proxy:fcgi://php-fpm.local
 /FilesMatch

or with ProxyPass:
 ProxyPass /php-bin proxy:fcgi://php-fpm.local/src/http/
unix=/run/php-fpm/php-fpm.sock
 ProxyPassMatch ^(/.*\.php)$ fcgi://php-fpm.local/srv/http/
unix=/run/php-fpm/php-fpm.sock

I can provide an incomplete patchset for this. I didn't touch the
documentation, mod_proxy_balancer output and log messages. This would
get rid of de_socketfy() and make the codepath much cleaner I think.

Andreas

PS: I found some strange behaviour with ProxyPassMatch. When you use a
group match (e.g. $1) in the result string, you'll have to define the
parameters in a separate proxy section. This Probably applies to
ProxyPass with the regex-tilde as well
 ProxyPassMatch ^(/.*\.php)$ fcgi://php-fpm.local/srv/http/$1
 Proxy fcgi://php-fpm.local/srv/http
 ProxySet unix=/run/php-fpm/php-fpm.sock
 /Proxy


Check [PATCH] Fix settings options with ProxyPassMatch thread for this 
particular problem.


Jan Kaluza



Re: [PATCH] Fix settings options with ProxyPassMatch

2014-03-19 Thread Jan Kaluža

On 03/18/2014 02:46 PM, Yann Ylavic wrote:

On Tue, Mar 18, 2014 at 2:38 PM, Yann Ylavic ylavic@gmail.com wrote:

Wouldn't it be possible to define wildcard workers when the URL is
known to be a regexp substitution?
For these workers' URLs, the dollars (plus the following digit) could
be replaced by a wildcard (ie. *) and ap_proxy_get_worker() could then
use ap_strcasecmp_match() against the requested URL.


I meant ap_strcmp_match(), this has to be case sensitive...



I've implemented your idea. Can you check the attached patch please? It 
fixes the original PR and also ProxyPassMatch with UDS for me.


If it's OK, I will commit it.

Regards,
Jan Kaluza

Index: modules/proxy/mod_proxy.c
===
--- modules/proxy/mod_proxy.c	(revision 1579155)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -1631,8 +1631,29 @@
 new-balancer = balancer;
 }
 else {
-proxy_worker *worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, de_socketfy(cmd-pool, r));
+proxy_worker *worker;
 int reuse = 0;
+/* When the scheme or the hostname contains '$', skip.
+ * When the path contains '$N', replace '$N' with wildcard. */
+if (use_regex) {
+char *r2 = apr_pstrdup(cmd-temp_pool, r);
+char *x, *y;
+y = ap_strstr(r2, ://);
+if (y != NULL) {
+for (x = y; *y; ++x, ++y) {
+if (*y != '$') {
+*x = *y;
+}
+else if (apr_isxdigit(*(y + 1))) {
+*x = '*';
+y += 1;
+}
+}
+*x = '\0';
+}
+r = r2;
+}
+worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, r);
 if (!worker) {
 const char *err = ap_proxy_define_worker(cmd-pool, worker, NULL, conf, r, 0);
 if (err)
Index: modules/proxy/proxy_util.c
===
--- modules/proxy/proxy_util.c	(revision 1579155)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1568,7 +1568,7 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }
@@ -1580,7 +1580,7 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }


Re: [PATCH] Fix settings options with ProxyPassMatch

2014-03-19 Thread Jan Kaluža

On 03/19/2014 09:59 AM, Jan Kaluža wrote:

On 03/18/2014 02:46 PM, Yann Ylavic wrote:

On Tue, Mar 18, 2014 at 2:38 PM, Yann Ylavic ylavic@gmail.com
wrote:

Wouldn't it be possible to define wildcard workers when the URL is
known to be a regexp substitution?
For these workers' URLs, the dollars (plus the following digit) could
be replaced by a wildcard (ie. *) and ap_proxy_get_worker() could then
use ap_strcasecmp_match() against the requested URL.


I meant ap_strcmp_match(), this has to be case sensitive...



I've implemented your idea. Can you check the attached patch please? It
fixes the original PR and also ProxyPassMatch with UDS for me.


Ignore this patch. It breaks ProxyPass. Attached is better version.


If it's OK, I will commit it.

Regards,
Jan Kaluza



Regards,
Jan Kaluza

Index: modules/proxy/mod_proxy.c
===
--- modules/proxy/mod_proxy.c	(revision 1579155)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -1631,8 +1631,29 @@
 new-balancer = balancer;
 }
 else {
-proxy_worker *worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, de_socketfy(cmd-pool, r));
+proxy_worker *worker;
 int reuse = 0;
+/* When the scheme or the hostname contains '$', skip.
+ * When the path contains '$N', replace '$N' with wildcard. */
+if (use_regex) {
+char *r2 = apr_pstrdup(cmd-temp_pool, r);
+char *x, *y;
+y = ap_strstr(r2, ://);
+if (y != NULL) {
+for (x = y; *y; ++x, ++y) {
+if (*y != '$') {
+*x = *y;
+}
+else if (apr_isxdigit(*(y + 1))) {
+*x = '*';
+y += 1;
+}
+}
+*x = '\0';
+}
+r = r2;
+}
+worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, r);
 if (!worker) {
 const char *err = ap_proxy_define_worker(cmd-pool, worker, NULL, conf, r, 0);
 if (err)
Index: modules/proxy/proxy_util.c
===
--- modules/proxy/proxy_util.c	(revision 1579155)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1568,7 +1568,8 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0
+|| (strncmp(url_copy, worker-s-name, worker_name_length) == 0)) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }
@@ -1580,7 +1581,8 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0
+|| (strncmp(url_copy, worker-s-name, worker_name_length) == 0)) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }


Re: [PATCH] Fix settings options with ProxyPassMatch

2014-03-19 Thread Jan Kaluža

On 03/19/2014 10:13 AM, Jan Kaluža wrote:

On 03/19/2014 09:59 AM, Jan Kaluža wrote:

On 03/18/2014 02:46 PM, Yann Ylavic wrote:

On Tue, Mar 18, 2014 at 2:38 PM, Yann Ylavic ylavic@gmail.com
wrote:

Wouldn't it be possible to define wildcard workers when the URL is
known to be a regexp substitution?
For these workers' URLs, the dollars (plus the following digit) could
be replaced by a wildcard (ie. *) and ap_proxy_get_worker() could then
use ap_strcasecmp_match() against the requested URL.


I meant ap_strcmp_match(), this has to be case sensitive...



I've implemented your idea. Can you check the attached patch please? It
fixes the original PR and also ProxyPassMatch with UDS for me.


Ignore this patch. It breaks ProxyPass. Attached is better version.


Not my day today. s/apr_isxdigit/apr_isdigit.




If it's OK, I will commit it.

Regards,
Jan Kaluza



Regards,
Jan Kaluza



Index: modules/proxy/mod_proxy.c
===
--- modules/proxy/mod_proxy.c	(revision 1579155)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -1631,8 +1631,29 @@
 new-balancer = balancer;
 }
 else {
-proxy_worker *worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, de_socketfy(cmd-pool, r));
+proxy_worker *worker;
 int reuse = 0;
+/* When the scheme or the hostname contains '$', skip.
+ * When the path contains '$N', replace '$N' with wildcard. */
+if (use_regex) {
+char *r2 = apr_pstrdup(cmd-temp_pool, r);
+char *x, *y;
+y = ap_strstr(r2, ://);
+if (y != NULL) {
+for (x = y; *y; ++x, ++y) {
+if (*y != '$') {
+*x = *y;
+}
+else if (apr_isdigit(*(y + 1))) {
+*x = '*';
+y += 1;
+}
+}
+*x = '\0';
+}
+r = r2;
+}
+worker = ap_proxy_get_worker(cmd-temp_pool, NULL, conf, r);
 if (!worker) {
 const char *err = ap_proxy_define_worker(cmd-pool, worker, NULL, conf, r, 0);
 if (err)
Index: modules/proxy/proxy_util.c
===
--- modules/proxy/proxy_util.c	(revision 1579155)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1568,7 +1568,8 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0
+|| (strncmp(url_copy, worker-s-name, worker_name_length) == 0)) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }
@@ -1580,7 +1581,8 @@
 if ( ((worker_name_length = strlen(worker-s-name)) = url_length)
  (worker_name_length = min_match)
  (worker_name_length  max_match)
- (strncmp(url_copy, worker-s-name, worker_name_length) == 0) ) {
+ (ap_strcmp_match(url_copy, worker-s-name) == 0
+|| (strncmp(url_copy, worker-s-name, worker_name_length) == 0)) ) {
 max_worker = worker;
 max_match = worker_name_length;
 }


[PATCH RESEND 55178 0/2] mod_authn_ldap: SASL support

2014-03-19 Thread Lubomir Rintel
Hi,

I've submitted a patch set [1] adding SASL support to mod_authn_ldap a while 
ago, but the ticket got no feedback. I'd be very thankful for a review and 
merge.

[1] https://issues.apache.org/bugzilla/show_bug.cgi?id=55178

Chained to this message are the patches.

Thank you!
Lubo



[PATCH RESEND 2/2] mod_authn_ldap: Allow specifying SASL interaction

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

---
 docs/manual/mod/mod_authnz_ldap.xml   | 28 +++
 docs/manual/style/scripts/prettify.js |  2 +-
 include/util_ldap.h   |  4 ++-
 modules/aaa/mod_authnz_ldap.c | 16 +++--
 modules/ldap/util_ldap.c  | 67 +--
 5 files changed, 102 insertions(+), 15 deletions(-)

diff --git a/docs/manual/mod/mod_authnz_ldap.xml 
b/docs/manual/mod/mod_authnz_ldap.xml
index 1a99079..264b447 100644
--- a/docs/manual/mod/mod_authnz_ldap.xml
+++ b/docs/manual/mod/mod_authnz_ldap.xml
@@ -191,6 +191,14 @@ for HTTP Basic authentication./description
 tdAn optional SASL mechanism to use for bind
 with during the search phase./td
   /tr
+
+  tr
+tddirective
+module=mod_authnz_ldapAuthLDAPBindSASLInteract/directive/td
+
+tdAn optional command to run when SASL
+requests interaction to obtain credentials./td
+  /tr
 /table
 /section
 
@@ -973,6 +981,26 @@ AuthLDAPBindSASLMech GSSAPI
 /directivesynopsis
 
 directivesynopsis
+nameAuthLDAPBindSASLInteract/name
+descriptionOptional command to run when SASL requests interaction to obtain 
credentials/description
+syntaxAuthLDAPBindSASLInteract emcommand/em/syntax
+contextlistcontextdirectory/contextcontext.htaccess/context
+/contextlist
+overrideAuthConfig/override
+
+usage
+pAn optional command to run when SASL
+requests interaction to obtain credentials./p
+
+examplepre
+#Initialize Kerberos Credentials Cache using a key from a keytab for given 
principal
+AuthLDAPBindSASLInteract /usr/bin/kinit -k -t /etc/httpd/conf/krb5.keytab 
host/example.com
+/pre/example
+
+/usage
+/directivesynopsis
+
+directivesynopsis
 nameAuthLDAPCharsetConfig/name
 descriptionLanguage to charset conversion configuration file/description
 syntaxAuthLDAPCharsetConfig emfile-path/em/syntax
diff --git a/docs/manual/style/scripts/prettify.js 
b/docs/manual/style/scripts/prettify.js
index f1ab2e6..5777258 100644
--- a/docs/manual/style/scripts/prettify.js
+++ b/docs/manual/style/scripts/prettify.js
@@ -132,7 +132,7 @@ var prettyPrint;
   var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, case,done,elif,esac,eval,fi, +
   function,in,local,set,then,until,echo];
   var CONFIG_ENVS = 
[User-Agent,HTTP_USER_AGENT,HTTP_REFERER,HTTP_COOKIE,HTTP_FORWARDED,HTTP_HOST,HTTP_PROXY_CONNECTION,HTTP_ACCEPT,REMOTE_ADDR,REMOTE_HOST,REMOTE_PORT,REMOTE_USER,REMOTE_IDENT,REQUEST_METHOD,SCRIPT_FILENAME,PATH_INFO,QUERY_STRING,AUTH_TYPE,DOCUMENT_ROOT,SERVER_ADMIN,SERVER_NAME,SERVER_ADDR,SERVER_PORT,SERVER_PROTOCOL,SERVER_SOFTWARE,TIME_YEAR,TIME_MON,TIME_DAY,TIME_HOUR,TIME_MIN,TIME_SEC,TIME_WDAY,TIME,API_VERSION,THE_REQUEST,REQUEST_URI,REQUEST_FILENAME,IS_SUBREQ,HTTPS,REQUEST_SCHEME];
-  var CONFIG_KEYWORDS = 
[Macro,UndefMacro,Use,AuthLDAPURL,AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicProvider,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNcCheck,AuthDigestNonceFormat,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation,
 
AuthFormLogoutLocation,AuthFormMethod,AuthFormMimetype,AuthFormPassword,AuthFormProvider,AuthFormSitePassphrase,AuthFormSize,AuthFormUsername,AuthGroupFile,AuthLDAPAuthorizePrefix,AuthLDAPBindAuthoritative,AuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPBindSASLMech,AuthLDAPCharsetConfig,AuthLDAPCompareAsUser,AuthLDAPCompareDNOnServer,AuthLDAPDereferenceAliases,AuthLDAPGroupAttribute,AuthLDAPGroupAttributeIsDN,AuthLDAPInitialBindAsUser,AuthLDAPInitialBindPattern,AuthLDAPMaxSubGroupDepth,AuthLDAPRemoteUserAttribute,AuthLDAPRemoteUserIsDN,AuthLDAPSearchAsUser,AuthLDAPSubGroupAttribute,AuthLDAPSubGroupClass,AuthLDAPUrl,AuthMerging,AuthName,AuthnCacheContext,AuthnCacheEnable,AuthnCacheProvideFor,AuthnCacheSOCache,AuthnCacheTimeout,AuthnProviderAlias,AuthType,AuthUserFile,AuthzDBDLoginToReferer,AuthzDBDQuery,AuthzDBDRedirectQuery,AuthzDBMType,AuthzProviderAlias,AuthzSendForbiddenOnFailure,BalancerGrowth,BalancerMember,BrowserMatch,BrowserMatchNoCase,BufferedLogs,BufferSize,CacheDefaultEx
 

[PATCH RESEND 1/2] mod_authn_ldap: Allow authentication with SASL

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

---
 docs/manual/mod/mod_authnz_ldap.xml   | 34 -
 docs/manual/style/scripts/prettify.js |  2 +-
 include/util_ldap.h   |  5 +-
 modules/aaa/mod_authnz_ldap.c | 14 +-
 modules/ldap/util_ldap.c  | 94 +++
 5 files changed, 111 insertions(+), 38 deletions(-)

diff --git a/docs/manual/mod/mod_authnz_ldap.xml 
b/docs/manual/mod/mod_authnz_ldap.xml
index de59a0b..1a99079 100644
--- a/docs/manual/mod/mod_authnz_ldap.xml
+++ b/docs/manual/mod/mod_authnz_ldap.xml
@@ -183,6 +183,14 @@ for HTTP Basic authentication./description
 tdAn optional password to bind
 with during the search phase./td
   /tr
+
+  tr
+tddirective
+module=mod_authnz_ldapAuthLDAPBindSASLMech/directive/td
+
+tdAn optional SASL mechanism to use for bind
+with during the search phase./td
+  /tr
 /table
 /section
 
@@ -903,8 +911,8 @@ to perform a DN lookup/description
 
 usage
 pAn optional DN used to bind to the server when searching for
-entries. If not provided, modulemod_authnz_ldap/module will use
-an anonymous bind./p
+entries. If not provided, and simple bind (not SASL) is used,
+modulemod_authnz_ldap/module will use an anonymous bind./p
 /usage
 /directivesynopsis
 
@@ -943,6 +951,28 @@ AuthLDAPBindPassword exec:/path/to/otherProgram argument1
 /directivesynopsis
 
 directivesynopsis
+nameAuthLDAPBindSASLMech/name
+descriptionOptional SASL mechanism to use in binding to the LDAP 
server/description
+syntaxAuthLDAPBindSASLMech emsasl-mech/em/syntax
+contextlistcontextdirectory/contextcontext.htaccess/context
+/contextlist
+overrideAuthConfig/override
+
+usage
+pAn optional SASL mechanism used to bind to the server when
+searching for entries. Multiple mechanisms can be used,
+separated with commas. If not provided,
+modulemod_authnz_ldap/module will use simple bind./p
+
+examplepre
+#Authenticate with Kerberos GSSAPI
+AuthLDAPBindSASLMech GSSAPI
+/pre/example
+
+/usage
+/directivesynopsis
+
+directivesynopsis
 nameAuthLDAPCharsetConfig/name
 descriptionLanguage to charset conversion configuration file/description
 syntaxAuthLDAPCharsetConfig emfile-path/em/syntax
diff --git a/docs/manual/style/scripts/prettify.js 
b/docs/manual/style/scripts/prettify.js
index 2fa959a..f1ab2e6 100644
--- a/docs/manual/style/scripts/prettify.js
+++ b/docs/manual/style/scripts/prettify.js
@@ -132,7 +132,7 @@ var prettyPrint;
   var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, case,done,elif,esac,eval,fi, +
   function,in,local,set,then,until,echo];
   var CONFIG_ENVS = 
[User-Agent,HTTP_USER_AGENT,HTTP_REFERER,HTTP_COOKIE,HTTP_FORWARDED,HTTP_HOST,HTTP_PROXY_CONNECTION,HTTP_ACCEPT,REMOTE_ADDR,REMOTE_HOST,REMOTE_PORT,REMOTE_USER,REMOTE_IDENT,REQUEST_METHOD,SCRIPT_FILENAME,PATH_INFO,QUERY_STRING,AUTH_TYPE,DOCUMENT_ROOT,SERVER_ADMIN,SERVER_NAME,SERVER_ADDR,SERVER_PORT,SERVER_PROTOCOL,SERVER_SOFTWARE,TIME_YEAR,TIME_MON,TIME_DAY,TIME_HOUR,TIME_MIN,TIME_SEC,TIME_WDAY,TIME,API_VERSION,THE_REQUEST,REQUEST_URI,REQUEST_FILENAME,IS_SUBREQ,HTTPS,REQUEST_SCHEME];
-  var CONFIG_KEYWORDS = 
[Macro,UndefMacro,Use,AuthLDAPURL,AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicProvider,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNcCheck,AuthDigestNonceFormat,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation,
 

[PATCH RESEND 1/4] mod_proxy: Rename dirconn_entry to exclude_entry

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

Currently they are used for NoProxy, but could be reusable to ProxyBlock.
Rename them to something more generic.
---
 modules/proxy/mod_proxy.c  |  8 
 modules/proxy/mod_proxy.h  |  4 ++--
 modules/proxy/proxy_util.c | 24 
 modules/proxy/proxy_util.h |  8 
 4 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 1c6716b..e027fd2 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -924,7 +924,7 @@ static int proxy_handler(request_rec *r)
 proxy_balancer *balancer = NULL;
 proxy_worker *worker = NULL;
 int attempts = 0, max_attempts = 0;
-struct dirconn_entry *list = (struct dirconn_entry *)conf-dirconn-elts;
+struct exclude_entry *list = (struct exclude_entry *)conf-dirconn-elts;
 
 /* is this for us? */
 if (!r-filename) {
@@ -1220,7 +1220,7 @@ static void * create_proxy_config(apr_pool_t *p, 
server_rec *s)
 ps-proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
 ps-aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
 ps-noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
-ps-dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry));
+ps-dirconn = apr_array_make(p, 10, sizeof(struct exclude_entry));
 ps-workers = apr_array_make(p, 10, sizeof(proxy_worker));
 ps-balancers = apr_array_make(p, 10, sizeof(proxy_balancer));
 ps-forward = NULL;
@@ -1783,8 +1783,8 @@ static const char *
 server_rec *s = parms-server;
 proxy_server_conf *conf =
 ap_get_module_config(s-module_config, proxy_module);
-struct dirconn_entry *New;
-struct dirconn_entry *list = (struct dirconn_entry *) conf-dirconn-elts;
+struct exclude_entry *New;
+struct exclude_entry *list = (struct exclude_entry *) conf-dirconn-elts;
 int found = 0;
 int i;
 
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 930d95a..fb9695a 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -115,11 +115,11 @@ struct proxy_alias {
 proxy_balancer *balancer; /* only valid for reverse-proxys */
 };
 
-struct dirconn_entry {
+struct exclude_entry {
 char *name;
 struct in_addr addr, mask;
 struct apr_sockaddr_t *hostaddr;
-int (*matcher) (struct dirconn_entry * This, request_rec *r);
+int (*matcher) (struct exclude_entry * This, request_rec *r);
 };
 
 struct noproxy_entry {
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 23dfba3..c6fcc43 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -79,10 +79,10 @@ const apr_strmatch_pattern PROXY_DECLARE_DATA 
*ap_proxy_strmatch_domain;
 
 extern apr_global_mutex_t *proxy_mutex;
 
-static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
-static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
-static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
-static int proxy_match_word(struct dirconn_entry *This, request_rec *r);
+static int proxy_match_ipaddr(struct exclude_entry *This, request_rec *r);
+static int proxy_match_domainname(struct exclude_entry *This, request_rec *r);
+static int proxy_match_hostname(struct exclude_entry *This, request_rec *r);
+static int proxy_match_word(struct exclude_entry *This, request_rec *r);
 
 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req,
(request_rec *r, request_rec *pr), (r, pr),
@@ -426,7 +426,7 @@ static const char *
 }
 
 /* Return TRUE if addr represents an IP address (or an IP network address) */
-PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t 
*p)
+PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct exclude_entry *This, apr_pool_t 
*p)
 {
 const char *addr = This-name;
 long ip_addr[4];
@@ -547,7 +547,7 @@ PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry 
*This, apr_pool_t *p)
 }
 
 /* Return TRUE if addr represents an IP address (or an IP network address) */
-static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r)
+static int proxy_match_ipaddr(struct exclude_entry *This, request_rec *r)
 {
 int i, ip_addr[4];
 struct in_addr addr, *ip;
@@ -635,7 +635,7 @@ static int proxy_match_ipaddr(struct dirconn_entry *This, 
request_rec *r)
 }
 
 /* Return TRUE if addr represents a domain name */
-PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, 
apr_pool_t *p)
+PROXY_DECLARE(int) ap_proxy_is_domainname(struct exclude_entry *This, 
apr_pool_t *p)
 {
 char *addr = This-name;
 int i;
@@ -672,7 +672,7 @@ PROXY_DECLARE(int) ap_proxy_is_domainname(struct 
dirconn_entry *This, apr_pool_t
 }
 
 /* Return TRUE if host host is in domain domain */
-static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r)
+static int proxy_match_domainname(struct 

[PATCH RESEND 3/4] mod_proxy: Split the NoProxy parameter parsing away

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

It is nice and could be reused by ProxyBlock.
---
 modules/proxy/mod_proxy.c | 98 +--
 1 file changed, 53 insertions(+), 45 deletions(-)

diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index e027fd2..bfb48b5 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -1740,56 +1740,17 @@ static const char* cookie_domain(cmd_parms *cmd, void 
*dconf, const char *f,
 return NULL;
 }
 
-static const char *
-set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
-{
-server_rec *s = parms-server;
-proxy_server_conf *conf =
-ap_get_module_config(s-module_config, proxy_module);
-struct noproxy_entry *new;
-struct noproxy_entry *list = (struct noproxy_entry *) 
conf-noproxies-elts;
-struct apr_sockaddr_t *addr;
-int found = 0;
-int i;
-
-/* Don't duplicate entries */
-for (i = 0; i  conf-noproxies-nelts; i++) {
-if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host 
names */
-found = 1;
-break;
-}
-}
-
-if (!found) {
-new = apr_array_push(conf-noproxies);
-new-name = arg;
-if (APR_SUCCESS == apr_sockaddr_info_get(addr, new-name, APR_UNSPEC, 
0, 0, parms-pool)) {
-new-addr = addr;
-}
-else {
-new-addr = NULL;
-}
-}
-return NULL;
-}
-
-
-/* Similar to set_proxy_exclude(), but defining directly connected hosts,
- * which should never be accessed via the configured ProxyRemote servers
- */
-static const char *
-set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg)
+/* Add an entry to a NoProxy or ProxyBlock list */
+const char *
+add_exclude_list(cmd_parms *parms, const char *arg, apr_array_header_t 
*array)
 {
-server_rec *s = parms-server;
-proxy_server_conf *conf =
-ap_get_module_config(s-module_config, proxy_module);
 struct exclude_entry *New;
-struct exclude_entry *list = (struct exclude_entry *) conf-dirconn-elts;
+struct exclude_entry *list = (struct exclude_entry *) array-elts;
 int found = 0;
 int i;
 
 /* Don't duplicate entries */
-for (i = 0; i  conf-dirconn-nelts; i++) {
+for (i = 0; i  array-nelts; i++) {
 if (strcasecmp(arg, list[i].name) == 0) {
 found = 1;
 break;
@@ -1797,7 +1758,7 @@ static const char *
 }
 
 if (!found) {
-New = apr_array_push(conf-dirconn);
+New = apr_array_push(array);
 New-name = apr_pstrdup(parms-pool, arg);
 New-hostaddr = NULL;
 
@@ -1834,6 +1795,53 @@ static const char *
 }
 
 static const char *
+set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
+{
+server_rec *s = parms-server;
+proxy_server_conf *conf =
+ap_get_module_config(s-module_config, proxy_module);
+struct noproxy_entry *new;
+struct noproxy_entry *list = (struct noproxy_entry *) 
conf-noproxies-elts;
+struct apr_sockaddr_t *addr;
+int found = 0;
+int i;
+
+/* Don't duplicate entries */
+for (i = 0; i  conf-noproxies-nelts; i++) {
+if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host 
names */
+found = 1;
+break;
+}
+}
+
+if (!found) {
+new = apr_array_push(conf-noproxies);
+new-name = arg;
+if (APR_SUCCESS == apr_sockaddr_info_get(addr, new-name, APR_UNSPEC, 
0, 0, parms-pool)) {
+new-addr = addr;
+}
+else {
+new-addr = NULL;
+}
+}
+return NULL;
+}
+
+
+/* Similar to set_proxy_exclude(), but defining directly connected hosts,
+ * which should never be accessed via the configured ProxyRemote servers
+ */
+static const char *
+set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg)
+{
+server_rec *s = parms-server;
+proxy_server_conf *conf =
+ap_get_module_config(s-module_config, proxy_module);
+
+return add_exclude_list(parms, arg, conf-dirconn);
+}
+
+static const char *
 set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg)
 {
 proxy_server_conf *psf =
-- 
1.8.3.1



[PATCH RESEND 56152 0/4] mod_proxy: Add support for network addresses to NoProxy

2014-03-19 Thread Lubomir Rintel
Hi,

I opened a ticket [1] with the patches (chained to this message), but got 
virtually 
no responsem, therefore I assume it might be a better idea to discuss them in a 
list.

[1] https://issues.apache.org/bugzilla/show_bug.cgi?id=56152

I'd very thankful for a review and evenutal merge.
The patches are chained to this message.

Thank you!
Lubo



[PATCH RESEND 4/4] mod_proxy: Share NoProxy parameter parsing and evaluation with ProxyBlock

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

They do the same task now, so we can remove some duplicate code. They do the
same thing except that ProxyBlock does certain things better -- they support
masked network addresses, thus we can now block subnets.
---
 docs/manual/mod/mod_proxy.xml | 14 +++---
 modules/proxy/mod_proxy.c | 27 ++-
 modules/proxy/mod_proxy.h |  5 -
 modules/proxy/proxy_util.c| 35 ++-
 4 files changed, 11 insertions(+), 70 deletions(-)

diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml
index e9c9b07..db95e4c 100644
--- a/docs/manual/mod/mod_proxy.xml
+++ b/docs/manual/mod/mod_proxy.xml
@@ -1526,8 +1526,8 @@ will rewrite a cookie with backend path code//code (or
 usage
 pThe directiveProxyBlock/directive directive can be used to
 block FTP or HTTP access to certain hosts via the proxy, based on
-a full or partial hostname match, or, if applicable, an IP address
-comparison./p
+a host name or a domain name match, or, if applicable, an IP host or
+network address comparison./p
 
 pEach of the arguments to the directiveProxyBlock/directive
 directive can be either code*/code or a alphanumeric string.
@@ -1539,11 +1539,11 @@ will rewrite a cookie with backend path code//code 
(or
 modulemod_proxy/module will deny access to all FTP or HTTP
 sites./p
 
-pOtherwise, for any request for an HTTP or FTP resource via the
-proxy, modulemod_proxy/module will check the hostname of the
-request URI against each specified string.  If a partial string
-match is found, access is denied.  If no matches against hostnames
-are found, and a remote (forward) proxy is configured using
+pOtherwise, the matching same as one used with
+directiveNoProxy/directive is conducted to check the hostname of
+the request URI against each specified string.  If a match is found,
+access is denied.  If no matches against hostnames are found, and a
+remote (forward) proxy is configured using
 directiveProxyRemote/directive or
 directiveProxyRemoteMatch/directive, access is allowed.  If no
 remote (forward) proxy is configured, the IP address of the
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index bfb48b5..e13d636 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -1219,7 +1219,7 @@ static void * create_proxy_config(apr_pool_t *p, 
server_rec *s)
 ps-sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *));
 ps-proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
 ps-aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
-ps-noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
+ps-noproxies = apr_array_make(p, 10, sizeof(struct exclude_entry));
 ps-dirconn = apr_array_make(p, 10, sizeof(struct exclude_entry));
 ps-workers = apr_array_make(p, 10, sizeof(proxy_worker));
 ps-balancers = apr_array_make(p, 10, sizeof(proxy_balancer));
@@ -1800,31 +1800,8 @@ static const char *
 server_rec *s = parms-server;
 proxy_server_conf *conf =
 ap_get_module_config(s-module_config, proxy_module);
-struct noproxy_entry *new;
-struct noproxy_entry *list = (struct noproxy_entry *) 
conf-noproxies-elts;
-struct apr_sockaddr_t *addr;
-int found = 0;
-int i;
 
-/* Don't duplicate entries */
-for (i = 0; i  conf-noproxies-nelts; i++) {
-if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host 
names */
-found = 1;
-break;
-}
-}
-
-if (!found) {
-new = apr_array_push(conf-noproxies);
-new-name = arg;
-if (APR_SUCCESS == apr_sockaddr_info_get(addr, new-name, APR_UNSPEC, 
0, 0, parms-pool)) {
-new-addr = addr;
-}
-else {
-new-addr = NULL;
-}
-}
-return NULL;
+return add_exclude_list(parms, arg, conf-noproxies);
 }
 
 
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index fb9695a..7e78249 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -122,11 +122,6 @@ struct exclude_entry {
 int (*matcher) (struct exclude_entry * This, request_rec *r);
 };
 
-struct noproxy_entry {
-const char *name;
-struct apr_sockaddr_t *addr;
-};
-
 typedef struct {
 apr_array_header_t *proxies;
 apr_array_header_t *sec_proxy;
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 382ff9c..15a02be 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -783,8 +783,6 @@ static int proxy_match_word(struct exclude_entry *This, 
request_rec *r)
 return host != NULL  ap_strstr_c(host, This-name) != NULL;
 }
 
-#define MAX_IP_STR_LEN (46)
-
 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf 
*conf,
 const char *hostname, 

[PATCH RESEND 2/4] mod_proxy: Match resolved addresses for NoProxy too

2014-03-19 Thread Lubomir Rintel
From: Lubomir Rintel lubo.rin...@gooddata.com

We resolve the names using the configuration parsing, thus we already have the
addresses. It could be redundant for NoProxy, but the same code could be used
with ProxyBlock if it did this.
---
 modules/proxy/proxy_util.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index c6fcc43..382ff9c 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -699,6 +699,7 @@ static int proxy_match_domainname(struct exclude_entry 
*This, request_rec *r)
 PROXY_DECLARE(int) ap_proxy_is_hostname(struct exclude_entry *This, apr_pool_t 
*p)
 {
 struct apr_sockaddr_t *addr;
+struct in_addr *ip;
 char *host = This-name;
 int i;
 
@@ -714,6 +715,9 @@ PROXY_DECLARE(int) ap_proxy_is_hostname(struct 
exclude_entry *This, apr_pool_t *
 }
 
 This-hostaddr = addr;
+ip = (struct in_addr *) addr-ipaddr_ptr;
+This-addr.s_addr = ip-s_addr;
+This-mask.s_addr = htonl(APR_INADDR_NONE);
 
 /* Strip trailing dots */
 for (i = strlen(host) - 1; i  0  host[i] == '.'; --i) {
@@ -736,6 +740,10 @@ static int proxy_match_hostname(struct exclude_entry 
*This, request_rec *r)
 return 0; /* oops! */
 }
 
+/* Maybe the ip address matches. */
+if (proxy_match_ipaddr(This, r))
+return 1;
+
 h2_len = strlen(host2);
 h1_len = strlen(host);
 
-- 
1.8.3.1



Re: mod_proxy: unwieldy unix socket implementation.

2014-03-19 Thread Jim Jagielski

On Mar 19, 2014, at 1:15 AM, Andreas B. regis...@progandy.de wrote:

 Hello,
 
 I saw the new unix sockets for mod_proxy in 2.4.9 and I am wondering why 
 there has to be a special url format. Wouldn't it be possible to supply the 
 socket path as a proxy parameter?

It would be. We chose otherwise. That way, we have a unified format
that could be used for other things.

 I have something like this in mind:
 
Proxy fcgi://php-fpm.local
ProxySet unix=/run/php-fpm/php-fpm.sock
/Proxy
FilesMatch \.php$
SetHandler proxy:fcgi://php-fpm.local
/FilesMatch
 
 or with ProxyPass:
ProxyPass /php-bin proxy:fcgi://php-fpm.local/src/http/ 
 unix=/run/php-fpm/php-fpm.sock
ProxyPassMatch ^(/.*\.php)$ fcgi://php-fpm.local/srv/http/ 
 unix=/run/php-fpm/php-fpm.sock
 
 I can provide an incomplete patchset for this. I didn't touch the 
 documentation, mod_proxy_balancer output and log messages. This would get rid 
 of de_socketfy() and make the codepath much cleaner I think.
 
 Andreas
 
 PS: I found some strange behaviour with ProxyPassMatch. When you use a group 
 match (e.g. $1) in the result string, you'll have to define the parameters in 
 a separate proxy section. This Probably applies to ProxyPass with the 
 regex-tilde as well
ProxyPassMatch ^(/.*\.php)$ fcgi://php-fpm.local/srv/http/$1
Proxy fcgi://php-fpm.local/srv/http
ProxySet unix=/run/php-fpm/php-fpm.sock
/Proxy
 



Re: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h include/ap_regex.h include/http_core.h modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c server/request.c ser

2014-03-19 Thread Jim Jagielski
As I understand it, we require PCRE_DUPNAMES functionality, right?
So I think we need to check for it at configure/build time
and bail if it isn't available.

The configure part is done in

http://svn.apache.org/r1579259




RE: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h include/ap_regex.h include/http_core.h modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c server/request.c ser

2014-03-19 Thread Plüm , Rüdiger , Vodafone Group


 -Original Message-
 From: Jim Jagielski  Sent: Mittwoch, 19. März 2014 16:37
 To: httpd
 Subject: Re: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES
 include/ap_mmn.h include/ap_regex.h include/http_core.h
 modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c
 server/request.c server/util_pcre.c
 
 As I understand it, we require PCRE_DUPNAMES functionality, right?
 So I think we need to check for it at configure/build time
 and bail if it isn't available.
 
 The configure part is done in
 
   http://svn.apache.org/r1579259
 

Keep in mind that this causes trunk to fail building on RHEL 5 with the system 
provided PCRE


Re: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h include/ap_regex.h include/http_core.h modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c server/request.c ser

2014-03-19 Thread Jim Jagielski
As noted, from how I understand it, currently we allow it to
build BUT the behavior is not as expected or designed, since
the expected behavior *requires* PCRE_DUPNAMES. If we require
PCRE_DUPNAMES then we require it, right?

On Mar 19, 2014, at 12:26 PM, Plüm, Rüdiger, Vodafone Group 
ruediger.pl...@vodafone.com wrote:

 
 
 -Original Message-
 From: Jim Jagielski  Sent: Mittwoch, 19. März 2014 16:37
 To: httpd
 Subject: Re: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES
 include/ap_mmn.h include/ap_regex.h include/http_core.h
 modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c
 server/request.c server/util_pcre.c
 
 As I understand it, we require PCRE_DUPNAMES functionality, right?
 So I think we need to check for it at configure/build time
 and bail if it isn't available.
 
 The configure part is done in
 
  http://svn.apache.org/r1579259
 
 
 Keep in mind that this causes trunk to fail building on RHEL 5 with the 
 system provided PCRE
 



[PATCH] mod_proxy_html deletes wrong data from HTML when meta http-equiv tag specifies Content-Type behind other meta http-equiv tag

2014-03-19 Thread Micha Lenk

Hi Apache developers,

over the time I've accumulated some patches for mod_proxy_html which I 
would like to get reviewed, and get applied in SVN (best both, trunk and 
then backported to 2.4). This is something that I feel to owe the Apache 
httpd community.


So, lets first start with a bug that lets mod_proxy_html delete the 
wrong data from HTML code when a http-equiv meta tag specifies a 
Content-Type behind any other http-equiv meta tag (Thomas, Ewald, this 
is issue #21648 in our Mantis). For better understanding of the issue, 
please consider the following HTML file treated by mod_proxy_html:


html
 head
  meta http-equiv=X-Dummy-Header content=dummy value
  style type=text/cssdiv.ok { color: green; }   /style
  meta http-equiv=Content-Type content=text/html; charset=utf8  
 head
 body
  div class=okIf the metafix is not broken, this text should get 
rendered in green color./div

 /body
/html

Without the attached patch, mod_proxy_html will remove the style tag 
inside the head tag as soon as it parses the meta tag with the 
http-equiv=Content-Type attribute. With the attached patch applied, 
mod_proxy_html removes the meta tag with the http-equiv=Content-Type 
attribute instead. I guess this is what the code intended to do.


The attached patch is based on httpd trunk, rev. 1579365.

Please provide feedback whether I should file an issue in Apaches 
Bugzilla or whether this isn't needed in this case.


Regards,
Micha
Index: modules/filters/mod_proxy_html.c
===
--- modules/filters/mod_proxy_html.c	(Revision 1579365)
+++ modules/filters/mod_proxy_html.c	(Arbeitskopie)
@@ -688,8 +688,8 @@
 }
 else if (!strncasecmp(header, Content-Type, 12)) {
 ret = apr_palloc(r-pool, sizeof(meta));
-ret-start = pmatch[0].rm_so;
-ret-end = pmatch[0].rm_eo;
+ret-start = offs+pmatch[0].rm_so;
+ret-end = offs+pmatch[0].rm_eo;
 }
 if (header  content) {
 #ifndef GO_FASTER


[PATCH] mod_proxy_html sometimes adds random characters to HTML pages smaller than 4 bytes

2014-03-19 Thread Micha Lenk

Hi Apache developers,

next is a bug that causes mod_proxy_html to add some random characters 
(+html code) to HTML pages, if the document is smaller than 4 bytes. 
(Thomas, Ewald, this is issue #18378 in our Mantis). It looks like the 
output is from some kind of uninitialized memory. The added string 
sometimes matches part of a previously delivered request. Also, it looks 
like this only happens when doing multiple HTTP requests with the same 
browser and using HTTP Keep Alive.


The root cause is that the charset guessing with xml2enc needs to 
consume at least 4 bytes from the document to come to a conclusion. The 
consumed bytes are buffered so that they can later get prepended to the 
output again. But apparently it is assumed that there are always at 
least 4 bytes available, which in some cases is not the case. In these 
cases the buffer may contain some bytes left behind from the previous 
request on the same connection.


The attached patch fixes that issue by simply skipping documents smaller 
than 4 bytes. The rationale behind this is, that for HTML rewriting to 
do something useful, it needs to work on an absolute URL (i.e. including 
a schema). But as the schema http is already 4 bytes, there would be 
nothing to rewrite.


The patch is based on httpd trunk, rev. 1579365.

Please provide feedback whether I should file an issue in Apaches 
Bugzilla or whether this isn't needed in this case.


Regards,
Micha
Index: modules/filters/mod_proxy_html.c
===
--- modules/filters/mod_proxy_html.c	(Revision 1579365)
+++ modules/filters/mod_proxy_html.c	(Arbeitskopie)
@@ -885,6 +885,15 @@
 else if (apr_bucket_read(b, buf, bytes, APR_BLOCK_READ)
  == APR_SUCCESS) {
 if (ctxt-parser == NULL) {
+/* For documents smaller than four bytes, there is no reason to do
+ * HTML rewriting. The URL schema (i.e. 'http') needs four bytes alone.
+ * And the HTML parser needs at least four bytes to initialise correctly.
+ */
+if ((bytes  4)  APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(b))) {
+ap_remove_output_filter(f) ;
+return ap_pass_brigade(f-next, bb) ;
+}
+
 const char *cenc;
 if (!xml2enc_charset ||
 (xml2enc_charset(f-r, enc, cenc) != APR_SUCCESS)) {


Re: svn commit: r1554300 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h include/ap_regex.h include/http_core.h modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h server/core.c server/request.c ser

2014-03-19 Thread Jim Jagielski
Just looking for verification here ;)

Thx!
On Mar 19, 2014, at 12:46 PM, Jim Jagielski j...@jagunet.com wrote:

 As noted, from how I understand it, currently we allow it to
 build BUT the behavior is not as expected or designed, since
 the expected behavior *requires* PCRE_DUPNAMES. If we require
 PCRE_DUPNAMES then we require it, right?
 



[PATCH] mod_proxy_html removes the !doctype tag and breaks XHTML documents

2014-03-19 Thread Micha Lenk

Hi Apache developers,

the next patch fixes the behavior of mod_proxy_html to remove any 
!doctype tags from the beginning of HTML and XHTML documents. (Thomas, 
Ewald, this is issue #19803 in our Mantis). This !doctype tag is 
needed by some browsers to correctly render XHTML documents.


Additionally it fixes the issue in XHTML documents that empty tags don't 
get terminated correctly unless ProxyHTMLDoctype XHTML is explicitly 
configured (Thomas, Ewald, this is issue #17643 in our Mantis).


The attached patch fixes the first issue by using the internalSubset 
hook of the libxml2 SAX parser to parse and output the !doctype tag. 
To address the second issue, the same hook is used to automatically 
detect whether the current document is an XHTML document or not. In case 
of an XHTML document the XHTML-style for closing empty tags is enabled 
for the current request. In my opinion the suggested patch makes the 
directive ProxyHTMLDoctype more or less obsolete. Of course it is kept 
for backwards compatibility.


The patch is based on httpd trunk, rev. 1579365.

Please provide feedback whether I should file an issue in Apaches 
Bugzilla or whether this isn't needed in this case.


Regards,
Micha
Index: modules/filters/mod_proxy_html.c
===
--- modules/filters/mod_proxy_html.c	(Revision 1579365)
+++ modules/filters/mod_proxy_html.c	(Arbeitskopie)
@@ -101,6 +101,7 @@
 typedef struct {
 ap_filter_t *f;
 proxy_html_conf *cfg;
+const char *etag;
 htmlParserCtxtPtr parser;
 apr_bucket_brigade *bb;
 char *buf;
@@ -280,6 +281,25 @@
 }
 AP_fwrite(ctx, ctx-buf, strlen(ctx-buf), 1);
 }
+
+static void pinternalSubset(void* ctxt, const xmlChar *name, const xmlChar *externalID, const xmlChar *sysID)
+{
+if (!ctxt) return;
+if (!name) return;
+saxctxt* ctx = (saxctxt*) ctxt;
+if (ctx-cfg-doctype  ctx-cfg-doctype[0]) return;
+ap_fprintf(ctx-f-next, ctx-bb, !DOCTYPE %s, (const char *)name);
+if (externalID) {
+if ((strcasecmp((const char*)name, html) == 0) 
+(strncasecmp((const char *)externalID, -//W3C//DTD XHTML , 18) == 0))
+ctx-etag = xhtml_etag;
+ap_fprintf(ctx-f-next, ctx-bb,  PUBLIC \%s\, (const char *)externalID);
+if (sysID)
+ap_fprintf(ctx-f-next, ctx-bb,  \%s\, (const char *)sysID);
+}
+ap_fprintf(ctx-f-next, ctx-bb, \n);
+}
+
 static void pcdata(void *ctxt, const xmlChar *uchars, int length)
 {
 const char *chars = (const char*) uchars;
@@ -632,7 +652,7 @@
 }
 ctx-offset = 0;
 if (desc  desc-empty)
-ap_fputs(ctx-f-next, ctx-bb, ctx-cfg-etag);
+ap_fputs(ctx-f-next, ctx-bb, ctx-etag);
 else
 ap_fputc(ctx-f-next, ctx-bb, '');
 
@@ -833,6 +853,7 @@
 fctx-bb = apr_brigade_create(f-r-pool,
   f-r-connection-bucket_alloc);
 fctx-cfg = cfg;
+fctx-etag = cfg-etag;
 apr_table_unset(f-r-headers_out, Content-Length);
 
 if (cfg-interp)
@@ -1236,6 +1257,7 @@
 sax.characters = pcharacters;
 sax.comment = pcomment;
 sax.cdataBlock = pcdata;
+sax.internalSubset = pinternalSubset;
 xml2enc_charset = APR_RETRIEVE_OPTIONAL_FN(xml2enc_charset);
 xml2enc_filter = APR_RETRIEVE_OPTIONAL_FN(xml2enc_filter);
 if (!xml2enc_charset) {


Re: [PATCH] mod_proxy_html sometimes adds random characters to HTML pages smaller than 4 bytes

2014-03-19 Thread Jim Jagielski
It's always best, imo, to follow-up with a bugzilla entry with
description and patch.

Thx!!
On Mar 19, 2014, at 3:58 PM, Micha Lenk mi...@lenk.info wrote:

 Hi Apache developers,
 
 next is a bug that causes mod_proxy_html to add some random characters (+html 
 code) to HTML pages, if the document is smaller than 4 bytes. (Thomas, Ewald, 
 this is issue #18378 in our Mantis). It looks like the output is from some 
 kind of uninitialized memory. The added string sometimes matches part of a 
 previously delivered request. Also, it looks like this only happens when 
 doing multiple HTTP requests with the same browser and using HTTP Keep Alive.
 
 The root cause is that the charset guessing with xml2enc needs to consume at 
 least 4 bytes from the document to come to a conclusion. The consumed bytes 
 are buffered so that they can later get prepended to the output again. But 
 apparently it is assumed that there are always at least 4 bytes available, 
 which in some cases is not the case. In these cases the buffer may contain 
 some bytes left behind from the previous request on the same connection.
 
 The attached patch fixes that issue by simply skipping documents smaller than 
 4 bytes. The rationale behind this is, that for HTML rewriting to do 
 something useful, it needs to work on an absolute URL (i.e. including a 
 schema). But as the schema http is already 4 bytes, there would be nothing 
 to rewrite.
 
 The patch is based on httpd trunk, rev. 1579365.
 
 Please provide feedback whether I should file an issue in Apaches Bugzilla or 
 whether this isn't needed in this case.
 
 Regards,
 Micha
 modproxyhtml_skip_too_small_documents.patch



[PATCH ASF bugzilla #56284] Extend mod_proxy_html to rewrite URLs in CSS documents too

2014-03-19 Thread Micha Lenk

Hi Apache developers,

next is a feature that extends mod_proxy_html to rewrite URLs in CSS 
documents too. This is done by applying the configured regex and string 
replacements for the content of HTML tags also on whole CSS documents, 
i.e. documents with Content-Type: text/css.


The attached patch is based on httpd trunk, rev. 1579365. I've also 
filed this in the ASF bugzilla as issue #56284.


Regards,
Micha
Index: modules/filters/mod_proxy_html.c
===
--- modules/filters/mod_proxy_html.c	(Revision 1579365)
+++ modules/filters/mod_proxy_html.c	(Arbeitskopie)
@@ -65,6 +65,8 @@
 #define M_INTERPOLATE_TO0x100
 #define M_INTERPOLATE_FROM  0x200
 
+#define M_PROXY_CSS_MIN_BUFFER_SIZE 4096
+
 typedef struct {
 const char *val;
 } tattr;
@@ -103,6 +105,7 @@
 proxy_html_conf *cfg;
 htmlParserCtxtPtr parser;
 apr_bucket_brigade *bb;
+apr_bucket_brigade *bbsave;
 char *buf;
 size_t offset;
 size_t avail;
@@ -953,6 +956,137 @@
 return APR_SUCCESS;
 }
 
+static int proxy_css_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+{
+apr_status_t rv;
+proxy_html_conf* cfg = ap_get_module_config(f-r-per_dir_config, proxy_html_module);
+saxctxt *fctx = f-ctx;
+if (fctx == NULL) {
+int skip_filter = 0;
+// Skip this filter if this is no proxy request
+if ( ! f-r-proxyreq ) {
+skip_filter = 1;
+// init filter only if content type is set
+} else if ( ! f-r-content_type ) {
+skip_filter = 1;
+// init filter only for MIME type text/css
+} else if ( strncmp(f-r-content_type, text/css, 8) != 0 ) {
+skip_filter = 1;
+}
+
+if (skip_filter) {
+ap_filter_t* fnext = f-next;
+ap_remove_output_filter(f);
+return ap_pass_brigade(fnext, bb);
+}
+
+// The CSS filter changes the output length
+apr_table_unset(f-r-headers_out, Content-Length) ;
+
+// Initialize CSS output filter
+fctx = f-ctx = apr_pcalloc(f-r-pool, sizeof(saxctxt));
+fctx-f = f;
+fctx-cfg = ap_get_module_config(f-r-per_dir_config, proxy_html_module);
+fctx-bb = apr_brigade_create(f-r-pool, f-c-bucket_alloc);
+fctx-bbsave = apr_brigade_create(f-r-pool, f-c-bucket_alloc);
+
+// Add rules for variable interpolation etc.
+if (cfg-interp) fixup_rules(fctx);
+else fctx-map = fctx-cfg-map;
+}
+
+int process_bb_out = 0;
+apr_bucket* current_bucket;
+apr_bucket* next_bucket = NULL;
+for (current_bucket = APR_BRIGADE_FIRST(bb);
+ current_bucket != APR_BRIGADE_SENTINEL(bb);
+ current_bucket = (next_bucket ? next_bucket : APR_BUCKET_NEXT(current_bucket))) {
+char* out_data = NULL;
+apr_size_t out_data_length = 0;
+next_bucket = NULL;
+if (APR_BUCKET_IS_EOS(current_bucket)) {
+process_bb_out = 1;
+} else if (APR_BUCKET_IS_METADATA(current_bucket)) {
+continue;
+} else {
+const char* in_data;
+apr_size_t in_data_length;
+rv = apr_bucket_read(current_bucket, in_data, in_data_length, APR_BLOCK_READ);
+if (rv != APR_SUCCESS) return rv;
+
+// skip empty data bucket
+if (in_data_length == 0) continue;
+
+// scan for newline characters
+apr_size_t newline_offset = 0;
+const char *le_r = memchr(in_data, '\r', in_data_length);
+const char *le_n = memchr(in_data, '\n', in_data_length);
+if (le_r) newline_offset = (le_r - in_data) + 1;
+if (le_n  le_r) newline_offset = (le_n - in_data) + 1;
+
+// Bucket without newline character: simply append to bbsave and process it later
+if (newline_offset == 0) {
+next_bucket = APR_BUCKET_NEXT(current_bucket);
+APR_BUCKET_REMOVE(current_bucket);
+apr_bucket_setaside(current_bucket, f-r-pool);
+APR_BRIGADE_INSERT_TAIL(fctx-bbsave, current_bucket);
+continue;
+}
+
+// If newline is in the middle of the bucket: split the bucket
+if (newline_offset  in_data_length) {
+apr_bucket_split(current_bucket, newline_offset);
+}
+
+// Append bucket (with data up to and including the newline character)
+// to fctx-bbsave and trigger its processing
+next_bucket = APR_BUCKET_NEXT(current_bucket);
+APR_BUCKET_REMOVE(current_bucket);
+APR_BRIGADE_INSERT_TAIL(fctx-bbsave, current_bucket);
+process_bb_out = 1;
+}
+
+if (process_bb_out == 0) continue;
+
+// Check buffer size requirements
+apr_off_t needed_buffer_length;
+apr_brigade_length(fctx-bbsave, 1, needed_buffer_length);
+if 

Re: [PATCH] mod_proxy_html removes the !doctype tag and breaks XHTML documents

2014-03-19 Thread Micha Lenk

Hi all,

just for the records: I've just filed this in the ASF bugzilla as
issue #56285.

Regards,
Micha


Re: [PATCH] mod_proxy_html deletes wrong data from HTML when meta http-equiv tag specifies Content-Type behind other meta http-equiv tag

2014-03-19 Thread Micha Lenk

Hi,

Just for the records, I've just filed this issue in ASF bugzilla as 
issue #56286.


Regards,
Micha


On 19.03.2014 20:40, Micha Lenk wrote:

Hi Apache developers,

over the time I've accumulated some patches for mod_proxy_html which I
would like to get reviewed, and get applied in SVN (best both, trunk and
then backported to 2.4). This is something that I feel to owe the Apache
httpd community.

So, lets first start with a bug that lets mod_proxy_html delete the
wrong data from HTML code when a http-equiv meta tag specifies a
Content-Type behind any other http-equiv meta tag (Thomas, Ewald, this
is issue #21648 in our Mantis). For better understanding of the issue,
please consider the following HTML file treated by mod_proxy_html:

html
  head
   meta http-equiv=X-Dummy-Header content=dummy value
   style type=text/cssdiv.ok { color: green; }   /style
   meta http-equiv=Content-Type content=text/html; charset=utf8  
  head
  body
   div class=okIf the metafix is not broken, this text should get
rendered in green color./div
  /body
/html

Without the attached patch, mod_proxy_html will remove the style tag
inside the head tag as soon as it parses the meta tag with the
http-equiv=Content-Type attribute. With the attached patch applied,
mod_proxy_html removes the meta tag with the http-equiv=Content-Type
attribute instead. I guess this is what the code intended to do.

The attached patch is based on httpd trunk, rev. 1579365.

Please provide feedback whether I should file an issue in Apaches
Bugzilla or whether this isn't needed in this case.

Regards,
Micha




Re: [PATCH] mod_proxy_html deletes wrong data from HTML when meta http-equiv tag specifies Content-Type behind other meta http-equiv tag

2014-03-19 Thread Micha Lenk

Hi again,

Err, #56287 that is.

Regards,
Micha

On 19.03.2014 22:05, Micha Lenk wrote:

Just for the records, I've just filed this issue in ASF bugzilla as
issue #56286.





Re: [PATCH] mod_proxy_html sometimes adds random characters to HTML pages smaller than 4 bytes

2014-03-19 Thread Micha Lenk

Hi,

On 19.03.2014 21:19, Jim Jagielski wrote:

It's always best, imo, to follow-up with a bugzilla entry with
description and patch.


Ok, this issue is now filed in ASF bugzilla as #56286.

Regards,
Micha


[PATCH ASF bugzilla #56288] mod_proxy_html could rewrite URLs in HTML style attributes too

2014-03-19 Thread Micha Lenk

Hi Apache developers,

In HTML you can have div tags that have a background image by 
providing a style attribute. E.g. this can be done by something fancy 
like this:


div style=background:url(http://www.example.com/fancy-background.png) 
right 0px no-repeat; height:325px;


Currently mod_proxy_html doesn't rewrite the URL in such style 
attributes (Thomas, Ewald, this is issue #22583 in our Mantis).


The attached patch tries to fix that by applying the configured string 
replacements also on style attributes.


Additionally it tries to make the code a bit more readable by renaming 
the function dump_content() to apply_urlmap(). This is what it actually 
does, especially after the call to AP_fwrite() has been moved outside of 
this function.


Please note that this patch requires the patch from issue #56284 to be 
applied first. Otherwise the last chunk will not apply. The attached 
patch is based on httpd trunk, rev. 1579365 plus the patch for issue 
#56284 applied.


Regards,
Micha


[PATCH ASF bugzilla #56289] Buffer overflow in mod_proxy_html's string replacement can cause a segfault

2014-03-19 Thread Micha Lenk

Hi developers,

The attached patch fixes a buffer overflow in at least one of the six 
string replacement implementations in mod_proxy_html.


Unfortunately I don't remember anymore how to reproduce the issue 
properly, but I know that some long time ago I fixed a segfault with 
this patch.


The patch tries to address the buffer overflow by introducing a new 
function preplace() dedicated to clean string replacement. This function 
is now used on all six places where the error-prone string replacement 
was previously implemented manually with memcpy() and memmove().


The patch is based on SVN trunk rev. 1579365.
I've filed it also in ASF bugzilla as issue #56289.

Regards,
Micha
Index: modules/filters/mod_proxy_html.c
===
--- modules/filters/mod_proxy_html.c	(Revision 1579365)
+++ modules/filters/mod_proxy_html.c	(Arbeitskopie)
@@ -29,6 +29,8 @@
 #define VERBOSEB(x) if (verbose) {x}
 #endif
 
+#include assert.h
+
 /* libxml2 */
 #include libxml/HTMLparser.h
 
@@ -191,6 +193,9 @@
 }
 }
 
+/**
+ * Appends the string buf with length len to ctx-buf at position ctx-offset
+ */
 static void pappend(saxctxt *ctx, const char *buf, const size_t len)
 {
 preserve(ctx, len);
@@ -198,6 +203,34 @@
 ctx-offset += len;
 }
 
+/**
+ * In ctx-buf replaces the substring starting at offset start with length old_length
+ * by the string new with length new_length
+ */
+static void preplace(saxctxt* ctx, const size_t start, const size_t old_length, const char* new, const size_t new_length) {
+  // check arguments
+  assert(ctx-offset  start + old_length);
+  assert(new != NULL);
+
+  // do the string replacement
+  if (old_length  new_length) {
+int old_buffer_length = ctx-offset;
+preserve(ctx, new_length - old_length);
+memmove(ctx-buf + start + new_length,
+ctx-buf + start + old_length,
+   ctx-offset - (start + old_length));
+ctx-offset += new_length - old_length;
+  }
+  memcpy(ctx-buf + start, new, new_length);
+  if (old_length  new_length) {
+memmove(ctx-buf + start + new_length,
+ctx-buf + start + old_length,
+   ctx-offset - (start + old_length));
+assert(ctx-offset = old_length - new_length);
+ctx-offset -= old_length - new_length;
+  }
+}
+
 static void dump_content(saxctxt *ctx)
 {
 urlmap *m;
@@ -236,17 +269,7 @@
 ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx-f-r,
   C/RX: match at %s, substituting %s, f, subs);
 )
-if (s_to  s_from) {
-preserve(ctx, s_to - s_from);
-memmove(ctx-buf+offs+s_to, ctx-buf+offs+s_from,
-len + 1 - s_from - offs);
-memcpy(ctx-buf+offs, subs, s_to);
-}
-else {
-memcpy(ctx-buf + offs, subs, s_to);
-memmove(ctx-buf+offs+s_to, ctx-buf+offs+s_from,
-len + 1 - s_from - offs);
-}
+preplace(ctx, offs, s_from, subs, s_to);
 offs += s_to;
 }
 }
@@ -264,17 +287,7 @@
 VERBOSE(ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx-f-r,
   C: matched %s, substituting %s,
   m-from.c, m-to));
-if (s_to  s_from) {
-preserve(ctx, s_to - s_from);
-memmove(ctx-buf+match+s_to, ctx-buf+match+s_from,
-len + 1 - s_from - match);
-memcpy(ctx-buf+match, m-to, s_to);
-}
-else {
-memcpy(ctx-buf+match, m-to, s_to);
-memmove(ctx-buf+match+s_to, ctx-buf+match+s_from,
-len + 1 - s_from - match);
-}
+preplace(ctx, match, s_from, m-to, s_to);
 }
 }
 }
@@ -481,19 +494,7 @@
 })
 s_to = strlen(subs);
 len = strlen(ctx-buf);
-if (s_to  s_from) {
-preserve(ctx, s_to - s_from);
-memmove(ctx-buf+offs+s_to,
-ctx-buf+offs+s_from,
-len + 1 - s_from - offs);
-memcpy(ctx-buf+offs, subs, s_to);
-}
-else {
-memcpy(ctx-buf + offs, subs, s_to);
-memmove(ctx-buf+offs+s_to,
-ctx-buf+offs+s_from,
-len + 1 - s_from - offs);
-}
+