2017-02-07 16:53:16 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  rewrite  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-07-08 03:18:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"regexp" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-14 07:00:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/coredns/coredns/plugin" 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/coredns/coredns/request" 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:53:16 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  exactNameRule  struct  {  
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									NextAction  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									From        string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									To          string 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ResponseRule 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  prefixNameRule  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NextAction   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Replacement  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:53:16 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  suffixNameRule  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NextAction   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Suffix       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Replacement  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:53:16 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  substringNameRule  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NextAction   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Substring    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Replacement  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  regexNameRule  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NextAction   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Pattern      * regexp . Regexp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Replacement  string 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ResponseRule 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExactMatch matches only on exact match of the name in the question section of a request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExactMatch  =  "exact" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// PrefixMatch matches when the name begins with the matching string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PrefixMatch  =  "prefix" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// SuffixMatch matches when the name ends with the matching string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SuffixMatch  =  "suffix" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// SubstringMatch matches on partial match of the name in the question section of a request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SubstringMatch  =  "substring" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// RegexMatch matches when the name in the question section of a request matches a regular expression 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RegexMatch  =  "regex" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Rewrite rewrites the current request based upon exact match of the name  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// in the question section of the request.  
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * exactNameRule )  Rewrite ( ctx  context . Context ,  state  request . Request )  Result  {  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rule . From  ==  state . Name ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state . Req . Question [ 0 ] . Name  =  rule . To 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:53:16 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  RewriteDone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  RewriteIgnored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-09-20 13:06:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Rewrite rewrites the current request when the name begins with the matching string.  
						 
					
						
							
								
									
										
										
										
											2018-07-08 03:18:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * prefixNameRule )  Rewrite ( ctx  context . Context ,  state  request . Request )  Result  {  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  strings . HasPrefix ( state . Name ( ) ,  rule . Prefix )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-06 15:02:07 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										state . Req . Question [ 0 ] . Name  =  rule . Replacement  +  strings . TrimPrefix ( state . Name ( ) ,  rule . Prefix ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  RewriteDone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  RewriteIgnored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Rewrite rewrites the current request when the name ends with the matching string.  
						 
					
						
							
								
									
										
										
										
											2018-07-08 03:18:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * suffixNameRule )  Rewrite ( ctx  context . Context ,  state  request . Request )  Result  {  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  strings . HasSuffix ( state . Name ( ) ,  rule . Suffix )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-06 16:10:46 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										state . Req . Question [ 0 ] . Name  =  strings . TrimSuffix ( state . Name ( ) ,  rule . Suffix )  +  rule . Replacement 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  RewriteDone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  RewriteIgnored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Rewrite rewrites the current request based upon partial match of the  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// name in the question section of the request.  
						 
					
						
							
								
									
										
										
										
											2018-07-08 03:18:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * substringNameRule )  Rewrite ( ctx  context . Context ,  state  request . Request )  Result  {  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  strings . Contains ( state . Name ( ) ,  rule . Substring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state . Req . Question [ 0 ] . Name  =  strings . Replace ( state . Name ( ) ,  rule . Substring ,  rule . Replacement ,  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  RewriteDone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  RewriteIgnored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Rewrite rewrites the current request when the name in the question  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// section of the request matches a regular expression.  
						 
					
						
							
								
									
										
										
										
											2018-07-08 03:18:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * regexNameRule )  Rewrite ( ctx  context . Context ,  state  request . Request )  Result  {  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									regexGroups  :=  rule . Pattern . FindStringSubmatch ( state . Name ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( regexGroups )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  RewriteIgnored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  rule . Replacement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  groupIndex ,  groupValue  :=  range  regexGroups  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										groupIndexStr  :=  "{"  +  strconv . Itoa ( groupIndex )  +  "}" 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-27 18:10:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s  =  strings . Replace ( s ,  groupIndexStr ,  groupValue ,  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									state . Req . Question [ 0 ] . Name  =  s 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  RewriteDone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// newNameRule creates a name matching rule based on exact, partial, or regex match  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newNameRule ( nextAction  string ,  args  ... string )  ( Rule ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  matchType ,  rewriteQuestionFrom ,  rewriteQuestionTo  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  rewriteAnswerField ,  rewriteAnswerFrom ,  rewriteAnswerTo  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( args )  <  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "too few arguments for a name rule" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( args )  ==  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										matchType  =  "exact" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionFrom  =  plugin . Name ( args [ 0 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionTo  =  plugin . Name ( args [ 1 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( args )  >=  3  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										matchType  =  strings . ToLower ( args [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionFrom  =  plugin . Name ( args [ 1 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionTo  =  plugin . Name ( args [ 2 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  matchType  ==  RegexMatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionFrom  =  args [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rewriteQuestionTo  =  args [ 2 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  matchType  ==  ExactMatch  ||  matchType  ==  SuffixMatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! hasClosingDot ( rewriteQuestionFrom )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteQuestionFrom  =  rewriteQuestionFrom  +  "." 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! hasClosingDot ( rewriteQuestionTo )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteQuestionTo  =  rewriteQuestionTo  +  "." 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( args )  >  3  &&  len ( args )  !=  7  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "response rewrites must consist only of a name rule with 3 arguments and an answer rule with 3 arguments" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( args )  <  7  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  matchType  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  ExactMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteAnswerFromPattern ,  err  :=  isValidRegexPattern ( rewriteQuestionTo ,  rewriteQuestionFrom ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & exactNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionFrom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ResponseRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Active :       true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Type :         "name" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Pattern :      rewriteAnswerFromPattern , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Replacement :  rewriteQuestionFrom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  PrefixMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & prefixNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionFrom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  SuffixMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & suffixNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionFrom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  SubstringMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & substringNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionFrom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  RegexMatch : 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteQuestionFromPattern ,  err  :=  isValidRegexPattern ( rewriteQuestionFrom ,  rewriteQuestionTo ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteQuestionTo  :=  plugin . Name ( args [ 2 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & regexNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionFromPattern , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ResponseRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Type :  "name" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-01 07:41:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "name rule supports only exact, prefix, suffix, substring, and regex name matching, received: %s" ,  matchType ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( args )  ==  7  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  matchType  ==  RegexMatch  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  args [ 3 ]  !=  "answer"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  fmt . Errorf ( "exceeded the number of arguments for a regex name rule" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteQuestionFromPattern ,  err  :=  isValidRegexPattern ( rewriteQuestionFrom ,  rewriteQuestionTo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteAnswerField  =  strings . ToLower ( args [ 4 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  rewriteAnswerField  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  "name" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  fmt . Errorf ( "exceeded the number of arguments for a regex name rule" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteAnswerFrom  =  args [ 5 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteAnswerTo  =  args [ 6 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteAnswerFromPattern ,  err  :=  isValidRegexPattern ( rewriteAnswerFrom ,  rewriteAnswerTo ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rewriteQuestionTo  =  plugin . Name ( args [ 2 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rewriteAnswerTo  =  plugin . Name ( args [ 6 ] ) . Normalize ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & regexNameRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nextAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rewriteQuestionFromPattern , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rewriteQuestionTo , 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ResponseRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Active :       true , 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-29 10:41:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Type :         "name" , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Pattern :      rewriteAnswerFromPattern , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Replacement :  rewriteAnswerTo , 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "the rewrite of response is supported only for name regex rule" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil ,  fmt . Errorf ( "the rewrite rule is invalid: %s" ,  args ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-13 11:31:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Mode returns the processing nextAction  
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * exactNameRule )  Mode ( )  string      {  return  rule . NextAction  }  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * prefixNameRule )  Mode ( )  string     {  return  rule . NextAction  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( rule  * suffixNameRule )  Mode ( )  string     {  return  rule . NextAction  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( rule  * substringNameRule )  Mode ( )  string  {  return  rule . NextAction  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( rule  * regexNameRule )  Mode ( )  string      {  return  rule . NextAction  }  
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetResponseRule return a rule to rewrite the response with. Currently not implemented.  
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * exactNameRule )  GetResponseRule ( )  ResponseRule  {  return  rule . ResponseRule  }  
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetResponseRule return a rule to rewrite the response with. Currently not implemented.  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * prefixNameRule )  GetResponseRule ( )  ResponseRule  {  return  ResponseRule { }  }  
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetResponseRule return a rule to rewrite the response with. Currently not implemented.  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * suffixNameRule )  GetResponseRule ( )  ResponseRule  {  return  ResponseRule { }  }  
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetResponseRule return a rule to rewrite the response with. Currently not implemented.  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * substringNameRule )  GetResponseRule ( )  ResponseRule  {  return  ResponseRule { }  }  
						 
					
						
							
								
									
										
										
										
											2018-01-18 10:41:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetResponseRule return a rule to rewrite the response with.  
						 
					
						
							
								
									
										
										
										
											2018-07-02 15:39:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rule  * regexNameRule )  GetResponseRule ( )  ResponseRule  {  return  rule . ResponseRule  }  
						 
					
						
							
								
									
										
										
										
											2018-07-13 14:32:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// hasClosingDot return true if s has a closing dot at the end.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  hasClosingDot ( s  string )  bool  {  
						 
					
						
							
								
									
										
										
										
											2019-09-27 18:10:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  strings . HasSuffix ( s ,  "." ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// getSubExprUsage return the number of subexpressions used in s.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getSubExprUsage ( s  string )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									subExprUsage  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <=  100 ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . Contains ( s ,  "{" + strconv . Itoa ( i ) + "}" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											subExprUsage ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  subExprUsage 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// isValidRegexPattern return a regular expression for pattern matching or errors, if any.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isValidRegexPattern ( rewriteFrom ,  rewriteTo  string )  ( * regexp . Regexp ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rewriteFromPattern ,  err  :=  regexp . Compile ( rewriteFrom ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-27 20:25:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "invalid regex matching pattern: %s" ,  rewriteFrom ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  getSubExprUsage ( rewriteTo )  >  rewriteFromPattern . NumSubexp ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-27 20:25:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "the rewrite regex pattern (%s) uses more subexpressions than its corresponding matching regex pattern (%s)" ,  rewriteTo ,  rewriteFrom ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rewriteFromPattern ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}