Bug 969547

Summary: RewriteConds are broken and not applied
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: Aaron Ogburn <aogburn>
Component: WebAssignee: Aaron Ogburn <aogburn>
Status: CLOSED CURRENTRELEASE QA Contact:
Severity: urgent Docs Contact:
Priority: urgent    
Version: 6.1.0CC: cdewolf, hokuda, jawilson, jclere, pkremens, rhatlapa, smumford
Target Milestone: ER1   
Target Release: EAP 6.1.1   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 974237 (view as bug list) Environment:
Last Closed: 2013-09-16 20:25:57 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 970751, 974237    

Description Aaron Ogburn 2013-05-31 18:45:33 UTC
Description of problem:

RewriteConds are broken and not applied


Version-Release number of selected component (if applicable):


How reproducible:

Always


Steps to Reproduce:
1. Set a rewrite rule with a condition
2. Note that the condition has no effect


Actual results:

RewriteConds are not applied and used as specified in the standalone/domain xml


Expected results:

RewriteConds are used


Additional info:

During start up with similar rewrite conditions on 6.0.1, we get a clear indication the rule is added along with the condition:

DEBUG [org.apache.catalina.core.ContainerBase.[default-host]] (MSC service thread 1-4) Add rule with pattern ^/foo(.*)$ and substitution /bar
DEBUG [org.apache.catalina.core.ContainerBase.[default-host]] (MSC service thread 1-4) Add condition 8081 test %{SERVER_PORT} to rule with pattern ^/foo(.*)$ and substitution /bar [NC]


On 6.1.0, there is only an indication that the rule is added and nothing about the condition, suggesting the condition never makes it from the config to the actual rewrite conditions/rules built and used by JBoss.

Comment 1 Aaron Ogburn 2013-05-31 18:51:33 UTC
I debugged further with ByteMan to see what was dropping the rewrite condition.  RewriteValve clearly received no RewriteConds in its configuration string that it parses to build the rules.  I believe the following byteman rules expose the issue clearly enough:

RULE WebVirtualHostAddResolveRewriteExpressionsCondCheck
CLASS org.jboss.as.web.WebVirtualHostAdd
METHOD resolveRewriteExpressions
AT LINE 170
IF TRUE
DO traceStack("----------------------->WebVirtualHostAdd.resolveRewriteExpressions: conditioncheck\n" + $resolvedCondition + "\n");
#DO $result.get(Constants.CONDITION, conditionProp.getName()).set(resolvedCondition);
ENDRULE

RULE WebVirtualHostServiceSetRewrite
CLASS org.jboss.as.web.WebVirtualHostService
METHOD setRewrite
IF TRUE
DO traceStack("----------------------->WebVirtualHostService.setRewrite:\n" + $1 + "\n");
ENDRULE


This shows we clearly provide no condition through WebVirtualHostService.setRewrite:

10:54:20,926 INFO  [stdout] (ServerService Thread Pool -- 45) ----------------------->WebVirtualHostService.setRewrite:
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45) {"rule-1" => {
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45)     "pattern" => "^/helloworld2(.*)$",
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45)     "substitution" => "-",
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45)     "flags" => "F"
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45) }}
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.web.WebVirtualHostService.setRewrite(WebVirtualHostService.java:-1)
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.web.WebVirtualHostAdd.performRuntime(WebVirtualHostAdd.java:108)
10:54:20,927 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractAddStepHandler$1.execute(AbstractAddStepHandler.java:50)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:440)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.doCompleteStep(AbstractOperationContext.java:322)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.completeStepInternal(AbstractOperationContext.java:229)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:224)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.ParallelBootOperationStepHandler$ParallelBootTask.run(ParallelBootOperationStepHandler.java:322)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) java.lang.Thread.run(Thread.java:636)
10:54:20,928 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.threads.JBossThread.run(JBossThread.java:122)


The other rule shows that that at line 170 we clearly have the full condition added to the resolved parent:

14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45) ----------------------->WebVirtualHostAdd.resolveRewriteExpressions: conditioncheck
14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45) {
14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45)     "test" => "%{SERVER_PORT}",
14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45)     "pattern" => "!8081",
14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45)     "flags" => "NC"
14:37:16,454 INFO  [stdout] (ServerService Thread Pool -- 45) }
14:37:16,455 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.web.WebVirtualHostAdd.resolveRewriteExpressions(WebVirtualHostAdd.java:170)
14:37:16,455 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.web.WebVirtualHostAdd.performRuntime(WebVirtualHostAdd.java:107)
14:37:16,455 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractAddStepHandler$1.execute(AbstractAddStepHandler.java:50)
14:37:16,455 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:440)
14:37:16,455 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.doCompleteStep(AbstractOperationContext.java:322)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.completeStepInternal(AbstractOperationContext.java:229)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:224)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) org.jboss.as.controller.ParallelBootOperationStepHandler$ParallelBootTask.run(ParallelBootOperationStepHandler.java:322)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
14:37:16,456 INFO  [stdout] (ServerService Thread Pool -- 45) java.lang.Thread.run(Thread.java:636)

Comment 2 Aaron Ogburn 2013-05-31 18:52:28 UTC
Looks like the problem is line 170 of WebVirtualHostService.resolveRewriteExpressions:

162     private ModelNode resolveRewriteExpressions(OperationContext context, ModelNode unresolvedRewriteChildren) throws OperationFailedException {
163         ModelNode result = new ModelNode();
164         for (Property prop : unresolvedRewriteChildren.asPropertyList()) {
165             ModelNode resolvedParent = resolveExpressions(context, prop.getValue(), WebReWriteDefinition.ATTRIBUTES);
166             result.get(prop.getName()).set(resolvedParent);
167             if (prop.getValue().hasDefined(Constants.CONDITION)) {
168                 for (Property conditionProp : prop.getValue().get(Constants.CONDITION).asPropertyList()) {
169                     ModelNode resolvedCondition = resolveExpressions(context, conditionProp.getValue(), WebReWriteConditionDefinition.ATTRIBUTES);
170                     resolvedParent.get(Constants.CONDITION, conditionProp.getName()).set(resolvedCondition);
171                 }
172             }
173         } 
174         return result;
175     }


result.get(prop.getName()).set means we copy the value of resolvedParent.  We're not using the same object as resolvedParent, we're using a copy of it, and so setting the resolvedCondition on resolvedParent isn't returned in the result ModelNode that we've built.  Looks like a simple change, applying the resolved condition to the rewrite prop in the result node, would do the trick: 

    result.get(prop.getName()).get(Constants.CONDITION, conditionProp.getName()).set(resolvedCondition);


Thoughts?

Comment 3 Aaron Ogburn 2013-05-31 19:18:18 UTC
WebVirtualHostAdd.resolveRewriteExpressions() being the problem method rather.

Comment 4 Aaron Ogburn 2013-06-03 13:16:59 UTC
Upstream bug:

https://issues.jboss.org/browse/WFLY-1282

Comment 8 Petr Kremensky 2013-06-19 08:31:51 UTC
Verified on EAP 6.1.1 ER1

Comment 9 Hisanobu Okuda 2013-08-23 07:35:24 UTC
*** Bug 1000230 has been marked as a duplicate of this bug. ***

Comment 10 Scott Mumford 2013-08-29 03:56:22 UTC
Marking for exclusion from the 6.1.1 Release Notes document as an entry for this bug could not be completed or verified in time.