wip - add JSON response for web-ip

This commit is contained in:
DataHearth 2022-09-02 21:40:23 +02:00
parent c5c69099dd
commit 8415836cb0
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
3 changed files with 64 additions and 11 deletions

View File

@ -15,6 +15,7 @@ type Provider interface {
UpdateSubdomains(ip string) error
updateSubdomain(subdomain, ip string) error
retrieveSubdomainIP(addr string) (string, error)
checkResponse(body []byte, tokenBased bool, ip string) error
}
type provider struct {
@ -96,7 +97,7 @@ func (p *provider) updateSubdomain(subdomain, ip string) error {
req, err := http.NewRequest("GET", newURL, nil)
if err != nil {
return utils.ErrCreateNewRequest
return fmt.Errorf("%v: %v", utils.ErrCreateNewRequest, err)
}
if !tokenBased {
req.SetBasicAuth(p.config.Username, p.config.Password)
@ -134,14 +135,14 @@ func (p *provider) retrieveSubdomainIP(addr string) (string, error) {
}
if len(ips) != 1 {
return "", utils.ErrIpLenght
return "", fmt.Errorf("%v: %v", utils.ErrIpLenght, ips)
}
ip := ips[0].String()
if strings.Contains(ip, ":") {
ip, _, err = net.SplitHostPort(ip)
if err != nil {
return "", utils.ErrSplitAddr
return "", fmt.Errorf("%v: %v", utils.ErrSplitAddr, ip)
}
}

View File

@ -13,7 +13,7 @@ var (
// ErrGetServerIP is thrown when HTTP can't contact the web-ip service
ErrGetServerIP = errors.New("HTTP error")
// ErrParseHTTPBody is thrown when the HTTP service can't parse the body response
ErrParseHTTPBody = errors.New("can't parse response body")
ErrParseHTTPBody = errors.New("can't read response body")
// ErrSplitAddr is thrown when the remote address can't be splitted
ErrSplitAddr = errors.New("can't split subdomain remote IP address")
// ErrCreateNewRequest is thrown when http request creation failed

View File

@ -1,8 +1,12 @@
package watcher
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/datahearth/ddnsclient/pkg/provider"
@ -102,18 +106,66 @@ func (w *watcher) runDDNSCheck() error {
}
func (w *watcher) retrieveServerIP() (string, error) {
resp, err := http.Get(w.webIP)
rsp, err := http.Get(w.webIP)
if err != nil {
return "", utils.ErrGetServerIP
return "", fmt.Errorf("%v: %v", utils.ErrGetServerIP, err)
}
if resp.StatusCode != 200 {
return "", utils.ErrWrongStatusCode
if rsp.StatusCode != 200 {
return "", fmt.Errorf("%v: %v", utils.ErrWrongStatusCode, rsp.Status)
}
d, err := ioutil.ReadAll(resp.Body)
b, err := ioutil.ReadAll(rsp.Body)
if err != nil {
return "", utils.ErrParseHTTPBody
return "", fmt.Errorf("%v: %v", utils.ErrParseHTTPBody, err)
}
return string(d), nil
var ip string
if rsp.Header.Get("content-type") == "application/json" {
body := make(map[string]interface{})
if err := json.Unmarshal(b, &body); err != nil {
return "", fmt.Errorf("failed to unmarshal JSON body: %v", err)
}
if v, ok := body["ip"]; ok {
if v, ok := v.(string); ok {
ip = v
} else {
return "", fmt.Errorf("\"ip\" field found in JSON response but is not a string value")
}
} else {
for _, v := range body {
if v, ok := v.(string); ok {
if parsedIP := net.ParseIP(v); parsedIP != nil {
ip = parsedIP.String()
}
}
}
if ip == "" {
return "", fmt.Errorf("no field found with a valid IPv4 address in JSON response")
}
}
} else {
body := string(b)
if strings.Count(body, "\n") > 0 {
for _, l := range strings.Split(body, "\n") {
if parsedIP := net.ParseIP(l); parsedIP != nil {
ip = parsedIP.String()
break
}
}
if ip == "" {
return "", fmt.Errorf("no field found with a valid IPv4 address in body response")
}
} else {
if body == "" {
return "", fmt.Errorf("body is empty")
}
ip = body
}
}
return ip, nil
}