|  |  | @ -20,6 +20,7 @@ import ( | 
			
		
	
		
			
				
					|  |  |  | 	"encoding/json" | 
			
		
	
		
			
				
					|  |  |  | 	"fmt" | 
			
		
	
		
			
				
					|  |  |  | 	"io" | 
			
		
	
		
			
				
					|  |  |  | 	"io/ioutil" | 
			
		
	
		
			
				
					|  |  |  | 	"log" | 
			
		
	
		
			
				
					|  |  |  | 	"net" | 
			
		
	
		
			
				
					|  |  |  | 	"net/http" | 
			
		
	
	
		
			
				
					|  |  | @ -29,6 +30,7 @@ import ( | 
			
		
	
		
			
				
					|  |  |  | 	"sync" | 
			
		
	
		
			
				
					|  |  |  | 	"time" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	"github.com/caddyserver/caddy/caddyconfig" | 
			
		
	
		
			
				
					|  |  |  | 	"github.com/mholt/certmagic" | 
			
		
	
		
			
				
					|  |  |  | 	"github.com/rs/cors" | 
			
		
	
		
			
				
					|  |  |  | ) | 
			
		
	
	
		
			
				
					|  |  | @ -164,12 +166,45 @@ func handleLoadConfig(w http.ResponseWriter, r *http.Request) { | 
			
		
	
		
			
				
					|  |  |  | 		return | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if !strings.Contains(r.Header.Get("Content-Type"), "/json") { | 
			
		
	
		
			
				
					|  |  |  | 		http.Error(w, "unacceptable Content-Type", http.StatusBadRequest) | 
			
		
	
		
			
				
					|  |  |  | 		return | 
			
		
	
		
			
				
					|  |  |  | 	var payload io.Reader = r.Body | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	// if the config is formatted other than Caddy's native
 | 
			
		
	
		
			
				
					|  |  |  | 	// JSON, we need to adapt it before loading it
 | 
			
		
	
		
			
				
					|  |  |  | 	ct := r.Header.Get("Content-Type") | 
			
		
	
		
			
				
					|  |  |  | 	if !strings.Contains(ct, "/json") { | 
			
		
	
		
			
				
					|  |  |  | 		slashIdx := strings.Index(ct, "/") | 
			
		
	
		
			
				
					|  |  |  | 		if slashIdx < 0 { | 
			
		
	
		
			
				
					|  |  |  | 			http.Error(w, "Malformed Content-Type", http.StatusBadRequest) | 
			
		
	
		
			
				
					|  |  |  | 			return | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		adapterName := ct[slashIdx+1:] | 
			
		
	
		
			
				
					|  |  |  | 		cfgAdapter := caddyconfig.GetAdapter(adapterName) | 
			
		
	
		
			
				
					|  |  |  | 		if cfgAdapter == nil { | 
			
		
	
		
			
				
					|  |  |  | 			http.Error(w, "Unrecognized config adapter: "+adapterName, http.StatusBadRequest) | 
			
		
	
		
			
				
					|  |  |  | 			return | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, 1024*1024)) | 
			
		
	
		
			
				
					|  |  |  | 		if err != nil { | 
			
		
	
		
			
				
					|  |  |  | 			http.Error(w, "Error reading request body: "+err.Error(), http.StatusBadRequest) | 
			
		
	
		
			
				
					|  |  |  | 			return | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		result, warnings, err := cfgAdapter.Adapt(body, nil) | 
			
		
	
		
			
				
					|  |  |  | 		if err != nil { | 
			
		
	
		
			
				
					|  |  |  | 			log.Printf("[ADMIN][ERROR] adapting config from %s: %v", adapterName, err) | 
			
		
	
		
			
				
					|  |  |  | 			http.Error(w, fmt.Sprintf("Adapting config from %s: %v", adapterName, err), http.StatusBadRequest) | 
			
		
	
		
			
				
					|  |  |  | 			return | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		if len(warnings) > 0 { | 
			
		
	
		
			
				
					|  |  |  | 			respBody, err := json.Marshal(warnings) | 
			
		
	
		
			
				
					|  |  |  | 			if err != nil { | 
			
		
	
		
			
				
					|  |  |  | 				log.Printf("[ADMIN][ERROR] marshaling warnings: %v", err) | 
			
		
	
		
			
				
					|  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  | 			w.Write(respBody) | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		payload = bytes.NewReader(result) | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	err := Load(r.Body) | 
			
		
	
		
			
				
					|  |  |  | 	err := Load(payload) | 
			
		
	
		
			
				
					|  |  |  | 	if err != nil { | 
			
		
	
		
			
				
					|  |  |  | 		log.Printf("[ADMIN][ERROR] loading config: %v", err) | 
			
		
	
		
			
				
					|  |  |  | 		http.Error(w, err.Error(), http.StatusBadRequest) | 
			
		
	
	
		
			
				
					|  |  | 
 |