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" 
  
						 
					
						
							
								
									
										
										
										
											2018-07-13 14:32:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/miekg/dns" 
  
						 
					
						
							
								
									
										
										
										
											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 )   +   "}" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   strings . Contains ( s ,   groupIndexStr )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s   =   strings . Replace ( s ,   groupIndexStr ,   groupValue ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											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 : 
  
						 
					
						
							
								
									
										
										
										
											2018-10-23 16:59:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   nil ,   fmt . Errorf ( "A 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-08-14 17:55:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// validName returns true if s is valid domain name and shorter than 256 characters. 
  
						 
					
						
							
								
									
										
										
										
											2018-07-13 14:32:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   validName ( s   string )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 _ ,   ok   :=   dns . IsDomainName ( s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   ! ok   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   len ( dns . Name ( s ) . String ( ) )   >   255   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											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   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   strings . HasSuffix ( s ,   "." )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}