2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2015 Matthew Holt and The Caddy Authors  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// you may not use this file except in compliance with the License.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You may obtain a copy of the License at  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     http://www.apache.org/licenses/LICENSE-2.0  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unless required by applicable law or agreed to in writing, software  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the License for the specific language governing permissions and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// limitations under the License.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  httpcaddyfile  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"html" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:24:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-14 23:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/caddyserver/certmagic" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/mholt/acmez/acme" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"go.uber.org/zap/zapcore" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-10 13:36:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/caddyserver/caddy/v2" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-22 21:26:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/caddyserver/caddy/v2/caddyconfig" 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-22 21:26:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/caddyserver/caddy/v2/modules/caddyhttp" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/caddyserver/caddy/v2/modules/caddytls" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  init ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RegisterDirective ( "bind" ,  parseBind ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RegisterDirective ( "tls" ,  parseTLS ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-13 14:12:43 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "fs" ,  parseFilesystem ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterDirective ( "root" ,  parseRoot ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 10:47:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "vars" ,  parseVars ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "redir" ,  parseRedir ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-16 11:04:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "respond" ,  parseRespond ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 12:54:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "abort" ,  parseAbort ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:25:49 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "error" ,  parseError ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "route" ,  parseRoute ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-28 13:38:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "handle" ,  parseHandle ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterDirective ( "handle_errors" ,  parseHandleErrors ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-16 11:27:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "invoke" ,  parseInvoke ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterDirective ( "log" ,  parseLog ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 12:05:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RegisterHandlerDirective ( "skip_log" ,  parseSkipLog ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseBind parses the bind directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	bind <addresses...>  
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseBind ( h  Helper )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  [ ] ConfigValue { { Class :  "bind" ,  Value :  h . RemainingArgs ( ) } } ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:24:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseTLS parses the tls directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	tls [<email>|internal]|[<cert_file> <key_file>] {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    protocols <min> [<max>]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    ciphers   <cipher_suites...>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    curves    <curves...>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    client_auth {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	        mode                   [request|require|verify_if_given|require_and_verify]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	        trusted_ca_cert        <base64_der>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	        trusted_ca_cert_file   <filename>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	        trusted_leaf_cert      <base64_der>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	        trusted_leaf_cert_file <filename>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    }  
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    alpn                          <values...>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    load                          <paths...>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    ca                            <acme_ca_endpoint>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    ca_root                       <pem_file>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    key_type                      [ed25519|p256|p384|rsa2048|rsa4096]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    dns                           <provider_name> [...]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    propagation_delay             <duration>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    propagation_timeout           <duration>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    resolvers                     <dns_servers...>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    dns_ttl                       <duration>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    dns_challenge_override_domain <domain>  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    on_demand  
						 
					
						
							
								
									
										
										
										
											2024-01-10 04:30:31 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    reuse_private_keys  
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    eab                           <key_id> <mac_key>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    issuer                        <module_name> [...]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    get_certificate               <module_name> [...]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    insecure_secrets_log          <log_file>  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	}  
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseTLS ( h  Helper )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cp  :=  new ( caddytls . ConnectionPolicy ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  fileLoader  caddytls . FileLoader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  folderLoader  caddytls . FolderLoader 
							 
						 
					
						
							
								
									
										
											 
										
											
												caddytls: Refactor certificate selection policies (close #1575)
Certificate selection used to be a module, but this seems unnecessary,
especially since the built-in CustomSelectionPolicy allows quite complex
selection logic on a number of fields in certs. If we need to extend
that logic, we can, but I don't think there are SO many possibilities
that we need modules.
This update also allows certificate selection to choose between multiple
matching certs based on client compatibility and makes a number of other
improvements in the default cert selection logic, both here and in the
latest CertMagic.
The hardest part of this was the conn policy consolidation logic
(Caddyfile only, of course). We have to merge connection policies that
we can easily combine, because if two certs are manually loaded in a
Caddyfile site block, that produces two connection policies, and each
cert is tagged with a different tag, meaning only the first would ever
be selected. So given the same matchers, we can merge the two, but this
required improving the Tag selection logic to support multiple tags to
choose from, hence "tags" changed to "any_tag" or "all_tags" (but we
use any_tag in our Caddyfile logic).
Combining conn policies with conflicting settings is impossible, so
that should return an error if two policies with the exact same matchers
have non-empty settings that are not the same (the one exception being
any_tag which we can merge because the logic for them is to OR them).
It was a bit complicated. It seems to work in numerous tests I've
conducted, but we'll see how it pans out in the release candidates.
											 
										 
										
											2020-04-01 20:49:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  certSelector  caddytls . CustomCertSelectionPolicy 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 11:06:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  acmeIssuer  * caddytls . ACMEIssuer 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 20:02:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  keyType  string 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 11:06:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  internalIssuer  * caddytls . InternalIssuer 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-16 11:05:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  issuers  [ ] certmagic . Issuer 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-25 11:28:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  certManagers  [ ] certmagic . Manager 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  onDemand  bool 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-10 04:30:31 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  reusePrivateKeys  bool 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-30 09:11:30 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// file certificate loader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									firstLine  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  len ( firstLine )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  firstLine [ 0 ]  ==  "internal"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											internalIssuer  =  new ( caddytls . InternalIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ! strings . Contains ( firstLine [ 0 ] ,  "@" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Err ( "single argument must either be 'internal' or an email address" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-05 05:58:49 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											acmeIssuer . Email  =  firstLine [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-05 05:58:49 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										certFilename  :=  firstLine [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										keyFilename  :=  firstLine [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// tag this certificate so if multiple certs match, specifically 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this one that the user has provided will be used, see #2588: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// https://github.com/caddyserver/caddy/issues/2588 ... but we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// must be careful about how we do this; being careless will 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// lead to failed handshakes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we need to remember which cert files we've seen, since we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// must load each cert only once; otherwise, they each get a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// different tag... since a cert loaded twice has the same 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// bytes, it will overwrite the first one in the cache, and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// only the last cert (and its tag) will survive, so any conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// policy that is looking for any tag other than the last one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to be loaded won't find it, and TLS handshakes will fail 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (see end of issue #3004) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// tlsCertTags maps certificate filenames to their tag. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is used to remember which tag is used for each 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// certificate files, since we need to avoid loading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the same certificate files more than once, overwriting 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// previous tags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tlsCertTags ,  ok  :=  h . State [ "tlsCertTags" ] . ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tlsCertTags  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											h . State [ "tlsCertTags" ]  =  tlsCertTags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												caddytls: Refactor certificate selection policies (close #1575)
Certificate selection used to be a module, but this seems unnecessary,
especially since the built-in CustomSelectionPolicy allows quite complex
selection logic on a number of fields in certs. If we need to extend
that logic, we can, but I don't think there are SO many possibilities
that we need modules.
This update also allows certificate selection to choose between multiple
matching certs based on client compatibility and makes a number of other
improvements in the default cert selection logic, both here and in the
latest CertMagic.
The hardest part of this was the conn policy consolidation logic
(Caddyfile only, of course). We have to merge connection policies that
we can easily combine, because if two certs are manually loaded in a
Caddyfile site block, that produces two connection policies, and each
cert is tagged with a different tag, meaning only the first would ever
be selected. So given the same matchers, we can merge the two, but this
required improving the Tag selection logic to support multiple tags to
choose from, hence "tags" changed to "any_tag" or "all_tags" (but we
use any_tag in our Caddyfile logic).
Combining conn policies with conflicting settings is impossible, so
that should return an error if two policies with the exact same matchers
have non-empty settings that are not the same (the one exception being
any_tag which we can merge because the logic for them is to OR them).
It was a bit complicated. It seems to work in numerous tests I've
conducted, but we'll see how it pans out in the release candidates.
											 
										 
										
											2020-04-01 20:49:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tag ,  ok  :=  tlsCertTags [ certFilename ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// haven't seen this cert file yet, let's give it a tag 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// and add a loader for it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag  =  fmt . Sprintf ( "cert%d" ,  len ( tlsCertTags ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fileLoader  =  append ( fileLoader ,  caddytls . CertKeyFilePair { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Certificate :  certFilename , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Key :          keyFilename , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Tags :         [ ] string { tag } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// remember this for next time we see this cert file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tlsCertTags [ certFilename ]  =  tag 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										certSelector . AnyTag  =  append ( certSelector . AnyTag ,  tag ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  hasBlock  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  h . NextBlock ( 0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hasBlock  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  h . Val ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "protocols" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "protocols requires one or two arguments" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  caddytls . SupportedProtocols [ args [ 0 ] ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "wrong protocol name or protocol not supported: '%s'" ,  args [ 0 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cp . ProtocolMin  =  args [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  caddytls . SupportedProtocols [ args [ 1 ] ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "wrong protocol name or protocol not supported: '%s'" ,  args [ 1 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cp . ProtocolMax  =  args [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "ciphers" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! caddytls . CipherSuiteNameSupported ( h . Val ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "wrong cipher suite name or cipher suite not supported: '%s'" ,  h . Val ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cp . CipherSuites  =  append ( cp . CipherSuites ,  h . Val ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "curves" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  caddytls . SupportedCurves [ h . Val ( ) ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "Wrong curve name or curve not supported: '%s'" ,  h . Val ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cp . Curves  =  append ( cp . Curves ,  h . Val ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "client_auth" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cp . ClientAuthentication  =  & caddytls . ClientAuthentication { } 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-25 11:44:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  :=  cp . ClientAuthentication . UnmarshalCaddyfile ( h . NewFromNextSegment ( ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "alpn" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cp . ALPN  =  args 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "load" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											folderLoader  =  append ( folderLoader ,  h . RemainingArgs ( ) ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "ca" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . CA  =  arg [ 0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 20:02:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "key_type" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											keyType  =  arg [ 0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:18:14 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "eab" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . ExternalAccount  =  & acme . EAB { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												KeyID :   arg [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												MACKey :  arg [ 1 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										
											
												caddytls: Add support for ZeroSSL; add Caddyfile support for issuers (#3633)
* caddytls: Add support for ZeroSSL; add Caddyfile support for issuers
Configuring issuers explicitly in a Caddyfile is not easily compatible
with existing ACME-specific parameters such as email or acme_ca which
infer the kind of issuer it creates (this is complicated now because
the ZeroSSL issuer wraps the ACME issuer)... oh well, we can revisit
that later if we need to.
New Caddyfile global option:
    {
        cert_issuer <name> ...
    }
Or, alternatively, as a tls subdirective:
    tls {
        issuer <name> ...
    }
For example, to use ZeroSSL with an API key:
    {
        cert_issuser zerossl API_KEY
    }
For now, that still uses ZeroSSL's ACME endpoint; it fetches EAB
credentials for you. You can also provide the EAB credentials directly
just like any other ACME endpoint:
    {
        cert_issuer acme {
            eab KEY_ID MAC_KEY
        }
    }
All these examples use the new global option (or tls subdirective). You
can still use traditional/existing options with ZeroSSL, since it's
just another ACME endpoint:
    {
        acme_ca  https://acme.zerossl.com/v2/DV90
        acme_eab KEY_ID MAC_KEY
    }
That's all there is to it. You just can't mix-and-match acme_* options
with cert_issuer, because it becomes confusing/ambiguous/complicated to
merge the settings.
* Fix broken test
This test was asserting buggy behavior, oops - glad this branch both
discovers and fixes the bug at the same time!
* Fix broken test (post-merge)
* Update modules/caddytls/acmeissuer.go
Fix godoc comment
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
* Add support for ZeroSSL's EAB-by-email endpoint
Also transform the ACMEIssuer into ZeroSSLIssuer implicitly if set to
the ZeroSSL endpoint without EAB (the ZeroSSLIssuer is needed to
generate EAB if not already provided); this is now possible with either
an API key or an email address.
* go.mod: Use latest certmagic, acmez, and x/net
* Wrap underlying logic rather than repeating it
Oops, duh
* Form-encode email info into request body for EAB endpoint
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
											 
										 
										
											2020-08-11 08:58:06 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "issuer" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modName  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modID  :=  "tls.issuance."  +  modName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unm ,  err  :=  caddyfile . UnmarshalModule ( h . Dispenser ,  modID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											issuer ,  ok  :=  unm . ( certmagic . Issuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "module %s (%T) is not a certmagic.Issuer" ,  modID ,  unm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											issuers  =  append ( issuers ,  issuer ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 15:40:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "get_certificate" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modName  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modID  :=  "tls.get_certificate."  +  modName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unm ,  err  :=  caddyfile . UnmarshalModule ( h . Dispenser ,  modID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											certManager ,  ok  :=  unm . ( certmagic . Manager ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "module %s (%T) is not a certmagic.CertificateManager" ,  modID ,  unm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											certManagers  =  append ( certManagers ,  certManager ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "dns" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											provName  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modID  :=  "dns.providers."  +  provName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unm ,  err  :=  caddyfile . UnmarshalModule ( h . Dispenser ,  modID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . ProviderRaw  =  caddyconfig . JSONModuleObject ( unm ,  "name" ,  provName ,  h . warnings ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-02 23:07:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "resolvers" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . Resolvers  =  args 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "propagation_delay" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delayStr  :=  arg [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delay ,  err  :=  caddy . ParseDuration ( delayStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "invalid propagation_delay duration %s: %v" ,  delayStr ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . PropagationDelay  =  caddy . Duration ( delay ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "propagation_timeout" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											timeoutStr  :=  arg [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  timeout  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  timeoutStr  ==  "-1"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												timeout  =  time . Duration ( - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												timeout ,  err  =  caddy . ParseDuration ( timeoutStr ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "invalid propagation_timeout duration %s: %v" ,  timeoutStr ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . PropagationTimeout  =  caddy . Duration ( timeout ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:44:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "dns_ttl" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ttlStr  :=  arg [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ttl ,  err  :=  caddy . ParseDuration ( ttlStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "invalid dns_ttl duration %s: %v" ,  ttlStr ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . TTL  =  caddy . Duration ( ttl ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-09 03:03:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "dns_challenge_override_domain" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges  =  new ( caddytls . ChallengesConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer . Challenges . DNS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer . Challenges . DNS  =  new ( caddytls . DNSChallengeConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . Challenges . DNS . OverrideDomain  =  arg [ 0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-08 16:52:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "ca_root" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( arg )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acmeIssuer  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												acmeIssuer  =  new ( caddytls . ACMEIssuer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											acmeIssuer . TrustedRootsPEMFiles  =  append ( acmeIssuer . TrustedRootsPEMFiles ,  arg [ 0 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "on_demand" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											onDemand  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-10 04:30:31 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "reuse_private_keys" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reusePrivateKeys  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "insecure_secrets_log" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cp . InsecureSecretsLog  =  h . Val ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Errf ( "unknown subdirective: %s" ,  h . Val ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// a naked tls directive is not allowed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( firstLine )  ==  0  &&  ! hasBlock  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 11:06:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// begin building the final config values 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 16:50:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									configVals  :=  [ ] ConfigValue { } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 11:06:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// certificate loaders 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( fileLoader )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-29 11:49:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Class :  "tls.cert_loader" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Value :  fileLoader , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( folderLoader )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-29 11:49:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Class :  "tls.cert_loader" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Value :  folderLoader , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-02 16:17:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// some tls subdirectives are shortcuts that implicitly configure issuers, and the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// user can also configure issuers explicitly using the issuer subdirective; the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// logic to support both would likely be complex, or at least unintuitive 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-16 11:05:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( issuers )  >  0  &&  ( acmeIssuer  !=  nil  ||  internalIssuer  !=  nil )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . Err ( "cannot mix issuer subdirective (explicit issuers) with other issuer-specific subdirectives (implicit issuers)" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 11:06:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-02 16:17:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  acmeIssuer  !=  nil  &&  internalIssuer  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . Err ( "cannot create both ACME and internal certificate issuers" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-16 11:05:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-02 16:17:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// now we should either have: explicitly-created issuers, or an implicitly-created 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ACME or internal issuer, or no issuers at all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  len ( issuers )  >  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  issuer  :=  range  issuers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Class :  "tls.cert_issuer" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Value :  issuer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  acmeIssuer  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// implicit ACME issuers (from various subdirectives) - use defaults; there might be more than one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defaultIssuers  :=  caddytls . DefaultIssuers ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// if a CA endpoint was set, override multiple implicit issuers since it's a specific one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  acmeIssuer . CA  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defaultIssuers  =  [ ] certmagic . Issuer { acmeIssuer } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  issuer  :=  range  defaultIssuers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  iss  :=  issuer . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  * caddytls . ACMEIssuer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												issuer  =  acmeIssuer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  * caddytls . ZeroSSLIssuer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												iss . ACMEIssuer  =  acmeIssuer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Class :  "tls.cert_issuer" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Value :  issuer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  internalIssuer  !=  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-06 23:15:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Class :  "tls.cert_issuer" , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-16 11:05:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Value :  internalIssuer , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-02 16:17:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// certificate key type 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 20:02:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  keyType  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Class :  "tls.key_type" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  keyType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// on-demand TLS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  onDemand  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Class :  "tls.on_demand" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 15:40:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  certManager  :=  range  certManagers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Class :  "tls.cert_manager" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  certManager , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-10 04:30:31 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// reuse private keys TLS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  reusePrivateKeys  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Class :  "tls.reuse_private_keys" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												caddytls: Refactor certificate selection policies (close #1575)
Certificate selection used to be a module, but this seems unnecessary,
especially since the built-in CustomSelectionPolicy allows quite complex
selection logic on a number of fields in certs. If we need to extend
that logic, we can, but I don't think there are SO many possibilities
that we need modules.
This update also allows certificate selection to choose between multiple
matching certs based on client compatibility and makes a number of other
improvements in the default cert selection logic, both here and in the
latest CertMagic.
The hardest part of this was the conn policy consolidation logic
(Caddyfile only, of course). We have to merge connection policies that
we can easily combine, because if two certs are manually loaded in a
Caddyfile site block, that produces two connection policies, and each
cert is tagged with a different tag, meaning only the first would ever
be selected. So given the same matchers, we can merge the two, but this
required improving the Tag selection logic to support multiple tags to
choose from, hence "tags" changed to "any_tag" or "all_tags" (but we
use any_tag in our Caddyfile logic).
Combining conn policies with conflicting settings is impossible, so
that should return an error if two policies with the exact same matchers
have non-empty settings that are not the same (the one exception being
any_tag which we can merge because the logic for them is to OR them).
It was a bit complicated. It seems to work in numerous tests I've
conducted, but we'll see how it pans out in the release candidates.
											 
										 
										
											2020-04-01 20:49:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// custom certificate selection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( certSelector . AnyTag )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cp . CertSelection  =  & certSelector 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-17 21:00:45 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// connection policy -- always add one, to ensure that TLS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is enabled, because this directive was used (this is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// needed, for instance, when a site block has a key of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// just ":5000" - i.e. no hostname, and only on-demand TLS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is enabled) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configVals  =  append ( configVals ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Class :  "tls.connection_policy" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Value :  cp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  configVals ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 12:50:36 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseRoot parses the root directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	root [<matcher>] <path>  
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseRoot ( h  Helper )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// count the tokens to determine what to do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									argsCount  :=  h . CountRemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  argsCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . Errf ( "too few arguments; must have at least a root path" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  argsCount  >  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . Errf ( "too many arguments; should only be a matcher and a path" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// with only one arg, assume it's a root path with no matcher token 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  argsCount  ==  1  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-22 23:13:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 12:50:36 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  h . NewRoute ( nil ,  caddyhttp . VarsMiddleware { "root" :  h . Val ( ) } ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// parse the matcher token into a matcher set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									userMatcherSet ,  err  :=  h . ExtractMatcherSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name again, matcher parsing does a reset 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// advance to the root path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 12:50:36 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-15 11:57:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// make the route with the matcher 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  h . NewRoute ( userMatcherSet ,  caddyhttp . VarsMiddleware { "root" :  h . Val ( ) } ) ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 12:50:36 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-13 14:12:43 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseFilesystem parses the fs directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	fs <filesystem>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseFilesystem ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-13 14:12:43 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  caddyhttp . VarsMiddleware { "fs" :  h . Val ( ) } ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-13 14:12:43 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 10:47:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseVars parses the vars directive. See its UnmarshalCaddyfile method for syntax.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseVars ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v  :=  new ( caddyhttp . VarsMiddleware ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  v . UnmarshalCaddyfile ( h . Dispenser ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  v ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseRedir parses the redir directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	redir [<matcher>] <to> [<code>]  
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// <code> can be "permanent" for 301, "temporary" for 302 (default),  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// a placeholder, or any number in the 3xx range or 401. The special  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// code "html" can be used to redirect only browser clients (will  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// respond with HTTP 200 and no Location header; redirect is performed  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with JS and a meta tag).  
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseRedir ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  code  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										code  =  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  body  string 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  hdr  http . Header 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  code  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "permanent" : 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										code  =  "301" 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  "temporary" ,  "" : 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										code  =  "302" 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  "html" : 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Script tag comes first since that will better imitate a redirect in the browser's 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// history, but the meta tag is a fallback for most non-JS clients. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  metaRedir  =  ` < ! DOCTYPE  html > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								< html >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< head > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< title > Redirecting ... < / title > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< script > window . location . replace ( "%s" ) ; < / script > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< meta  http - equiv = "refresh"  content = "0; URL='%s'" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / head > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< body > Redirecting  to  < a  href = "%s" > % s < / a > ... < / body > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								< / html >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										safeTo  :=  html . EscapeString ( to ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body  =  fmt . Sprintf ( metaRedir ,  safeTo ,  safeTo ,  safeTo ,  safeTo ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-10 17:54:47 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hdr  =  http . Header { "Content-Type" :  [ ] string { "text/html; charset=utf-8" } } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										code  =  "200"  // don't redirect non-browser clients 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-06 10:50:26 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Allow placeholders for the code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( code ,  "{" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Try to validate as an integer otherwise 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										codeInt ,  err  :=  strconv . Atoi ( code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Errf ( "Not a supported redir code type or not valid integer: '%s'" ,  code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-06 10:50:26 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Sometimes, a 401 with Location header is desirable because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// requests made with XHR will "eat" the 3xx redirect; so if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the intent was to redirect to an auth page, a 3xx won't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// work. Responding with 401 allows JS code to read the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Location header and do a window.location redirect manually. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// see https://stackoverflow.com/a/2573589/846934 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// see https://github.com/oauth2-proxy/oauth2-proxy/issues/1522 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  codeInt  <  300  ||  ( codeInt  >  399  &&  codeInt  !=  401 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Errf ( "Redir code not in the 3xx range or 401: '%v'" ,  codeInt ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 14:59:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// don't redirect non-browser clients 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  code  !=  "200"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hdr  =  http . Header { "Location" :  [ ] string { to } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  caddyhttp . StaticResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StatusCode :  caddyhttp . WeakString ( code ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-09 11:11:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Headers :     hdr , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 10:46:35 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Body :        body , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 12:05:47 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-09-16 11:04:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseRespond parses the respond directive.  
						 
					
						
							
								
									
										
										
										
											2019-09-16 11:04:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseRespond ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sr  :=  new ( caddyhttp . StaticResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  sr . UnmarshalCaddyfile ( h . Dispenser ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  sr ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-16 11:04:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-28 12:54:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseAbort parses the abort directive.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseAbort ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . Next ( )  // consume directive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  h . Next ( )  ||  h . NextBlock ( 0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & caddyhttp . StaticResponse { Abort :  true } ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:25:49 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseError parses the error directive.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseError ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									se  :=  new ( caddyhttp . StaticError ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  se . UnmarshalCaddyfile ( h . Dispenser ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  se ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:25:49 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 09:32:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseRoute parses the route directive.  
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseRoute ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-08-05 15:42:29 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									allResults ,  err  :=  parseSegmentAsConfig ( h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 15:42:29 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  result  :=  range  allResults  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 05:04:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  result . Value . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  caddyhttp . Route ,  caddyhttp . Subroute : 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 15:42:29 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Errf ( "%s directive returned something other than an HTTP route or subroute: %#v (only handler directives can be used in routes)" ,  result . directive ,  result . Value ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 05:04:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  buildSubroute ( allResults ,  h . groupCounter ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-09 14:00:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-01-16 17:08:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseHandle ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-05-26 17:27:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ParseSegmentAsSubroute ( h ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-01-16 17:08:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseHandleErrors ( h  Helper )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-16 00:24:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									expression  :=  "" 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									args  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-16 00:24:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( args )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										codes  :=  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  val  :=  range  args  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( val )  !=  3  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "bad status value '%s'" ,  val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  strings . HasSuffix ( val ,  "xx" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												val  =  val [ : 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_ ,  err  :=  strconv . Atoi ( val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "bad status value '%s': %v" ,  val ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  expression  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													expression  +=  " || " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression  +=  fmt . Sprintf ( "{http.error.status_code} >= %s00 && {http.error.status_code} <= %s99" ,  val ,  val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  err  :=  strconv . Atoi ( val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "bad status value '%s': %v" ,  val ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											codes  =  append ( codes ,  val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( codes )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  expression  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression  +=  " || " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression  +=  "{http.error.status_code} in ["  +  strings . Join ( codes ,  ", " )  +  "]" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Reset cursor position to get ready for ParseSegmentAsSubroute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . Reset ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . Next ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . Prev ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If no arguments present reset the cursor position to get ready for ParseSegmentAsSubroute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . Prev ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handler ,  err  :=  ParseSegmentAsSubroute ( h ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 17:08:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-16 00:24:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									subroute ,  ok  :=  handler . ( * caddyhttp . Subroute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . Errf ( "segment was not parsed as a subroute" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  expression  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusMatcher  :=  caddy . ModuleMap { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"expression" :  h . JSON ( caddyhttp . MatchExpression { Expr :  expression } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i  :=  range  subroute . Routes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											subroute . Routes [ i ] . MatcherSetsRaw  =  [ ] caddy . ModuleMap { statusMatcher } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-16 22:24:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  [ ] ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Class :  "error_route" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  subroute , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 17:08:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-02-06 12:55:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-16 11:27:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseInvoke parses the invoke directive.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseInvoke ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . Next ( )  // consume directive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  h . Next ( )  ||  h . NextBlock ( 0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// remember that we're invoking this name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to populate the server with these named routes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . State [ namedRouteKey ]  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . State [ namedRouteKey ]  =  map [ string ] struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . State [ namedRouteKey ] . ( map [ string ] struct { } ) [ h . Val ( ) ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// return the handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & caddyhttp . Invoke { Name :  h . Val ( ) } ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parseLog parses the log directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	log <logger_name> {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    hostnames <hostnames...>  
						 
					
						
							
								
									
										
										
										
											2022-09-16 16:05:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    output <writer_module> ...  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    format <encoder_module> ...  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    level  <level>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	}  
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parseLog ( h  Helper )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  parseLogHelper ( h ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// parseLogHelper is used both for the parseLog directive within Server Blocks,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// as well as the global "log" option for configuring loggers at the global  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// level. The parseAsGlobalOption parameter is used to distinguish any differing logic  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// between the two.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseLogHelper ( h  Helper ,  globalLogNames  map [ string ] struct { } )  ( [ ] ConfigValue ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume option name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// When the globalLogNames parameter is passed in, we make 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// modifications to the parsing behavior. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parseAsGlobalOption  :=  globalLogNames  !=  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  configValues  [ ] ConfigValue 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Logic below expects that a name is always present when a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// global option is being parsed; or an optional override 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is supported for access logs. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  logName  string 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  parseAsGlobalOption  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logName  =  h . Val ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Only a single argument is supported. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If there is no log name specified, we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// reference the default logger. See the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// setupNewDefault function in the logging 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// package for where this is configured. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logName  =  caddy . DefaultLoggerName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Verify this name is unused. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  used  :=  globalLogNames [ logName ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  used  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Err ( "duplicate global log option for: "  +  logName ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 17:57:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalLogNames [ logName ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// An optional override of the logger name can be provided; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// otherwise a default will be used, like "log0", "log1", etc. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logName  =  h . Val ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 17:57:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Only a single argument is supported. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cl  :=  new ( caddy . CustomLog ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// allow overriding the current site block's hostnames for this logger; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is useful for setting up loggers per subdomain in a site block 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// with a wildcard domain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									customHostnames  :=  [ ] string { } 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  h . NextBlock ( 0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  h . Val ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "hostnames" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  parseAsGlobalOption  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Err ( "hostnames is not allowed in the log global options" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  :=  h . RemainingArgs ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( args )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											customHostnames  =  append ( customHostnames ,  args ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "output" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											moduleName  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// can't use the usual caddyfile.Unmarshaler flow with the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// standard writers because they are in the caddy package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// (because they are the default) and implementing that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// interface there would unfortunately create circular import 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  wo  caddy . WriterOpener 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  moduleName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  "stdout" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												wo  =  caddy . StdoutWriter { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  "stderr" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												wo  =  caddy . StderrWriter { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  "discard" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												wo  =  caddy . DiscardWriter { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												modID  :=  "caddy.logging.writers."  +  moduleName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unm ,  err  :=  caddyfile . UnmarshalModule ( h . Dispenser ,  modID ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												var  ok  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												wo ,  ok  =  unm . ( caddy . WriterOpener ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nil ,  h . Errf ( "module %s (%T) is not a WriterOpener" ,  modID ,  unm ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cl . WriterRaw  =  caddyconfig . JSONModuleObject ( wo ,  "output" ,  moduleName ,  h . warnings ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "format" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											moduleName  :=  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											moduleID  :=  "caddy.logging.encoders."  +  moduleName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unm ,  err  :=  caddyfile . UnmarshalModule ( h . Dispenser ,  moduleID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enc ,  ok  :=  unm . ( zapcore . Encoder ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Errf ( "module %s (%T) is not a zapcore.Encoder" ,  moduleID ,  unm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cl . EncoderRaw  =  caddyconfig . JSONModuleObject ( enc ,  "format" ,  moduleName ,  h . warnings ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "level" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cl . Level  =  h . Val ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "include" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! parseAsGlobalOption  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Err ( "include is not allowed in the log directive" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cl . Include  =  append ( cl . Include ,  h . Val ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 15:00:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "exclude" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! parseAsGlobalOption  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  h . Err ( "exclude is not allowed in the log directive" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cl . Exclude  =  append ( cl . Exclude ,  h . Val ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  h . Errf ( "unrecognized subdirective: %s" ,  h . Val ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  val  namedCustomLog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									val . hostnames  =  customHostnames 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									isEmptyConfig  :=  reflect . DeepEqual ( cl ,  new ( caddy . CustomLog ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Skip handling of empty logging configs 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  parseAsGlobalOption  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Use indicated name for global log options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val . name  =  logName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  logName  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											val . name  =  logName 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ! isEmptyConfig  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Construct a log name for server log streams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logCounter ,  ok  :=  h . State [ "logCounter" ] . ( int ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logCounter  =  0 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											val . name  =  fmt . Sprintf ( "log%d" ,  logCounter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logCounter ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											h . State [ "logCounter" ]  =  logCounter 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-02 03:13:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  val . name  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cl . Include  =  [ ] string { "http.log.access."  +  val . name } 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isEmptyConfig  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val . log  =  cl 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configValues  =  append ( configValues ,  ConfigValue { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Class :  "custom_log" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Value :  val , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:00:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  configValues ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-09-15 12:05:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// parseSkipLog parses the skip_log directive. Syntax:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	skip_log [<matcher>]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parseSkipLog ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-23 19:36:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h . Next ( )  // consume directive name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . NextArg ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  h . ArgErr ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 12:05:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  caddyhttp . VarsMiddleware { "skip_log" :  true } ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}