diff options
| author | Shulhan <ms@kilabit.info> | 2022-04-11 23:20:21 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2022-04-11 23:20:21 +0700 |
| commit | 9e752edba9bcedfe1c1c3db98a5bc9778f220d2f (patch) | |
| tree | f6f42ebd73b19a3334d4491f0f7fac960618dc43 | |
| parent | c60cd24822081c45c3b2da25e4a708d2a58e2a87 (diff) | |
| download | rescached-9e752edba9bcedfe1c1c3db98a5bc9778f220d2f.tar.xz | |
all: replace internal response with lib/http.EndpointResponse
Both types are similar, since the lib/http already imported we replace
the internal response to minimize duplicate and confusion later.
While at it, use consistent variable naming and declaration using var
in all methods.
| -rw-r--r-- | httpd.go | 406 |
1 files changed, 233 insertions, 173 deletions
@@ -16,7 +16,6 @@ import ( "strings" "github.com/shuLhan/share/lib/dns" - liberrors "github.com/shuLhan/share/lib/errors" libhttp "github.com/shuLhan/share/lib/http" libnet "github.com/shuLhan/share/lib/net" ) @@ -38,15 +37,6 @@ const ( apiZoneRRType = "/api/zone.d/:name/rr/:type" ) -type response struct { - liberrors.E - Data interface{} `json:"data"` -} - -func (r *response) Unwrap() error { - return &r.E -} - func (srv *Server) httpdInit() (err error) { srv.httpd, err = libhttp.NewServer(srv.env.HttpdOptions) if err != nil { @@ -251,39 +241,42 @@ func (srv *Server) httpdRun() { } func (srv *Server) apiCaches(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - res := response{} + var ( + res = libhttp.EndpointResponse{} + answers = srv.dns.CachesLRU() + ) res.Code = http.StatusOK - answers := srv.dns.CachesLRU() if len(answers) == 0 { res.Data = make([]struct{}, 0, 1) } else { res.Data = answers } - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiCachesSearch(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - res := response{ - E: liberrors.E{ - Code: http.StatusInternalServerError, - }, - } + var ( + res = libhttp.EndpointResponse{} + q = epr.HttpRequest.Form.Get(paramNameQuery) - q := epr.HttpRequest.Form.Get(paramNameQuery) + re *regexp.Regexp + listMsg []*dns.Message + ) if len(q) == 0 { res.Code = http.StatusOK res.Data = make([]struct{}, 0, 1) - return json.Marshal(res) + return json.Marshal(&res) } - re, err := regexp.Compile(q) + re, err = regexp.Compile(q) if err != nil { + res.Code = http.StatusInternalServerError res.Message = err.Error() return nil, &res } - listMsg := srv.dns.SearchCaches(re) + listMsg = srv.dns.SearchCaches(re) if listMsg == nil { listMsg = make([]*dns.Message, 0) } @@ -291,18 +284,19 @@ func (srv *Server) apiCachesSearch(epr *libhttp.EndpointRequest) (resBody []byte res.Code = http.StatusOK res.Data = listMsg - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) httpdAPIDeleteCaches(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - res := &liberrors.E{ - Code: http.StatusInternalServerError, - } + var ( + res = libhttp.EndpointResponse{} + q = epr.HttpRequest.Form.Get(paramNameName) + ) - q := epr.HttpRequest.Form.Get(paramNameName) if len(q) == 0 { + res.Code = http.StatusInternalServerError res.Message = "empty query 'name' parameter" - return nil, res + return nil, &res } srv.dns.RemoveCachesByNames([]string{q}) @@ -310,35 +304,37 @@ func (srv *Server) httpdAPIDeleteCaches(epr *libhttp.EndpointRequest) (resBody [ res.Code = http.StatusOK res.Message = fmt.Sprintf("%q has been removed from caches", q) - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) httpdAPIGetEnvironment(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + ) + res.Code = http.StatusOK res.Data = srv.env - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) httpdAPIPostEnvironment(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - res := &response{ - E: liberrors.E{ - Code: http.StatusOK, - Message: "Restarting DNS server", - }, - } + var ( + res = libhttp.EndpointResponse{} + newOpts = new(Environment) + ) - newOpts := new(Environment) err = json.Unmarshal(epr.RequestBody, newOpts) if err != nil { - return nil, err + res.Code = http.StatusBadRequest + res.Message = err.Error() + return nil, &res } if len(newOpts.NameServers) == 0 { res.Code = http.StatusBadRequest res.Message = "at least one parent name servers must be defined" - return nil, res + return nil, &res } newOpts.init() @@ -349,7 +345,7 @@ func (srv *Server) httpdAPIPostEnvironment(epr *libhttp.EndpointRequest) (resBod if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } srv.env = newOpts @@ -359,10 +355,12 @@ func (srv *Server) httpdAPIPostEnvironment(epr *libhttp.EndpointRequest) (resBod if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } - return json.Marshal(res) + res.Code = http.StatusOK + res.Message = "Restarting DNS server" + return json.Marshal(&res) } // @@ -375,22 +373,25 @@ func (srv *Server) httpdAPIPostEnvironment(epr *libhttp.EndpointRequest) (resBod // and remove it from list of HostsFiles. // func (srv *Server) apiHostsBlockUpdate(epr *libhttp.EndpointRequest) (resBody []byte, err error) { - hostsBlocks := make([]*hostsBlock, 0) + var ( + res = libhttp.EndpointResponse{} + hostsBlocks = make([]*hostsBlock, 0) + + hbx *hostsBlock + hby *hostsBlock + ) err = json.Unmarshal(epr.RequestBody, &hostsBlocks) if err != nil { - return nil, err + res.Code = http.StatusBadRequest + res.Message = err.Error() + return nil, &res } - res := &response{ - E: liberrors.E{ - Code: http.StatusInternalServerError, - }, - } + res.Code = http.StatusInternalServerError - for _, hbx := range hostsBlocks { - for x := 0; x < len(srv.env.HostsBlocks); x++ { - hby := srv.env.HostsBlocks[x] + for _, hbx = range hostsBlocks { + for _, hby = range srv.env.HostsBlocks { if hbx.Name != hby.Name { continue } @@ -402,13 +403,13 @@ func (srv *Server) apiHostsBlockUpdate(epr *libhttp.EndpointRequest) (resBody [] err = srv.hostsBlockEnable(hby) if err != nil { res.Message = err.Error() - return nil, res + return nil, &res } } else { err = srv.hostsBlockDisable(hby) if err != nil { res.Message = err.Error() - return nil, res + return nil, &res } hby.IsEnabled = false } @@ -419,16 +420,20 @@ func (srv *Server) apiHostsBlockUpdate(epr *libhttp.EndpointRequest) (resBody [] if err != nil { log.Println("apiHostsBlockUpdate:", err.Error()) res.Message = err.Error() - return nil, res + return nil, &res } res.Code = http.StatusOK res.Data = hostsBlocks - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) hostsBlockEnable(hb *hostsBlock) (err error) { + var ( + hfile *dns.HostsFile + ) + hb.IsEnabled = true err = hb.unhide() @@ -443,7 +448,7 @@ func (srv *Server) hostsBlockEnable(hb *hostsBlock) (err error) { } } - hfile, err := dns.ParseHostsFile(filepath.Join(dirHosts, hb.Name)) + hfile, err = dns.ParseHostsFile(filepath.Join(dirHosts, hb.Name)) if err != nil { return err } @@ -464,8 +469,9 @@ func (srv *Server) hostsBlockEnable(hb *hostsBlock) (err error) { } func (srv *Server) hostsBlockDisable(hb *hostsBlock) (err error) { - hfile, found := srv.env.HostsFiles[hb.Name] - if !found { + var hfile *dns.HostsFile + hfile = srv.env.HostsFiles[hb.Name] + if hfile == nil { return fmt.Errorf("unknown hosts block: %q", hb.Name) } @@ -481,23 +487,29 @@ func (srv *Server) hostsBlockDisable(hb *hostsBlock) (err error) { } func (srv *Server) apiHostsFileCreate(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + name = epr.HttpRequest.Form.Get(paramNameName) + + hfile *dns.HostsFile + path string + found bool + ) - name := epr.HttpRequest.Form.Get(paramNameName) if len(name) == 0 { res.Code = http.StatusBadRequest - res.Message = "hosts file name is invalid or empty" - return nil, res + res.Message = "parameter hosts file name is empty" + return nil, &res } - _, found := srv.env.HostsFiles[name] + _, found = srv.env.HostsFiles[name] if !found { - path := filepath.Join(dirHosts, name) - hfile, err := dns.NewHostsFile(path, nil) + path = filepath.Join(dirHosts, name) + hfile, err = dns.NewHostsFile(path, nil) if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } srv.env.HostsFiles[hfile.Name] = hfile } @@ -505,19 +517,23 @@ func (srv *Server) apiHostsFileCreate(epr *libhttp.EndpointRequest) (resbody []b res.Code = http.StatusOK res.Message = fmt.Sprintf("Hosts file %q has been created", name) - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiHostsFileGet(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + name = epr.HttpRequest.Form.Get(paramNameName) - name := epr.HttpRequest.Form.Get(paramNameName) + hf *dns.HostsFile + found bool + ) - hf, found := srv.env.HostsFiles[name] + hf, found = srv.env.HostsFiles[name] if !found { res.Code = http.StatusNotFound res.Message = "invalid or empty hosts file " + name - return nil, res + return nil, &res } if hf.Records == nil || cap(hf.Records) == 0 { hf.Records = make([]*dns.ResourceRecord, 0, 1) @@ -526,24 +542,29 @@ func (srv *Server) apiHostsFileGet(epr *libhttp.EndpointRequest) (resbody []byte res.Code = http.StatusOK res.Data = hf.Records - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiHostsFileDelete(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + name = epr.HttpRequest.Form.Get(paramNameName) + + hfile *dns.HostsFile + found bool + ) - name := epr.HttpRequest.Form.Get(paramNameName) if len(name) == 0 { res.Code = http.StatusBadRequest - res.Message = "empty or invalid host file name" - return nil, res + res.Message = "empty or invalid parameter for host file name" + return nil, &res } - hfile, found := srv.env.HostsFiles[name] + hfile, found = srv.env.HostsFiles[name] if !found { res.Code = http.StatusBadRequest res.Message = "apiDeleteHostsFile: " + name + " not found" - return nil, res + return nil, &res } // Remove the records associated with hosts file. @@ -553,53 +574,61 @@ func (srv *Server) apiHostsFileDelete(epr *libhttp.EndpointRequest) (resbody []b if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } delete(srv.env.HostsFiles, name) res.Code = http.StatusOK res.Message = name + " has been deleted" - return json.Marshal(res) + return json.Marshal(&res) } // // apiHostsFileRRCreate create new record and save it to the hosts file. // func (srv *Server) apiHostsFileRRCreate(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + hostsFileName = epr.HttpRequest.Form.Get(paramNameName) + + hfile *dns.HostsFile + rr *dns.ResourceRecord + v string + found bool + ) + res.Code = http.StatusBadRequest - hostsFileName := epr.HttpRequest.Form.Get(paramNameName) if len(hostsFileName) == 0 { res.Message = "empty hosts file name in request path" - return nil, res + return nil, &res } - hfile, found := srv.env.HostsFiles[hostsFileName] + hfile, found = srv.env.HostsFiles[hostsFileName] if !found { res.Message = "unknown hosts file name: " + hostsFileName - return nil, res + return nil, &res } - rr := &dns.ResourceRecord{ + rr = &dns.ResourceRecord{ Class: dns.RecordClassIN, } rr.Name = epr.HttpRequest.Form.Get(paramNameDomain) if len(rr.Name) == 0 { res.Message = "empty 'domain' query parameter" - return nil, res + return nil, &res } - v := epr.HttpRequest.Form.Get(paramNameValue) + v = epr.HttpRequest.Form.Get(paramNameValue) if len(v) == 0 { res.Message = "empty 'value' query parameter" - return nil, res + return nil, &res } rr.Type = dns.RecordTypeFromAddress([]byte(v)) if rr.Type == 0 { res.Message = "invalid address value: " + v - return nil, res + return nil, &res } rr.Value = v @@ -607,55 +636,59 @@ func (srv *Server) apiHostsFileRRCreate(epr *libhttp.EndpointRequest) (resbody [ if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } err = srv.dns.PopulateCachesByRR([]*dns.ResourceRecord{rr}, hostsFileName) if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } res.Code = http.StatusOK res.Data = rr - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiHostsFileRRDelete(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &liberrors.E{ - Code: http.StatusBadRequest, - } + var ( + res = libhttp.EndpointResponse{} + hostsFileName = epr.HttpRequest.Form.Get(paramNameName) + domainName = epr.HttpRequest.Form.Get(paramNameDomain) + + hfile *dns.HostsFile + found bool + ) + + res.Code = http.StatusBadRequest - hostsFileName := epr.HttpRequest.Form.Get(paramNameName) if len(hostsFileName) == 0 { res.Message = "empty hosts file name in request path" - return nil, res + return nil, &res + } + if len(domainName) == 0 { + res.Message = "empty 'domain' query parameter" + return nil, &res } - hfile, found := srv.env.HostsFiles[hostsFileName] + hfile, found = srv.env.HostsFiles[hostsFileName] if !found { res.Message = "unknown hosts file name: " + hostsFileName - return nil, res - } - - domainName := epr.HttpRequest.Form.Get(paramNameDomain) - if len(domainName) == 0 { - res.Message = "empty 'domain' query parameter" - return nil, res + return nil, &res } found = hfile.RemoveRecord(domainName) if !found { res.Message = "unknown domain name: " + domainName - return nil, res + return nil, &res } err = hfile.Save() if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } srv.dns.RemoveLocalCachesByNames([]string{domainName}) @@ -663,113 +696,135 @@ func (srv *Server) apiHostsFileRRDelete(epr *libhttp.EndpointRequest) (resbody [ res.Code = http.StatusOK res.Message = "domain name '" + domainName + "' has been removed from hosts file" - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiZoneCreate(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + zoneName = epr.HttpRequest.Form.Get(paramNameName) + + zone *dns.Zone + zoneFile string + ) + res.Code = http.StatusBadRequest - zoneName := epr.HttpRequest.Form.Get(paramNameName) if len(zoneName) == 0 { res.Message = "empty or invalid zone file name" - return nil, res + return nil, &res } if !libnet.IsHostnameValid([]byte(zoneName), true) { res.Message = "zone file name must be valid hostname" - return nil, res + return nil, &res } - mf, ok := srv.env.Zones[zoneName] - if ok { + zone = srv.env.Zones[zoneName] + if zone != nil { res.Code = http.StatusOK - res.Data = mf - return json.Marshal(res) + res.Data = zone + return json.Marshal(&res) } - zoneFile := filepath.Join(dirZone, zoneName) - mf = dns.NewZone(zoneFile, zoneName) - err = mf.Save() + zoneFile = filepath.Join(dirZone, zoneName) + zone = dns.NewZone(zoneFile, zoneName) + err = zone.Save() if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } - srv.env.Zones[zoneName] = mf + srv.env.Zones[zoneName] = zone res.Code = http.StatusOK - res.Data = mf + res.Data = zone - return json.Marshal(res) + return json.Marshal(&res) } func (srv *Server) apiZoneDelete(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + zoneName = epr.HttpRequest.Form.Get(paramNameName) + + zone *dns.Zone + names []string + name string + ) + res.Code = http.StatusBadRequest - zoneName := epr.HttpRequest.Form.Get(paramNameName) if len(zoneName) == 0 { res.Message = "empty or invalid zone file name" - return nil, res + return nil, &res } - mf, ok := srv.env.Zones[zoneName] - if !ok { - res.Message = "unknown zone file name " + zoneName - return nil, res + zone = srv.env.Zones[zoneName] + if zone == nil { + res.Message = "zone file not found: " + zoneName + return nil, &res } - names := make([]string, 0, len(mf.Records)) - for name := range mf.Records { + names = make([]string, 0, len(zone.Records)) + for name = range zone.Records { names = append(names, name) } srv.dns.RemoveLocalCachesByNames(names) delete(srv.env.Zones, zoneName) - err = mf.Delete() + err = zone.Delete() if err != nil { res.Code = http.StatusInternalServerError res.Message = err.Error() - return nil, res + return nil, &res } res.Code = http.StatusOK res.Message = zoneName + " has been deleted" - return json.Marshal(res) + return json.Marshal(&res) } // // apiZoneRRCreate create new RR for the zone file. // func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + zoneFileName = epr.HttpRequest.Form.Get(paramNameName) + rrTypeValue = epr.HttpRequest.Form.Get(paramNameType) + + zoneFile *dns.Zone + rr *dns.ResourceRecord + v string + listRR []*dns.ResourceRecord + rrType int + ) + res.Code = http.StatusBadRequest - zoneFileName := epr.HttpRequest.Form.Get(paramNameName) if len(zoneFileName) == 0 { res.Message = "empty or invalid zone file name" - return nil, res + return nil, &res } - zoneFile := srv.env.Zones[zoneFileName] + zoneFile = srv.env.Zones[zoneFileName] if zoneFile == nil { res.Message = "unknown zone file name " + zoneFileName - return nil, res + return nil, &res } - rrTypeValue := epr.HttpRequest.Form.Get(paramNameType) - rrType, err := strconv.Atoi(rrTypeValue) + rrType, err = strconv.Atoi(rrTypeValue) if err != nil { res.Message = fmt.Sprintf("invalid or empty RR type %q: %s", rrTypeValue, err.Error()) - return nil, res + return nil, &res } - rr := &dns.ResourceRecord{} + rr = &dns.ResourceRecord{} switch dns.RecordType(rrType) { case dns.RecordTypeSOA: rr.Value = &dns.RDataSOA{} @@ -779,7 +834,7 @@ func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte err = json.Unmarshal(epr.RequestBody, rr) if err != nil { res.Message = "json.Unmarshal:" + err.Error() - return nil, res + return nil, &res } rr.Name = strings.TrimRight(rr.Name, ".") @@ -787,9 +842,9 @@ func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte if rr.Type == dns.RecordTypePTR { if len(rr.Name) == 0 { res.Message = "empty PTR name" - return nil, res + return nil, &res } - v := rr.Value.(string) + v = rr.Value.(string) if len(v) == 0 { rr.Value = zoneFileName } else { @@ -803,12 +858,12 @@ func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte } } - listRR := []*dns.ResourceRecord{rr} + listRR = []*dns.ResourceRecord{rr} err = srv.dns.PopulateCachesByRR(listRR, zoneFile.Path) if err != nil { res.Code = http.StatusBadRequest res.Message = "PopulateCacheByRR: " + err.Error() - return nil, res + return nil, &res } // Update the Zone file. @@ -816,7 +871,7 @@ func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte err = zoneFile.Save() if err != nil { res.Message = err.Error() - return nil, res + return nil, &res } res.Code = http.StatusOK @@ -827,37 +882,43 @@ func (srv *Server) apiZoneRRCreate(epr *libhttp.EndpointRequest) (resbody []byte res.Data = zoneFile.Records } - return json.Marshal(res) + return json.Marshal(&res) } // // apiZoneRRDelete delete RR from the zone file. // func (srv *Server) apiZoneRRDelete(epr *libhttp.EndpointRequest) (resbody []byte, err error) { - res := &response{} + var ( + res = libhttp.EndpointResponse{} + zoneFileName = epr.HttpRequest.Form.Get(paramNameName) + paramType = epr.HttpRequest.Form.Get(paramNameType) + rr = dns.ResourceRecord{} + + zone *dns.Zone + rrType int + ) + res.Code = http.StatusBadRequest - zoneFileName := epr.HttpRequest.Form.Get(paramNameName) if len(zoneFileName) == 0 { res.Message = "empty zone file name" - return nil, res + return nil, &res } - mf := srv.env.Zones[zoneFileName] - if mf == nil { + zone = srv.env.Zones[zoneFileName] + if zone == nil { res.Message = "unknown zone file name " + zoneFileName - return nil, res + return nil, &res } - v := epr.HttpRequest.Form.Get(paramNameType) - rrType, err := strconv.Atoi(v) + rrType, err = strconv.Atoi(paramType) if err != nil { res.Message = fmt.Sprintf("invalid or empty param type %s: %s", paramNameType, err) - return nil, res + return nil, &res } - rr := dns.ResourceRecord{} switch dns.RecordType(rrType) { case dns.RecordTypeSOA: rr.Value = &dns.RDataSOA{} @@ -867,32 +928,31 @@ func (srv *Server) apiZoneRRDelete(epr *libhttp.EndpointRequest) (resbody []byte err = json.Unmarshal(epr.RequestBody, &rr) if err != nil { res.Message = "json.Unmarshal:" + err.Error() - return nil, res + return nil, &res } if len(rr.Name) == 0 { res.Message = "invalid or empty ResourceRecord.Name" - return nil, res + return nil, &res } // Remove the RR from caches. err = srv.dns.RemoveCachesByRR(&rr) if err != nil { res.Message = err.Error() - return nil, res + return nil, &res } // Remove the RR from zone file. - err = mf.Remove(&rr) + err = zone.Remove(&rr) if err != nil { res.Message = err.Error() - return nil, res + return nil, &res } res.Code = http.StatusOK - res.Message = fmt.Sprintf("The RR type %d and name %s has been deleted", - rr.Type, rr.Name) - res.Data = mf.Records + res.Message = fmt.Sprintf("The RR type %d and name %s has been deleted", rr.Type, rr.Name) + res.Data = zone.Records - return json.Marshal(res) + return json.Marshal(&res) } |
