Code refactoring

This commit is contained in:
Alexey Khit
2023-01-14 22:46:11 +03:00
parent 2039aa60b3
commit 1c830d6e60
+33 -48
View File
@@ -1,13 +1,11 @@
package api package api
import ( import (
"io"
"io/ioutil"
"net/http"
"os"
"github.com/AlexxIT/go2rtc/cmd/app" "github.com/AlexxIT/go2rtc/cmd/app"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"io"
"net/http"
"os"
) )
func configHandler(w http.ResponseWriter, r *http.Request) { func configHandler(w http.ResponseWriter, r *http.Request) {
@@ -22,42 +20,27 @@ func configHandler(w http.ResponseWriter, r *http.Request) {
log.Warn().Err(err).Caller().Send() log.Warn().Err(err).Caller().Send()
} }
case "POST": case "POST", "PATCH":
data, err := io.ReadAll(r.Body) data, err := io.ReadAll(r.Body)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return return
} }
// validate config if r.Method == "PATCH" {
var tmp struct{} // no need to validate after merge
if err = yaml.Unmarshal(data, &tmp); err != nil { data, err = mergeYAML(app.ConfigPath, data)
http.Error(w, err.Error(), http.StatusInternalServerError) if err != nil {
return http.Error(w, err.Error(), http.StatusBadRequest)
} return
}
if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil { } else {
http.Error(w, err.Error(), http.StatusInternalServerError) // validate config
return var tmp struct{}
} if err = yaml.Unmarshal(data, &tmp); err != nil {
case "PATCH": http.Error(w, err.Error(), http.StatusInternalServerError)
rawdata, err := io.ReadAll(r.Body) return
if err != nil { }
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
data, err := mergeYAML(app.ConfigPath, rawdata)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// validate config
var tmp struct{}
if err = yaml.Unmarshal(data, &tmp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil { if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil {
@@ -69,44 +52,46 @@ func configHandler(w http.ResponseWriter, r *http.Request) {
func mergeYAML(file1 string, yaml2 []byte) ([]byte, error) { func mergeYAML(file1 string, yaml2 []byte) ([]byte, error) {
// Read the contents of the first YAML file // Read the contents of the first YAML file
data1, err := ioutil.ReadFile(file1) data1, err := os.ReadFile(file1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Unmarshal the first YAML file into a map // Unmarshal the first YAML file into a map
var config1 map[string]interface{} var config1 map[string]interface{}
err = yaml.Unmarshal(data1, &config1) if err = yaml.Unmarshal(data1, &config1); err != nil {
if err != nil {
return nil, err return nil, err
} }
// Unmarshal the second YAML document into a map // Unmarshal the second YAML document into a map
var config2 map[string]interface{} var config2 map[string]interface{}
err = yaml.Unmarshal(yaml2, &config2) if err = yaml.Unmarshal(yaml2, &config2); err != nil {
if err != nil {
return nil, err return nil, err
} }
// Merge the two maps // Merge the two maps
config1 = merge(config1, config2) config1 = merge(config1, config2)
// Marshal the merged map into YAML // Marshal the merged map into YAML
return yaml.Marshal(&config1) return yaml.Marshal(&config1)
} }
func merge(a, b map[string]interface{}) map[string]interface{} { func merge(dst, src map[string]interface{}) map[string]interface{} {
for k, v := range b { for k, v := range src {
if vv, ok := a[k]; ok { if vv, ok := dst[k]; ok {
switch vv := vv.(type) { switch vv := vv.(type) {
case map[string]interface{}: case map[string]interface{}:
v := v.(map[string]interface{}) v := v.(map[string]interface{})
a[k] = merge(vv, v) dst[k] = merge(vv, v)
case []interface{}: case []interface{}:
v := v.([]interface{}) v := v.([]interface{})
a[k] = v dst[k] = v
default: default:
a[k] = v dst[k] = v
} }
} else { } else {
a[k] = v dst[k] = v
} }
} }
return a return dst
} }