Re: mod_proxy: unwieldy unix socket implementation.
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
-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
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
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
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
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
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
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
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
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
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
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
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
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
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); -} +